~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

Viewing changes to plugin/innobase/srv/srv0start.c

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
 
4
Copyright (c) 2008, Google Inc.
 
5
 
 
6
Portions of this file contain modifications contributed and copyrighted by
 
7
Google, Inc. Those modifications are gratefully acknowledged and are described
 
8
briefly in the InnoDB documentation. The contributions by Google are
 
9
incorporated with their permission, and subject to the conditions contained in
 
10
the file COPYING.Google.
 
11
 
 
12
This program is free software; you can redistribute it and/or modify it under
 
13
the terms of the GNU General Public License as published by the Free Software
 
14
Foundation; version 2 of the License.
 
15
 
 
16
This program is distributed in the hope that it will be useful, but WITHOUT
 
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
19
 
 
20
You should have received a copy of the GNU General Public License along with
 
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
22
Place, Suite 330, Boston, MA 02111-1307 USA
 
23
 
 
24
*****************************************************************************/
 
25
/***********************************************************************
 
26
 
 
27
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
28
Copyright (c) 2009, Percona Inc.
 
29
 
 
30
Portions of this file contain modifications contributed and copyrighted
 
31
by Percona Inc.. Those modifications are
 
32
gratefully acknowledged and are described briefly in the InnoDB
 
33
documentation. The contributions by Percona Inc. are incorporated with
 
34
their permission, and subject to the conditions contained in the file
 
35
COPYING.Percona.
 
36
 
 
37
This program is free software; you can redistribute it and/or modify it
 
38
under the terms of the GNU General Public License as published by the
 
39
Free Software Foundation; version 2 of the License.
 
40
 
 
41
This program is distributed in the hope that it will be useful, but
 
42
WITHOUT ANY WARRANTY; without even the implied warranty of
 
43
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 
44
Public License for more details.
 
45
 
 
46
You should have received a copy of the GNU General Public License along
 
47
with this program; if not, write to the Free Software Foundation, Inc.,
 
48
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
49
 
 
50
***********************************************************************/
 
51
 
 
52
/********************************************************************//**
 
53
@file srv/srv0start.c
 
54
Starts the InnoDB database server
 
55
 
 
56
Created 2/16/1996 Heikki Tuuri
 
57
*************************************************************************/
 
58
 
 
59
#include "ut0mem.h"
 
60
#include "mem0mem.h"
 
61
#include "data0data.h"
 
62
#include "data0type.h"
 
63
#include "dict0dict.h"
 
64
#include "buf0buf.h"
 
65
#include "os0file.h"
 
66
#include "os0thread.h"
 
67
#include "fil0fil.h"
 
68
#include "fsp0fsp.h"
 
69
#include "rem0rec.h"
 
70
#include "mtr0mtr.h"
 
71
#include "log0log.h"
 
72
#include "log0recv.h"
 
73
#include "page0page.h"
 
74
#include "page0cur.h"
 
75
#include "trx0trx.h"
 
76
#include "trx0sys.h"
 
77
#include "btr0btr.h"
 
78
#include "btr0cur.h"
 
79
#include "rem0rec.h"
 
80
#include "ibuf0ibuf.h"
 
81
#include "srv0start.h"
 
82
#include "srv0srv.h"
 
83
#ifndef UNIV_HOTBACKUP
 
84
# include "os0proc.h"
 
85
# include "sync0sync.h"
 
86
# include "buf0flu.h"
 
87
# include "buf0rea.h"
 
88
# include "dict0boot.h"
 
89
# include "dict0load.h"
 
90
# include "que0que.h"
 
91
# include "usr0sess.h"
 
92
# include "lock0lock.h"
 
93
# include "trx0roll.h"
 
94
# include "trx0purge.h"
 
95
# include "lock0lock.h"
 
96
# include "pars0pars.h"
 
97
# include "btr0sea.h"
 
98
# include "rem0cmp.h"
 
99
# include "dict0crea.h"
 
100
# include "row0ins.h"
 
101
# include "row0sel.h"
 
102
# include "row0upd.h"
 
103
# include "row0row.h"
 
104
# include "row0mysql.h"
 
105
# include "btr0pcur.h"
 
106
 
 
107
#include <errno.h>
 
108
#include <unistd.h>
 
109
 
 
110
/** Log sequence number immediately after startup */
 
111
UNIV_INTERN ib_uint64_t srv_start_lsn;
 
112
/** Log sequence number at shutdown */
 
113
UNIV_INTERN ib_uint64_t srv_shutdown_lsn;
 
114
 
 
115
#ifdef HAVE_DARWIN_THREADS
 
116
# include <sys/utsname.h>
 
117
/** TRUE if the F_FULLFSYNC option is available */
 
118
UNIV_INTERN ibool       srv_have_fullfsync = FALSE;
 
119
#endif
 
120
 
 
121
/** TRUE if a raw partition is in use */
 
122
UNIV_INTERN ibool       srv_start_raw_disk_in_use = FALSE;
 
123
 
 
124
/** TRUE if the server is being started, before rolling back any
 
125
incomplete transactions */
 
126
UNIV_INTERN ibool       srv_startup_is_before_trx_rollback_phase = FALSE;
 
127
/** TRUE if the server is being started */
 
128
UNIV_INTERN ibool       srv_is_being_started = FALSE;
 
129
/** TRUE if the server was successfully started */
 
130
UNIV_INTERN ibool       srv_was_started = FALSE;
 
131
/** TRUE if innobase_start_or_create_for_mysql() has been called */
 
132
static ibool    srv_start_has_been_called = FALSE;
 
133
 
 
134
/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
 
135
SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
 
136
UNIV_INTERN enum srv_shutdown_state     srv_shutdown_state = SRV_SHUTDOWN_NONE;
 
137
 
 
138
/** Files comprising the system tablespace */
 
139
static os_file_t        files[1000];
 
140
 
 
141
/** Mutex protecting the ios count */
 
142
static mutex_t          ios_mutex;
 
143
/** Count of I/O operations in io_handler_thread() */
 
144
static ulint            ios;
 
145
 
 
146
/** io_handler_thread parameters for thread identification */
 
147
static ulint            n[SRV_MAX_N_IO_THREADS + 5];
 
148
/** io_handler_thread identifiers */
 
149
static os_thread_id_t   thread_ids[SRV_MAX_N_IO_THREADS + 5];
 
150
 
 
151
/** We use this mutex to test the return value of pthread_mutex_trylock
 
152
   on successful locking. HP-UX does NOT return 0, though Linux et al do. */
 
153
static os_fast_mutex_t  srv_os_test_mutex;
 
154
 
 
155
/** Name of srv_monitor_file */
 
156
static char*    srv_monitor_file_name;
 
157
#endif /* !UNIV_HOTBACKUP */
 
158
 
 
159
/** */
 
160
#define SRV_N_PENDING_IOS_PER_THREAD    OS_AIO_N_PENDING_IOS_PER_THREAD
 
161
#define SRV_MAX_N_PENDING_SYNC_IOS      100
 
162
 
 
163
 
 
164
/*********************************************************************//**
 
165
Convert a numeric string that optionally ends in G or M, to a number
 
166
containing megabytes.
 
167
@return next character in string */
 
168
static
 
169
char*
 
170
srv_parse_megabytes(
 
171
/*================*/
 
172
        char*   str,    /*!< in: string containing a quantity in bytes */
 
173
        ulint*  megs)   /*!< out: the number in megabytes */
 
174
{
 
175
        char*   endp;
 
176
        ulint   size;
 
177
 
 
178
        size = strtoul(str, &endp, 10);
 
179
 
 
180
        str = endp;
 
181
 
 
182
        switch (*str) {
 
183
        case 'G': case 'g':
 
184
                size *= 1024;
 
185
                /* fall through */
 
186
        case 'M': case 'm':
 
187
                str++;
 
188
                break;
 
189
        default:
 
190
                size /= 1024 * 1024;
 
191
                break;
 
192
        }
 
193
 
 
194
        *megs = size;
 
195
        return(str);
 
196
}
 
197
 
 
198
/*********************************************************************//**
 
199
Reads the data files and their sizes from a character string given in
 
200
the .cnf file.
 
201
@return TRUE if ok, FALSE on parse error */
 
202
UNIV_INTERN
 
203
ibool
 
204
srv_parse_data_file_paths_and_sizes(
 
205
/*================================*/
 
206
        char*   str)    /*!< in/out: the data file path string */
 
207
{
 
208
        char*   input_str;
 
209
        char*   path;
 
210
        ulint   size;
 
211
        ulint   i       = 0;
 
212
 
 
213
        srv_auto_extend_last_data_file = FALSE;
 
214
        srv_last_file_size_max = 0;
 
215
        srv_data_file_names = NULL;
 
216
        srv_data_file_sizes = NULL;
 
217
        srv_data_file_is_raw_partition = NULL;
 
218
 
 
219
        input_str = str;
 
220
 
 
221
        /* First calculate the number of data files and check syntax:
 
222
        path:size[M | G];path:size[M | G]... . Note that a Windows path may
 
223
        contain a drive name and a ':'. */
 
224
 
 
225
        while (*str != '\0') {
 
226
                path = str;
 
227
 
 
228
                while ((*str != ':' && *str != '\0')
 
229
                       || (*str == ':'
 
230
                           && (*(str + 1) == '\\' || *(str + 1) == '/'
 
231
                               || *(str + 1) == ':'))) {
 
232
                        str++;
 
233
                }
 
234
 
 
235
                if (*str == '\0') {
 
236
                        return(FALSE);
 
237
                }
 
238
 
 
239
                str++;
 
240
 
 
241
                str = srv_parse_megabytes(str, &size);
 
242
 
 
243
                if (0 == strncmp(str, ":autoextend",
 
244
                                 (sizeof ":autoextend") - 1)) {
 
245
 
 
246
                        str += (sizeof ":autoextend") - 1;
 
247
 
 
248
                        if (0 == strncmp(str, ":max:",
 
249
                                         (sizeof ":max:") - 1)) {
 
250
 
 
251
                                str += (sizeof ":max:") - 1;
 
252
 
 
253
                                str = srv_parse_megabytes(str, &size);
 
254
                        }
 
255
 
 
256
                        if (*str != '\0') {
 
257
 
 
258
                                return(FALSE);
 
259
                        }
 
260
                }
 
261
 
 
262
                if (strlen(str) >= 6
 
263
                    && *str == 'n'
 
264
                    && *(str + 1) == 'e'
 
265
                    && *(str + 2) == 'w') {
 
266
                        str += 3;
 
267
                }
 
268
 
 
269
                if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') {
 
270
                        str += 3;
 
271
                }
 
272
 
 
273
                if (size == 0) {
 
274
                        return(FALSE);
 
275
                }
 
276
 
 
277
                i++;
 
278
 
 
279
                if (*str == ';') {
 
280
                        str++;
 
281
                } else if (*str != '\0') {
 
282
 
 
283
                        return(FALSE);
 
284
                }
 
285
        }
 
286
 
 
287
        if (i == 0) {
 
288
                /* If innodb_data_file_path was defined it must contain
 
289
                at least one data file definition */
 
290
 
 
291
                return(FALSE);
 
292
        }
 
