📄 srv0start.c
字号:
/************************************************************************Starts the InnoDB database server(c) 1996-2000 Innobase OyCreated 2/16/1996 Heikki Tuuri*************************************************************************/#include "os0proc.h"#include "sync0sync.h"#include "ut0mem.h"#include "mem0mem.h"#include "mem0pool.h"#include "data0data.h"#include "data0type.h"#include "dict0dict.h"#include "buf0buf.h"#include "buf0flu.h"#include "buf0rea.h"#include "os0file.h"#include "os0thread.h"#include "fil0fil.h"#include "fsp0fsp.h"#include "rem0rec.h"#include "rem0cmp.h"#include "mtr0mtr.h"#include "log0log.h"#include "log0recv.h"#include "page0page.h"#include "page0cur.h"#include "trx0trx.h"#include "dict0boot.h"#include "dict0load.h"#include "trx0sys.h"#include "dict0crea.h"#include "btr0btr.h"#include "btr0pcur.h"#include "btr0cur.h"#include "btr0sea.h"#include "rem0rec.h"#include "srv0srv.h"#include "que0que.h"#include "usr0sess.h"#include "lock0lock.h"#include "trx0roll.h"#include "trx0purge.h"#include "row0ins.h"#include "row0sel.h"#include "row0upd.h"#include "row0row.h"#include "row0mysql.h"#include "lock0lock.h"#include "ibuf0ibuf.h"#include "pars0pars.h"#include "btr0sea.h"#include "srv0start.h"#include "que0que.h"/* Log sequence number immediately after startup */dulint srv_start_lsn;/* Log sequence number at shutdown */dulint srv_shutdown_lsn;#ifdef HAVE_DARWIN_THREADS# include <sys/utsname.h>ibool srv_have_fullfsync = FALSE;#endifibool srv_start_raw_disk_in_use = FALSE;static ibool srv_start_has_been_called = FALSE;ulint srv_sizeof_trx_t_in_ha_innodb_cc;ibool srv_startup_is_before_trx_rollback_phase = FALSE;ibool srv_is_being_started = FALSE;static ibool srv_was_started = FALSE;/* At a shutdown the value first climbs to SRV_SHUTDOWN_CLEANUPand then to SRV_SHUTDOWN_LAST_PHASE */ulint srv_shutdown_state = 0;ibool measure_cont = FALSE;static os_file_t files[1000];static mutex_t ios_mutex;static ulint ios;static ulint n[SRV_MAX_N_IO_THREADS + 5];static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5];/* We use this mutex to test the return value of pthread_mutex_trylock on successful locking. HP-UX does NOT return 0, though Linux et al do. */static os_fast_mutex_t srv_os_test_mutex;/* Name of srv_monitor_file */static char* srv_monitor_file_name;#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD#define SRV_MAX_N_PENDING_SYNC_IOS 100/* Avoid warnings when using purify */#ifdef HAVE_purifystatic int inno_bcmp(register const char *s1, register const char *s2, register uint len){ while (len-- != 0 && *s1++ == *s2++) ; return len+1;}#define memcmp(A,B,C) inno_bcmp((A),(B),(C))#endif/*************************************************************************Reads the data files and their sizes from a character string given inthe .cnf file. */iboolsrv_parse_data_file_paths_and_sizes(/*================================*/ /* out: TRUE if ok, FALSE if parsing error */ char* str, /* in: the data file path string */ char*** data_file_names, /* out, own: array of data file names */ ulint** data_file_sizes, /* out, own: array of data file sizes in megabytes */ ulint** data_file_is_raw_partition,/* out, own: array of flags showing which data files are raw partitions */ ulint* n_data_files, /* out: number of data files */ ibool* is_auto_extending, /* out: TRUE if the last data file is auto-extending */ ulint* max_auto_extend_size) /* out: max auto extend size for the last file if specified, 0 if not */{ char* input_str; char* endp; char* path; ulint size; ulint i = 0; *is_auto_extending = FALSE; *max_auto_extend_size = 0; input_str = str; /* First calculate the number of data files and check syntax: path:size[M | G];path:size[M | G]... . Note that a Windows path may contain a drive name and a ':'. */ while (*str != '\0') { path = str; while ((*str != ':' && *str != '\0') || (*str == ':' && (*(str + 1) == '\\' || *(str + 1) == '/' || *(str + 1) == ':'))) { str++; } if (*str == '\0') { return(FALSE); } str++; size = strtoul(str, &endp, 10); str = endp; if (*str != 'M' && *str != 'G') { size = size / (1024 * 1024); } else if (*str == 'G') { size = size * 1024; str++; } else { str++; } if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { str += (sizeof ":autoextend") - 1; if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { str += (sizeof ":max:") - 1; size = strtoul(str, &endp, 10); str = endp; if (*str != 'M' && *str != 'G') { size = size / (1024 * 1024); } else if (*str == 'G') { size = size * 1024; str++; } else { str++; } } if (*str != '\0') { return(FALSE); } } if (strlen(str) >= 6 && *str == 'n' && *(str + 1) == 'e' && *(str + 2) == 'w') { str += 3; } if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') { str += 3; } if (size == 0) { return(FALSE); } i++; if (*str == ';') { str++; } else if (*str != '\0') { return(FALSE); } } if (i == 0) { /* If innodb_data_file_path was defined it must contain at least one data file definition */ return(FALSE); } *data_file_names = (char**)ut_malloc(i * sizeof(void*)); *data_file_sizes = (ulint*)ut_malloc(i * sizeof(ulint)); *data_file_is_raw_partition = (ulint*)ut_malloc(i * sizeof(ulint)); *n_data_files = i; /* Then store the actual values to our arrays */ str = input_str; i = 0; while (*str != '\0') { path = str; /* Note that we must step over the ':' in a Windows path; a Windows path normally looks like C:\ibdata\ibdata1:1G, but a Windows raw partition may have a specification like \\.\C::1Gnewraw or \\.\PHYSICALDRIVE2:1Gnewraw */ while ((*str != ':' && *str != '\0') || (*str == ':' && (*(str + 1) == '\\' || *(str + 1) == '/' || *(str + 1) == ':'))) { str++; } if (*str == ':') { /* Make path a null-terminated string */ *str = '\0'; str++; } size = strtoul(str, &endp, 10); str = endp; if ((*str != 'M') && (*str != 'G')) { size = size / (1024 * 1024); } else if (*str == 'G') { size = size * 1024; str++; } else { str++; } (*data_file_names)[i] = path; (*data_file_sizes)[i] = size; if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { *is_auto_extending = TRUE; str += (sizeof ":autoextend") - 1; if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { str += (sizeof ":max:") - 1; size = strtoul(str, &endp, 10); str = endp; if (*str != 'M' && *str != 'G') { size = size / (1024 * 1024); } else if (*str == 'G') { size = size * 1024; str++; } else { str++; } *max_auto_extend_size = size; } if (*str != '\0') { return(FALSE); } } (*data_file_is_raw_partition)[i] = 0; if (strlen(str) >= 6 && *str == 'n' && *(str + 1) == 'e' && *(str + 2) == 'w') { str += 3; (*data_file_is_raw_partition)[i] = SRV_NEW_RAW; } if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') { str += 3; if ((*data_file_is_raw_partition)[i] == 0) { (*data_file_is_raw_partition)[i] = SRV_OLD_RAW; } } i++; if (*str == ';') { str++; } } return(TRUE);}/*************************************************************************Reads log group home directories from a character string given inthe .cnf file. */iboolsrv_parse_log_group_home_dirs(/*==========================*/ /* out: TRUE if ok, FALSE if parsing error */ char* str, /* in: character string */ char*** log_group_home_dirs) /* out, own: log group home dirs */{ char* input_str; char* path; ulint i = 0; input_str = str; /* First calculate the number of directories and check syntax: path;path;... */ while (*str != '\0') { path = str; while (*str != ';' && *str != '\0') { str++; } i++; if (*str == ';') { str++; } else if (*str != '\0') { return(FALSE); } } if (i != 1) { /* If innodb_log_group_home_dir was defined it must contain exactly one path definition under current MySQL */ return(FALSE); } *log_group_home_dirs = (char**) ut_malloc(i * sizeof(void*)); /* Then store the actual values to our array */ str = input_str; i = 0; while (*str != '\0') { path = str; while (*str != ';' && *str != '\0') { str++; } if (*str == ';') { *str = '\0'; str++; } (*log_group_home_dirs)[i] = path; i++; } return(TRUE);}/************************************************************************I/o-handler thread function. */static#ifndef __WIN__void*#elseulint#endifio_handler_thread(/*==============*/ void* arg){ ulint segment; ulint i; segment = *((ulint*)arg);#ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Io handler thread %lu starts, id %lu\n", segment, os_thread_pf(os_thread_get_curr_id()));#endif for (i = 0;; i++) { fil_aio_wait(segment); mutex_enter(&ios_mutex); ios++; mutex_exit(&ios_mutex); } /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. The thread actually never comes here because it is exited in an os_event_wait(). */ os_thread_exit(NULL);#ifndef __WIN__ return(NULL); /* Not reached */#else return(0);#endif}#ifdef __WIN__#define SRV_PATH_SEPARATOR '\\'#else#define SRV_PATH_SEPARATOR '/'#endif/*************************************************************************Normalizes a directory path for Windows: converts slashes to backslashes. */voidsrv_normalize_path_for_win(/*=======================*/ char* str __attribute__((unused))) /* in/out: null-terminated character string */{#ifdef __WIN__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -