~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-07-16 22:37:01 UTC
  • mto: This revision was merged to the branch mainline in revision 1100.
  • Revision ID: brian@gaz-20090716223701-vbbbo8dmgd2ljqqo
Refactor TableShare has to be behind class.

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
 
        /* If user has set the value of innodb_file_io_threads then
1300
 
        we'll emit a message telling the user that this parameter
1301
 
        is now deprecated. */
1302
 
        if (srv_n_file_io_threads != 4) {
1303
 
                fprintf(stderr, "InnoDB: Warning:"
1304
 
                        " innodb_file_io_threads is deprecated."
1305
 
                        " Please use innodb_read_io_threads and"
1306
 
                        " innodb_write_io_threads instead\n");
1307
 
        }
1308
 
 
1309
 
        /* Now overwrite the value on srv_n_file_io_threads */
1310
 
        srv_n_file_io_threads = 2 + srv_n_read_io_threads
1311
 
                                + srv_n_write_io_threads;
1312
 
 
1313
 
        ut_a(srv_n_file_io_threads <= SRV_MAX_N_IO_THREADS);
1314
 
 
1315
 
        /* TODO: Investigate if SRV_N_PENDING_IOS_PER_THREAD (32) limit
1316
 
        still applies to windows. */
1317
 
        if (!os_aio_use_native_aio) {
1318
 
                io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
1319
 
        } else {
1320
 
                io_limit = SRV_N_PENDING_IOS_PER_THREAD;
1321
 
        }
1322
 
 
1323
 
        os_aio_init(io_limit,
1324
 
                    srv_n_read_io_threads,
1325
 
                    srv_n_write_io_threads,
1326
 
                    SRV_MAX_N_PENDING_SYNC_IOS);
1327
 
 
1328
 
        fil_init(srv_file_per_table ? 50000 : 5000,
1329
 
                 srv_max_n_open_files);
1330
 
 
1331
 
        ret = buf_pool_init();
1332
 
 
1333
 
        if (ret == NULL) {
1334
 
                fprintf(stderr,
1335
 
                        "InnoDB: Fatal error: cannot allocate the memory"
1336
 
                        " for the buffer pool\n");
1337
 
 
1338
 
                return(DB_ERROR);
1339
 
        }
1340
 
 
1341
 
#ifdef UNIV_DEBUG
1342
 
        /* We have observed deadlocks with a 5MB buffer pool but
1343
 
        the actual lower limit could very well be a little higher. */
1344
 
 
1345
 
        if (srv_buf_pool_size <= 5 * 1024 * 1024) {
1346
 
 
1347
 
                fprintf(stderr, "InnoDB: Warning: Small buffer pool size "
1348
 
                        "(%luM), the flst_validate() debug function "
1349
 
                        "can cause a deadlock if the buffer pool fills up.\n",
1350
 
                        srv_buf_pool_size / 1024 / 1024);
1351
 
        }
1352
 
#endif
1353
 
 
1354
 
        fsp_init();
1355
 
        log_init();
1356
 
 
1357
 
        lock_sys_create(srv_lock_table_size);
1358
 
 
1359
 
        /* Create i/o-handler threads: */
1360
 
 
1361
 
        for (i = 0; i < srv_n_file_io_threads; i++) {
1362
 
                n[i] = i;
1363
 
 
1364
 
                os_thread_create(io_handler_thread, n + i, thread_ids + i);
1365
 
        }
1366
 
 
1367
 
#ifdef UNIV_LOG_ARCHIVE
1368
 
        if (0 != ut_strcmp(srv_log_group_home_dirs[0], srv_arch_dir)) {
1369
 
                fprintf(stderr,
1370
 
                        "InnoDB: Error: you must set the log group"
1371
 
                        " home dir in my.cnf the\n"
1372
 
                        "InnoDB: same as log arch dir.\n");
1373
 
 
1374
 
                return(DB_ERROR);
1375
 
        }
1376
 
#endif /* UNIV_LOG_ARCHIVE */
1377
 
 
1378
 
        if (srv_n_log_files * srv_log_file_size >= 262144) {
1379
 
                fprintf(stderr,
1380
 
                        "InnoDB: Error: combined size of log files"
1381
 
                        " must be < 4 GB\n");
1382
 
 
1383
 
                return(DB_ERROR);
1384
 
        }
1385
 
 
1386
 
        sum_of_new_sizes = 0;
