~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Jay Pipes
  • Date: 2009-01-30 04:38:21 UTC
  • mto: This revision was merged to the branch mainline in revision 830.
  • Revision ID: jpipes@serialcoder-20090130043821-4d7jg2ftabefamxb
Fixes for the QUARTER() function to use new Temporal system and throw
errors on bad datetime values.

Added test case for QUARTER() function and modified func_time.test existing
test to correctly throw errors and report NULL, not 0 on NULL input.

Show diffs side-by-side

added added

removed removed

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