293
 
 
294
        srv_data_file_names = malloc(i * sizeof *srv_data_file_names);
 
295
        srv_data_file_sizes = malloc(i * sizeof *srv_data_file_sizes);
 
296
        srv_data_file_is_raw_partition = malloc(
 
297
                i * sizeof *srv_data_file_is_raw_partition);
 
298
 
 
299
        srv_n_data_files = i;
 
300
 
 
301
        /* Then store the actual values to our arrays */
 
302
 
 
303
        str = input_str;
 
304
        i = 0;
 
305
 
 
306
        while (*str != '\0') {
 
307
                path = str;
 
308
 
 
309
                /* Note that we must step over the ':' in a Windows path;
 
310
                a Windows path normally looks like C:\ibdata\ibdata1:1G, but
 
311
                a Windows raw partition may have a specification like
 
312
                \\.\C::1Gnewraw or \\.\PHYSICALDRIVE2:1Gnewraw */
 
313
 
 
314
                while ((*str != ':' && *str != '\0')
 
315
                       || (*str == ':'
 
316
                           && (*(str + 1) == '\\' || *(str + 1) == '/'
 
317
                               || *(str + 1) == ':'))) {
 
318
                        str++;
 
319
                }
 
320
 
 
321
                if (*str == ':') {
 
322
                        /* Make path a null-terminated string */
 
323
                        *str = '\0';
 
324
                        str++;
 
325
                }
 
326
 
 
327
                str = srv_parse_megabytes(str, &size);
 
328
 
 
329
                srv_data_file_names[i] = path;
 
330
                srv_data_file_sizes[i] = size;
 
331
 
 
332
                if (0 == strncmp(str, ":autoextend",
 
333
                                 (sizeof ":autoextend") - 1)) {
 
334
 
 
335
                        srv_auto_extend_last_data_file = TRUE;
 
336
 
 
337
                        str += (sizeof ":autoextend") - 1;
 
338
 
 
339
                        if (0 == strncmp(str, ":max:",
 
340
                                         (sizeof ":max:") - 1)) {
 
341
 
 
342
                                str += (sizeof ":max:") - 1;
 
343
 
 
344
                                str = srv_parse_megabytes(
 
345
                                        str, &srv_last_file_size_max);
 
346
                        }
 
347
 
 
348
                        if (*str != '\0') {
 
349
 
 
350
                                return(FALSE);
 
351
                        }
 
352
                }
 
353
 
 
354
                (srv_data_file_is_raw_partition)[i] = 0;
 
355
 
 
356
                if (strlen(str) >= 6
 
357
                    && *str == 'n'
 
358
                    && *(str + 1) == 'e'
 
359
                    && *(str + 2) == 'w') {
 
360
                        str += 3;
 
361
                        (srv_data_file_is_raw_partition)[i] = SRV_NEW_RAW;
 
362
                }
 
363
 
 
364
                if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') {
 
365
                        str += 3;
 
366
 
 
367
                        if ((srv_data_file_is_raw_partition)[i] == 0) {
 
368
                                (srv_data_file_is_raw_partition)[i] = SRV_OLD_RAW;
 
369
                        }
 
370
                }
 
371
 
 
372
                i++;
 
373
 
 
374
                if (*str == ';') {
 
375
                        str++;
 
376
                }
 
377
        }
 
378
 
 
379
        return(TRUE);
 
380
}
 
381
 
 
382
/*********************************************************************//**
 
383
Reads log group home directories from a character string given in
 
384
the .cnf file.
 
385
@return TRUE if ok, FALSE on parse error */
 
386
UNIV_INTERN
 
387
ibool
 
388
srv_parse_log_group_home_dirs(
 
389
/*==========================*/
 
390
        char*   str)    /*!< in/out: character string */
 
391
{
 
392
        char*   input_str;
 
393
        char*   path;
 
394
        ulint   i       = 0;
 
395
 
 
396
        srv_log_group_home_dirs = NULL;
 
397
 
 
398
        input_str = str;
 
399
 
 
400
        /* First calculate the number of directories and check syntax:
 
401
        path;path;... */
 
402
 
 
403
        while (*str != '\0') {
 
404
                path = str;
 
405
 
 
406
                while (*str != ';' && *str != '\0') {
 
407
                        str++;
 
408
                }
 
409
 
 
410
                i++;
 
411
 
 
412
                if (*str == ';') {
 
413
                        str++;
 
414
                } else if (*str != '\0') {
 
415
 
 
416
                        return(FALSE);
 
417
                }
 
418
        }
 
419
 
 
420
        if (i != 1) {
 
421
                /* If innodb_log_group_home_dir was defined it must
 
422
                contain exactly one path definition under current MySQL */
 
423
 
 
424
                return(FALSE);
 
425
        }
 
426
 
 
427
        srv_log_group_home_dirs = malloc(i * sizeof *srv_log_group_home_dirs);
 
428
 
 
429
        /* Then store the actual values to our array */
 
430
 
 
431
        str = input_str;
 
432
        i = 0;
 
433
 
 
434
        while (*str != '\0') {
 
435
                path = str;
 
436
 
 
437
                while (*str != ';' && *str != '\0') {
 
438
                        str++;
 
439
                }
 
440
 
 
441
                if (*str == ';') {
 
442
                        *str = '\0';
 
443
                        str++;
 
444
                }
 
445
 
 
446
                srv_log_group_home_dirs[i] = path;
 
447
 
 
448
                i++;
 
449
        }
 
450
 
 
451
        return(TRUE);
 
452
}
 
453
 
 
454
/*********************************************************************//**
 
455
Frees the memory allocated by srv_parse_data_file_paths_and_sizes()
 
456
and srv_parse_log_group_home_dirs(). */
 
457
UNIV_INTERN
 
458
void
 
459
srv_free_paths_and_sizes(void)
 
460
/*==========================*/
 
461
{
 
462
        free(srv_data_file_names);
 
463
        srv_data_file_names = NULL;
 
464
        free(srv_data_file_sizes);
 
465
        srv_data_file_sizes = NULL;
 
466
        free(srv_data_file_is_raw_partition);
 
467
        srv_data_file_is_raw_partition = NULL;
 
468
        free(srv_log_group_home_dirs);
 
469
        srv_log_group_home_dirs = NULL;
 
470
}
 
471
 
 
472
#ifndef UNIV_HOTBACKUP
 
473
/********************************************************************//**
 
474
I/o-handler thread function.
 
475
@return OS_THREAD_DUMMY_RETURN */
 
476
static
 
477
os_thread_ret_t
 
478
io_handler_thread(
 
479
/*==============*/
 
480
        void*   arg)    /*!< in: pointer to the number of the segment in
 
481
                        the aio array */
 
482
{
 
483
        ulint   segment;
 
484
        ulint   i;
 
485
 
 
486
        segment = *((ulint*)arg);
 
487
 
 
488
#ifdef UNIV_DEBUG_THREAD_CREATION
 
489
        fprintf(stderr, "Io handler thread %lu starts, id %lu\n", segment,
 
490
                os_thread_pf(os_thread_get_curr_id()));
 
491
#endif
 
492
        for (i = 0;; i++) {
 
493
                fil_aio_wait(segment);
 
494
 
 
495
                mutex_enter(&ios_mutex);
 
496
                ios++;
 
497
                mutex_exit(&ios_mutex);
 
498
        }
 
499
 
 
500
        /* We count the number of threads in os_thread_exit(). A created
 
501
        thread should always use that to exit and not use return() to exit.
 
502
        The thread actually never comes here because it is exited in an
 
503
        os_event_wait(). */
 
504
#if (!defined(__SUNPRO_C) && !defined(__SUNPRO_CC))
 
505
        return 0;
 
506
#endif
 
507
}
 
508
#endif /* !UNIV_HOTBACKUP */
 
509
 
 
510
#ifdef __WIN__
 
511
#define SRV_PATH_SEPARATOR      '\\'
 
512
#else
 
513
#define SRV_PATH_SEPARATOR      '/'
 
514
#endif
 
515
 
 
516
/*********************************************************************//**
 
517
Normalizes a directory path for Windows: converts slashes to backslashes. */
 
518
UNIV_INTERN
 
519
void
 
520
srv_normalize_path_for_win(
 
521
/*=======================*/
 
522
        char*   str __attribute__((unused)))    /*!< in/out: null-terminated
 
523
                                                character string */
 
524
{
 
525
#ifdef __WIN__
 
526
        for (; *str; str++) {
 
527
 
 
528
                if (*str == '/') {
 
529
                        *str = '\\';
 
530
                }
 
531
        }
 
532
#endif
 
533
}
 
534
 
 
535
/*********************************************************************//**
 
536
Adds a slash or a backslash to the end of a string if it is missing
 
537
and the string is not empty.
 
538
@return string which has the separator if the string is not empty */
 
539
UNIV_INTERN
 
540
char*
 
541
srv_add_path_separator_if_needed(
 
542
/*=============================*/
 
543
        char*   str)    /*!< in: null-terminated character string */
 
544
{
 
545
        char*   out_str;
 
546
        ulint   len     = ut_strlen(str);
 
547
 
 
548
        if (len == 0 || str[len - 1] == SRV_PATH_SEPARATOR) {
 
549
 
 
550
                return(str);
 
551
        }
 
552
 
 
553
        out_str = ut_malloc(len + 2);
 
554
        memcpy(out_str, str, len);
 
555
        out_str[len] = SRV_PATH_SEPARATOR;
 
556
        out_str[len + 1] = 0;
 
557
 
 
558
        return(out_str);
 
559
}
 
560
 
 
561
#ifndef UNIV_HOTBACKUP
 
562
/*********************************************************************//**
 
563
Calculates the low 32 bits when a file size which is given as a number
 
564
database pages is converted to the number of bytes.
 
565
@return low 32 bytes of file size when expressed in bytes */
 
566
static
 
567
ulint
 
568
srv_calc_low32(
 
569
/*===========*/
 
570
        ulint   file_size)      /*!< in: file size in database pages */
 
571
{
 
572
        return(0xFFFFFFFFUL & (file_size << UNIV_PAGE_SIZE_SHIFT));
 
573
}
 
574
 
 
575
/*********************************************************************//**
 
576
Calculates the high 32 bits when a file size which is given as a number
 
577
database pages is converted to the number of bytes.
 
578
@return high 32 bytes of file size when expressed in bytes */
 
579
static
 
580
ulint
 
581
srv_calc_high32(
 
582
/*============*/
 
583
        ulint   file_size)      /*!< in: file size in database pages */
 
584
{
 
585
        return(file_size >> (32 - UNIV_PAGE_SIZE_SHIFT));
 
586
}
 
587
 
 
588
/*********************************************************************//**
 
589
Creates or opens the log files and closes them.
 
590
@return DB_SUCCESS or error code */
 
591
static
 
592
ulint
 