1387
 
 
1388
 
        for (i = 0; i < srv_n_data_files; i++) {
1389
 
#ifndef __WIN__
1390
 
                if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
1391
 
                        fprintf(stderr,
1392
 
                                "InnoDB: Error: file size must be < 4 GB"
1393
 
                                " with this MySQL binary\n"
1394
 
                                "InnoDB: and operating system combination,"
1395
 
                                " in some OS's < 2 GB\n");
1396
 
 
1397
 
                        return(DB_ERROR);
1398
 
                }
1399
 
#endif
1400
 
                sum_of_new_sizes += srv_data_file_sizes[i];
1401
 
        }
1402
 
 
1403
 
        if (sum_of_new_sizes < 640) {
1404
 
                fprintf(stderr,
1405
 
                        "InnoDB: Error: tablespace size must be"
1406
 
                        " at least 10 MB\n");
1407
 
 
1408
 
                return(DB_ERROR);
1409
 
        }
1410
 
 
1411
 
        err = open_or_create_data_files(&create_new_db,
1412
 
#ifdef UNIV_LOG_ARCHIVE
1413
 
                                        &min_arch_log_no, &max_arch_log_no,
1414
 
#endif /* UNIV_LOG_ARCHIVE */
1415
 
                                        &min_flushed_lsn, &max_flushed_lsn,
1416
 
                                        &sum_of_new_sizes);
1417
 
        if (err != DB_SUCCESS) {
1418
 
                fprintf(stderr,
1419
 
                        "InnoDB: Could not open or create data files.\n"
1420
 
                        "InnoDB: If you tried to add new data files,"
1421
 
                        " and it failed here,\n"
1422
 
                        "InnoDB: you should now edit innodb_data_file_path"
1423
 
                        " in my.cnf back\n"
1424
 
                        "InnoDB: to what it was, and remove the"
1425
 
                        " new ibdata files InnoDB created\n"
1426
 
                        "InnoDB: in this failed attempt. InnoDB only wrote"
1427
 
                        " those files full of\n"
1428
 
                        "InnoDB: zeros, but did not yet use them in any way."
1429
 
                        " But be careful: do not\n"
1430
 
                        "InnoDB: remove old data files"
1431
 
                        " which contain your precious data!\n");
1432
 
 
1433
 
                return((int) err);
1434
 
        }
1435
 
 
1436
 
#ifdef UNIV_LOG_ARCHIVE
1437
 
        srv_normalize_path_for_win(srv_arch_dir);
1438
 
        srv_arch_dir = srv_add_path_separator_if_needed(srv_arch_dir);
1439
 
#endif /* UNIV_LOG_ARCHIVE */
1440
 
 
1441
 
        for (i = 0; i < srv_n_log_files; i++) {
1442
 
                err = open_or_create_log_file(create_new_db, &log_file_created,
1443
 
                                              log_opened, 0, i);
1444
 
                if (err != DB_SUCCESS) {
1445
 
 
1446
 
                        return((int) err);
1447
 
                }
1448
 
 
1449
 
                if (log_file_created) {
1450
 
                        log_created = TRUE;
1451
 
                } else {
1452
 
                        log_opened = TRUE;
1453
 
                }
1454
 
                if ((log_opened && create_new_db)
1455
 
                    || (log_opened && log_created)) {
1456
 
                        fprintf(stderr,
1457
 
                                "InnoDB: Error: all log files must be"
1458
 
                                " created at the same time.\n"
1459
 
                                "InnoDB: All log files must be"
1460
 
                                " created also in database creation.\n"
1461
 
                                "InnoDB: If you want bigger or smaller"
1462
 
                                " log files, shut down the\n"
1463
 
                                "InnoDB: database and make sure there"
1464
 
                                " were no errors in shutdown.\n"
1465
 
                                "InnoDB: Then delete the existing log files."
1466
 
                                " Edit the .cnf file\n"
1467
 
                                "InnoDB: and start the database again.\n");
1468
 
 
1469
 
                        return(DB_ERROR);
1470
 
                }
1471
 
        }
1472
 
 
1473
 
        /* Open all log files and data files in the system tablespace: we
1474
 
        keep them open until database shutdown */
1475
 
 
1476
 
        fil_open_log_and_system_tablespace_files();
