~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2008-11-24 05:39:31 UTC
  • mto: This revision was merged to the branch mainline in revision 610.
  • Revision ID: mordred@solanthus.local-20081124053931-tzlxsgkdvs3b7n8n
Reverted libuuid check code. 

Show diffs side-by-side

added added

removed removed

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