~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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 defined(__NETWARE__)
 
1173
 
 
1174
        /* Create less event semaphores because Win 98/ME had
 
1175
        difficulty creating 40000 event semaphores.  Comment from
 
1176
        Novell, Inc.: also, these just take a lot of memory on
 
1177
        NetWare. */
 
1178
        srv_max_n_threads = 1000;
 
1179
#else
 
1180
        if (srv_pool_size >= 1000 * 1024) {
 
1181
                /* Here we still have srv_pool_size counted
 
1182
                in kilobytes (in 4.0 this was in bytes)
 
1183
                srv_boot() converts the value to
 
1184
                pages; if buffer pool is less than 1000 MB,
 
1185
                assume fewer threads. */
 
1186
                srv_max_n_threads = 50000;
 
1187
 
 
1188
        } else if (srv_pool_size >= 8 * 1024) {
 
1189
 
 
1190
                srv_max_n_threads = 10000;
 
1191
        } else {
 
1192
                srv_max_n_threads = 1000;       /* saves several MB of memory,
 
1193
                                                especially in 64-bit
 
1194
                                                computers */
 
1195
        }
 
1196
#endif
 
1197
        err = srv_boot(); /* This changes srv_pool_size to units of a page */
 
1198
 
 
1199
        if (err != DB_SUCCESS) {
 
1200
 
 
1201
                return((int) err);
 
1202
        }
 
1203
 
 
1204
        mutex_create(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK);
 
1205
 
 
1206
        if (srv_innodb_status) {
 
1207
                srv_monitor_file_name = mem_alloc(
 
1208
                        strlen(fil_path_to_mysql_datadir)
 
1209
                        + 20 + sizeof "/innodb_status.");
 
1210
                sprintf(srv_monitor_file_name, "%s/innodb_status.%lu",
 
1211
                        fil_path_to_mysql_datadir, os_proc_get_number());
 
1212
                srv_monitor_file = fopen(srv_monitor_file_name, "w+");
 
1213
                if (!srv_monitor_file) {
 
1214
                        fprintf(stderr, "InnoDB: unable to create %s: %s\n",
 
1215
                                srv_monitor_file_name, strerror(errno));
 
1216
                        return(DB_ERROR);
 
1217
                }
 
1218
        } else {
 
1219
                srv_monitor_file_name = NULL;
 
1220
                srv_monitor_file = os_file_create_tmpfile();
 
1221
                if (!srv_monitor_file) {
 
1222
                        return(DB_ERROR);
 
1223
                }
 
1224
        }
 
1225
 
 
1226
        mutex_create(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION);
 
1227
 
 
1228
        srv_dict_tmpfile = os_file_create_tmpfile();
 
1229
        if (!srv_dict_tmpfile) {
 
1230
                return(DB_ERROR);
 
1231
        }
 
1232
 
 
1233
        mutex_create(&srv_misc_tmpfile_mutex, SYNC_ANY_LATCH);
 
1234
 
 
1235
        srv_misc_tmpfile = os_file_create_tmpfile();
 
1236
        if (!srv_misc_tmpfile) {
 
1237
                return(DB_ERROR);
 
1238
        }
 
1239
 
 
1240
        /* Restrict the maximum number of file i/o threads */
 
1241
        if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) {
 
1242
 
 
1243
                srv_n_file_io_threads = SRV_MAX_N_IO_THREADS;
 
1244
        }
 
1245
 
 
1246
        if (!os_aio_use_native_aio) {
 
1247
                /* In simulated aio we currently have use only for 4 threads */
 
1248
                srv_n_file_io_threads = 4;
 
1249
 
 
1250
                os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD
 
1251
                            * srv_n_file_io_threads,
 
1252
                            srv_n_file_io_threads,
 
1253
                            SRV_MAX_N_PENDING_SYNC_IOS);
 
1254
        } else {
 
1255
                os_aio_init(SRV_N_PENDING_IOS_PER_THREAD
 
1256
                            * srv_n_file_io_threads,
 
1257
                            srv_n_file_io_threads,
 
1258
                            SRV_MAX_N_PENDING_SYNC_IOS);
 
1259
        }
 
1260
 
 
1261
        fil_init(srv_max_n_open_files);
 
