~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Tags: innodb-plugin-1.0.1
Imported 1.0.1 with clean - with no changes.

Show diffs side-by-side

added added

removed removed

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