~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Stewart Smith
  • Date: 2009-10-08 06:16:39 UTC
  • mto: This revision was merged to the branch mainline in revision 1179.
  • Revision ID: stewart@flamingspork.com-20091008061639-p37e93j3h3hapwyj
don't even think of mucking around with opt_range.cc it burns like... burny things

Show diffs side-by-side

added added

removed removed

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