1262
 
 
1263
        if (srv_use_awe) {
 
1264
                fprintf(stderr,
 
1265
                        "InnoDB: Using AWE: Memory window is %lu MB"
 
1266
                        " and AWE memory is %lu MB\n",
 
1267
                        (ulong) (srv_awe_window_size / ((1024 * 1024)
 
1268
                                                        / UNIV_PAGE_SIZE)),
 
1269
                        (ulong) (srv_pool_size / ((1024 * 1024)
 
1270
                                                  / UNIV_PAGE_SIZE)));
 
1271
 
 
1272
                /* We must disable adaptive hash indexes because they do not
 
1273
                tolerate remapping of pages in AWE */
 
1274
 
 
1275
                srv_use_adaptive_hash_indexes = FALSE;
 
1276
                ret = buf_pool_init(srv_pool_size, srv_pool_size,
 
1277
                                    srv_awe_window_size);
 
1278
        } else {
 
1279
                ret = buf_pool_init(srv_pool_size, srv_pool_size,
 
1280
                                    srv_pool_size);
 
1281
        }
 
1282
 
 
1283
        if (ret == NULL) {
 
1284
                fprintf(stderr,
 
1285
                        "InnoDB: Fatal error: cannot allocate the memory"
 
1286
                        " for the buffer pool\n");
 
1287
 
 
1288
                return(DB_ERROR);
 
1289
        }
 
1290
 
 
1291
        fsp_init();
 
1292
        log_init();
 
1293
 
 
1294
        lock_sys_create(srv_lock_table_size);
 
1295
 
 
1296
        /* Create i/o-handler threads: */
 
1297
 
 
1298
        for (i = 0; i < srv_n_file_io_threads; i++) {
 
1299
                n[i] = i;
 
1300
 
 
1301
                os_thread_create(io_handler_thread, n + i, thread_ids + i);
 
1302
        }
 
1303
 
 
1304
#ifdef UNIV_LOG_ARCHIVE
 
1305
        if (0 != ut_strcmp(srv_log_group_home_dirs[0], srv_arch_dir)) {
 
1306
                fprintf(stderr,
 
1307
                        "InnoDB: Error: you must set the log group"
 
1308
                        " home dir in my.cnf the\n"
 
1309
                        "InnoDB: same as log arch dir.\n");
 
1310
 
 
1311
                return(DB_ERROR);
 
1312
        }
 
1313
#endif /* UNIV_LOG_ARCHIVE */
 
1314
 
 
1315
        if (srv_n_log_files * srv_log_file_size >= 262144) {
 
1316
                fprintf(stderr,
 
1317
                        "InnoDB: Error: combined size of log files"
 
1318
                        " must be < 4 GB\n");
 
1319
 
 
1320
                return(DB_ERROR);
 
1321
        }
 
1322
 
 
1323
        sum_of_new_sizes = 0;
 
1324
 
 
1325
        for (i = 0; i < srv_n_data_files; i++) {
 
1326
#ifndef __WIN__
 
1327
                if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
 
1328
                        fprintf(stderr,
 
1329
                                "InnoDB: Error: file size must be < 4 GB"
 
1330
                                " with this MySQL binary\n"
 
1331
                                "InnoDB: and operating system combination,"
 
1332
                                " in some OS's < 2 GB\n");
 
1333
 
 
1334
                        return(DB_ERROR);
 
1335
                }
 
1336
#endif
 
1337
                sum_of_new_sizes += srv_data_file_sizes[i];
 
1338
        }
 
1339
 
 
1340
        if (sum_of_new_sizes < 640) {
 
1341
                fprintf(stderr,
 
1342
                        "InnoDB: Error: tablespace size must be"
 
1343
                        " at least 10 MB\n");
 
1344
 
 
1345
                return(DB_ERROR);
 
1346
        }
 
1347
 
 
1348
        err = open_or_create_data_files(&create_new_db,
 
1349
#ifdef UNIV_LOG_ARCHIVE
 
1350
                                        &min_arch_log_no, &max_arch_log_no,
 
1351
#endif /* UNIV_LOG_ARCHIVE */
 
1352
                                        &min_flushed_lsn, &max_flushed_lsn,
 
1353
                                        &sum_of_new_sizes);
 
1354
        if (err != DB_SUCCESS) {
 
1355
                fprintf(stderr,
 
1356
                        "InnoDB: Could not open or create data files.\n"
 
1357
                        "InnoDB: If you tried to add new data files,"
 
1358
                        " and it failed here,\n"
 
1359
                        "InnoDB: you should now edit innodb_data_file_path"
 
1360
                        " in my.cnf back\n"
 
1361
                        "InnoDB: to what it was, and remove the"
 
1362
                        " new ibdata files InnoDB created\n"
 
1363
                        "InnoDB: in this failed attempt. InnoDB only wrote"
 
1364
                        " those files full of\n"
 
1365
                        "InnoDB: zeros, but did not yet use them in any way."
 
1366
                        " But be careful: do not\n"
 
1367
                        "InnoDB: remove old data files"
 
1368
                        " which contain your precious data!\n");
 
1369
 
 
1370
                return((int) err);
 
1371
        }
 
1372
 
 
1373
#ifdef UNIV_LOG_ARCHIVE
 