593
open_or_create_log_file(
 
594
/*====================*/
 
595
        ibool   create_new_db,          /*!< in: TRUE if we should create a
 
596
                                        new database */
 
597
        ibool*  log_file_created,       /*!< out: TRUE if new log file
 
598
                                        created */
 
599
        ibool   log_file_has_been_opened,/*!< in: TRUE if a log file has been
 
600
                                        opened before: then it is an error
 
601
                                        to try to create another log file */
 
602
        ulint   k,                      /*!< in: log group number */
 
603
        ulint   i)                      /*!< in: log file number in group */
 
604
{
 
605
        ibool   ret;
 
606
        ulint   size;
 
607
        ulint   size_high;
 
608
        char    name[10000];
 
609
 
 
610
        UT_NOT_USED(create_new_db);
 
611
 
 
612
        *log_file_created = FALSE;
 
613
 
 
614
        srv_normalize_path_for_win(srv_log_group_home_dirs[k]);
 
615
        srv_log_group_home_dirs[k] = srv_add_path_separator_if_needed(
 
616
                srv_log_group_home_dirs[k]);
 
617
 
 
618
        ut_a(strlen(srv_log_group_home_dirs[k])
 
619
             < (sizeof name) - 10 - sizeof "ib_logfile");
 
620
        sprintf(name, "%s%s%lu", srv_log_group_home_dirs[k],
 
621
                "ib_logfile", (ulong) i);
 
622
 
 
623
        files[i] = os_file_create(name, OS_FILE_CREATE, OS_FILE_NORMAL,
 
624
                                  OS_LOG_FILE, &ret);
 
625
        if (ret == FALSE) {
 
626
                if (os_file_get_last_error(FALSE) != OS_FILE_ALREADY_EXISTS
 
627
#ifdef UNIV_AIX
 
628
                    /* AIX 5.1 after security patch ML7 may have errno set
 
629
                    to 0 here, which causes our function to return 100;
 
630
                    work around that AIX problem */
 
631
                    && os_file_get_last_error(FALSE) != 100
 
632
#endif
 
633
                    ) {
 
634
                        fprintf(stderr,
 
635
                                "InnoDB: Error in creating"
 
636
                                " or opening %s\n", name);
 
637
 
 
638
                        return(DB_ERROR);
 
639
                }
 
640
 
 
641
                files[i] = os_file_create(name, OS_FILE_OPEN, OS_FILE_AIO,
 
642
                                          OS_LOG_FILE, &ret);
 
643
                if (!ret) {
 
644
                        fprintf(stderr,
 
645
                                "InnoDB: Error in opening %s\n", name);
 
646
 
 
647
                        return(DB_ERROR);
 
648
                }
 
649
 
 
650
                ret = os_file_get_size(files[i], &size, &size_high);
 
651
                ut_a(ret);
 
652
 
 
653
                if (size != srv_calc_low32(srv_log_file_size)
 
654
                    || size_high != srv_calc_high32(srv_log_file_size)) {
 
655
 
 
656
                        fprintf(stderr,
 
657
                                "InnoDB: Error: log file %s is"
 
658
                                " of different size %lu %lu bytes\n"
 
659
                                "InnoDB: than specified in the .cnf"
 
660
                                " file %lu %lu bytes!\n",
 
661
                                name, (ulong) size_high, (ulong) size,
 
662
                                (ulong) srv_calc_high32(srv_log_file_size),
 
663
                                (ulong) srv_calc_low32(srv_log_file_size));
 
664
 
 
665
                        return(DB_ERROR);
 
666
                }
 
667
        } else {
 
668
                *log_file_created = TRUE;
 
669
 
 
670
                ut_print_timestamp(stderr);
 
671
 
 
672
                fprintf(stderr,
 
673
                        "  InnoDB: Log file %s did not exist:"
 
674
                        " new to be created\n",
 
675
                        name);
 
676
                if (log_file_has_been_opened) {
 
677
 
 
678
                        return(DB_ERROR);
 
679
                }
 
680
 
 
681
                fprintf(stderr, "InnoDB: Setting log file %s size to %lu MB\n",
 
682
                        name, (ulong) srv_log_file_size
 
683
                        >> (20 - UNIV_PAGE_SIZE_SHIFT));
 
684
 
 
685
                fprintf(stderr,
 
686
                        "InnoDB: Database physically writes the file"
 
687
                        " full: wait...\n");
 
688
 
 
689
                ret = os_file_set_size(name, files[i],
 
690
                                       srv_calc_low32(srv_log_file_size),
 
691
                                       srv_calc_high32(srv_log_file_size));
 
692
                if (!ret) {
 
693
                        fprintf(stderr,
 
694
                                "InnoDB: Error in creating %s:"
 
695
                                " probably out of disk space\n",
 
696
                                name);
 
697
 
 
698
                        return(DB_ERROR);
 
699
                }
 
700
        }
 
701
 
 
702
        ret = os_file_close(files[i]);
 
703
        ut_a(ret);
 
704
 
 
705
        if (i == 0) {
 
706
                /* Create in memory the file space object
 
707
                which is for this log group */
 
708
 
 
709
                fil_space_create(name,
 
710
                                 2 * k + SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG);
 
711
        }
 
712
 
 
713
        ut_a(fil_validate());
 
714
 
 
715
        fil_node_create(name, srv_log_file_size,
 
716
                        2 * k + SRV_LOG_SPACE_FIRST_ID, FALSE);
 
717
#ifdef UNIV_LOG_ARCHIVE
 
718
        /* If this is the first log group, create the file space object
 
719
        for archived logs.
 
720
        Under MySQL, no archiving ever done. */
 
721
 
 
722
        if (k == 0 && i == 0) {
 
723
                arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID;
 
724
 
 
725
                fil_space_create("arch_log_space", arch_space_id, 0, FIL_LOG);
 
726
        } else {
 
727
                arch_space_id = ULINT_UNDEFINED;
 
728
        }
 
729
#endif /* UNIV_LOG_ARCHIVE */
 
730
        if (i == 0) {
 
731
                log_group_init(k, srv_n_log_files,
 
732
                               srv_log_file_size * UNIV_PAGE_SIZE,
 
733
                               2 * k + SRV_LOG_SPACE_FIRST_ID,
 
734
                               SRV_LOG_SPACE_FIRST_ID + 1); /* dummy arch
 
735
                                                            space id */
 
736
        }
 
737
 
 
738
        return(DB_SUCCESS);
 
739
}
 
740
 
 
741
/*********************************************************************//**
 
742
Creates or opens database data files and closes them.
 
743
@return DB_SUCCESS or error code */
 
744
static
 
745
ulint
 
746
open_or_create_data_files(
 
747
/*======================*/
 
748
        ibool*          create_new_db,  /*!< out: TRUE if new database should be
 
749
                                        created */
 
750
#ifdef UNIV_LOG_ARCHIVE
 
751
        ulint*          min_arch_log_no,/*!< out: min of archived log
 
752
                                        numbers in data files */
 
753
        ulint*          max_arch_log_no,/*!< out: max of archived log
 
754
                                        numbers in data files */
 
755
#endif /* UNIV_LOG_ARCHIVE */
 
756
        ib_uint64_t*    min_flushed_lsn,/*!< out: min of flushed lsn
 
757
                                        values in data files */
 
758
        ib_uint64_t*    max_flushed_lsn,/*!< out: max of flushed lsn
 
759
                                        values in data files */
 
760
        ulint*          sum_of_new_sizes)/*!< out: sum of sizes of the
 
761
                                        new files added */
 
762
{
 
763
        ibool   ret;
 
764
        ulint   i;
 
765
        ibool   one_opened      = FALSE;
 
766
        ibool   one_created     = FALSE;
 
767
        ulint   size;
 
768
        ulint   size_high;
 
769
        ulint   rounded_size_pages;
 
770
        char    name[10000];
 
771
 
 
772
        if (srv_n_data_files >= 1000) {
 
773
                fprintf(stderr, "InnoDB: can only have < 1000 data files\n"
 
774
                        "InnoDB: you have defined %lu\n",
 
775
                        (ulong) srv_n_data_files);
 
776
                return(DB_ERROR);
 
777
        }
 
778
 
 
779
        *sum_of_new_sizes = 0;
 
780
 
 
781
        *create_new_db = FALSE;
 
782
 
 
783
        srv_normalize_path_for_win(srv_data_home);
 
784
        srv_data_home = srv_add_path_separator_if_needed(srv_data_home);
 
785
 
 
786
        for (i = 0; i < srv_n_data_files; i++) {
 
787
                srv_normalize_path_for_win(srv_data_file_names[i]);
 
788
 
 
789
                ut_a(strlen(srv_data_home) + strlen(srv_data_file_names[i])
 
790
                     < (sizeof name) - 1);
 
791
                sprintf(name, "%s%s", srv_data_home, srv_data_file_names[i]);
 
792
 
 
793
                if (srv_data_file_is_raw_partition[i] == 0) {
 
794
 
 
795
                        /* First we try to create the file: if it already
 
796
                        exists, ret will get value FALSE */
 
797
 
 
798
                        files[i] = os_file_create(name, OS_FILE_CREATE,
 
799
                                                  OS_FILE_NORMAL,
 
800
                                                  OS_DATA_FILE, &ret);
 
801
 
 
802
                        if (ret == FALSE && os_file_get_last_error(FALSE)
 
803
                            != OS_FILE_ALREADY_EXISTS
 
804
#ifdef UNIV_AIX
 
805
                            /* AIX 5.1 after security patch ML7 may have
 
806
                            errno set to 0 here, which causes our function
 
807
                            to return 100; work around that AIX problem */
 
808
                            && os_file_get_last_error(FALSE) != 100
 
809
#endif
 
810
                            ) {
 
811
                                fprintf(stderr,
 
812
                                        "InnoDB: Error in creating"
 
813
                                        " or opening %s\n",
 
814
                                        name);
 
815
 
 
816
                                return(DB_ERROR);
 
817
                        }
 
818
                } else if (srv_data_file_is_raw_partition[i] == SRV_NEW_RAW) {
 
819
                        /* The partition is opened, not created; then it is
 
820
                        written over */
 
821
 
 
822
                        srv_start_raw_disk_in_use = TRUE;
 
823
                        srv_created_new_raw = TRUE;
 
824
 
 
825
                        files[i] = os_file_create(name, OS_FILE_OPEN_RAW,
 
826
                                                  OS_FILE_NORMAL,
 
827
                                                  OS_DATA_FILE, &ret);
 
828
                        if (!ret) {
 
829
                                fprintf(stderr,
 
830
                                        "InnoDB: Error in opening %s\n", name);
 
831
 
 
832
                                return(DB_ERROR);
 
833
                        }
 
834
                } else if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
 
835
                        srv_start_raw_disk_in_use = TRUE;
 
836
 
 
837
                        ret = FALSE;
 
838
                } else {
 
839
                        ut_a(0);
 
840
                }
 
841
 
 
842
                if (ret == FALSE) {
 
843
                        /* We open the data file */
 
844
 
 
845
                        if (one_created) {
 
846
                                fprintf(stderr,
 
847
                                        "InnoDB: Error: data files can only"
 
848
                                        " be added at the end\n");
 
849
                                fprintf(stderr,
 
850
                                        "InnoDB: of a tablespace, but"
 
851
                                        " data file %s existed beforehand.\n",
 
852
                                        name);
 
853
                                return(DB_ERROR);
 
854
                        }
 
855
 
 
856
                        if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
 
857
                                files[i] = os_file_create(
 
858
                                        name, OS_FILE_OPEN_RAW,
 
859
                                        OS_FILE_NORMAL, OS_DATA_FILE, &ret);
 
860
                        } else if (i == 0) {
 
861
                                files[i] = os_file_create(
 
862
                                        name, OS_FILE_OPEN_RETRY,
 
863
                                        OS_FILE_NORMAL, OS_DATA_FILE, &ret);
 
864
                        } else {
 
865
                                files[i] = os_file_create(
 
866
                                        name, OS_FILE_OPEN, OS_FILE_NORMAL,
 
867
                                        OS_DATA_FILE, &ret);
 
868
                        }
 
869
 
 
870
                        if (!ret) {
 
871
                                fprintf(stderr,
 
872
                                        "InnoDB: Error in opening %s\n", name);
 
873
                                os_file_get_last_error(TRUE);
 
874
 
 
875
                                return(DB_ERROR);
 
876
                        }
 
877
 
 
878
                        if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
 
879
 
 
880
                                goto skip_size_check;
 
881
                        }
 