1477
 
 
1478
 
        if (log_created && !create_new_db
1479
 
#ifdef UNIV_LOG_ARCHIVE
1480
 
            && !srv_archive_recovery
1481
 
#endif /* UNIV_LOG_ARCHIVE */
1482
 
            ) {
1483
 
                if (max_flushed_lsn != min_flushed_lsn
1484
 
#ifdef UNIV_LOG_ARCHIVE
1485
 
                    || max_arch_log_no != min_arch_log_no
1486
 
#endif /* UNIV_LOG_ARCHIVE */
1487
 
                    ) {
1488
 
                        fprintf(stderr,
1489
 
                                "InnoDB: Cannot initialize created"
1490
 
                                " log files because\n"
1491
 
                                "InnoDB: data files were not in sync"
1492
 
                                " with each other\n"
1493
 
                                "InnoDB: or the data files are corrupt.\n");
1494
 
 
1495
 
                        return(DB_ERROR);
1496
 
                }
1497
 
 
1498
 
                if (max_flushed_lsn < (ib_uint64_t) 1000) {
1499
 
                        fprintf(stderr,
1500
 
                                "InnoDB: Cannot initialize created"
1501
 
                                " log files because\n"
1502
 
                                "InnoDB: data files are corrupt,"
1503
 
                                " or new data files were\n"
1504
 
                                "InnoDB: created when the database"
1505
 
                                " was started previous\n"
1506
 
                                "InnoDB: time but the database"
1507
 
                                " was not shut down\n"
1508
 
                                "InnoDB: normally after that.\n");
1509
 
 
1510
 
                        return(DB_ERROR);
1511
 
                }
1512
 
 
1513
 
                mutex_enter(&(log_sys->mutex));
1514
 
 
1515
 
#ifdef UNIV_LOG_ARCHIVE
1516
 
                /* Do not + 1 arch_log_no because we do not use log
1517
 
                archiving */
1518
 
                recv_reset_logs(max_flushed_lsn, max_arch_log_no, TRUE);
1519
 
#else
1520
 
                recv_reset_logs(max_flushed_lsn, TRUE);
1521
 
#endif /* UNIV_LOG_ARCHIVE */
1522
 
 
1523
 
                mutex_exit(&(log_sys->mutex));
1524
 
        }
1525
 
 
1526
 
        trx_sys_file_format_init();
1527
 
 
1528
 
        if (create_new_db) {
1529
 
                mtr_start(&mtr);
1530
 
                fsp_header_init(0, sum_of_new_sizes, &mtr);
1531
 
 
1532
 
                mtr_commit(&mtr);
1533
 
 
1534
 
                trx_sys_create();
1535
 
                dict_create();
1536
 
                srv_startup_is_before_trx_rollback_phase = FALSE;
1537
 
 
1538
 
#ifdef UNIV_LOG_ARCHIVE
1539
 
        } else if (srv_archive_recovery) {
1540
 
                fprintf(stderr,
1541
 
                        "InnoDB: Starting archive"
1542
 
                        " recovery from a backup...\n");
1543
 
                err = recv_recovery_from_archive_start(
1544
 
                        min_flushed_lsn, srv_archive_recovery_limit_lsn,
1545
 
                        min_arch_log_no);
1546
 
                if (err != DB_SUCCESS) {
1547
 
 
1548
 
                        return(DB_ERROR);
1549
 
                }
1550
 
                /* Since ibuf init is in dict_boot, and ibuf is needed
1551
 
                in any disk i/o, first call dict_boot */
1552
 
 
1553
 
                dict_boot();
1554
 
                trx_sys_init_at_db_start();
1555
 
                srv_startup_is_before_trx_rollback_phase = FALSE;
1556
 
 
1557
 
                /* Initialize the fsp free limit global variable in the log
1558
 
                system */
1559
 
                fsp_header_get_free_limit();
1560
 
 
1561
 
                recv_recovery_from_archive_finish();
1562
 
#endif /* UNIV_LOG_ARCHIVE */
1563
 
        } else {
1564
 
 
1565
 
                /* Check if we support the max format that is stamped
1566
 
                on the system tablespace. 
1567
 
                Note:  We are NOT allowed to make any modifications to
1568
 
                the TRX_SYS_PAGE_NO page before recovery  because this
1569
 
                page also contains the max_trx_id etc. important system
1570
 
                variables that are required for recovery.  We need to
1571
 
                ensure that we return the system to a state where normal
1572
 
                recovery is guaranteed to work. We do this by
1573
 
                invalidating the buffer cache, this will force the
1574
 
                reread of the page and restoration to its last known
1575
 
                consistent state, this is REQUIRED for the recovery
1576
 
                process to work. */
1577
 
                err = trx_sys_file_format_max_check(
1578
 
                        srv_check_file_format_at_startup);
1579
 
 
1580
 
                if (err != DB_SUCCESS) {
1581
 
                        return(err);
1582
 
                }
1583
 
 
1584
 
                /* Invalidate the buffer pool to ensure that we reread
1585
 
                the page that we read above, during recovery.
1586
 
                Note that this is not as heavy weight as it seems. At
1587
 
                this point there will be only ONE page in the buf_LRU
1588
 
                and there must be no page in the buf_flush list. */
1589
 
                buf_pool_invalidate();
1590
 
 
1591
 
                /* We always try to do a recovery, even if the database had
1592
 
                been shut down normally: this is the normal startup path */
1593
 
 
1594
 
                err = recv_recovery_from_checkpoint_start(LOG_CHECKPOINT,
1595
 
                                                          IB_ULONGLONG_MAX,
1596
 
                                                          min_flushed_lsn,
1597
 
                                                          max_flushed_lsn);
1598
 
                if (err != DB_SUCCESS) {
1599
 
 
1600
 
                        return(DB_ERROR);
1601
 
                }
1602
 
 
1603
 
                /* Since the insert buffer init is in dict_boot, and the
1604
 
                insert buffer is needed in any disk i/o, first we call
1605
 
                dict_boot(). Note that trx_sys_init_at_db_start() only needs
1606
 
                to access space 0, and the insert buffer at this stage already
1607
 
                works for space 0. */
1608
 
 
1609
 
                dict_boot();
1610
 
                trx_sys_init_at_db_start();
1611
 
 
1612
 
                if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
1613
 
                        /* The following call is necessary for the insert
1614
 
                        buffer to work with multiple tablespaces. We must
1615
 
                        know the mapping between space id's and .ibd file
1616
 
                        names.
1617
 
 
1618
 
                        In a crash recovery, we check that the info in data
1619
 
                        dictionary is consistent with what we already know
1620
 
                        about space id's from the call of
1621
 
                        fil_load_single_table_tablespaces().
1622
 
 
1623
 
                        In a normal startup, we create the space objects for
1624
 
                        every table in the InnoDB data dictionary that has
1625
 
                        an .ibd file.
1626
 
 
1627
 
                        We also determine the maximum tablespace id used.
1628
 
 
1629
 
                        TODO: We may have incomplete transactions in the
1630
 
                        data dictionary tables. Does that harm the scanning of
1631
 
                        the data dictionary below? */
1632
 
 
1633
 
                        dict_check_tablespaces_and_store_max_id(
1634
 
                                recv_needed_recovery);
1635
 
                }