1374
        srv_normalize_path_for_win(srv_arch_dir);
 
1375
        srv_arch_dir = srv_add_path_separator_if_needed(srv_arch_dir);
 
1376
#endif /* UNIV_LOG_ARCHIVE */
 
1377
 
 
1378
        for (i = 0; i < srv_n_log_files; i++) {
 
1379
                err = open_or_create_log_file(create_new_db, &log_file_created,
 
1380
                                              log_opened, 0, i);
 
1381
                if (err != DB_SUCCESS) {
 
1382
 
 
1383
                        return((int) err);
 
1384
                }
 
1385
 
 
1386
                if (log_file_created) {
 
1387
                        log_created = TRUE;
 
1388
                } else {
 
1389
                        log_opened = TRUE;
 
1390
                }
 
1391
                if ((log_opened && create_new_db)
 
1392
                    || (log_opened && log_created)) {
 
1393
                        fprintf(stderr,
 
1394
                                "InnoDB: Error: all log files must be"
 
1395
                                " created at the same time.\n"
 
1396
                                "InnoDB: All log files must be"
 
1397
                                " created also in database creation.\n"
 
1398
                                "InnoDB: If you want bigger or smaller"
 
1399
                                " log files, shut down the\n"
 
1400
                                "InnoDB: database and make sure there"
 
1401
                                " were no errors in shutdown.\n"
 
1402
                                "InnoDB: Then delete the existing log files."
 
1403
                                " Edit the .cnf file\n"
 
1404
                                "InnoDB: and start the database again.\n");
 
1405
 
 
1406
                        return(DB_ERROR);
 
1407
                }
 
1408
        }
 
1409
 
 
1410
        /* Open all log files and data files in the system tablespace: we
 
1411
        keep them open until database shutdown */
 
1412
 
 
1413
        fil_open_log_and_system_tablespace_files();
 
1414
 
 
1415
        if (log_created && !create_new_db
 
1416
#ifdef UNIV_LOG_ARCHIVE
 
1417
            && !srv_archive_recovery
 
1418
#endif /* UNIV_LOG_ARCHIVE */
 
1419
            ) {
 
1420
                if (ut_dulint_cmp(max_flushed_lsn, min_flushed_lsn) != 0
 
1421
#ifdef UNIV_LOG_ARCHIVE
 
1422
                    || max_arch_log_no != min_arch_log_no
 
1423
#endif /* UNIV_LOG_ARCHIVE */
 
1424
                    ) {
 
1425
                        fprintf(stderr,
 
1426
                                "InnoDB: Cannot initialize created"
 
1427
                                " log files because\n"
 
1428
                                "InnoDB: data files were not in sync"
 
1429
                                " with each other\n"
 
1430
                                "InnoDB: or the data files are corrupt.\n");
 
1431
 
 
1432
                        return(DB_ERROR);
 
1433
                }
 
1434
 
 
1435
                if (ut_dulint_cmp(max_flushed_lsn, ut_dulint_create(0, 1000))
 
1436
                    < 0) {
 
1437
                        fprintf(stderr,
 
1438
                                "InnoDB: Cannot initialize created"
 
1439
                                " log files because\n"
 
1440
                                "InnoDB: data files are corrupt,"
 
1441
                                " or new data files were\n"
 
1442
                                "InnoDB: created when the database"
 
1443
                                " was started previous\n"
 
1444
                                "InnoDB: time but the database"
 
1445
                                " was not shut down\n"
 
1446
                                "InnoDB: normally after that.\n");
 
1447
 
 
1448
                        return(DB_ERROR);
 
1449
                }
 
1450
 
 
1451
                mutex_enter(&(log_sys->mutex));
 
1452
 
 
1453
#ifdef UNIV_LOG_ARCHIVE
 
1454
                /* Do not + 1 arch_log_no because we do not use log
 
1455
                archiving */
 
1456
                recv_reset_logs(max_flushed_lsn, max_arch_log_no, TRUE);
 
1457
#else
 
1458
                recv_reset_logs(max_flushed_lsn, TRUE);
 
1459
#endif /* UNIV_LOG_ARCHIVE */
 
1460
 
 
1461
                mutex_exit(&(log_sys->mutex));
 
1462
        }
 