882
 
 
883
                        ret = os_file_get_size(files[i], &size, &size_high);
 
884
                        ut_a(ret);
 
885
                        /* Round size downward to megabytes */
 
886
 
 
887
                        rounded_size_pages
 
888
                                = (size / (1024 * 1024) + 4096 * size_high)
 
889
                                        << (20 - UNIV_PAGE_SIZE_SHIFT);
 
890
 
 
891
                        if (i == srv_n_data_files - 1
 
892
                            && srv_auto_extend_last_data_file) {
 
893
 
 
894
                                if (srv_data_file_sizes[i] > rounded_size_pages
 
895
                                    || (srv_last_file_size_max > 0
 
896
                                        && srv_last_file_size_max
 
897
                                        < rounded_size_pages)) {
 
898
 
 
899
                                        fprintf(stderr,
 
900
                                                "InnoDB: Error: auto-extending"
 
901
                                                " data file %s is"
 
902
                                                " of a different size\n"
 
903
                                                "InnoDB: %lu pages (rounded"
 
904
                                                " down to MB) than specified"
 
905
                                                " in the .cnf file:\n"
 
906
                                                "InnoDB: initial %lu pages,"
 
907
                                                " max %lu (relevant if"
 
908
                                                " non-zero) pages!\n",
 
909
                                                name,
 
910
                                                (ulong) rounded_size_pages,
 
911
                                                (ulong) srv_data_file_sizes[i],
 
912
                                                (ulong)
 
913
                                                srv_last_file_size_max);
 
914
 
 
915
                                        return(DB_ERROR);
 
916
                                }
 
917
 
 
918
                                srv_data_file_sizes[i] = rounded_size_pages;
 
919
                        }
 
920
 
 
921
                        if (rounded_size_pages != srv_data_file_sizes[i]) {
 
922
 
 
923
                                fprintf(stderr,
 
924
                                        "InnoDB: Error: data file %s"
 
925
                                        " is of a different size\n"
 
926
                                        "InnoDB: %lu pages"
 
927
                                        " (rounded down to MB)\n"
 
928
                                        "InnoDB: than specified"
 
929
                                        " in the .cnf file %lu pages!\n",
 
930
                                        name,
 
931
                                        (ulong) rounded_size_pages,
 
932
                                        (ulong) srv_data_file_sizes[i]);
 
933
 
 
934
                                return(DB_ERROR);
 
935
                        }
 
936
skip_size_check:
 
937
                        fil_read_flushed_lsn_and_arch_log_no(
 
938
                                files[i], one_opened,
 
939
#ifdef UNIV_LOG_ARCHIVE
 
940
                                min_arch_log_no, max_arch_log_no,
 
941
#endif /* UNIV_LOG_ARCHIVE */
 
942
                                min_flushed_lsn, max_flushed_lsn);
 
943
                        one_opened = TRUE;
 
944
                } else {
 
945
                        /* We created the data file and now write it full of
 
946
                        zeros */
 
947
 
 
948
                        one_created = TRUE;
 
949
 
 
950
                        if (i > 0) {
 
951
                                ut_print_timestamp(stderr);
 
952
                                fprintf(stderr,
 
953
                                        "  InnoDB: Data file %s did not"
 
954
                                        " exist: new to be created\n",
 
955
                                        name);
 
956
                        } else {
 
957
                                fprintf(stderr,
 
958
                                        "InnoDB: The first specified"
 
959
                                        " data file %s did not exist:\n"
 
960
                                        "InnoDB: a new database"
 
961
                                        " to be created!\n", name);
 
962
                                *create_new_db = TRUE;
 
963
                        }
 
964
 
 
965
                        ut_print_timestamp(stderr);
 
966
                        fprintf(stderr,
 
967
                                "  InnoDB: Setting file %s size to %lu MB\n",
 
968
                                name,
 
969
                                (ulong) (srv_data_file_sizes[i]
 
970
                                         >> (20 - UNIV_PAGE_SIZE_SHIFT)));
 
971
 
 
972
                        fprintf(stderr,
 
973
                                "InnoDB: Database physically writes the"
 
974
                                " file full: wait...\n");
 
975
 
 
976
                        ret = os_file_set_size(
 
977
                                name, files[i],
 
978
                                srv_calc_low32(srv_data_file_sizes[i]),
 
979
                                srv_calc_high32(srv_data_file_sizes[i]));
 
980
 
 
981
                        if (!ret) {
 
982
                                fprintf(stderr,
 
983
                                        "InnoDB: Error in creating %s:"
 
984
                                        " probably out of disk space\n", name);
 
985
 
 
986
                                return(DB_ERROR);
 
987
                        }
 
988
 
 
989
                        *sum_of_new_sizes = *sum_of_new_sizes
 
990
                                + srv_data_file_sizes[i];
 
991
                }
 
992
 
 
993
                ret = os_file_close(files[i]);
 
994
                ut_a(ret);
 
995
 
 
996
                if (i == 0) {
 
997
                        fil_space_create(name, 0, 0, FIL_TABLESPACE);
 
998
                }
 
999
 
 
1000
                ut_a(fil_validate());
 
1001
 
 
1002
                fil_node_create(name, srv_data_file_sizes[i], 0,
 
1003
                                srv_data_file_is_raw_partition[i] != 0);
 
1004
        }
 
1005
 
 
1006
        ios = 0;
 
1007
 
 
1008
        mutex_create(&ios_mutex, SYNC_NO_ORDER_CHECK);
 
1009
 
 
1010
        return(DB_SUCCESS);
 
1011
}
 
1012
 
 
1013
/****************************************************************//**
 
1014
Starts InnoDB and creates a new database if database files
 
1015
are not found and the user wants.
 
1016
@return DB_SUCCESS or error code */
 
1017
UNIV_INTERN
 
1018
int
 
1019
innobase_start_or_create_for_mysql(void)
 
1020
/*====================================*/
 