1636
 
 
1637
 
                srv_startup_is_before_trx_rollback_phase = FALSE;
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
 
 
1648
 
                /* It is possible that file_format tag has never
1649
 
                been set. In this case we initialize it to minimum
1650
 
                value.  Important to note that we can do it ONLY after
1651
 
                we have finished the recovery process so that the
1652
 
                image of TRX_SYS_PAGE_NO is not stale. */
1653
 
                trx_sys_file_format_tag_init();
1654
 
        }
1655
 
 
1656
 
        if (!create_new_db && sum_of_new_sizes > 0) {
1657
 
                /* New data file(s) were added */
1658
 
                mtr_start(&mtr);
1659
 
 
1660
 
                fsp_header_inc_size(0, sum_of_new_sizes, &mtr);
1661
 
 
1662
 
                mtr_commit(&mtr);
1663
 
 
1664
 
                /* Immediately write the log record about increased tablespace
1665
 
                size to disk, so that it is durable even if mysqld would crash
1666
 
                quickly */
1667
 
 
1668
 
                log_buffer_flush_to_disk();
1669
 
        }
1670
 
 
1671
 
#ifdef UNIV_LOG_ARCHIVE
1672
 
        /* Archiving is always off under MySQL */
1673
 
        if (!srv_log_archive_on) {
1674
 
                ut_a(DB_SUCCESS == log_archive_noarchivelog());
1675
 
        } else {
1676
 
                mutex_enter(&(log_sys->mutex));
1677
 
 
1678
 
                start_archive = FALSE;
1679
 
 
1680
 
                if (log_sys->archiving_state == LOG_ARCH_OFF) {
1681
 
                        start_archive = TRUE;
1682
 
                }
1683
 
 
1684
 
                mutex_exit(&(log_sys->mutex));
1685
 
 
1686
 
                if (start_archive) {
1687
 
                        ut_a(DB_SUCCESS == log_archive_archivelog());
1688
 
                }
1689
 
        }
1690
 
#endif /* UNIV_LOG_ARCHIVE */
1691
 
 
1692
 
        /* fprintf(stderr, "Max allowed record size %lu\n",
1693
 
        page_get_free_space_of_empty() / 2); */