1463
 
 
1464
        if (create_new_db) {
 
1465
                mtr_start(&mtr);
 
1466
 
 
1467
                fsp_header_init(0, sum_of_new_sizes, &mtr);
 
1468
 
 
1469
                mtr_commit(&mtr);
 
1470
 
 
1471
                trx_sys_create();
 
1472
                dict_create();
 
1473
                srv_startup_is_before_trx_rollback_phase = FALSE;
 
1474
 
 
1475
#ifdef UNIV_LOG_ARCHIVE
 
1476
        } else if (srv_archive_recovery) {
 
1477
                fprintf(stderr,
 
1478
                        "InnoDB: Starting archive"
 
1479
                        " recovery from a backup...\n");
 
1480
                err = recv_recovery_from_archive_start(
 
1481
                        min_flushed_lsn, srv_archive_recovery_limit_lsn,
 
1482
                        min_arch_log_no);
 
1483
                if (err != DB_SUCCESS) {
 
1484
 
 
1485
                        return(DB_ERROR);
 
1486
                }
 
1487
                /* Since ibuf init is in dict_boot, and ibuf is needed
 
1488
                in any disk i/o, first call dict_boot */
 
1489
 
 
1490
                dict_boot();
 
1491
                trx_sys_init_at_db_start();
 
1492
                srv_startup_is_before_trx_rollback_phase = FALSE;
 
1493
 
 
1494
                /* Initialize the fsp free limit global variable in the log
 
1495
                system */
 
1496
                fsp_header_get_free_limit(0);
 
1497
 
 
1498
                recv_recovery_from_archive_finish();
 
1499
#endif /* UNIV_LOG_ARCHIVE */
 
1500
        } else {
 
1501
                /* We always try to do a recovery, even if the database had
 
1502
                been shut down normally: this is the normal startup path */
 
1503
 
 
1504
                err = recv_recovery_from_checkpoint_start(LOG_CHECKPOINT,
 
1505
                                                          ut_dulint_max,
 
1506
                                                          min_flushed_lsn,
 
1507
                                                          max_flushed_lsn);
 
1508
                if (err != DB_SUCCESS) {
 
1509
 
 
1510
                        return(DB_ERROR);
 
1511
                }
 
1512
 
 
1513
                /* Since the insert buffer init is in dict_boot, and the
 
1514
                insert buffer is needed in any disk i/o, first we call
 
1515
                dict_boot(). Note that trx_sys_init_at_db_start() only needs
 
1516
                to access space 0, and the insert buffer at this stage already
 
1517
                works for space 0. */
 
1518
 
 
1519
                dict_boot();
 
1520
                trx_sys_init_at_db_start();
 
1521
 
 
1522
                if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
 
1523
                        /* The following call is necessary for the insert
 
1524
                        buffer to work with multiple tablespaces. We must
 
1525
                        know the mapping between space id's and .ibd file
 
1526
                        names.
 
1527
 
 
1528
                        In a crash recovery, we check that the info in data
 
1529
                        dictionary is consistent with what we already know
 
1530
                        about space id's from the call of
 
1531
                        fil_load_single_table_tablespaces().
 
1532
 
 
1533
                        In a normal startup, we create the space objects for
 
1534
                        every table in the InnoDB data dictionary that has
 
1535
                        an .ibd file.
 
1536
 
 
1537
                        We also determine the maximum tablespace id used.
 
1538
 
 
1539
                        TODO: We may have incomplete transactions in the
 
1540
                        data dictionary tables. Does that harm the scanning of
 
1541
                        the data dictionary below? */
 
1542
 
 
1543
                        dict_check_tablespaces_and_store_max_id(
 
1544
                                recv_needed_recovery);
 
1545
                }
 
1546
 
 
1547
                srv_startup_is_before_trx_rollback_phase = FALSE;
 
1548
 
 
1549
                /* Initialize the fsp free limit global variable in the log
 
1550
                system */
 
1551
                fsp_header_get_free_limit(0);
 
1552
 
 
1553
                /* recv_recovery_from_checkpoint_finish needs trx lists which
 
1554
                are initialized in trx_sys_init_at_db_start(). */
 
1555
 
 
1556
                recv_recovery_from_checkpoint_finish();
 
1557
        }
 
1558
 
 
1559
        if (!create_new_db && sum_of_new_sizes > 0) {
 
1560
                /* New data file(s) were added */
 
1561
                mtr_start(&mtr);
 
1562
 
 
1563
                fsp_header_inc_size(0, sum_of_new_sizes, &mtr);
 
1564
 
 
1565
                mtr_commit(&mtr);
 
1566
 
 
1567
                /* Immediately write the log record about increased tablespace
 
1568
                size to disk, so that it is durable even if mysqld would crash
 
1569
                quickly */
 
1570
 
 
1571
                log_buffer_flush_to_disk();
 
1572
        }
 
1573
 
 
1574
#ifdef UNIV_LOG_ARCHIVE
 
1575
        /* Archiving is always off under MySQL */
 