1021
{
 
1022
        buf_pool_t*     ret;
 
1023
        ibool           create_new_db;
 
1024
        ibool           log_file_created;
 
1025
        ibool           log_created     = FALSE;
 
1026
        ibool           log_opened      = FALSE;
 
1027
        ib_uint64_t     min_flushed_lsn;
 
1028
        ib_uint64_t     max_flushed_lsn;
 
1029
#ifdef UNIV_LOG_ARCHIVE
 
1030
        ulint           min_arch_log_no;
 
1031
        ulint           max_arch_log_no;
 
1032
#endif /* UNIV_LOG_ARCHIVE */
 
1033
        ulint           sum_of_new_sizes;
 
1034
        ulint           sum_of_data_file_sizes;
 
1035
        ulint           tablespace_size_in_header;
 
1036
        ulint           err;
 
1037
        ulint           i;
 
1038
        ulint           io_limit;
 
1039
        my_bool         srv_file_per_table_original_value
 
1040
                = srv_file_per_table;
 
1041
        mtr_t           mtr;
 
1042
#ifdef HAVE_DARWIN_THREADS
 
1043
# ifdef F_FULLFSYNC
 
1044
        /* This executable has been compiled on Mac OS X 10.3 or later.
 
1045
        Assume that F_FULLFSYNC is available at run-time. */
 
1046
        srv_have_fullfsync = TRUE;
 
1047
# else /* F_FULLFSYNC */
 
1048
        /* This executable has been compiled on Mac OS X 10.2
 
1049
        or earlier.  Determine if the executable is running
 
1050
        on Mac OS X 10.3 or later. */
 
1051
        struct utsname utsname;
 
1052
        if (uname(&utsname)) {
 
1053
                fputs("InnoDB: cannot determine Mac OS X version!\n", stderr);
 
1054
        } else {
 
1055
                srv_have_fullfsync = strcmp(utsname.release, "7.") >= 0;
 
1056
        }
 
1057
        if (!srv_have_fullfsync) {
 
1058
                fputs("InnoDB: On Mac OS X, fsync() may be"
 
1059
                      " broken on internal drives,\n"
 
1060
                      "InnoDB: making transactions unsafe!\n", stderr);
 
1061
        }
 
1062
# endif /* F_FULLFSYNC */
 
1063
#endif /* HAVE_DARWIN_THREADS */
 
1064
 
 
1065
        if (sizeof(ulint) != sizeof(void*)) {
 
1066
                fprintf(stderr,
 
1067
                        "InnoDB: Error: size of InnoDB's ulint is %lu,"
 
1068
                        " but size of void* is %lu.\n"
 
1069
                        "InnoDB: The sizes should be the same"
 
1070
                        " so that on a 64-bit platform you can\n"
 
1071
                        "InnoDB: allocate more than 4 GB of memory.",
 
1072
                        (ulong)sizeof(ulint), (ulong)sizeof(void*));
 
1073
        }
 
1074
 
 
1075
        /* System tables are created in tablespace 0.  Thus, we must
 
1076
        temporarily clear srv_file_per_table.  This is ok, because the
 
1077
        server will not accept connections (which could modify
 
1078
        innodb_file_per_table) until this function has returned. */
 
1079
        srv_file_per_table = FALSE;
 
1080
#ifdef UNIV_DEBUG
 
1081
        fprintf(stderr,
 
1082
                "InnoDB: !!!!!!!! UNIV_DEBUG switched on !!!!!!!!!\n");
 
1083
#endif
 
1084
 
 
1085
#ifdef UNIV_IBUF_DEBUG
 
1086
        fprintf(stderr,
 
1087
                "InnoDB: !!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!\n"
 
1088
                "InnoDB: Crash recovery will fail with UNIV_IBUF_DEBUG\n");
 
1089
#endif
 
1090
 
 
1091
#ifdef UNIV_SYNC_DEBUG
 
1092
        fprintf(stderr,
 
1093
                "InnoDB: !!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!\n");
 
1094
#endif
 
1095
 
 
1096
#ifdef UNIV_SEARCH_DEBUG
 
1097
        fprintf(stderr,
 
1098
                "InnoDB: !!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!\n");
 
1099
#endif
 
1100
 
 
1101
#ifdef UNIV_MEM_DEBUG
 
1102
        fprintf(stderr,
 
1103
                "InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n");
 
1104
#endif
 
1105
 
 
1106
        if (UNIV_LIKELY(srv_use_sys_malloc)) {
 
1107
                fprintf(stderr,
 
1108
                        "InnoDB: The InnoDB memory heap is disabled\n");
 
1109
        }
 
1110
 
 
1111
#ifdef HAVE_GCC_ATOMIC_BUILTINS
 
1112
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
 
1113
        fprintf(stderr,
 
1114
                "InnoDB: Mutexes and rw_locks use GCC atomic builtins.\n");
 
1115
# else /* INNODB_RW_LOCKS_USE_ATOMICS */
 
1116
        fprintf(stderr,
 
1117
                "InnoDB: Mutexes use GCC atomic builtins, rw_locks do not.\n");
 
1118
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
 
1119
#elif defined(HAVE_SOLARIS_ATOMICS)
 
1120
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
 
1121
        fprintf(stderr,
 
1122
                "InnoDB: Mutexes and rw_locks use Solaris atomic functions.\n");
 
1123
# else
 
1124
        fprintf(stderr,
 
1125
                "InnoDB: Mutexes use Solaris atomic functions.\n");
 
1126
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
 
1127
#elif defined(HAVE_WINDOWS_ATOMICS)
 
1128
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
 
1129
        fprintf(stderr,
 
1130
                "InnoDB: Mutexes and rw_locks use Windows interlocked functions.\n");
 
1131
# else
 
1132
        fprintf(stderr,
 
1133
                "InnoDB: Mutexes use Windows interlocked functions.\n");
 
1134
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
 
1135
#else /* HAVE_GCC_ATOMIC_BUILTINS */
 
1136
        fprintf(stderr,
 
1137
                "InnoDB: Neither mutexes nor rw_locks use GCC atomic builtins.\n");
 
1138
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
 
1139
 
 
1140
        /* Since InnoDB does not currently clean up all its internal data
 
1141
        structures in MySQL Embedded Server Library server_end(), we
 
1142
        print an error message if someone tries to start up InnoDB a
 
1143
        second time during the process lifetime. */
 
1144
 
 
1145
        if (srv_start_has_been_called) {
 
1146
                fprintf(stderr,
 
1147
                        "InnoDB: Error:startup called second time"
 
1148
                        " during the process lifetime.\n"
 
1149
                        "InnoDB: In the MySQL Embedded Server Library"
 
1150
                        " you cannot call server_init()\n"
 
1151
                        "InnoDB: more than once during"
 
1152
                        " the process lifetime.\n");
 
1153
        }
 
1154
 
 
1155
        srv_start_has_been_called = TRUE;
 
1156
 
 
1157
#ifdef UNIV_DEBUG
 
1158
        log_do_write = TRUE;
 
1159
#endif /* UNIV_DEBUG */
 
1160
        /*      yydebug = TRUE; */
 
1161
 
 
1162
        srv_is_being_started = TRUE;
 
1163
        srv_startup_is_before_trx_rollback_phase = TRUE;
 
1164
        os_aio_use_native_aio = FALSE;
 
1165
 
 
1166
#ifdef __WIN__
 
1167
        switch (os_get_os_version()) {
 
1168
        case OS_WIN95:
 
1169
        case OS_WIN31:
 
1170
        case OS_WINNT:
 
1171
                /* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
 
1172
                and NT use simulated aio. In NT Windows provides async i/o,
 
1173
                but when run in conjunction with InnoDB Hot Backup, it seemed
 
1174
                to corrupt the data files. */
 
1175
 
 
1176
                os_aio_use_native_aio = FALSE;
 
1177
                break;
 
1178
        default:
 
1179
                /* On Win 2000 and XP use async i/o */
 
1180
                os_aio_use_native_aio = TRUE;
 
1181
                break;
 
1182
        }
 
1183
#endif
 
1184
        if (srv_file_flush_method_str == NULL) {
 
1185
                /* These are the default options */
 
1186
 
 
1187
                srv_unix_file_flush_method = SRV_UNIX_FSYNC;
 
1188
 
 
1189
                srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
 
1190
#ifndef __WIN__
 
1191
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
 
1192
                srv_unix_file_flush_method = SRV_UNIX_FSYNC;
 
1193
 
 
1194
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) {
 
1195
                srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;
 
1196
 
 
1197
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
 
1198
                srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
 
1199
 
 
1200
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
 
1201
                srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
 
1202
 
 
1203
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
 
1204
                srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
 
1205
#else
 
1206
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
 
1207
                srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
 
1208
                os_aio_use_native_aio = FALSE;
 
1209
 
 
1210
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
 
1211
                srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
 
1212
                os_aio_use_native_aio = FALSE;
 
1213
 
 
1214
        } else if (0 == ut_strcmp(srv_file_flush_method_str,
 
1215
                                  "async_unbuffered")) {
 
1216
                srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
 
1217
#endif
 
1218
        } else {
 
1219
                fprintf(stderr,
 
1220
                        "InnoDB: Unrecognized value %s for"
 
1221
                        " innodb_flush_method\n",
 
1222
                        srv_file_flush_method_str);
 
1223
                return(DB_ERROR);
 
1224
        }
 
1225
 
 
1226
        /* Note that the call srv_boot() also changes the values of
 
1227
        some variables to the units used by InnoDB internally */
 
1228
 
 
1229
        /* Set the maximum number of threads which can wait for a semaphore
 
1230
        inside InnoDB: this is the 'sync wait array' size, as well as the
 
1231
        maximum number of threads that can wait in the 'srv_conc array' for
 
1232
        their time to enter InnoDB. */
 
1233
 
 
1234
#if defined(__NETWARE__)
 
1235
 
 
1236
        /* Create less event semaphores because Win 98/ME had
 
1237
        difficulty creating 40000 event semaphores.  Comment from
 
1238
        Novell, Inc.: also, these just take a lot of memory on
 
1239
        NetWare. */
 
1240
        srv_max_n_threads = 1000;
 
1241
#else
 
1242
        if (srv_buf_pool_size >= 1000 * 1024 * 1024) {
 
1243
                /* If buffer pool is less than 1000 MB,
 
1244
                assume fewer threads. */
 
1245
                srv_max_n_threads = 50000;
 
1246
 
 
1247
        } else if (srv_buf_pool_size >= 8 * 1024 * 1024) {
 
1248
 
 
1249
                srv_max_n_threads = 10000;
 
1250
        } else {
 
1251
                srv_max_n_threads = 1000;       /* saves several MB of memory,
 
1252
                                                especially in 64-bit
 
1253
                                                computers */
 
1254
        }
 
1255
#endif
 
1256
        err = srv_boot();
 
1257
 
 
1258
        if (err != DB_SUCCESS) {
 
1259
 
 
1260
                return((int) err);
 
1261
        }
 
1262
 
 
1263
        mutex_create(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK);
 
1264
 
 
1265
        if (srv_innodb_status) {
 
1266
                srv_monitor_file_name = mem_alloc(
 
1267
                        strlen(fil_path_to_mysql_datadir)
 
1268
                        + 20 + sizeof "/innodb_status.");
 
1269
                sprintf(srv_monitor_file_name, "%s/innodb_status.%lu",
 
1270
                        fil_path_to_mysql_datadir, os_proc_get_number());
 
1271
                srv_monitor_file = fopen(srv_monitor_file_name, "w+");
 
1272
                if (!srv_monitor_file) {
 
1273
                        fprintf(stderr, "InnoDB: unable to create %s: %s\n",
 
1274
                                srv_monitor_file_name, strerror(errno));
 
1275
                        return(DB_ERROR);
 
1276
                }
 
1277
        } else {
 
1278
                srv_monitor_file_name = NULL;
 
1279
                srv_monitor_file = os_file_create_tmpfile();
 
1280
                if (!srv_monitor_file) {
 
1281
                        return(DB_ERROR);
 
1282
                }
 
1283
        }
 
1284
 
 
1285
        mutex_create(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION);
 
1286
 
 
1287
        srv_dict_tmpfile = os_file_create_tmpfile();
 
1288
        if (!srv_dict_tmpfile) {
 
1289
                return(DB_ERROR);
 
1290
        }
 
1291
 
 
1292
        mutex_create(&srv_misc_tmpfile_mutex, SYNC_ANY_LATCH);
 
1293
 
 
1294
        srv_misc_tmpfile = os_file_create_tmpfile();
 
1295
        if (!srv_misc_tmpfile) {
 
1296
                return(DB_ERROR);
 
1297
        }
 
1298
 
 
1299
        /* If user has set the value of innodb_file_io_threads then
 
1300
        we'll emit a message telling the user that this parameter
 
1301
        is now deprecated. */
 
1302
        if (srv_n_file_io_threads != 4) {
 
1303
                fprintf(stderr, "InnoDB: Warning:"
 
1304
                        " innodb_file_io_threads is deprecated."
 
1305
                        " Please use innodb_read_io_threads and"
 
1306
                        " innodb_write_io_threads instead\n");
 
1307
        }
 
1308
 
 
1309
        /* Now overwrite the value on srv_n_file_io_threads */
 
1310
        srv_n_file_io_threads = 2 + srv_n_read_io_threads
 
1311
                                + srv_n_write_io_threads;
 
1312
 
 
1313
        ut_a(srv_n_file_io_threads <= SRV_MAX_N_IO_THREADS);
 
1314
 
 
1315
        /* TODO: Investigate if SRV_N_PENDING_IOS_PER_THREAD (32) limit
 
1316
        still applies to windows. */
 
1317
        if (!os_aio_use_native_aio) {
 
1318
                io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
 
1319
        } else {
 
1320
                io_limit = SRV_N_PENDING_IOS_PER_THREAD;
 
1321
        }
 
1322
 
 
1323
        os_aio_init(io_limit,
 
1324
                    srv_n_read_io_threads,
 
1325
                    srv_n_write_io_threads,
 
1326
                    SRV_MAX_N_PENDING_SYNC_IOS);
 
1327
 
 
1328
        fil_init(srv_file_per_table ? 50000 : 5000,
 
1329
                 srv_max_n_open_files);
 
1330
 
 
1331
        ret = buf_pool_init();
 
1332
 
 
1333
        if (ret == NULL) {
 
1334
                fprintf(stderr,
 
1335
                        "InnoDB: Fatal error: cannot allocate the memory"
 
1336
                        " for the buffer pool\n");
 
1337
 
 
1338
                return(DB_ERROR);
 
1339
        }
 
1340
 
 
1341
#ifdef UNIV_DEBUG
 
1342
        /* We have observed deadlocks with a 5MB buffer pool but
 
1343
        the actual lower limit could very well be a little higher. */
 
1344
 
 
1345
        if (srv_buf_pool_size <= 5 * 1024 * 1024) {
 
1346
 
 
1347
                fprintf(stderr, "InnoDB: Warning: Small buffer pool size "
 
1348
                        "(%luM), the flst_validate() debug function "
 
1349
                        "can cause a deadlock if the buffer pool fills up.\n",
 
1350
                        srv_buf_pool_size / 1024 / 1024);
 
1351
        }
 
1352
#endif
 
1353
 
 
1354
        fsp_init();
 
1355
        log_init();
 
1356
 
 
1357
        lock_sys_create(srv_lock_table_size);
 
1358
 
 
1359
        /* Create i/o-handler threads: */
 
1360
 
 
1361
        for (i = 0; i < srv_n_file_io_threads; i++) {
 
1362
                n[i] = i;
 
1363
 
 
1364
                os_thread_create(io_handler_thread, n + i, thread_ids + i);
 
1365
        }
 
1366
 
 
1367
#ifdef UNIV_LOG_ARCHIVE
 
1368
        if (0 != ut_strcmp(srv_log_group_home_dirs[0], srv_arch_dir)) {
 
1369
                fprintf(stderr,
 
1370
                        "InnoDB: Error: you must set the log group"
 
1371
                        " home dir in my.cnf the\n"
 
1372
                        "InnoDB: same as log arch dir.\n");
 
1373
 
 
1374
                return(DB_ERROR);
 
1375
        }
 
1376
#endif /* UNIV_LOG_ARCHIVE */
 
1377
 
 
1378
        if (srv_n_log_files * srv_log_file_size >= 262144) {
 
1379
                fprintf(stderr,
 
1380
                        "InnoDB: Error: combined size of log files"
 
1381
                        " must be < 4 GB\n");
 
1382
 
 
1383
                return(DB_ERROR);
 
1384
        }
 
1385
 
 
1386
        sum_of_new_sizes = 0;
 
1387
 
 
1388
        for (i = 0; i < srv_n_data_files; i++) {
 
1389
#ifndef __WIN__
 
1390
                if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
 
1391
                        fprintf(stderr,
 
1392
                                "InnoDB: Error: file size must be < 4 GB"
 
1393
                                " with this MySQL binary\n"
 
1394
                                "InnoDB: and operating system combination,"
 
1395
                                " in some OS's < 2 GB\n");
 
1396
 
 
1397
                        return(DB_ERROR);
 
1398
                }
 
1399
#endif
 
1400
                sum_of_new_sizes += srv_data_file_sizes[i];
 
1401
        }
 
