~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2008-08-16 21:06:22 UTC
  • Revision ID: monty@inaugust.com-20080816210622-zpnn13unyinqzn72
Updated po files.

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 */