1576
        if (!srv_log_archive_on) {
 
1577
                ut_a(DB_SUCCESS == log_archive_noarchivelog());
 
1578
        } else {
 
1579
                mutex_enter(&(log_sys->mutex));
 
1580
 
 
1581
                start_archive = FALSE;
 
1582
 
 
1583
                if (log_sys->archiving_state == LOG_ARCH_OFF) {
 
1584
                        start_archive = TRUE;
 
1585
                }
 
1586
 
 
1587
                mutex_exit(&(log_sys->mutex));
 
1588
 
 
1589
                if (start_archive) {
 
1590
                        ut_a(DB_SUCCESS == log_archive_archivelog());
 
1591
                }
 
1592
        }
 
1593
#endif /* UNIV_LOG_ARCHIVE */
 
1594
 
 
1595
        /* fprintf(stderr, "Max allowed record size %lu\n",
 
1596
        page_get_free_space_of_empty() / 2); */
 
1597
 
 
1598
        /* Create the thread which watches the timeouts for lock waits
 
1599
        and prints InnoDB monitor info */
 
1600
 
 
1601
        os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL,
 
1602
                         thread_ids + 2 + SRV_MAX_N_IO_THREADS);
 
1603
 
 
1604
        /* Create the thread which warns of long semaphore waits */
 
1605
        os_thread_create(&srv_error_monitor_thread, NULL,
 
1606
                         thread_ids + 3 + SRV_MAX_N_IO_THREADS);
 
1607
        srv_was_started = TRUE;
 
1608
        srv_is_being_started = FALSE;
 
1609
 
 
1610
        if (trx_doublewrite == NULL) {
 
1611
                /* Create the doublewrite buffer to a new tablespace */
 
1612
 
 
1613
                trx_sys_create_doublewrite_buf();
 
1614
        }
 
1615
 
 
1616
        err = dict_create_or_check_foreign_constraint_tables();
 
1617
 
 
1618
        if (err != DB_SUCCESS) {
 
1619
                return((int)DB_ERROR);
 
1620
        }
 
1621
 
 
1622
        /* Create the master thread which does purge and other utility
 
1623
        operations */
 
1624
 
 
1625
        os_thread_create(&srv_master_thread, NULL, thread_ids
 
1626
                         + (1 + SRV_MAX_N_IO_THREADS));
 
1627
#ifdef UNIV_DEBUG
 
1628
        /* buf_debug_prints = TRUE; */
 
1629
#endif /* UNIV_DEBUG */
 
1630
        sum_of_data_file_sizes = 0;
 
1631
 
 
1632
        for (i = 0; i < srv_n_data_files; i++) {
 
1633
                sum_of_data_file_sizes += srv_data_file_sizes[i];
 
1634
        }
 
1635
 
 
1636
        tablespace_size_in_header = fsp_header_get_tablespace_size(0);
 
1637
 
 
1638
        if (!srv_auto_extend_last_data_file
 
1639
            && sum_of_data_file_sizes != tablespace_size_in_header) {
 
1640
 
 
1641
                fprintf(stderr,
 
1642
                        "InnoDB: Error: tablespace size"
 
1643
                        " stored in header is %lu pages, but\n"
 
1644
                        "InnoDB: the sum of data file sizes is %lu pages\n",
 
1645
                        (ulong) tablespace_size_in_header,
 
1646
                        (ulong) sum_of_data_file_sizes);
 
1647
 
 
1648
                if (srv_force_recovery == 0
 
1649
                    && sum_of_data_file_sizes < tablespace_size_in_header) {
 
1650
                        /* This is a fatal error, the tail of a tablespace is
 
1651
                        missing */
 
1652
 
 
1653
                        fprintf(stderr,
 
1654
                                "InnoDB: Cannot start InnoDB."
 
1655
                                " The tail of the system tablespace is\n"
 
1656
                                "InnoDB: missing. Have you edited"
 
1657
                                " innodb_data_file_path in my.cnf in an\n"
 
1658
                                "InnoDB: inappropriate way, removing"
 
1659
                                " ibdata files from there?\n"
 
1660
                                "InnoDB: You can set innodb_force_recovery=1"
 
1661
                                " in my.cnf to force\n"
 
1662
                                "InnoDB: a startup if you are trying"
 
1663
                                " to recover a badly corrupt database.\n");
 
1664
 
 
1665
                        return(DB_ERROR);
 
1666
                }
 
1667
        }
 