1402
 
 
1403
        if (sum_of_new_sizes < 640) {
 
1404
                fprintf(stderr,
 
1405
                        "InnoDB: Error: tablespace size must be"
 
1406
                        " at least 10 MB\n");
 
1407
 
 
1408
                return(DB_ERROR);
 
1409
        }
 
1410
 
 
1411
        err = open_or_create_data_files(&create_new_db,
 
1412
#ifdef UNIV_LOG_ARCHIVE
 
1413
                                        &min_arch_log_no, &max_arch_log_no,
 
1414
#endif /* UNIV_LOG_ARCHIVE */
 
1415
                                        &min_flushed_lsn, &max_flushed_lsn,
 
1416
                                        &sum_of_new_sizes);
 
1417
        if (err != DB_SUCCESS) {
 
1418
                fprintf(stderr,
 
1419
                        "InnoDB: Could not open or create data files.\n"
 
1420
                        "InnoDB: If you tried to add new data files,"
 
1421
                        " and it failed here,\n"
 
1422
                        "InnoDB: you should now edit innodb_data_file_path"
 
1423
                        " in my.cnf back\n"
 
1424
                        "InnoDB: to what it was, and remove the"
 
1425
                        " new ibdata files InnoDB created\n"
 
1426
                        "InnoDB: in this failed attempt. InnoDB only wrote"
 
1427
                        " those files full of\n"
 
1428
                        "InnoDB: zeros, but did not yet use them in any way."
 
1429
                        " But be careful: do not\n"
 
1430
                        "InnoDB: remove old data files"
 
1431
                        " which contain your precious data!\n");
 
1432
 
 
1433
                return((int) err);
 
1434
        }
 
1435
 
 
1436
#ifdef UNIV_LOG_ARCHIVE
 
1437
        srv_normalize_path_for_win(srv_arch_dir);
 
1438
        srv_arch_dir = srv_add_path_separator_if_needed(srv_arch_dir);
 
1439
#endif /* UNIV_LOG_ARCHIVE */
 
1440
 
 
1441
        for (i = 0; i < srv_n_log_files; i++) {
 
1442
                err = open_or_create_log_file(create_new_db, &log_file_created,
 
1443
                                              log_opened, 0, i);
 
1444
                if (err != DB_SUCCESS) {
 
1445
 
 
1446
                        return((int) err);
 
1447
                }
 
1448
 
 
1449
                if (log_file_created) {
 
1450
                        log_created = TRUE;
 
1451
                } else {
 
1452
                        log_opened = TRUE;
 
1453
                }
 
1454
                if ((log_opened && create_new_db)
 
1455
                    || (log_opened && log_created)) {
 
1456
                        fprintf(stderr,
 
1457
                                "InnoDB: Error: all log files must be"
 
1458
                                " created at the same time.\n"
 
1459
                                "InnoDB: All log files must be"
 
1460
                                " created also in database creation.\n"
 
1461
                                "InnoDB: If you want bigger or smaller"
 
1462
                                " log files, shut down the\n"
 
1463
                                "InnoDB: database and make sure there"
 
1464
                                " were no errors in shutdown.\n"
 
1465
                                "InnoDB: Then delete the existing log files."
 
1466
                                " Edit the .cnf file\n"
 
1467
                                "InnoDB: and start the database again.\n");
 
1468
 
 
1469
                        return(DB_ERROR);
 
1470
                }
 
1471
        }
 
1472
 
 
1473
        /* Open all log files and data files in the system tablespace: we
 
1474
        keep them open until database shutdown */
 
1475
 
 
1476
        fil_open_log_and_system_tablespace_files();
 
1477
 
 
1478
        if (log_created && !create_new_db
 
1479
#ifdef UNIV_LOG_ARCHIVE
 
1480
            && !srv_archive_recovery
 
1481
#endif /* UNIV_LOG_ARCHIVE */
 
1482
            ) {
 
1483
                if (max_flushed_lsn != min_flushed_lsn
 
1484
#ifdef UNIV_LOG_ARCHIVE
 
1485
                    || max_arch_log_no != min_arch_log_no
 
1486
#endif /* UNIV_LOG_ARCHIVE */
 
1487
                    ) {
 
1488
                        fprintf(stderr,
 
1489
                                "InnoDB: Cannot initialize created"
 
1490
                                " log files because\n"
 
1491
                                "InnoDB: data files were not in sync"
 
1492
                                " with each other\n"
 
1493
                                "InnoDB: or the data files are corrupt.\n");
 
1494
 
 
1495
                        return(DB_ERROR);
 
1496
                }
 
1497
 
 
1498
                if (max_flushed_lsn < (ib_uint64_t) 1000) {
 
1499
                        fprintf(stderr,
 
1500
                                "InnoDB: Cannot initialize created"
 
1501
                                " log files because\n"
 
1502
                                "InnoDB: data files are corrupt,"
 
1503
                                " or new data files were\n"
 
1504
                                "InnoDB: created when the database"
 
1505
                                " was started previous\n"
 
1506
                                "InnoDB: time but the database"
 
1507
                                " was not shut down\n"
 
1508
                                "InnoDB: normally after that.\n");
 
1509
 
 
1510
                        return(DB_ERROR);
 
1511
                }
 
1512
 
 
1513
                mutex_enter(&(log_sys->mutex));
 
1514
 
 
1515
#ifdef UNIV_LOG_ARCHIVE
 
1516
                /* Do not + 1 arch_log_no because we do not use log
 
1517
                archiving */
 
1518
                recv_reset_logs(max_flushed_lsn, max_arch_log_no, TRUE);
 
1519
#else
 
1520
                recv_reset_logs(max_flushed_lsn, TRUE);
 
1521
#endif /* UNIV_LOG_ARCHIVE */
 
1522
 
 
1523
                mutex_exit(&(log_sys->mutex));
 
1524
        }
 
1525
 
 
1526
        trx_sys_file_format_init();
 
1527
 
 
1528
        if (create_new_db) {
 
1529
                mtr_start(&mtr);
 
1530
                fsp_header_init(0, sum_of_new_sizes, &mtr);
 
1531
 
 
1532
                mtr_commit(&mtr);
 
1533
 
 
1534
                trx_sys_create();
 
1535
                dict_create();
 
1536
                srv_startup_is_before_trx_rollback_phase = FALSE;
 
1537
 
 
1538
#ifdef UNIV_LOG_ARCHIVE
 
1539
        } else if (srv_archive_recovery) {
 
1540
                fprintf(stderr,
 
1541
                        "InnoDB: Starting archive"
 
1542
                        " recovery from a backup...\n");
 
1543
                err = recv_recovery_from_archive_start(
 
1544
                        min_flushed_lsn, srv_archive_recovery_limit_lsn,
 
1545
                        min_arch_log_no);
 
1546
                if (err != DB_SUCCESS) {
 
1547
 
 
1548
                        return(DB_ERROR);
 
1549
                }
 
1550
                /* Since ibuf init is in dict_boot, and ibuf is needed
 
1551
                in any disk i/o, first call dict_boot */
 
1552
 
 
1553
                dict_boot();
 
1554
                trx_sys_init_at_db_start();
 
1555
                srv_startup_is_before_trx_rollback_phase = FALSE;
 
1556
 
 
1557
                /* Initialize the fsp free limit global variable in the log
 
1558
                system */
 
1559
                fsp_header_get_free_limit();
 
1560
 
 
1561
                recv_recovery_from_archive_finish();
 
1562
#endif /* UNIV_LOG_ARCHIVE */
 
1563
        } else {
 
1564
 
 
1565
                /* Check if we support the max format that is stamped
 
1566
                on the system tablespace. 
 
1567
                Note:  We are NOT allowed to make any modifications to
 
1568
                the TRX_SYS_PAGE_NO page before recovery  because this
 
1569
                page also contains the max_trx_id etc. important system
 
1570
                variables that are required for recovery.  We need to
 
1571
                ensure that we return the system to a state where normal
 
1572
                recovery is guaranteed to work. We do this by
 
1573
                invalidating the buffer cache, this will force the
 
1574
                reread of the page and restoration to its last known
 
1575
                consistent state, this is REQUIRED for the recovery
 
1576
                process to work. */
 
1577
                err = trx_sys_file_format_max_check(
 
1578
                        srv_check_file_format_at_startup);
 
1579
 
 
1580
                if (err != DB_SUCCESS) {
 
1581
                        return(err);
 
1582
                }
 
1583
 
 
1584
                /* Invalidate the buffer pool to ensure that we reread
 
1585
                the page that we read above, during recovery.
 
1586
                Note that this is not as heavy weight as it seems. At
 
1587
                this point there will be only ONE page in the buf_LRU
 
1588
                and there must be no page in the buf_flush list. */
 
1589
                buf_pool_invalidate();
 
1590
 
 
1591
                /* We always try to do a recovery, even if the database had
 
1592
                been shut down normally: this is the normal startup path */
 
1593
 
 
1594
                err = recv_recovery_from_checkpoint_start(LOG_CHECKPOINT,
 
1595
                                                          IB_ULONGLONG_MAX,
 
1596
                                                          min_flushed_lsn,
 
1597
                                                          max_flushed_lsn);
 
1598
                if (err != DB_SUCCESS) {
 
1599
 
 
1600
                        return(DB_ERROR);
 
1601
                }
 
1602
 
 
1603
                /* Since the insert buffer init is in dict_boot, and the
 
1604
                insert buffer is needed in any disk i/o, first we call
 
1605
                dict_boot(). Note that trx_sys_init_at_db_start() only needs
 
1606
                to access space 0, and the insert buffer at this stage already
 
1607
                works for space 0. */
 
1608
 
 
1609
                dict_boot();
 
1610
                trx_sys_init_at_db_start();
 
1611
 
 
1612
                if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
 
1613
                        /* The following call is necessary for the insert
 
1614
                        buffer to work with multiple tablespaces. We must
 
1615
                        know the mapping between space id's and .ibd file
 
1616
                        names.
 
1617
 
 
1618
                        In a crash recovery, we check that the info in data
 
1619
                        dictionary is consistent with what we already know
 
1620
                        about space id's from the call of
 
1621
                        fil_load_single_table_tablespaces().
 
1622
 
 
1623
                        In a normal startup, we create the space objects for
 
1624
                        every table in the InnoDB data dictionary that has
 
1625
                        an .ibd file.
 
1626
 
 
1627
                        We also determine the maximum tablespace id used.
 
1628
 
 
1629
                        TODO: We may have incomplete transactions in the
 
1630
                        data dictionary tables. Does that harm the scanning of
 
1631
                        the data dictionary below? */
 
1632
 
 
1633
                        dict_check_tablespaces_and_store_max_id(
 
1634
                                recv_needed_recovery);
 
1635
                }
 