1694
 
 
1695
 
        /* Create the thread which watches the timeouts for lock waits
1696
 
        and prints InnoDB monitor info */
1697
 
 
1698
 
        os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL,
1699
 
                         thread_ids + 2 + SRV_MAX_N_IO_THREADS);
1700
 
 
1701
 
        /* Create the thread which warns of long semaphore waits */
1702
 
        os_thread_create(&srv_error_monitor_thread, NULL,
1703
 
                         thread_ids + 3 + SRV_MAX_N_IO_THREADS);
1704
 
        srv_is_being_started = FALSE;
1705
 
 
1706
 
        if (trx_doublewrite == NULL) {
1707
 
                /* Create the doublewrite buffer to a new tablespace */
1708
 
 
1709
 
                trx_sys_create_doublewrite_buf();
1710
 
        }
1711
 
 
1712
 
        err = dict_create_or_check_foreign_constraint_tables();
1713
 
 
1714
 
        if (err != DB_SUCCESS) {
1715
 
                return((int)DB_ERROR);
1716
 
        }
1717
 
 
1718
 
        /* Create the master thread which does purge and other utility
1719
 
        operations */
1720
 
 
1721
 
        os_thread_create(&srv_master_thread, NULL, thread_ids
1722
 
                         + (1 + SRV_MAX_N_IO_THREADS));
1723
 
#ifdef UNIV_DEBUG
1724
 
        /* buf_debug_prints = TRUE; */
1725
 
#endif /* UNIV_DEBUG */
1726
 
        sum_of_data_file_sizes = 0;
1727
 
 
1728
 
        for (i = 0; i < srv_n_data_files; i++) {
1729
 
                sum_of_data_file_sizes += srv_data_file_sizes[i];
1730
 
        }
1731
 
 
1732
 
        tablespace_size_in_header = fsp_header_get_tablespace_size();
1733
 
 
1734
 
        if (!srv_auto_extend_last_data_file
1735
 
            && sum_of_data_file_sizes != tablespace_size_in_header) {
1736
 
 
1737
 
                fprintf(stderr,
1738
 
                        "InnoDB: Error: tablespace size"
1739
 
                        " stored in header is %lu pages, but\n"
1740
 
                        "InnoDB: the sum of data file sizes is %lu pages\n",
1741
 
                        (ulong) tablespace_size_in_header,
1742
 
                        (ulong) sum_of_data_file_sizes);
1743
 
 
1744
 
                if (srv_force_recovery == 0
1745
 
                    && sum_of_data_file_sizes < tablespace_size_in_header) {
1746
 
                        /* This is a fatal error, the tail of a tablespace is
1747
 
                        missing */
1748
 
 
1749
 
                        fprintf(stderr,
1750
 
                                "InnoDB: Cannot start InnoDB."
1751
 
                                " The tail of the system tablespace is\n"
1752
 
                                "InnoDB: missing. Have you edited"
1753
 
                                " innodb_data_file_path in my.cnf in an\n"
1754
 
                                "InnoDB: inappropriate way, removing"
1755
 
                                " ibdata files from there?\n"
1756
 
                                "InnoDB: You can set innodb_force_recovery=1"
1757
 
                                " in my.cnf to force\n"
1758
 
                                "InnoDB: a startup if you are trying"
1759
 
                                " to recover a badly corrupt database.\n");
1760
 
 
1761
 
                        return(DB_ERROR);
1762
 
                }
1763
 
        }
1764
 
 
1765
 
        if (srv_auto_extend_last_data_file
1766
 
            && sum_of_data_file_sizes < tablespace_size_in_header) {
1767
 
 
1768
 
                fprintf(stderr,
1769
 
                        "InnoDB: Error: tablespace size stored in header"
1770
 
                        " is %lu pages, but\n"
1771
 
                        "InnoDB: the sum of data file sizes"
1772
 
                        " is only %lu pages\n",
1773
 
                        (ulong) tablespace_size_in_header,
1774
 
                        (ulong) sum_of_data_file_sizes);
1775
 
 
1776
 
                if (srv_force_recovery == 0) {
1777
 
 
1778
 
                        fprintf(stderr,
1779
 
                                "InnoDB: Cannot start InnoDB. The tail of"
1780
 
                                " the system tablespace is\n"
1781
 
                                "InnoDB: missing. Have you edited"
1782
 
                                " innodb_data_file_path in my.cnf in an\n"
1783
 
                                "InnoDB: inappropriate way, removing"
1784
 
                                " ibdata files from there?\n"
1785
 
                                "InnoDB: You can set innodb_force_recovery=1"
1786
 
                                " in my.cnf to force\n"
1787
 
                                "InnoDB: a startup if you are trying to"
1788
 
                                " recover a badly corrupt database.\n");
1789
 
 
1790
 
                        return(DB_ERROR);
1791
 
                }
1792
 
        }