1668
 
 
1669
        if (srv_auto_extend_last_data_file
 
1670
            && sum_of_data_file_sizes < tablespace_size_in_header) {
 
1671
 
 
1672
                fprintf(stderr,
 
1673
                        "InnoDB: Error: tablespace size stored in header"
 
1674
                        " is %lu pages, but\n"
 
1675
                        "InnoDB: the sum of data file sizes"
 
1676
                        " is only %lu pages\n",
 
1677
                        (ulong) tablespace_size_in_header,
 
1678
                        (ulong) sum_of_data_file_sizes);
 
1679
 
 
1680
                if (srv_force_recovery == 0) {
 
1681
 
 
1682
                        fprintf(stderr,
 
1683
                                "InnoDB: Cannot start InnoDB. The tail of"
 
1684
                                " the system tablespace is\n"
 
1685
                                "InnoDB: missing. Have you edited"
 
1686
                                " innodb_data_file_path in my.cnf in an\n"
 
1687
                                "InnoDB: inappropriate way, removing"
 
1688
                                " ibdata files from there?\n"
 
1689
                                "InnoDB: You can set innodb_force_recovery=1"
 
1690
                                " in my.cnf to force\n"
 
1691
                                "InnoDB: a startup if you are trying to"
 
1692
                                " recover a badly corrupt database.\n");
 
1693
 
 
1694
                        return(DB_ERROR);
 
1695
                }
 
1696
        }
 
1697
 
 
1698
        /* Check that os_fast_mutexes work as expected */
 
1699
        os_fast_mutex_init(&srv_os_test_mutex);
 
1700
 
 
1701
        if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
 
1702
                fprintf(stderr,
 
1703
                        "InnoDB: Error: pthread_mutex_trylock returns"
 
1704
                        " an unexpected value on\n"
 
1705
                        "InnoDB: success! Cannot continue.\n");
 
1706
                exit(1);
 
1707
        }
 
1708
 
 
1709
        os_fast_mutex_unlock(&srv_os_test_mutex);
 
1710
 
 
1711
        os_fast_mutex_lock(&srv_os_test_mutex);
 
1712
 
 
1713
        os_fast_mutex_unlock(&srv_os_test_mutex);
 
1714
 
 
1715
        os_fast_mutex_free(&srv_os_test_mutex);
 
1716
 
 
1717
        if (srv_print_verbose_log) {
 
1718
                ut_print_timestamp(stderr);
 
1719
                fprintf(stderr,
 
1720
                        "  InnoDB: Started; log sequence number %lu %lu\n",
 
1721
                        (ulong) ut_dulint_get_high(srv_start_lsn),
 
1722
                        (ulong) ut_dulint_get_low(srv_start_lsn));
 
1723
        }
 
1724
 
 
1725
        if (srv_force_recovery > 0) {
 
1726
                fprintf(stderr,
 
1727
                        "InnoDB: !!! innodb_force_recovery"
 
1728
                        " is set to %lu !!!\n",
 
1729
                        (ulong) srv_force_recovery);
 
1730
        }
 
1731
 
 
1732
        fflush(stderr);
 
1733
 
 
1734
        if (trx_doublewrite_must_reset_space_ids) {
 
1735
                /* Actually, we did not change the undo log format between
 
1736
                4.0 and 4.1.1, and we would not need to run purge to
 
1737
                completion. Note also that the purge algorithm in 4.1.1
 
1738
                can process the the history list again even after a full
 
1739
                purge, because our algorithm does not cut the end of the
 
1740
                history list in all cases so that it would become empty
 
1741
                after a full purge. That mean that we may purge 4.0 type
 
1742
                undo log even after this phase.
 
1743
 
 
1744
                The insert buffer record format changed between 4.0 and
 
1745
                4.1.1. It is essential that the insert buffer is emptied
 
1746
                here! */
 
1747
 
 
1748
                fprintf(stderr,
 
1749
                        "InnoDB: You are upgrading to an"
 
1750
                        " InnoDB version which allows multiple\n"
 
1751
                        "InnoDB: tablespaces. Wait that purge"
 
1752
                        " and insert buffer merge run to\n"
 
1753
                        "InnoDB: completion...\n");
 
1754
                for (;;) {
 
1755
                        os_thread_sleep(1000000);
 
1756
 
 
1757
                        if (0 == strcmp(srv_main_thread_op_info,
 
1758
                                        "waiting for server activity")) {
 
1759
 
 
1760
                                ut_a(ibuf_is_empty());
 
1761
 
 
1762
                                break;
 
1763
                        }
 
1764
                }
 
1765
                fprintf(stderr,
 
1766
                        "InnoDB: Full purge and insert buffer merge"
 
1767
                        " completed.\n");
 
1768
 
 
1769
                trx_sys_mark_upgraded_to_multiple_tablespaces();
 
1770
 
 
1771
                fprintf(stderr,
 
1772
                        "InnoDB: You have now successfully upgraded"
 
1773
                        " to the multiple tablespaces\n"
 
1774
                        "InnoDB: format. You should NOT DOWNGRADE"
 
1775
                        " to an earlier version of\n"
 
1776
                        "InnoDB: InnoDB! But if you absolutely need to"
 
1777
                        " downgrade, see\n"
 
1778
                        "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
 
1779
                        "multiple-tablespaces.html\n"
 
1780
                        "InnoDB: for instructions.\n");
 
1781
        }
 