1636
 
 
1637
                srv_startup_is_before_trx_rollback_phase = FALSE;
 
1638
 
 
1639
                /* Initialize the fsp free limit global variable in the log
 
1640
                system */
 
1641
                fsp_header_get_free_limit();
 
1642
 
 
1643
                /* recv_recovery_from_checkpoint_finish needs trx lists which
 
1644
                are initialized in trx_sys_init_at_db_start(). */
 
1645
 
 
1646
                recv_recovery_from_checkpoint_finish();
 
1647
 
 
1648
                /* It is possible that file_format tag has never
 
1649
                been set. In this case we initialize it to minimum
 
1650
                value.  Important to note that we can do it ONLY after
 
1651
                we have finished the recovery process so that the
 
1652
                image of TRX_SYS_PAGE_NO is not stale. */
 
1653
                trx_sys_file_format_tag_init();
 
1654
        }
 
1655
 
 
1656
        if (!create_new_db && sum_of_new_sizes > 0) {
 
1657
                /* New data file(s) were added */
 
1658
                mtr_start(&mtr);
 
1659
 
 
1660
                fsp_header_inc_size(0, sum_of_new_sizes, &mtr);
 
1661
 
 
1662
                mtr_commit(&mtr);
 
1663
 
 
1664
                /* Immediately write the log record about increased tablespace
 
1665
                size to disk, so that it is durable even if mysqld would crash
 
1666
                quickly */
 
1667
 
 
1668
                log_buffer_flush_to_disk();
 
1669
        }
 
1670
 
 
1671
#ifdef UNIV_LOG_ARCHIVE
 
1672
        /* Archiving is always off under MySQL */
 
1673
        if (!srv_log_archive_on) {
 
1674
                ut_a(DB_SUCCESS == log_archive_noarchivelog());
 
1675
        } else {
 
1676
                mutex_enter(&(log_sys->mutex));
 
1677
 
 
1678
                start_archive = FALSE;
 
1679
 
 
1680
                if (log_sys->archiving_state == LOG_ARCH_OFF) {
 
1681
                        start_archive = TRUE;
 
1682
                }
 
1683
 
 
1684
                mutex_exit(&(log_sys->mutex));
 
1685
 
 
1686
                if (start_archive) {
 
1687
                        ut_a(DB_SUCCESS == log_archive_archivelog());
 
1688
                }
 
1689
        }
 
1690
#endif /* UNIV_LOG_ARCHIVE */
 
1691
 
 
1692
        /* fprintf(stderr, "Max allowed record size %lu\n",
 
1693
        page_get_free_space_of_empty() / 2); */
 
1694
 
 
1695
        /* Create the thread which watches the timeouts for lock waits
 
1696
        and prints InnoDB monitor info */
 
1697
 
 
1698
        os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL,
 
1699
                         thread_ids + 2 + SRV_MAX_N_IO_THREADS);
 
1700
 
 
1701
        /* Create the thread which warns of long semaphore waits */
 
1702
        os_thread_create(&srv_error_monitor_thread, NULL,
 
1703
                         thread_ids + 3 + SRV_MAX_N_IO_THREADS);
 
1704
        srv_is_being_started = FALSE;
 
1705
 
 
1706
        if (trx_doublewrite == NULL) {
 
1707
                /* Create the doublewrite buffer to a new tablespace */
 
1708
 
 
1709
                trx_sys_create_doublewrite_buf();
 
1710
        }
 
1711
 
 
1712
        err = dict_create_or_check_foreign_constraint_tables();
 
1713
 
 
1714
        if (err != DB_SUCCESS) {
 
1715
                return((int)DB_ERROR);
 
1716
        }
 
1717
 
 
1718
        /* Create the master thread which does purge and other utility
 
1719
        operations */
 
1720
 
 
1721
        os_thread_create(&srv_master_thread, NULL, thread_ids
 
1722
                         + (1 + SRV_MAX_N_IO_THREADS));
 
1723
#ifdef UNIV_DEBUG
 
1724
        /* buf_debug_prints = TRUE; */
 
1725
#endif /* UNIV_DEBUG */
 
1726
        sum_of_data_file_sizes = 0;
 
1727
 
 
1728
        for (i = 0; i < srv_n_data_files; i++) {
 
1729
                sum_of_data_file_sizes += srv_data_file_sizes[i];
 
1730
        }
 
1731
 
 
1732
        tablespace_size_in_header = fsp_header_get_tablespace_size();
 
1733
 
 
1734
        if (!srv_auto_extend_last_data_file
 
1735
            && sum_of_data_file_sizes != tablespace_size_in_header) {
 
1736
 
 
1737
                fprintf(stderr,
 
1738
                        "InnoDB: Error: tablespace size"
 
1739
                        " stored in header is %lu pages, but\n"
 
1740
                        "InnoDB: the sum of data file sizes is %lu pages\n",
 
1741
                        (ulong) tablespace_size_in_header,
 
1742
                        (ulong) sum_of_data_file_sizes);
 
1743
 
 
1744
                if (srv_force_recovery == 0
 
1745
                    && sum_of_data_file_sizes < tablespace_size_in_header) {
 
1746
                        /* This is a fatal error, the tail of a tablespace is
 
1747
                        missing */
 
1748
 
 
1749
                        fprintf(stderr,
 
1750
                                "InnoDB: Cannot start InnoDB."
 
1751
                                " The tail of the system tablespace is\n"
 
1752
                                "InnoDB: missing. Have you edited"
 
1753
                                " innodb_data_file_path in my.cnf in an\n"
 
1754
                                "InnoDB: inappropriate way, removing"
 
1755
                                " ibdata files from there?\n"
 
1756
                                "InnoDB: You can set innodb_force_recovery=1"
 
1757
                                " in my.cnf to force\n"
 
1758
                                "InnoDB: a startup if you are trying"
 
1759
                                " to recover a badly corrupt database.\n");
 
1760
 
 
1761
                        return(DB_ERROR);
 
1762
                }
 
1763
        }
 
1764
 
 
1765
        if (srv_auto_extend_last_data_file
 
1766
            && sum_of_data_file_sizes < tablespace_size_in_header) {
 
1767
 
 
1768
                fprintf(stderr,
 
1769
                        "InnoDB: Error: tablespace size stored in header"
 
1770
                        " is %lu pages, but\n"
 
1771
                        "InnoDB: the sum of data file sizes"
 
1772
                        " is only %lu pages\n",
 
1773
                        (ulong) tablespace_size_in_header,
 
1774
                        (ulong) sum_of_data_file_sizes);
 
1775
 
 
1776
                if (srv_force_recovery == 0) {
 
1777
 
 
1778
                        fprintf(stderr,
 
1779
                                "InnoDB: Cannot start InnoDB. The tail of"
 
1780
                                " the system tablespace is\n"
 
1781
                                "InnoDB: missing. Have you edited"
 
1782
                                " innodb_data_file_path in my.cnf in an\n"
 
1783
                                "InnoDB: inappropriate way, removing"
 
1784
                                " ibdata files from there?\n"
 
1785
                                "InnoDB: You can set innodb_force_recovery=1"
 
1786
                                " in my.cnf to force\n"
 
1787
                                "InnoDB: a startup if you are trying to"
 
1788
                                " recover a badly corrupt database.\n");
 
1789
 
 
1790
                        return(DB_ERROR);
 
1791
                }
 
1792
        }
 
1793
 
 
1794
        /* Check that os_fast_mutexes work as expected */
 
1795
        os_fast_mutex_init(&srv_os_test_mutex);
 
1796
 
 
1797
        if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
 
1798
                fprintf(stderr,
 
1799
                        "InnoDB: Error: pthread_mutex_trylock returns"
 
1800
                        " an unexpected value on\n"
 
1801
                        "InnoDB: success! Cannot continue.\n");
 
1802
                exit(1);
 
1803
        }
 
1804
 
 
1805
        os_fast_mutex_unlock(&srv_os_test_mutex);
 
1806
 
 
1807
        os_fast_mutex_lock(&srv_os_test_mutex);
 
1808
 
 
1809
        os_fast_mutex_unlock(&srv_os_test_mutex);
 
1810
 
 
1811
        os_fast_mutex_free(&srv_os_test_mutex);
 
1812
 
 
1813
        if (srv_print_verbose_log) {
 
1814
                ut_print_timestamp(stderr);
 
1815
                fprintf(stderr,
 
1816
                        " InnoDB Plugin %s started; "
 
1817
                        "log sequence number %"PRIu64"\n",
 
1818
                        INNODB_VERSION_STR, srv_start_lsn);
 
1819
        }
 
1820
 
 
1821
        if (srv_force_recovery > 0) {
 
1822
                fprintf(stderr,
 
1823
                        "InnoDB: !!! innodb_force_recovery"
 
1824
                        " is set to %lu !!!\n",
 
1825
                        (ulong) srv_force_recovery);
 
1826
        }
 
1827
 
 
1828
        fflush(stderr);
 
