summaryrefslogtreecommitdiff
path: root/storage/xtradb/srv/srv0start.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/srv/srv0start.cc')
-rw-r--r--storage/xtradb/srv/srv0start.cc419
1 files changed, 205 insertions, 214 deletions
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index aa51012816d..fd129c3e55f 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation
@@ -121,6 +121,9 @@ UNIV_INTERN ibool srv_have_fullfsync = FALSE;
/** TRUE if a raw partition is in use */
UNIV_INTERN ibool srv_start_raw_disk_in_use = FALSE;
+/** UNDO tablespaces starts with space id. */
+ulint srv_undo_space_id_start;
+
/** TRUE if the server is being started, before rolling back any
incomplete transactions */
UNIV_INTERN ibool srv_startup_is_before_trx_rollback_phase = FALSE;
@@ -129,7 +132,11 @@ UNIV_INTERN ibool srv_is_being_started = FALSE;
/** TRUE if the server was successfully started */
UNIV_INTERN ibool srv_was_started = FALSE;
/** TRUE if innobase_start_or_create_for_mysql() has been called */
-static ibool srv_start_has_been_called = FALSE;
+static ibool srv_start_has_been_called;
+
+/** Whether any undo log records can be generated */
+UNIV_INTERN bool srv_undo_sources;
+
#ifdef UNIV_DEBUG
/** InnoDB system tablespace to set during recovery */
UNIV_INTERN uint srv_sys_space_size_debug;
@@ -139,8 +146,8 @@ UNIV_INTERN uint srv_sys_space_size_debug;
SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE;
-/** Files comprising the system tablespace */
-os_file_t files[1000];
+/** Files comprising the system tablespace. Also used by Mariabackup. */
+UNIV_INTERN pfs_os_file_t files[1000];
/** io_handler_thread parameters for thread identification */
static ulint n[SRV_MAX_N_IO_THREADS];
@@ -203,6 +210,39 @@ UNIV_INTERN mysql_pfs_key_t srv_purge_thread_key;
UNIV_INTERN mysql_pfs_key_t srv_log_tracking_thread_key;
#endif /* UNIV_PFS_THREAD */
+/** Innobase start-up aborted. Perform cleanup actions.
+@param[in] create_new_db TRUE if new db is being created
+@param[in] file File name
+@param[in] line Line number
+@param[in] err Reason for aborting InnoDB startup
+@return DB_SUCCESS or error code. */
+static
+dberr_t
+srv_init_abort(
+ bool create_new_db,
+ const char* file,
+ ulint line,
+ dberr_t err)
+{
+ if (create_new_db) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Database creation was aborted"
+ " at %s [" ULINTPF "]"
+ " with error %s. You may need"
+ " to delete the ibdata1 file before trying to start"
+ " up again.",
+ file, line, ut_strerr(err));
+ } else {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Plugin initialization aborted"
+ " at %s [" ULINTPF "]"
+ " with error %s.",
+ file, line, ut_strerr(err));
+ }
+
+ return(err);
+}
+
/*********************************************************************//**
Convert a numeric string that optionally ends in G or M or K, to a number
containing megabytes.
@@ -584,7 +624,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
create_log_file(
/*============*/
- os_file_t* file, /*!< out: file handle */
+ pfs_os_file_t* file, /*!< out: file handle */
const char* name) /*!< in: log file name */
{
ibool ret;
@@ -802,7 +842,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
open_log_file(
/*==========*/
- os_file_t* file, /*!< out: file handle */
+ pfs_os_file_t* file, /*!< out: file handle */
const char* name, /*!< in: log file name */
os_offset_t* size) /*!< out: file size */
{
@@ -823,32 +863,32 @@ open_log_file(
return(DB_SUCCESS);
}
-/*********************************************************************//**
-Creates or opens database data files and closes them.
+
+/** Creates or opens database data files and closes them.
+@param[out] create_new_db true = create new database
+@param[out] min_arch_log_no min of archived log numbers in
+ data files
+@param[out] max_arch_log_no max of archived log numbers in
+ data files
+@param[out] flushed_lsn flushed lsn in fist datafile
+@param[out] sum_of_new_sizes sum of sizes of the new files
+ added
@return DB_SUCCESS or error code */
MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
open_or_create_data_files(
-/*======================*/
- ibool* create_new_db, /*!< out: TRUE if new database should be
- created */
+ bool* create_new_db,
#ifdef UNIV_LOG_ARCHIVE
- lsn_t* min_arch_log_no,/*!< out: min of archived log
- numbers in data files */
- lsn_t* max_arch_log_no,/*!< out: max of archived log
- numbers in data files */
+ lsn_t* min_arch_log_no,
+ lsn_t* max_arch_log_no,
#endif /* UNIV_LOG_ARCHIVE */
- lsn_t* min_flushed_lsn,/*!< out: min of flushed lsn
- values in data files */
- lsn_t* max_flushed_lsn,/*!< out: max of flushed lsn
- values in data files */
- ulint* sum_of_new_sizes)/*!< out: sum of sizes of the
- new files added */
+ lsn_t* flushed_lsn,
+ ulint* sum_of_new_sizes)
{
ibool ret;
ulint i;
- ibool one_opened = FALSE;
- ibool one_created = FALSE;
+ bool one_opened = false;
+ bool one_created = false;
os_offset_t size;
ulint flags;
ulint space;
@@ -867,7 +907,7 @@ open_or_create_data_files(
*sum_of_new_sizes = 0;
- *create_new_db = FALSE;
+ *create_new_db = false;
srv_normalize_path_for_win(srv_data_home);
@@ -919,7 +959,7 @@ open_or_create_data_files(
&& os_file_get_last_error(false)
!= OS_FILE_ALREADY_EXISTS
#ifdef UNIV_AIX
- /* AIX 5.1 after security patch ML7 may have
+ /* AIX 5.1 after security patch ML7 may have
errno set to 0 here, which causes our
function to return 100; work around that
AIX problem */
@@ -955,9 +995,10 @@ open_or_create_data_files(
}
const char* check_msg;
+
check_msg = fil_read_first_page(
files[i], FALSE, &flags, &space,
- min_flushed_lsn, max_flushed_lsn, NULL);
+ flushed_lsn, NULL);
/* If first page is valid, don't overwrite DB.
It prevents overwriting DB when mysql_install_db
@@ -988,6 +1029,7 @@ open_or_create_data_files(
name);
return(DB_ERROR);
}
+
if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
ut_a(!srv_read_only_mode);
files[i] = os_file_create(
@@ -1007,7 +1049,6 @@ open_or_create_data_files(
}
if (!ret) {
-
os_file_get_last_error(true);
ib_logf(IB_LOG_LEVEL_ERROR,
@@ -1017,7 +1058,6 @@ open_or_create_data_files(
}
if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
-
goto skip_size_check;
}
@@ -1044,16 +1084,15 @@ size_check:
"auto-extending "
"data file %s is "
"of a different size "
- "%lu pages (rounded "
+ ULINTPF " pages (rounded "
"down to MB) than specified "
"in the .cnf file: "
- "initial %lu pages, "
- "max %lu (relevant if "
+ "initial " ULINTPF " pages, "
+ "max " ULINTPF " (relevant if "
"non-zero) pages!",
name,
- (ulong) rounded_size_pages,
- (ulong) srv_data_file_sizes[i],
- (ulong)
+ rounded_size_pages,
+ srv_data_file_sizes[i],
srv_last_file_size_max);
return(DB_ERROR);
@@ -1066,12 +1105,12 @@ size_check:
ib_logf(IB_LOG_LEVEL_ERROR,
"Data file %s is of a different "
- "size %lu pages (rounded down to MB) "
+ "size " ULINTPF " pages (rounded down to MB) "
"than specified in the .cnf file "
- "%lu pages!",
+ ULINTPF " pages!",
name,
- (ulong) rounded_size_pages,
- (ulong) srv_data_file_sizes[i]);
+ rounded_size_pages,
+ srv_data_file_sizes[i]);
return(DB_ERROR);
}
@@ -1090,7 +1129,7 @@ skip_size_check:
check_first_page:
check_msg = fil_read_first_page(
files[i], one_opened, &flags, &space,
- min_flushed_lsn, max_flushed_lsn, &crypt_data);
+ flushed_lsn, &crypt_data);
if (check_msg) {
@@ -1127,9 +1166,9 @@ check_first_page:
!= fsp_flags_get_page_size(flags)) {
ib_logf(IB_LOG_LEVEL_ERROR,
- "Data file \"%s\" uses page size %lu,"
+ "Data file \"%s\" uses page size " ULINTPF " ,"
"but the start-up parameter "
- "is --innodb-page-size=%lu",
+ "is --innodb-page-size=" ULINTPF " .",
name,
fsp_flags_get_page_size(flags),
UNIV_PAGE_SIZE);
@@ -1160,9 +1199,9 @@ check_first_page:
}
ib_logf(IB_LOG_LEVEL_INFO,
- "Setting file %s size to %lu MB",
+ "Setting file %s size to " ULINTPF " MB",
name,
- (ulong) (srv_data_file_sizes[i]
+ (srv_data_file_sizes[i]
>> (20 - UNIV_PAGE_SIZE_SHIFT)));
ret = os_file_set_size(
@@ -1221,7 +1260,7 @@ srv_undo_tablespace_create(
const char* name, /*!< in: tablespace name */
ulint size) /*!< in: tablespace size in pages */
{
- os_file_t fh;
+ pfs_os_file_t fh;
ibool ret;
dberr_t err = DB_SUCCESS;
@@ -1299,7 +1338,7 @@ srv_undo_tablespace_open(
const char* name, /*!< in: tablespace name */
ulint space) /*!< in: tablespace id */
{
- os_file_t fh;
+ pfs_os_file_t fh;
dberr_t err = DB_ERROR;
ibool ret;
ulint flags;
@@ -1404,13 +1443,23 @@ srv_undo_tablespaces_init(
for (i = 0; create_new_db && i < n_conf_tablespaces; ++i) {
char name[OS_FILE_MAX_PATH];
+ ulint space_id = i + 1;
+
+ DBUG_EXECUTE_IF("innodb_undo_upgrade",
+ space_id = i + 3;);
ut_snprintf(
name, sizeof(name),
"%s%cundo%03lu",
- srv_undo_dir, SRV_PATH_SEPARATOR, i + 1);
+ srv_undo_dir, SRV_PATH_SEPARATOR, space_id);
+
+ if (i == 0) {
+ srv_undo_space_id_start = space_id;
+ prev_space_id = srv_undo_space_id_start - 1;
+ }
+
+ undo_tablespace_ids[i] = space_id;
- /* Undo space ids start from 1. */
err = srv_undo_tablespace_create(
name, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES);
@@ -1432,14 +1481,16 @@ srv_undo_tablespaces_init(
if (!create_new_db && !backup_mode) {
n_undo_tablespaces = trx_rseg_get_n_undo_tablespaces(
undo_tablespace_ids);
- } else {
- n_undo_tablespaces = n_conf_tablespaces;
- for (i = 1; i <= n_undo_tablespaces; ++i) {
- undo_tablespace_ids[i - 1] = i;
+ if (n_undo_tablespaces != 0) {
+ srv_undo_space_id_start = undo_tablespace_ids[0];
+ prev_space_id = srv_undo_space_id_start - 1;
}
- undo_tablespace_ids[i] = ULINT_UNDEFINED;
+ } else {
+ n_undo_tablespaces = n_conf_tablespaces;
+
+ undo_tablespace_ids[n_conf_tablespaces] = ULINT_UNDEFINED;
}
/* Open all the undo tablespaces that are currently in use. If we
@@ -1463,8 +1514,6 @@ srv_undo_tablespaces_init(
ut_a(undo_tablespace_ids[i] != 0);
ut_a(undo_tablespace_ids[i] != ULINT_UNDEFINED);
- /* Undo space ids start from 1. */
-
err = srv_undo_tablespace_open(name, undo_tablespace_ids[i]);
if (err != DB_SUCCESS) {
@@ -1499,11 +1548,23 @@ srv_undo_tablespaces_init(
break;
}
+ /** Note the first undo tablespace id in case of
+ no active undo tablespace. */
+ if (n_undo_tablespaces == 0) {
+ srv_undo_space_id_start = i;
+ }
+
++n_undo_tablespaces;
++*n_opened;
}
+ /** Explictly specify the srv_undo_space_id_start
+ as zero when there are no undo tablespaces. */
+ if (n_undo_tablespaces == 0) {
+ srv_undo_space_id_start = 0;
+ }
+
/* If the user says that there are fewer than what we find we
tolerate that discrepancy but not the inverse. Because there could
be unused undo tablespaces for future use. */
@@ -1548,10 +1609,11 @@ srv_undo_tablespaces_init(
mtr_start(&mtr);
/* The undo log tablespace */
- for (i = 1; i <= n_undo_tablespaces; ++i) {
+ for (i = 0; i < n_undo_tablespaces; ++i) {
fsp_header_init(
- i, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
+ undo_tablespace_ids[i],
+ SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
}
mtr_commit(&mtr);
@@ -1626,12 +1688,10 @@ are not found and the user wants.
@return DB_SUCCESS or error code */
UNIV_INTERN
dberr_t
-innobase_start_or_create_for_mysql(void)
-/*====================================*/
+innobase_start_or_create_for_mysql()
{
- ibool create_new_db;
- lsn_t min_flushed_lsn;
- lsn_t max_flushed_lsn;
+ bool create_new_db;
+ lsn_t flushed_lsn;
#ifdef UNIV_LOG_ARCHIVE
lsn_t min_arch_log_no = LSN_MAX;
lsn_t max_arch_log_no = LSN_MAX;
@@ -1665,6 +1725,10 @@ innobase_start_or_create_for_mysql(void)
/* This should be initialized early */
ut_init_timer();
+ if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
+ srv_read_only_mode = 1;
+ }
+
high_level_read_only = srv_read_only_mode
|| srv_force_recovery > SRV_FORCE_NO_TRX_UNDO;
@@ -2176,7 +2240,7 @@ innobase_start_or_create_for_mysql(void)
#ifdef UNIV_LOG_ARCHIVE
&min_arch_log_no, &max_arch_log_no,
#endif /* UNIV_LOG_ARCHIVE */
- &min_flushed_lsn, &max_flushed_lsn,
+ &flushed_lsn,
&sum_of_new_sizes);
if (err == DB_FAIL) {
@@ -2220,12 +2284,12 @@ innobase_start_or_create_for_mysql(void)
bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL);
ut_a(success);
- min_flushed_lsn = max_flushed_lsn = log_get_lsn();
+ flushed_lsn = log_get_lsn();
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
err = create_log_files(create_new_db, logfilename, dirnamelen,
- max_flushed_lsn, logfile0);
+ flushed_lsn, logfile0);
if (err != DB_SUCCESS) {
return(err);
@@ -2245,19 +2309,8 @@ innobase_start_or_create_for_mysql(void)
if (err == DB_NOT_FOUND) {
if (i == 0) {
- if (max_flushed_lsn
- != min_flushed_lsn) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Cannot create"
- " log files because"
- " data files are"
- " corrupt or"
- " not in sync"
- " with each other");
- return(DB_ERROR);
- }
- if (max_flushed_lsn < (lsn_t) 1000) {
+ if (flushed_lsn < (lsn_t) 1000) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Cannot create"
" log files because"
@@ -2272,14 +2325,14 @@ innobase_start_or_create_for_mysql(void)
err = create_log_files(
create_new_db, logfilename,
- dirnamelen, max_flushed_lsn,
+ dirnamelen, flushed_lsn,
logfile0);
if (err == DB_SUCCESS) {
err = create_log_files_rename(
logfilename,
dirnamelen,
- max_flushed_lsn,
+ flushed_lsn,
logfile0);
}
@@ -2289,8 +2342,7 @@ innobase_start_or_create_for_mysql(void)
/* Suppress the message about
crash recovery. */
- max_flushed_lsn = min_flushed_lsn
- = log_get_lsn();
+ flushed_lsn = log_get_lsn();
goto files_checked;
} else if (i < 2 && !IS_XTRABACKUP()) {
/* must have at least 2 log files */
@@ -2420,9 +2472,23 @@ files_checked:
mtr_start(&mtr);
fsp_header_init(0, sum_of_new_sizes, &mtr);
+ compile_time_assert(TRX_SYS_SPACE == 0);
+ compile_time_assert(IBUF_SPACE_ID == 0);
+
+ ulint ibuf_root = btr_create(
+ DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
+ 0, 0, DICT_IBUF_ID_MIN,
+ dict_ind_redundant, &mtr);
mtr_commit(&mtr);
+ if (ibuf_root == FIL_NULL) {
+ return(srv_init_abort(true, __FILE__, __LINE__,
+ DB_ERROR));
+ }
+
+ ut_ad(ibuf_root == IBUF_TREE_ROOT_PAGE_NO);
+
/* To maintain backward compatibility we create only
the first rollback segment before the double write buffer.
All the remaining rollback segments will be created later,
@@ -2448,17 +2514,19 @@ files_checked:
bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL);
ut_a(success);
- min_flushed_lsn = max_flushed_lsn = log_get_lsn();
+ flushed_lsn = log_get_lsn();
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
/* Stamp the LSN to the data files. */
- fil_write_flushed_lsn_to_data_files(max_flushed_lsn, 0);
+ err = fil_write_flushed_lsn(flushed_lsn);
- fil_flush_file_spaces(FIL_TABLESPACE);
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
err = create_log_files_rename(logfilename, dirnamelen,
- max_flushed_lsn, logfile0);
+ flushed_lsn, logfile0);
if (err != DB_SUCCESS) {
return(err);
@@ -2513,7 +2581,7 @@ files_checked:
err = recv_recovery_from_checkpoint_start(
LOG_CHECKPOINT, LSN_MAX,
- min_flushed_lsn, max_flushed_lsn);
+ flushed_lsn);
if (err != DB_SUCCESS) {
return(err);
@@ -2696,7 +2764,7 @@ files_checked:
DBUG_EXECUTE_IF("innodb_log_abort_1",
return(DB_ERROR););
- min_flushed_lsn = max_flushed_lsn = log_get_lsn();
+ flushed_lsn = log_get_lsn();
ib_logf(IB_LOG_LEVEL_WARN,
"Resizing redo log from %u*%u to %u*%u pages"
@@ -2705,7 +2773,7 @@ files_checked:
(unsigned) srv_log_file_size,
(unsigned) srv_n_log_files,
(unsigned) srv_log_file_size_requested,
- max_flushed_lsn);
+ flushed_lsn);
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
@@ -2715,7 +2783,7 @@ files_checked:
we need to explicitly flush the log buffers. */
fil_flush(SRV_LOG_SPACE_FIRST_ID);
- ut_ad(max_flushed_lsn == log_get_lsn());
+ ut_ad(flushed_lsn == log_get_lsn());
/* Prohibit redo log writes from any other
threads until creating a log checkpoint at the
@@ -2727,8 +2795,7 @@ files_checked:
return(DB_ERROR););
/* Stamp the LSN to the data files. */
- fil_write_flushed_lsn_to_data_files(
- max_flushed_lsn, 0);
+ err = fil_write_flushed_lsn(flushed_lsn);
DBUG_EXECUTE_IF("innodb_log_abort_4", err = DB_ERROR;);
@@ -2736,8 +2803,6 @@ files_checked:
return(err);
}
- fil_flush_file_spaces(FIL_TABLESPACE);
-
/* Close and free the redo log files, so that
we can replace them. */
fil_close_log_files(true);
@@ -2754,28 +2819,23 @@ files_checked:
srv_log_file_size = srv_log_file_size_requested;
err = create_log_files(create_new_db, logfilename,
- dirnamelen, max_flushed_lsn,
+ dirnamelen, flushed_lsn,
logfile0);
if (err != DB_SUCCESS) {
return(err);
}
- /* create_log_files() can increase system lsn that is
- why FIL_PAGE_FILE_FLUSH_LSN have to be updated */
- min_flushed_lsn = max_flushed_lsn = log_get_lsn();
- fil_write_flushed_lsn_to_data_files(min_flushed_lsn, 0);
- fil_flush_file_spaces(FIL_TABLESPACE);
-
err = create_log_files_rename(logfilename, dirnamelen,
log_get_lsn(), logfile0);
+
if (err != DB_SUCCESS) {
return(err);
}
}
- srv_startup_is_before_trx_rollback_phase = FALSE;
recv_recovery_rollback_active();
+ srv_startup_is_before_trx_rollback_phase = FALSE;
/* It is possible that file_format tag has never
been set. In this case we initialize it to minimum
@@ -2815,10 +2875,9 @@ files_checked:
/* fprintf(stderr, "Max allowed record size %lu\n",
page_get_free_space_of_empty() / 2); */
- if (buf_dblwr == NULL) {
- /* Create the doublewrite buffer to a new tablespace */
-
- buf_dblwr_create();
+ if (!buf_dblwr_create()) {
+ return(srv_init_abort(create_new_db, __FILE__, __LINE__,
+ DB_ERROR));
}
/* Here the double write buffer has already been created and so
@@ -2848,6 +2907,9 @@ files_checked:
/* Can only happen if server is read only. */
ut_a(srv_read_only_mode);
srv_undo_logs = ULONG_UNDEFINED;
+ } else if (srv_available_undo_logs < srv_undo_logs) {
+ /* Should due to out of file space. */
+ return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
}
if (!srv_read_only_mode) {
@@ -2905,6 +2967,16 @@ files_checked:
srv_master_thread,
NULL, thread_ids + (1 + SRV_MAX_N_IO_THREADS));
thread_started[1 + SRV_MAX_N_IO_THREADS] = true;
+
+ srv_undo_sources = true;
+ /* Create the dict stats gathering thread */
+ srv_dict_stats_thread_active = true;
+ dict_stats_thread_handle = os_thread_create(
+ dict_stats_thread, NULL, NULL);
+ dict_stats_thread_started = true;
+
+ /* Create the thread that will optimize the FTS sub-system. */
+ fts_optimize_init();
}
if (!srv_read_only_mode
@@ -2949,12 +3021,16 @@ files_checked:
}
- buf_flush_page_cleaner_thread_handle = os_thread_create(buf_flush_page_cleaner_thread, NULL, NULL);
+ buf_page_cleaner_is_active = true;
+ buf_flush_page_cleaner_thread_handle = os_thread_create(
+ buf_flush_page_cleaner_thread, NULL, NULL);
buf_flush_page_cleaner_thread_started = true;
- }
- buf_flush_lru_manager_thread_handle = os_thread_create(buf_flush_lru_manager_thread, NULL, NULL);
- buf_flush_lru_manager_thread_started = true;
+ buf_lru_manager_is_active = true;
+ buf_flush_lru_manager_thread_handle = os_thread_create(
+ buf_flush_lru_manager_thread, NULL, NULL);
+ buf_flush_lru_manager_thread_started = true;
+ }
if (!srv_file_per_table && srv_pass_corrupt_table) {
fprintf(stderr, "InnoDB: Warning:"
@@ -3002,10 +3078,10 @@ files_checked:
if (!wsrep_recovery) {
#endif /* WITH_WSREP */
/* Create the buffer pool dump/load thread */
+ srv_buf_dump_thread_active = true;
buf_dump_thread_handle=
os_thread_create(buf_dump_thread, NULL, NULL);
- srv_buf_dump_thread_active = true;
buf_dump_thread_started = true;
#ifdef WITH_WSREP
} else {
@@ -3015,26 +3091,19 @@ files_checked:
}
#endif /* WITH_WSREP */
- /* Create the dict stats gathering thread */
- dict_stats_thread_handle = os_thread_create(
- dict_stats_thread, NULL, NULL);
- srv_dict_stats_thread_active = true;
- dict_stats_thread_started = true;
-
- /* Create the thread that will optimize the FTS sub-system. */
- fts_optimize_init();
-
/* Create thread(s) that handles key rotation */
fil_system_enter();
fil_crypt_threads_init();
fil_system_exit();
- }
- /* Init data for datafile scrub threads */
- btr_scrub_init();
+ /* Init data for datafile scrub threads */
+ btr_scrub_init();
- /* Initialize online defragmentation. */
- btr_defragment_init();
+ /* Initialize online defragmentation. */
+ btr_defragment_init();
+ btr_defragment_thread_active = true;
+ os_thread_create(btr_defragment_thread, NULL, NULL);
+ }
srv_was_started = TRUE;
@@ -3071,13 +3140,10 @@ srv_fts_close(void)
}
#endif
-/****************************************************************//**
-Shuts down the InnoDB database.
-@return DB_SUCCESS or error code */
+/** Shut down InnoDB. */
UNIV_INTERN
-dberr_t
-innobase_shutdown_for_mysql(void)
-/*=============================*/
+void
+innodb_shutdown()
{
ulint i;
@@ -3087,15 +3153,20 @@ innobase_shutdown_for_mysql(void)
"Shutting down an improperly started, "
"or created database!");
}
-
- return(DB_SUCCESS);
}
- if (!srv_read_only_mode) {
+ if (srv_undo_sources) {
+ ut_ad(!srv_read_only_mode);
/* Shutdown the FTS optimize sub system. */
fts_optimize_start_shutdown();
fts_optimize_end();
+ dict_stats_shutdown();
+ while (row_get_background_drop_list_len_low()) {
+ srv_wake_master_thread();
+ os_thread_yield();
+ }
+ srv_undo_sources = false;
}
/* 1. Flush the buffer pool to disk, write the current lsn to
@@ -3199,11 +3270,10 @@ innobase_shutdown_for_mysql(void)
if (!srv_read_only_mode) {
dict_stats_thread_deinit();
fil_crypt_threads_cleanup();
+ btr_scrub_cleanup();
+ btr_defragment_shutdown();
}
- /* Cleanup data for datafile scrubbing */
- btr_scrub_cleanup();
-
#ifdef __WIN__
/* MDEV-361: ha_innodb.dll leaks handles on Windows
MDEV-7403: should not pass recv_writer_thread_handle to
@@ -3311,88 +3381,9 @@ innobase_shutdown_for_mysql(void)
srv_start_has_been_called = FALSE;
/* reset io_tid_i, in case current process does second innodb start (xtrabackup might do that).*/
io_tid_i = 0;
- return(DB_SUCCESS);
}
#endif /* !UNIV_HOTBACKUP */
-
-/********************************************************************
-Signal all per-table background threads to shutdown, and wait for them to do
-so. */
-UNIV_INTERN
-void
-srv_shutdown_table_bg_threads(void)
-/*===============================*/
-{
- dict_table_t* table;
- dict_table_t* first;
- dict_table_t* last = NULL;
-
- mutex_enter(&dict_sys->mutex);
-
- /* Signal all threads that they should stop. */
- table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
- first = table;
- while (table) {
- dict_table_t* next;
- fts_t* fts = table->fts;
-
- if (fts != NULL) {
- fts_start_shutdown(table, fts);
- }
-
- next = UT_LIST_GET_NEXT(table_LRU, table);
-
- if (!next) {
- last = table;
- }
-
- table = next;
- }
-
- /* We must release dict_sys->mutex here; if we hold on to it in the
- loop below, we will deadlock if any of the background threads try to
- acquire it (for example, the FTS thread by calling que_eval_sql).
-
- Releasing it here and going through dict_sys->table_LRU without
- holding it is safe because:
-
- a) MySQL only starts the shutdown procedure after all client
- threads have been disconnected and no new ones are accepted, so no
- new tables are added or old ones dropped.
-
- b) Despite its name, the list is not LRU, and the order stays
- fixed.
-
- To safeguard against the above assumptions ever changing, we store
- the first and last items in the list above, and then check that
- they've stayed the same below. */
-
- mutex_exit(&dict_sys->mutex);
-
- /* Wait for the threads of each table to stop. This is not inside
- the above loop, because by signaling all the threads first we can
- overlap their shutting down delays. */
- table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
- ut_a(first == table);
- while (table) {
- dict_table_t* next;
- fts_t* fts = table->fts;
-
- if (fts != NULL) {
- fts_shutdown(table, fts);
- }
-
- next = UT_LIST_GET_NEXT(table_LRU, table);
-
- if (table == last) {
- ut_a(!next);
- }
-
- table = next;
- }
-}
-
/*****************************************************************//**
Get the meta-data filename from the table name. */
UNIV_INTERN