1782
 
 
1783
        if (srv_force_recovery == 0) {
 
1784
                /* In the insert buffer we may have even bigger tablespace
 
1785
                id's, because we may have dropped those tablespaces, but
 
1786
                insert buffer merge has not had time to clean the records from
 
1787
                the ibuf tree. */
 
1788
 
 
1789
                ibuf_update_max_tablespace_id();
 
1790
        }
 
1791
 
 
1792
        srv_file_per_table = srv_file_per_table_original_value;
 
1793
 
 
1794
        return((int) DB_SUCCESS);
 
1795
}
 
1796
 
 
1797
/********************************************************************
 
1798
Shuts down the InnoDB database. */
 
1799
 
 
1800
int
 
1801
innobase_shutdown_for_mysql(void)
 
1802
/*=============================*/
 
1803
                                /* out: DB_SUCCESS or error code */
 
1804
{
 
1805
        ulint   i;
 
1806
#ifdef __NETWARE__
 
1807
        extern ibool panic_shutdown;
 
1808
#endif
 
1809
        if (!srv_was_started) {
 
1810
                if (srv_is_being_started) {
 
1811
                        ut_print_timestamp(stderr);
 
1812
                        fprintf(stderr,
 
1813
                                "  InnoDB: Warning: shutting down"
 
1814
                                " a not properly started\n"
 
1815
                                "InnoDB: or created database!\n");
 
1816
                }
 
1817
 
 
1818
                return(DB_SUCCESS);
 
1819
        }
 
1820
 
 
1821
        /* 1. Flush the buffer pool to disk, write the current lsn to
 
1822
        the tablespace header(s), and copy all log data to archive.
 
1823
        The step 1 is the real InnoDB shutdown. The remaining steps 2 - ...
 
1824
        just free data structures after the shutdown. */
 
1825
 
 
1826
 
 
1827
        if (srv_fast_shutdown == 2) {
 
1828
                ut_print_timestamp(stderr);
 
1829
                fprintf(stderr,
 
1830
                        "  InnoDB: MySQL has requested a very fast shutdown"
 
1831
                        " without flushing "
 
1832
                        "the InnoDB buffer pool to data files."
 
1833
                        " At the next mysqld startup "
 
1834
                        "InnoDB will do a crash recovery!\n");
 
1835
        }
 
1836
 
 
1837
#ifdef __NETWARE__
 
1838
        if(!panic_shutdown)
 
1839
#endif
 
1840
                logs_empty_and_mark_files_at_shutdown();
 
1841
 
 
1842
        if (srv_conc_n_threads != 0) {
 
1843
                fprintf(stderr,
 
1844
                        "InnoDB: Warning: query counter shows %ld queries"
 
1845
                        " still\n"
 
1846
                        "InnoDB: inside InnoDB at shutdown\n",
 
1847
                        srv_conc_n_threads);
 
1848
        }
 
1849
 
 
1850
        /* 2. Make all threads created by InnoDB to exit */
 
1851
 
 
1852
        srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
 
1853
 
 
1854
        /* In a 'very fast' shutdown, we do not need to wait for these threads
 
1855
        to die; all which counts is that we flushed the log; a 'very fast'
 
1856
        shutdown is essentially a crash. */
 
1857
 
 
1858
        if (srv_fast_shutdown == 2) {
 
1859
                return(DB_SUCCESS);
 
1860
        }
 
1861
 
 
1862
        /* All threads end up waiting for certain events. Put those events
 
1863
        to the signaled state. Then the threads will exit themselves in
 
1864
        os_thread_event_wait(). */
 
1865
 
 
1866
        for (i = 0; i < 1000; i++) {
 
1867
                /* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
 
1868
                HERE OR EARLIER */
 
1869
 
 
1870
                /* a. Let the lock timeout thread exit */
 
1871
                os_event_set(srv_lock_timeout_thread_event);
 
1872
 
 
1873
                /* b. srv error monitor thread exits automatically, no need
 
1874
                to do anything here */
 
1875
 
 
1876
                /* c. We wake the master thread so that it exits */
 
1877
                srv_wake_master_thread();
 
1878
 
 
1879
                /* d. Exit the i/o threads */
 
1880
 
 
1881
                os_aio_wake_all_threads_at_shutdown();
 
1882
 
 
1883
                os_mutex_enter(os_sync_mutex);
 
1884
 
 
1885
                if (os_thread_count == 0) {
 
1886
                        /* All the threads have exited or are just exiting;
 
1887
                        NOTE that the threads may not have completed their
 
1888
                        exit yet. Should we use pthread_join() to make sure
 
1889
                        they have exited? Now we just sleep 0.1 seconds and
 
1890
                        hope that is enough! */
 
1891
 
 
1892
                        os_mutex_exit(os_sync_mutex);
 
1893
 
 
1894
                        os_thread_sleep(100000);
 
1895
 
 
1896
                        break;
 
1897
                }
 
1898
 
 
1899
                os_mutex_exit(os_sync_mutex);
 
1900
 
 
1901
                os_thread_sleep(100000);
 
1902
        }
 
1903
 
 
1904
        if (i == 1000) {
 
1905
                fprintf(stderr,
 
1906
                        "InnoDB: Warning: %lu threads created by InnoDB"
 
1907
                        " had not exited at shutdown!\n",
 
1908
                        (ulong) os_thread_count);
 
1909
        }
 
1910
 
 
1911
        if (srv_monitor_file) {
 
1912
                fclose(srv_monitor_file);
 
1913
                srv_monitor_file = 0;
 
1914
                if (srv_monitor_file_name) {
 
1915
                        unlink(srv_monitor_file_name);
 
1916
                        mem_free(srv_monitor_file_name);
 
1917
                }
 
1918
        }
 
1919
        if (srv_dict_tmpfile) {
 
1920
                fclose(srv_dict_tmpfile);
 
1921
                srv_dict_tmpfile = 0;
 
1922
        }
 
1923
 
 
1924
        if (srv_misc_tmpfile) {
 
1925
                fclose(srv_misc_tmpfile);
 
1926
                srv_misc_tmpfile = 0;
 
1927
        }
 
1928
 
 
1929
        mutex_free(&srv_monitor_file_mutex);
 
1930
        mutex_free(&srv_dict_tmpfile_mutex);
 
1931
        mutex_free(&srv_misc_tmpfile_mutex);
 
1932
 
 
1933
        /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
 
1934
        them */
 
1935
        sync_close();
 
1936
 
 
1937
        /* 4. Free the os_conc_mutex and all os_events and os_mutexes */
 
1938
 
 
1939
        srv_free();
 
1940
        os_sync_free();
 
1941
 
 
1942
        /* Check that all read views are closed except read view owned
 
1943
        by a purge. */
 
1944
 
 
1945
        if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
 
1946
                fprintf(stderr,
 
1947
                        "InnoDB: Error: all read views were not closed"
 
1948
                        " before shutdown:\n"
 
1949
                        "InnoDB: %lu read views open \n",
 
1950
                        UT_LIST_GET_LEN(trx_sys->view_list) - 1);
 
1951
        }
 
