~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge of Jay

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