summaryrefslogtreecommitdiff
path: root/innobase/srv
diff options
context:
space:
mode:
authorheikki@hundin.mysql.fi <>2002-03-21 18:03:09 +0200
committerheikki@hundin.mysql.fi <>2002-03-21 18:03:09 +0200
commite90a57aa49c79d75cabef38c764b5f81ba0288dc (patch)
tree8484c3bb65d40af0743b44a24a788dc2d5cf7d48 /innobase/srv
parent254df5fdd66989c404ff2f4253bf05afc2df53fa (diff)
downloadmariadb-git-e90a57aa49c79d75cabef38c764b5f81ba0288dc.tar.gz
Many files:
Merge InnoDB-3.23.50
Diffstat (limited to 'innobase/srv')
-rw-r--r--innobase/srv/srv0srv.c34
-rw-r--r--innobase/srv/srv0start.c374
2 files changed, 381 insertions, 27 deletions
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 553c012bf85..8afe1396f1b 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -69,13 +69,19 @@ char* srv_main_thread_op_info = "";
names, where the file name itself may also contain a path */
char* srv_data_home = NULL;
-char* srv_logs_home = NULL;
char* srv_arch_dir = NULL;
ulint srv_n_data_files = 0;
char** srv_data_file_names = NULL;
ulint* srv_data_file_sizes = NULL; /* size in database pages */
+ibool srv_auto_extend_last_data_file = FALSE; /* if TRUE, then we
+ auto-extend the last data
+ file */
+ulint srv_last_file_size_max = 0; /* if != 0, this tells
+ the max size auto-extending
+ may increase the last data
+ file size */
ulint* srv_data_file_is_raw_partition = NULL;
/* If the following is TRUE we do not allow inserts etc. This protects
@@ -1596,7 +1602,7 @@ srv_read_initfile(
/*************************************************************************
Initializes the server. */
-static
+
void
srv_init(void)
/*==========*/
@@ -1664,7 +1670,7 @@ srv_init(void)
/*************************************************************************
Initializes the synchronization primitives, memory system, and the thread
local storage. */
-static
+
void
srv_general_init(void)
/*==================*/
@@ -1686,6 +1692,7 @@ srv_conc_enter_innodb(
trx_t* trx) /* in: transaction object associated with the
thread */
{
+ ibool has_slept = FALSE;
srv_conc_slot_t* slot;
ulint i;
@@ -1703,7 +1710,7 @@ srv_conc_enter_innodb(
return;
}
-
+retry:
os_fast_mutex_lock(&srv_conc_mutex);
if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
@@ -1716,7 +1723,23 @@ srv_conc_enter_innodb(
return;
}
+
+ /* If the transaction is not holding resources, let it sleep
+ for 100 milliseconds, and try again then */
+ if (!has_slept && !trx->has_search_latch
+ && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) {
+
+ has_slept = TRUE; /* We let is sleep only once to avoid
+ starvation */
+
+ os_fast_mutex_unlock(&srv_conc_mutex);
+
+ os_thread_sleep(100000);
+
+ goto retry;
+ }
+
/* Too many threads inside: put the current thread to a queue */
for (i = 0; i < OS_THREAD_MAX_N; i++) {
@@ -1908,6 +1931,9 @@ srv_normalize_init_values(void)
* ((1024 * 1024) / UNIV_PAGE_SIZE);
}
+ srv_last_file_size_max = srv_last_file_size_max
+ * ((1024 * 1024) / UNIV_PAGE_SIZE);
+
srv_log_file_size = srv_log_file_size / UNIV_PAGE_SIZE;
srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE;
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index f9a13944bb5..1fcf8c76a5f 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -84,6 +84,308 @@ we may get an assertion failure in os0file.c */
#define SRV_LOG_SPACE_FIRST_ID 1000000000
+/*************************************************************************
+Reads the data files and their sizes from a character string given in
+the .cnf file. */
+
+ibool
+srv_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++;
+ }
+
+ 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 (strlen(str) >= ut_strlen(":autoextend")
+ && 0 == ut_memcmp(str, ":autoextend",
+ ut_strlen(":autoextend"))) {
+
+ str += ut_strlen(":autoextend");
+
+ if (strlen(str) >= ut_strlen(":max:")
+ && 0 == ut_memcmp(str, ":max:",
+ ut_strlen(":max:"))) {
+
+ str += ut_strlen(":max:");
+
+ 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 (strlen(str) >= 3
+ && *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);
+ }
+ }
+
+ *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 ignore the ':' in a Windows path */
+
+ while ((*str != ':' && *str != '\0')
+ || (*str == ':'
+ && (*(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 (strlen(str) >= ut_strlen(":autoextend")
+ && 0 == ut_memcmp(str, ":autoextend",
+ ut_strlen(":autoextend"))) {
+
+ *is_auto_extending = TRUE;
+
+ str += ut_strlen(":autoextend");
+
+ if (strlen(str) >= ut_strlen(":max:")
+ && 0 == ut_memcmp(str, ":max:",
+ ut_strlen(":max:"))) {
+
+ str += ut_strlen(":max:");
+
+ 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 (strlen(str) >= 3
+ && *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 in
+the .cnf file. */
+
+ibool
+srv_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);
+ }
+ }
+
+ *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
@@ -127,7 +429,7 @@ io_handler_thread(
/*************************************************************************
Normalizes a directory path for Windows: converts slashes to backslashes. */
-static
+
void
srv_normalize_path_for_win(
/*=======================*/
@@ -148,7 +450,7 @@ srv_normalize_path_for_win(
/*************************************************************************
Adds a slash or a backslash to the end of a string if it is missing
and the string is not empty. */
-static
+
char*
srv_add_path_separator_if_needed(
/*=============================*/
@@ -354,6 +656,7 @@ open_or_create_data_files(
ibool one_created = FALSE;
ulint size;
ulint size_high;
+ ulint rounded_size_pages;
char name[10000];
if (srv_n_data_files >= 1000) {
@@ -433,17 +736,35 @@ open_or_create_data_files(
ret = os_file_get_size(files[i], &size,
&size_high);
ut_a(ret);
+ /* Round size downward to megabytes */
- /* File sizes in srv_... are given in
- database pages */
-
- if (size != srv_calc_low32(
- srv_data_file_sizes[i])
- || size_high != srv_calc_high32(
- srv_data_file_sizes[i])) {
+ rounded_size_pages = (size / (1024 * 1024)
+ + 4096 * size_high)
+ << (20 - UNIV_PAGE_SIZE_SHIFT);
+
+ if (i == srv_n_data_files - 1
+ && srv_auto_extend_last_data_file) {
+
+ if (srv_data_file_sizes[i] >
+ rounded_size_pages
+ || (srv_last_file_size_max > 0
+ && srv_last_file_size_max <
+ rounded_size_pages)) {
+
+ fprintf(stderr,
+ "InnoDB: Error: data file %s is of a different size\n"
+ "InnoDB: than specified in the .cnf file!\n", name);
+ }
+
+ srv_data_file_sizes[i] =
+ rounded_size_pages;
+ }
+
+ if (rounded_size_pages
+ != srv_data_file_sizes[i]) {
fprintf(stderr,
- "InnoDB: Error: data file %s is of different size\n"
+ "InnoDB: Error: data file %s is of a different size\n"
"InnoDB: than specified in the .cnf file!\n", name);
return(DB_ERROR);
@@ -477,7 +798,7 @@ open_or_create_data_files(
>> (20 - UNIV_PAGE_SIZE_SHIFT)));
fprintf(stderr,
- "InnoDB: Database physically writes the file full: wait...\n");
+ "InnoDB: Database physically writes the file full: wait...\n");
ret = os_file_set_size(name, files[i],
srv_calc_low32(srv_data_file_sizes[i]),
@@ -675,6 +996,8 @@ innobase_start_or_create_for_mysql(void)
os_aio_use_native_aio = TRUE;
}
#endif
+ os_aio_use_native_aio = FALSE;
+
if (!os_aio_use_native_aio) {
os_aio_init(4 * SRV_N_PENDING_IOS_PER_THREAD
* srv_n_file_io_threads,
@@ -721,12 +1044,10 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR);
}
- if (sizeof(ulint) == 4
- && srv_n_log_files * srv_log_file_size >= 262144) {
+ if (srv_n_log_files * srv_log_file_size >= 262144) {
fprintf(stderr,
- "InnoDB: Error: combined size of log files must be < 4 GB\n"
- "InnoDB: on 32-bit computers\n");
+ "InnoDB: Error: combined size of log files must be < 4 GB\n");
return(DB_ERROR);
}
@@ -758,7 +1079,6 @@ innobase_start_or_create_for_mysql(void)
&max_flushed_lsn, &max_arch_log_no,
&sum_of_new_sizes);
if (err != DB_SUCCESS) {
-
fprintf(stderr, "InnoDB: Could not open data files\n");
return((int) err);
@@ -797,9 +1117,9 @@ innobase_start_or_create_for_mysql(void)
|| (log_opened && log_created)) {
fprintf(stderr,
"InnoDB: Error: all log files must be created at the same time.\n"
- "InnoDB: If you want bigger or smaller log files,\n"
- "InnoDB: shut down the database and make sure there\n"
- "InnoDB: were no errors in shutdown.\n"
+ "InnoDB: All log files must be created also in database creation.\n"
+ "InnoDB: If you want bigger or smaller log files, shut down the\n"
+ "InnoDB: database and make sure there were no errors in shutdown.\n"
"InnoDB: Then delete the existing log files. Edit the .cnf file\n"
"InnoDB: and start the database again.\n");
@@ -835,9 +1155,7 @@ innobase_start_or_create_for_mysql(void)
mutex_enter(&(log_sys->mutex));
- recv_reset_logs(ut_dulint_align_down(max_flushed_lsn,
- OS_FILE_LOG_BLOCK_SIZE),
- max_arch_log_no + 1, TRUE);
+ recv_reset_logs(max_flushed_lsn, max_arch_log_no + 1, TRUE);
mutex_exit(&(log_sys->mutex));
}
@@ -877,6 +1195,10 @@ innobase_start_or_create_for_mysql(void)
srv_startup_is_before_trx_rollback_phase = FALSE;
+ /* Initialize the fsp free limit global variable in the log
+ system */
+ fsp_header_get_free_limit(0);
+
recv_recovery_from_archive_finish();
} else {
/* We always try to do a recovery, even if the database had
@@ -893,6 +1215,7 @@ innobase_start_or_create_for_mysql(void)
/* Since ibuf init is in dict_boot, and ibuf is needed
in any disk i/o, first call dict_boot */
+
dict_boot();
trx_sys_init_at_db_start();
@@ -900,6 +1223,11 @@ innobase_start_or_create_for_mysql(void)
trx_sys_init_at_db_start */
srv_startup_is_before_trx_rollback_phase = FALSE;
+
+ /* Initialize the fsp free limit global variable in the log
+ system */
+ fsp_header_get_free_limit(0);
+
recv_recovery_from_checkpoint_finish();
}
@@ -969,7 +1297,7 @@ innobase_start_or_create_for_mysql(void)
if (err != DB_SUCCESS) {
return((int)DB_ERROR);
}
-
+
/* Create the master thread which monitors the database
server, and does purge and other utility operations */