1829
 
 
1830
        if (trx_doublewrite_must_reset_space_ids) {
 
1831
                /* Actually, we did not change the undo log format between
 
1832
                4.0 and 4.1.1, and we would not need to run purge to
 
1833
                completion. Note also that the purge algorithm in 4.1.1
 
1834
                can process the the history list again even after a full
 
1835
                purge, because our algorithm does not cut the end of the
 
1836
                history list in all cases so that it would become empty
 
1837
                after a full purge. That mean that we may purge 4.0 type
 
1838
                undo log even after this phase.
 
1839
 
 
1840
                The insert buffer record format changed between 4.0 and
 
1841
                4.1.1. It is essential that the insert buffer is emptied
 
1842
                here! */
 
1843
 
 
1844
                fprintf(stderr,
 
1845
                        "InnoDB: You are upgrading to an"
 
1846
                        " InnoDB version which allows multiple\n"
 
1847
                        "InnoDB: tablespaces. Wait that purge"
 
1848
                        " and insert buffer merge run to\n"
 
1849
                        "InnoDB: completion...\n");
 
1850
                for (;;) {
 
1851
                        os_thread_sleep(1000000);
 
1852
 
 
1853
                        if (0 == strcmp(srv_main_thread_op_info,
 
1854
                                        "waiting for server activity")) {
 
1855
 
 
1856
                                ut_a(ibuf_is_empty());
 
1857
 
 
1858
                                break;
 
1859
                        }
 
1860
                }
 
1861
                fprintf(stderr,
 
1862
                        "InnoDB: Full purge and insert buffer merge"
 
1863
                        " completed.\n");
 
1864
 
 
1865
                trx_sys_mark_upgraded_to_multiple_tablespaces();
 
1866
 
 
1867
                fprintf(stderr,
 
1868
                        "InnoDB: You have now successfully upgraded"
 
1869
                        " to the multiple tablespaces\n"
 
1870
                        "InnoDB: format. You should NOT DOWNGRADE"
 
1871
                        " to an earlier version of\n"
 
1872
                        "InnoDB: InnoDB! But if you absolutely need to"
 
1873
                        " downgrade, see\n"
 
1874
                        "InnoDB: " REFMAN "multiple-tablespaces.html\n"
 
1875
                        "InnoDB: for instructions.\n");
 
1876
        }
 
1877
 
 
1878
        if (srv_force_recovery == 0) {
 
1879
                /* In the insert buffer we may have even bigger tablespace
 
1880
                id's, because we may have dropped those tablespaces, but
 
1881
                insert buffer merge has not had time to clean the records from
 
1882
                the ibuf tree. */
 
1883
 
 
1884
                ibuf_update_max_tablespace_id();
 
1885
        }
 
1886
 
 
1887
        srv_file_per_table = srv_file_per_table_original_value;
 
1888
 
 
1889
        srv_was_started = TRUE;
 
1890
 
 
1891
        return((int) DB_SUCCESS);
 
1892
}
 
1893
 
 
1894
/****************************************************************//**
 
1895
Shuts down the InnoDB database.
 
1896
@return DB_SUCCESS or error code */
 
1897
UNIV_INTERN
 
1898
int
 
1899
innobase_shutdown_for_mysql(void)
 
1900
/*=============================*/
 
1901
{
 
1902
        ulint   i;
 
1903
#ifdef __NETWARE__
 
1904
        extern ibool panic_shutdown;
 
1905
#endif
 
1906
        if (!srv_was_started) {
 
1907
                if (srv_is_being_started) {
 
1908
                        ut_print_timestamp(stderr);
 
1909
                        fprintf(stderr,
 
1910
                                "  InnoDB: Warning: shutting down"
 
1911
                                " a not properly started\n"
 
1912
                                "InnoDB: or created database!\n");
 
1913
                }
 
1914
 
 
1915
                return(DB_SUCCESS);
 
1916
        }
 
1917
 
 
1918
        /* 1. Flush the buffer pool to disk, write the current lsn to
 
1919
        the tablespace header(s), and copy all log data to archive.
 
1920
        The step 1 is the real InnoDB shutdown. The remaining steps 2 - ...
 
1921
        just free data structures after the shutdown. */
 
1922
 
 
1923
 
 
1924
        if (srv_fast_shutdown == 2) {
 
1925
                ut_print_timestamp(stderr);
 
1926
                fprintf(stderr,
 
1927
                        "  InnoDB: MySQL has requested a very fast shutdown"
 
1928
                        " without flushing "
 
1929
                        "the InnoDB buffer pool to data files."
 
1930
                        " At the next mysqld startup "
 
1931
                        "InnoDB will do a crash recovery!\n");
 
1932
        }
 
1933
 
 
1934
#ifdef __NETWARE__
 
1935
        if (!panic_shutdown)
 
1936
#endif
 
1937
                logs_empty_and_mark_files_at_shutdown();
 
1938
 
 
1939
        if (srv_conc_n_threads != 0) {
 
1940
                fprintf(stderr,
 
1941
                        "InnoDB: Warning: query counter shows %ld queries"
 
1942
                        " still\n"
 
1943
                        "InnoDB: inside InnoDB at shutdown\n",
 
1944
                        srv_conc_n_threads);
 
1945
        }
 
1946
 
 
1947
        /* 2. Make all threads created by InnoDB to exit */
 
1948
 
 
1949
        srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
 
1950
 
 
1951
        /* In a 'very fast' shutdown, we do not need to wait for these threads
 
1952
        to die; all which counts is that we flushed the log; a 'very fast'
 
1953
        shutdown is essentially a crash. */
 
1954
 
 
1955
        if (srv_fast_shutdown == 2) {
 
1956
                return(DB_SUCCESS);
 
1957
        }
 
1958
 
 
1959
        /* All threads end up waiting for certain events. Put those events
 
1960
        to the signaled state. Then the threads will exit themselves in
 
1961
        os_thread_event_wait(). */
 
1962
 
 
1963
        for (i = 0; i < 1000; i++) {
 
1964
                /* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
 
1965
                HERE OR EARLIER */
 
1966
 
 
1967
                /* a. Let the lock timeout thread exit */
 
1968
                os_event_set(srv_lock_timeout_thread_event);
 
1969
 
 
1970
                /* b. srv error monitor thread exits automatically, no need
 
1971
                to do anything here */
 
1972
 
 
1973
                /* c. We wake the master thread so that it exits */
 
1974
                srv_wake_master_thread();
 
1975
 
 
1976
                /* d. Exit the i/o threads */
 
1977
 
 
1978
                os_aio_wake_all_threads_at_shutdown();
 
1979
 
 
1980
                os_mutex_enter(os_sync_mutex);
 
1981
 
 
1982
                if (os_thread_count == 0) {
 
1983
                        /* All the threads have exited or are just exiting;
 
1984
                        NOTE that the threads may not have completed their
 
1985
                        exit yet. Should we use pthread_join() to make sure
 
1986
                        they have exited? Now we just sleep 0.1 seconds and
 
1987
                        hope that is enough! */
 
1988
 
 
1989
                        os_mutex_exit(os_sync_mutex);
 
1990
 
 
1991
                        os_thread_sleep(100000);
 
1992
 
 
1993
                        break;
 
1994
                }
 
1995
 
 
1996
                os_mutex_exit(os_sync_mutex);
 
1997
 
 
1998
                os_thread_sleep(100000);
 
1999
        }
 
2000
 
 
2001
        if (i == 1000) {
 
2002
                fprintf(stderr,
 
2003
                        "InnoDB: Warning: %lu threads created by InnoDB"
 
2004
                        " had not exited at shutdown!\n",
 
2005
                        (ulong) os_thread_count);
 
2006
        }
 
2007
 
 
2008
        if (srv_monitor_file) {
 
2009
                fclose(srv_monitor_file);
 
2010
                srv_monitor_file = 0;
 
2011
                if (srv_monitor_file_name) {
 
2012
                        unlink(srv_monitor_file_name);
 
2013
                        mem_free(srv_monitor_file_name);
 
2014
                }
 
2015
        }
 
2016
        if (srv_dict_tmpfile) {
 
2017
                fclose(srv_dict_tmpfile);
 
2018
                srv_dict_tmpfile = 0;
 
2019
        }
 
2020
 
 
2021
        if (srv_misc_tmpfile) {
 
2022
                fclose(srv_misc_tmpfile);
 
2023
                srv_misc_tmpfile = 0;
 
2024
        }
 
2025
 
 
2026
        trx_sys_file_format_close();
 
2027
 
 
2028
        mutex_free(&srv_monitor_file_mutex);
 
2029
        mutex_free(&srv_dict_tmpfile_mutex);
 
2030
        mutex_free(&srv_misc_tmpfile_mutex);
 
2031
 
 
2032
        /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
 
2033
        them */
 
2034
        sync_close();
 
2035
 
 
2036
        /* 4. Free the os_conc_mutex and all os_events and os_mutexes */
 
2037
 
 
2038
        srv_free();
 
2039
        os_sync_free();
 
2040
 
 
2041
        /* Check that all read views are closed except read view owned
 
2042
        by a purge. */
 
2043
 
 
2044
        if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
 
2045
                fprintf(stderr,
 
2046
                        "InnoDB: Error: all read views were not closed"
 
2047
                        " before shutdown:\n"
 
2048
                        "InnoDB: %lu read views open \n",
 
2049
                        UT_LIST_GET_LEN(trx_sys->view_list) - 1);
 
2050
        }
 
2051
 
 
2052
        /* 5. Free all allocated memory and the os_fast_mutex created in
 
2053
        ut0mem.c */
 
2054
 
 
2055
        buf_pool_free();
 
2056
        ut_free_all_mem();
 
2057
 
 
2058
        if (os_thread_count != 0
 
2059
            || os_event_count != 0
 
2060
            || os_mutex_count != 0
 
2061
            || os_fast_mutex_count != 0) {
 
2062
                fprintf(stderr,
 
2063
                        "InnoDB: Warning: some resources were not"
 
2064
                        " cleaned up in shutdown:\n"
 
2065
                        "InnoDB: threads %lu, events %lu,"
 
2066
                        " os_mutexes %lu, os_fast_mutexes %lu\n",
 
2067
                        (ulong) os_thread_count, (ulong) os_event_count,
 
2068
                        (ulong) os_mutex_count, (ulong) os_fast_mutex_count);
 
2069
        }
 
2070
 
 
2071
        if (dict_foreign_err_file) {
 
2072
                fclose(dict_foreign_err_file);
 
2073
        }
 
2074
        if (lock_latest_err_file) {
 
2075
                fclose(lock_latest_err_file);
 
2076
        }
 
2077
 
 
2078
        if (srv_print_verbose_log) {
 
2079
                ut_print_timestamp(stderr);
 
2080
                fprintf(stderr,
 
2081
                        "  InnoDB: Shutdown completed;"
 
2082
                        " log sequence number %"PRIu64"\n",
 
2083
                        srv_shutdown_lsn);
 
2084
        }
 
2085
 
 
2086
        srv_was_started = FALSE;
 
2087
 
 
2088
        return((int) DB_SUCCESS);
 
2089
}
 
2090
 
 
2091
#ifdef __NETWARE__
 
2092
void set_panic_flag_for_netware()
 
2093
{
 
2094
        extern ibool panic_shutdown;
 
2095
        panic_shutdown = TRUE;
 
2096
}
 
2097
#endif /* __NETWARE__ */
 
2098
#endif /* !UNIV_HOTBACKUP */