1952
 
 
1953
        /* 5. Free all allocated memory and the os_fast_mutex created in
 
1954
        ut0mem.c */
 
1955
 
 
1956
        ut_free_all_mem();
 
1957
 
 
1958
        if (os_thread_count != 0
 
1959
            || os_event_count != 0
 
1960
            || os_mutex_count != 0
 
1961
            || os_fast_mutex_count != 0) {
 
1962
                fprintf(stderr,
 
1963
                        "InnoDB: Warning: some resources were not"
 
1964
                        " cleaned up in shutdown:\n"
 
1965
                        "InnoDB: threads %lu, events %lu,"
 
1966
                        " os_mutexes %lu, os_fast_mutexes %lu\n",
 
1967
                        (ulong) os_thread_count, (ulong) os_event_count,
 
1968
                        (ulong) os_mutex_count, (ulong) os_fast_mutex_count);
 
1969
        }
 
1970
 
 
1971
        if (dict_foreign_err_file) {
 
1972
                fclose(dict_foreign_err_file);
 
1973
        }
 
1974
        if (lock_latest_err_file) {
 
1975
                fclose(lock_latest_err_file);
 
1976
        }
 
1977
 
 
1978
        if (srv_print_verbose_log) {
 
1979
                ut_print_timestamp(stderr);
 
1980
                fprintf(stderr,
 
1981
                        "  InnoDB: Shutdown completed;"
 
1982
                        " log sequence number %lu %lu\n",
 
1983
                        (ulong) ut_dulint_get_high(srv_shutdown_lsn),
 
1984
                        (ulong) ut_dulint_get_low(srv_shutdown_lsn));
 
1985
        }
 
1986
 
 
1987
        return((int) DB_SUCCESS);
 
1988
}
 
1989
 
 
1990
#ifdef __NETWARE__
 
1991
void set_panic_flag_for_netware()
 
1992
{
 
1993
        extern ibool panic_shutdown;
 
1994
        panic_shutdown = TRUE;
 
1995
}
 
1996
#endif /* __NETWARE__ */
 
1997
#endif /* !UNIV_HOTBACKUP */