1793
 
 
1794
 
        /* Check that os_fast_mutexes work as expected */
1795
 
        os_fast_mutex_init(&srv_os_test_mutex);
1796
 
 
1797
 
        if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
1798
 
                fprintf(stderr,
1799
 
                        "InnoDB: Error: pthread_mutex_trylock returns"
1800
 
                        " an unexpected value on\n"
1801
 
                        "InnoDB: success! Cannot continue.\n");
1802
 
                exit(1);
1803
 
        }
1804
 
 
1805
 
        os_fast_mutex_unlock(&srv_os_test_mutex);
1806
 
 
1807
 
        os_fast_mutex_lock(&srv_os_test_mutex);
1808
 
 
1809
 
        os_fast_mutex_unlock(&srv_os_test_mutex);
1810
 
 
1811
 
        os_fast_mutex_free(&srv_os_test_mutex);
1812
 
 
1813
 
        if (srv_print_verbose_log) {
1814
 
                ut_print_timestamp(stderr);
1815
 
                fprintf(stderr,
1816
 
                        " InnoDB Plugin %s started; "
1817
 
                        "log sequence number %"PRIu64"\n",
1818
 
                        INNODB_VERSION_STR, srv_start_lsn);
1819
 
        }
1820
 
 
1821
 
        if (srv_force_recovery > 0) {
1822
 
                fprintf(stderr,
1823
 
                        "InnoDB: !!! innodb_force_recovery"
1824
 
                        " is set to %lu !!!\n",
1825
 
                        (ulong) srv_force_recovery);
1826
 
        }
1827
 
 
1828
 
        fflush(stderr);
1829
 
 
1830
 
        if (trx_doublewrite_must_reset_space_ids) {
1831
 
                /* Actually, we did not change the undo log format between
1832
 
                4.0 and 4.1.1, and we would not need to run purge to
1833
 
                completion. Note also that the purge algorithm in 4.1.1
1834
 
                can process the the history list again even after a full
1835
 
                purge, because our algorithm does not cut the end of the
1836
 
                history list in all cases so that it would become empty
1837
 
                after a full purge. That mean that we may purge 4.0 type
1838
 
                undo log even after this phase.
1839
 
 
1840
 
                The insert buffer record format changed between 4.0 and
1841
 
                4.1.1. It is essential that the insert buffer is emptied
1842
 
                here! */
1843
 
 
1844
 
                fprintf(stderr,
1845
 
                        "InnoDB: You are upgrading to an"
1846
 
                        " InnoDB version which allows multiple\n"
1847
 
                        "InnoDB: tablespaces. Wait that purge"
1848
 
                        " and insert buffer merge run to\n"
1849
 
                        "InnoDB: completion...\n");
1850
 
                for (;;) {
1851
 
                        os_thread_sleep(1000000);
1852
 
 
1853
 
                        if (0 == strcmp(srv_main_thread_op_info,
1854
 
                                        "waiting for server activity")) {
1855
 
 
1856
 
                                ut_a(ibuf_is_empty());
1857
 
 
1858
 
                                break;
1859
 
                        }
1860
 
                }
1861
 
                fprintf(stderr,
1862
 
                        "InnoDB: Full purge and insert buffer merge"
1863
 
                        " completed.\n");
1864
 
 
1865
 
                trx_sys_mark_upgraded_to_multiple_tablespaces();
1866
 
 
1867
 
                fprintf(stderr,
1868
 
                        "InnoDB: You have now successfully upgraded"
1869
 
                        " to the multiple tablespaces\n"
1870
 
                        "InnoDB: format. You should NOT DOWNGRADE"
1871
 
                        " to an earlier version of\n"
1872
 
                        "InnoDB: InnoDB! But if you absolutely need to"
1873
 
                        " downgrade, see\n"
1874
 
                        "InnoDB: " REFMAN "multiple-tablespaces.html\n"
1875
 
                        "InnoDB: for instructions.\n");
1876
 
        }
1877
 
 
1878
 
        if (srv_force_recovery == 0) {
1879
 
                /* In the insert buffer we may have even bigger tablespace
1880
 
                id's, because we may have dropped those tablespaces, but
1881
 
                insert buffer merge has not had time to clean the records from
1882
 
                the ibuf tree. */
1883
 
 
1884
 
                ibuf_update_max_tablespace_id();
1885
 
        }
1886
 
 
1887
 
        srv_file_per_table = srv_file_per_table_original_value;
1888
 
 
1889
 
        srv_was_started = TRUE;
1890
 
 
1891
 
        return((int) DB_SUCCESS);
1892
 
}
1893
 
 
1894
 
/****************************************************************//**
1895
 
Shuts down the InnoDB database.
1896
 
@return DB_SUCCESS or error code */
1897
 
UNIV_INTERN
1898
 
int
1899
 
innobase_shutdown_for_mysql(void)
1900
 
/*=============================*/
1901
 
{
1902
 
        ulint   i;
1903
 
#ifdef __NETWARE__
1904
 
        extern ibool panic_shutdown;
1905
 
#endif
1906
 
        if (!srv_was_started) {
1907
 
                if (srv_is_being_started) {
1908
 
                        ut_print_timestamp(stderr);
1909
 
                        fprintf(stderr,
1910
 
                                "  InnoDB: Warning: shutting down"
1911
 
                                " a not properly started\n"
1912
 
                                "InnoDB: or created database!\n");
1913
 
                }
1914
 
 
1915
 
                return(DB_SUCCESS);
1916
 
        }
1917
 
 
1918
 
        /* 1. Flush the buffer pool to disk, write the current lsn to
1919
 
        the tablespace header(s), and copy all log data to archive.
1920
 
        The step 1 is the real InnoDB shutdown. The remaining steps 2 - ...
1921
 
        just free data structures after the shutdown. */
1922
 
 
1923
 
 
1924
 
        if (srv_fast_shutdown == 2) {
1925
 
                ut_print_timestamp(stderr);
1926
 
                fprintf(stderr,
1927
 
                        "  InnoDB: MySQL has requested a very fast shutdown"
1928
 
                        " without flushing "
1929
 
                        "the InnoDB buffer pool to data files."
1930
 
                        " At the next mysqld startup "
1931
 
                        "InnoDB will do a crash recovery!\n");
1932
 
        }
1933
 
 
1934
 
#ifdef __NETWARE__
1935
 
        if (!panic_shutdown)
1936
 
#endif
1937
 
                logs_empty_and_mark_files_at_shutdown();
1938
 
 
1939
 
        if (srv_conc_n_threads != 0) {
1940
 
                fprintf(stderr,
1941
 
                        "InnoDB: Warning: query counter shows %ld queries"
1942
 
                        " still\n"
1943
 
                        "InnoDB: inside InnoDB at shutdown\n",
1944
 
                        srv_conc_n_threads);
1945
 
        }
1946
 
 
1947
 
        /* 2. Make all threads created by InnoDB to exit */
1948
 
 
1949
 
        srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
1950
 
 
1951
 
        /* In a 'very fast' shutdown, we do not need to wait for these threads
1952
 
        to die; all which counts is that we flushed the log; a 'very fast'
1953
 
        shutdown is essentially a crash. */
1954
 
 
1955
 
        if (srv_fast_shutdown == 2) {
1956
 
                return(DB_SUCCESS);
1957
 
        }
1958
 
 
1959
 
        /* All threads end up waiting for certain events. Put those events
1960
 
        to the signaled state. Then the threads will exit themselves in
1961
 
        os_thread_event_wait(). */
1962
 
 
1963
 
        for (i = 0; i < 1000; i++) {
1964
 
                /* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
1965
 
                HERE OR EARLIER */
1966
 
 
1967
 
                /* a. Let the lock timeout thread exit */
1968
 
                os_event_set(srv_lock_timeout_thread_event);
1969
 
 
1970
 
                /* b. srv error monitor thread exits automatically, no need
1971
 
                to do anything here */
1972
 
 
1973
 
                /* c. We wake the master thread so that it exits */
1974
 
                srv_wake_master_thread();
1975
 
 
1976
 
                /* d. Exit the i/o threads */
1977
 
 
1978
 
                os_aio_wake_all_threads_at_shutdown();
1979
 
 
1980
 
                os_mutex_enter(os_sync_mutex);
1981
 
 
1982
 
                if (os_thread_count == 0) {
1983
 
                        /* All the threads have exited or are just exiting;
1984
 
                        NOTE that the threads may not have completed their
1985
 
                        exit yet. Should we use pthread_join() to make sure
1986
 
                        they have exited? Now we just sleep 0.1 seconds and
1987
 
                        hope that is enough! */
1988
 
 
1989
 
                        os_mutex_exit(os_sync_mutex);
1990
 
 
1991
 
                        os_thread_sleep(100000);
1992
 
 
1993
 
                        break;
1994
 
                }
1995
 
 
1996
 
                os_mutex_exit(os_sync_mutex);
1997
 
 
1998
 
                os_thread_sleep(100000);
1999
 
        }
2000
 
 
2001
 
        if (i == 1000) {
2002
 
                fprintf(stderr,
2003
 
                        "InnoDB: Warning: %lu threads created by InnoDB"
2004
 
                        " had not exited at shutdown!\n",
2005
 
                        (ulong) os_thread_count);
2006
 
        }
2007
 
 
2008
 
        if (srv_monitor_file) {
2009
 
                fclose(srv_monitor_file);
2010
 
                srv_monitor_file = 0;
2011
 
                if (srv_monitor_file_name) {
2012
 
                        unlink(srv_monitor_file_name);
2013
 
                        mem_free(srv_monitor_file_name);
2014
 
                }
2015
 
        }
2016
 
        if (srv_dict_tmpfile) {
2017
 
                fclose(srv_dict_tmpfile);
2018
 
                srv_dict_tmpfile = 0;
2019
 
        }
2020
 
 
2021
 
        if (srv_misc_tmpfile) {
2022
 
                fclose(srv_misc_tmpfile);
2023
 
                srv_misc_tmpfile = 0;
2024
 
        }
2025
 
 
2026
 
        trx_sys_file_format_close();
2027
 
 
2028
 
        mutex_free(&srv_monitor_file_mutex);
2029
 
        mutex_free(&srv_dict_tmpfile_mutex);
2030
 
        mutex_free(&srv_misc_tmpfile_mutex);
2031
 
 
2032
 
        /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
2033
 
        them */
2034
 
        sync_close();
2035
 
 
2036
 
        /* 4. Free the os_conc_mutex and all os_events and os_mutexes */
2037
 
 
2038
 
        srv_free();
2039
 
        os_sync_free();
2040
 
 
2041
 
        /* Check that all read views are closed except read view owned
2042
 
        by a purge. */
2043
 
 
2044
 
        if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
2045
 
                fprintf(stderr,
2046
 
                        "InnoDB: Error: all read views were not closed"
2047
 
                        " before shutdown:\n"
2048
 
                        "InnoDB: %lu read views open \n",
2049
 
                        UT_LIST_GET_LEN(trx_sys->view_list) - 1);
2050
 
        }
2051
 
 
2052
 
        /* 5. Free all allocated memory and the os_fast_mutex created in
2053
 
        ut0mem.c */
2054
 
 
2055
 
        buf_pool_free();
2056
 
        ut_free_all_mem();
2057
 
 
2058
 
        if (os_thread_count != 0
2059
 
            || os_event_count != 0
2060
 
            || os_mutex_count != 0
2061
 
            || os_fast_mutex_count != 0) {
2062
 
                fprintf(stderr,
2063
 
                        "InnoDB: Warning: some resources were not"
2064
 
                        " cleaned up in shutdown:\n"
2065
 
                        "InnoDB: threads %lu, events %lu,"
2066
 
                        " os_mutexes %lu, os_fast_mutexes %lu\n",
2067
 
                        (ulong) os_thread_count, (ulong) os_event_count,
2068
 
                        (ulong) os_mutex_count, (ulong) os_fast_mutex_count);
2069
 
        }
2070
 
 
2071
 
        if (dict_foreign_err_file) {
2072
 
                fclose(dict_foreign_err_file);
2073
 
        }
2074
 
        if (lock_latest_err_file) {
2075
 
                fclose(lock_latest_err_file);
2076
 
        }
2077
 
 
2078
 
        if (srv_print_verbose_log) {
2079
 
                ut_print_timestamp(stderr);
2080
 
                fprintf(stderr,
2081
 
                        "  InnoDB: Shutdown completed;"
2082
 
                        " log sequence number %"PRIu64"\n",
2083
 
                        srv_shutdown_lsn);
2084
 
        }
2085
 
 
2086
 
        srv_was_started = FALSE;
2087
 
 
2088
 
        return((int) DB_SUCCESS);
2089
 
}
2090
 
 
2091
 
#ifdef __NETWARE__
2092
 
void set_panic_flag_for_netware()
2093
 
{
2094
 
        extern ibool panic_shutdown;
2095
 
        panic_shutdown = TRUE;
2096
 
}
2097
 
#endif /* __NETWARE__ */
2098
 
#endif /* !UNIV_HOTBACKUP */