/** TRUE if a raw partition is in use */
ibool srv_start_raw_disk_in_use;
/** UNDO tablespaces starts with space id. */
uint32_t srv_undo_space_id_start;
/** TRUE if the server is being started, before rolling back any
incomplete transactions */ bool srv_startup_is_before_trx_rollback_phase; /** TRUE if the server is being started */ bool srv_is_being_started; /** TRUE if the server was successfully started */ bool srv_was_started; /** whether srv_start() has been called */ staticbool srv_start_has_been_called;
/** Whether any undo log records can be generated */ bool srv_undo_sources;
#ifdef UNIV_DEBUG /** InnoDB system tablespace to set during recovery */
uint srv_sys_space_size_debug; /** whether redo log file have been created at startup */ bool srv_log_file_created; #endif/* UNIV_DEBUG */
/** whether some background threads that create redo log have been started */ staticbool srv_started_redo;
/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */ enum srv_shutdown_t srv_shutdown_state = SRV_SHUTDOWN_NONE;
/** Name of srv_monitor_file */ staticchar* srv_monitor_file_name;
std::unique_ptr<tpool::timer> srv_master_timer;
/** */ #define SRV_MAX_N_PENDING_SYNC_IOS 100
#ifdef UNIV_PFS_THREAD /* Keys to register InnoDB threads with performance schema */
mysql_pfs_key_t thread_pool_thread_key; #endif/* UNIV_PFS_THREAD */
/** Only created if !srv_read_only_mode. Protected by lock_sys.latch. */ extern FILE *lock_latest_err_file;
#ifdef HAVE_PSI_STAGE_INTERFACE /** Array of all InnoDB stage events for monitoring activities via
performance schema. */ static PSI_stage_info* srv_stages[] =
{
&srv_stage_alter_table_end,
&srv_stage_alter_table_insert,
&srv_stage_alter_table_log_index,
&srv_stage_alter_table_log_table,
&srv_stage_alter_table_merge_sort,
&srv_stage_alter_table_read_pk_internal_sort,
&srv_stage_buffer_pool_load,
}; #endif/* HAVE_PSI_STAGE_INTERFACE */
/** Delete any garbage log files */ staticvoid delete_log_files()
{ for (size_t i= 1; i < 102; i++)
os_file_delete_if_exists_func(log_sys.get_circular_path(i).c_str(), nullptr);
}
/* We will retain ib_logfile0 until we have written a new logically emptylogasib_logfile101andatomicallyrenameditto
ib_logfile0 in log_t::resize_rename(). */
delete_log_files();
ut_ad(!os_aio_pending_reads()); /* os_aio_pending_writes() may hold here if some write_io_callback()didnotreleasetheslotyet.However, thepagewriteitselfmusthavecompleted,becausethe buf_pool.flush_listisempty.Indebugbuilds,wewaitfor thistohappen,hopingtogetahungprocessifthis
assumption does not hold. */
ut_d(os_aio_wait_until_no_pending_writes(false));
if (!ret) { if (os_file_get_last_error(false) != OS_FILE_ALREADY_EXISTS #ifdef _AIX /* AIX 5.1 after security patch ML7 may have errnosetto0here,whichcausesourfunction
to return 100; work around that AIX problem */
&& os_file_get_last_error(false) != 100 #endif
) {
ib::error() << "Can't create UNDO tablespace "
<< name;
}
err = DB_ERROR;
} elseif (srv_read_only_mode) {
ib::info() << name << " opened in read-only mode";
} else { /* We created the data file and now write it full of zeros */
ib::info() << "Data file " << name << " did not exist: new to" " be created";
ib::info() << "Setting file " << name << " size to "
<< ib::bytes_iec{SRV_UNDO_TABLESPACE_SIZE_IN_PAGES
<< srv_page_size_shift};
/* Assign the new space id for the first undo tablespace */
latest_space_id= mach_read_from_4(
DICT_HDR + DICT_HDR_MAX_SPACE_ID + dict_hdr->page.frame);
if (latest_space_id + srv_undo_tablespaces > SRV_SPACE_ID_UPPER_BOUND)
{
err= DB_ERROR;
sql_print_error("InnoDB: Running out of tablespace id"); goto func_exit;
}
/* Re-create the new undo tablespaces */
err= srv_undo_tablespaces_init(true, &mtr);
func_exit:
mtr.commit();
if (err == DB_SUCCESS)
{ /* Usually, recovery must work no matter when log_checkpointsaretriggered.Thisisaspecialcase, becausethiscodeisexecutedaspartofInnoDBstartup. Backuprequiresthattheserverhasbeenstartedup, backupshouldneverobservethelogrecordsthat werewritteninmtrandalsosrv_undo_tablespaces_init() initializestheundotablespacestartidbasedonpage0
content before reading the redo log */
srv_undo_tablespaces_active= srv_undo_tablespaces;
log_make_checkpoint();
} return err;
}
/** Reinitialize the undo tablespaces when there is no undo log lefttopurge/rollbackandvalidatethenumberofundoopened undotablespaceandusergivenundotablespace
@return DB_SUCCESS if it is valid */ static dberr_t srv_undo_tablespaces_reinitialize()
{
/* Re-create the undo tablespaces if it has no undo logs
left to purge/rollback */ if (srv_undo_tablespaces != srv_undo_tablespaces_open &&
trx_sys.is_undo_empty()) return srv_undo_tablespaces_reinit();
/* If the user says that there are fewer than what we find we toleratethatdiscrepancybutnottheinverse.Becausetherecould
be unused undo tablespaces for future use. */
if (srv_undo_tablespaces != srv_undo_tablespaces_open)
{
sql_print_warning("InnoDB: Cannot change innodb_undo_tablespaces=%u " "because previous shutdown was not with " "innodb_fast_shutdown=0", srv_undo_tablespaces);
srv_undo_tablespaces= srv_undo_tablespaces_open;
} elseif (srv_undo_tablespaces_open > 0)
sql_print_information("InnoDB: Opened " UINT32PF " undo tablespaces",
srv_undo_tablespaces_open);
return DB_SUCCESS;
}
/** @return the number of active undo tablespaces (except system tablespace) */ static uint32_t trx_rseg_get_n_undo_tablespaces()
{
std::set<uint32_t> space_ids;
mtr_t mtr{nullptr};
mtr.start();
if (const buf_block_t *sys_header=
recv_sys.recover({TRX_SYS_SPACE, TRX_SYS_PAGE_NO}, &mtr, nullptr)) for (ulint rseg_id= 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) if (trx_sysf_rseg_get_page_no(sys_header, rseg_id) != FIL_NULL) if (uint32_t space= trx_sysf_rseg_get_space(sys_header, rseg_id))
space_ids.insert(space);
mtr.commit(); returnstatic_cast<uint32_t>(space_ids.size());
}
/** Open an undo tablespace. @param[in]createwhetherundotablespacesarebeingcreated @param[in]nametablespacefilename @param[in]iundotablespacecount @returnundotablespaceidentifier @retval0iffiledoesn'texist
@retval ~0U if page0 is corrupted */ static uint32_t srv_undo_tablespace_open(bool create, constchar* name,
uint32_t i)
{ bool success;
uint32_t space_id= 0;
uint32_t fsp_flags= 0;
if (create)
{
space_id= srv_undo_space_id_start + i; switch (srv_checksum_algorithm) { case SRV_CHECKSUM_ALGORITHM_FULL_CRC32: case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
fsp_flags= FSP_FLAGS_FCRC32_MASK_MARKER | FSP_FLAGS_FCRC32_PAGE_SSIZE(); break; default:
fsp_flags= FSP_FLAGS_PAGE_SSIZE();
}
}
if (buf_page_is_corrupted(false, page, fsp_flags))
{
page= recv_sys.dblwr.find_page(page_id_t{space_id, 0}, LSN_MAX); if (!page)
{ /* If the first page of the given user tablespace is not there inthedoublewritebuffer,thentherecoveryisgoingtofail
now. Report error only when doublewrite buffer is not empty */
sql_print_error("InnoDB: Corrupted page " "[page id: space=" UINT32PF ", page number=0]" " of datafile '%s' could not be found" " in the doublewrite buffer", space_id, name); goto err_exit;
}
/** Check if undo tablespaces and redo log files exist before creating a newsystemtablespace @retvalDB_SUCCESSifallundoandredologsarenotfound
@retval DB_ERROR if any undo and redo logs are found */ static
dberr_t
srv_check_undo_redo_logs_exists()
{ bool ret;
os_file_t fh; char name[OS_FILE_MAX_PATH];
/* Check if any undo tablespaces exist */ for (ulint i = 1; i <= srv_undo_tablespaces; ++i) {
if (ret) {
os_file_close_func(fh);
ib::error()
<< "undo tablespace '" << name << "' exists." " Creating system tablespace with existing undo" " tablespaces is not supported. Please delete" " all undo tablespaces before creating new" " system tablespace."; return(DB_ERROR);
}
}
/* Check if redo log file exists */
std::string logfilename{log_sys.get_circular_path()};
if (ret) {
os_file_close_func(fh);
found_log:
ib::error() << "redo log file '" << logfilename
<< "' exists. Creating system tablespace with" " existing redo log file is not recommended." " Please delete redo log file before" " creating new system tablespace."; return DB_ERROR;
}
#ifdef _WIN32
logfilename.assign(srv_log_group_home_dir); switch (logfilename.back()) { case'\\': case'/': break; default:
logfilename.push_back('/');
}
logfilename.append("ib_????????????????.log");
WIN32_FIND_DATAA entry;
HANDLE d = FindFirstFileA(logfilename.c_str(), &entry); if (d != INVALID_HANDLE_VALUE) {
FindClose(d); goto found_log;
} #else if (DIR* d = opendir(srv_log_group_home_dir)) { while (dirent* e = readdir(d)) {
lsn_t lsn; int n{0}; constchar* fn{e->d_name}; if (1 != sscanf(fn, LOG_ARCHIVE_NAME "%n", &lsn, &n)
|| fn[n] || lsn < log_t::FIRST_LSN) { continue;
}
logfilename.assign(srv_log_group_home_dir);
logfilename.push_back('/');
log_sys.append_archive_name(logfilename, lsn);
closedir(d); goto found_log;
}
closedir(d);
} #endif
return(DB_SUCCESS);
}
static dberr_t srv_all_undo_tablespaces_open(bool create_new_undo,
uint32_t n_undo)
{ /* Open all the undo tablespaces that are currently in use. If we failtoopenanyoftheseitisafatalerror.Thetablespaceids shouldbecontiguous.Itisafatalerrorbecausetheyarerequired
for recovery and are referenced by the UNDO logs (a.k.a RBS). */
for (uint32_t i= 0; i < n_undo; ++i)
{ char name[OS_FILE_MAX_PATH];
snprintf(name, sizeof name, "%s/undo%03u", srv_undo_dir, i + 1);
uint32_t space_id= srv_undo_tablespace_open(create_new_undo, name, i); switch (space_id) { case ~0U: return DB_CORRUPTION; case0: if (!create_new_undo) goto unused_undo;
sql_print_error("InnoDB: Unable to open create tablespace '%s'.", name); return DB_ERROR; default: /* Should be no gaps in undo tablespace ids. */
ut_a(!i || prev_id + 1 == space_id);
}
prev_id= space_id;
/* Note the first undo tablespace id in case of
no active undo tablespace. */ if (0 == srv_undo_tablespaces_open++)
srv_undo_space_id_start= space_id;
}
/* Open any extra unused undo tablespaces. These must be contiguous. Westopatthefirstfailure.Theseareundotablespacesthatare notinuseandthereforenotrequiredbyrecovery.Weonlycheck
that there are no gaps. */
unused_undo: for (uint32_t i= prev_id + 1; i < srv_undo_space_id_start + TRX_SYS_N_RSEGS;
++i)
{ char name[OS_FILE_MAX_PATH];
snprintf(name, sizeof name, "%s/undo%03u", srv_undo_dir, i);
uint32_t space_id= srv_undo_tablespace_open(false, name, i); if (!space_id || space_id == ~0U) break; if (0 == srv_undo_tablespaces_open++)
srv_undo_space_id_start= space_id;
}
return DB_SUCCESS;
}
PRAGMA_DISABLE_CHECK_STACK_FRAME
/** Open the configured number of dedicated undo tablespaces. @param[in]create_new_undowhethertheundotablespaceshastobecreated @param[in,out]mtrmini-transaction
@return DB_SUCCESS or error code */
dberr_t srv_undo_tablespaces_init(bool create_new_undo, mtr_t *mtr)
{
srv_undo_tablespaces_open= 0;
if (srv_undo_tablespaces == 1)
srv_undo_tablespaces= 0;
/* Create the undo spaces only if we are creating a new instance.Wedon'tallowcreatingofnewundotablespaces
in an existing instance (yet). */ if (create_new_undo)
{
DBUG_EXECUTE_IF("innodb_undo_upgrade", srv_undo_space_id_start= 3;);
for (ulint i= 0; i < srv_undo_tablespaces; ++i)
{ char name[OS_FILE_MAX_PATH];
snprintf(name, sizeof name, "%s/undo%03zu", srv_undo_dir, i + 1); if (dberr_t err= srv_undo_tablespace_create(name))
{
ib::error() << "Could not create undo tablespace '" << name << "'."; return err;
}
}
}
/* Get the tablespace ids of all the undo segments excluding thesystemtablespace(0).Ifwearecreatinganewinstancethen webuildtheundo_tablespace_idsourselvessincetheydon't
already exist. */
srv_undo_tablespaces_active= srv_undo_tablespaces;
/* Initialize srv_undo_space_id_start=0 when there are no
dedicated undo tablespaces. */ if (srv_undo_tablespaces_open == 0)
srv_undo_space_id_start= 0;
if (create_new_undo) for (uint32_t i= 0; err == DB_SUCCESS && i < srv_undo_tablespaces; ++i)
err= fsp_header_init(fil_space_get(srv_undo_space_id_start + i),
SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, mtr);
return err;
}
PRAGMA_REENABLE_CHECK_STACK_FRAME
/** Create the temporary file tablespace. @param[in]create_new_dbwhetherwearecreatinganewdatabase
@return DB_SUCCESS or error code. */ static
dberr_t
srv_open_tmp_tablespace(bool create_new_db)
{
ulint sum_of_new_sizes;
/* Will try to remove if there is existing file left-over by last
unclean shutdown */
srv_tmp_space.set_sanity_check_status(true);
srv_tmp_space.delete_files();
srv_tmp_space.set_ignore_read_only(true);
if (err == DB_FAIL) {
ib::error() << "The innodb_temporary" " data file must be writable!";
err = DB_ERROR;
} elseif (err != DB_SUCCESS) {
ib::error() << "Could not create the shared innodb_temporary.";
} elseif ((err = srv_tmp_space.open_or_create( true, create_new_db, &sum_of_new_sizes))
!= DB_SUCCESS) {
ib::error() << "Unable to create the shared innodb_temporary";
} elseif (fil_system.temp_space->open(true)) { /* Initialize the header page */
mtr_t mtr{nullptr};
mtr.start();
mtr.set_log_mode(MTR_LOG_NO_REDO);
err = fsp_header_init(fil_system.temp_space,
srv_tmp_space.get_sum_of_sizes(),
&mtr);
mtr.commit(); if (err == DB_SUCCESS) {
err = trx_temp_rseg_create(&mtr);
}
} else { /* This file was just opened in the code above! */
ib::error() << "The innodb_temporary" " data file cannot be re-opened" " after check_file_spec() succeeded!";
err = DB_ERROR;
}
return(err);
}
/** Shutdown background threads, except the page cleaner.
@param init_abort set to true when InnoDB startup aborted */ staticvoid srv_shutdown_threads(bool init_abort= false)
{
ut_ad(!srv_undo_sources);
srv_master_timer.reset(); /* In case of InnoDB start up aborted, Don't change thesrv_shutdown_state.Becauseinnodb_shutdown() doescallinnodb_preshutdown()whichchangesthe
srv_shutdown_state back to SRV_SHUTDOWN_INITIATED */ if (!init_abort) {
srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
}
if (purge_sys.enabled()) {
srv_purge_shutdown();
}
if (srv_n_fil_crypt_threads) {
fil_crypt_set_thread_cnt(0);
}
}
/** Shut down background threads that can generate undo log. */ staticvoid srv_shutdown_bg_undo_sources()
{
srv_shutdown_state= SRV_SHUTDOWN_INITIATED;
/** Prepare to delete the redo log file. Flush the dirty pages from all the bufferpools.Flushtheredologbuffertotheredologfile. @returnlsnuptowhichdatapageshavebeenflushedandlog_sys.latchacquired
@retval 0 in case of error; log_sys.latch will not be acquired */ static ATTRIBUTE_COLD lsn_t srv_prepare_to_delete_redo_log_file() noexcept
{
DBUG_ENTER("srv_prepare_to_delete_redo_log_file");
/** Upgrade the redo log to the latest format, or change its size
or encryption, before starting to write any log records. */
ATTRIBUTE_COLD static dberr_t srv_log_rebuild() noexcept
{ /* Prepare to delete the old redo log file */ const lsn_t lsn{srv_prepare_to_delete_redo_log_file()}; if (!lsn) return DB_ERROR;
mysql_mutex_lock(&buf_pool.flush_list_mutex);
ut_ad(!buf_pool.get_oldest_modification(0)); /* Prohibit redo log writes from any other threads until creating a
log checkpoint at the end of create_log_file(). */
ut_d(recv_no_log_write= true);
ut_ad(!os_aio_pending_reads());
DBUG_EXECUTE_IF("innodb_log_abort_5",
recv_sys.recovery_on= false; recv_no_log_write= false;
log_sys.latch.wr_unlock();
mysql_mutex_unlock(&buf_pool.flush_list_mutex); return DB_ERROR;); /* Close the redo log file, so that we can replace it */
log_sys.close_file();
dberr_t err= create_log_file(false, lsn);
if (err == DB_SUCCESS && log_sys.resize_rename())
err = DB_ERROR;
return err;
}
/** Rebuild the redo log if needed. */ static dberr_t srv_log_rebuild_if_needed() noexcept
{
ut_ad(!srv_read_only_mode || recv_sys.rpo);
if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) /* Completely ignore the redo log. */ return DB_SUCCESS; if (recv_sys.rpo) /* Leave the redo log alone. */ return DB_SUCCESS; if (log_sys.archive) return DB_SUCCESS; /* Never rebuild archived log files. */
if (log_sys.file_size == srv_log_file_size &&
log_sys.format ==
(srv_encrypt_log ? log_t::FORMAT_ENC_11 : log_t::FORMAT_10_8))
{ /* No need to add or remove encryption, upgrade, or resize. */
delete_log_files(); return DB_SUCCESS;
}
#ifdef UNIV_DEBUG
ib::info() << "!!!!!!!! UNIV_DEBUG switched on !!!!!!!!!"; #endif
ib::info() << "Compressed tables use zlib " ZLIB_VERSION #ifdef UNIV_ZIP_DEBUG " with validation" #endif/* UNIV_ZIP_DEBUG */
; #ifdef UNIV_ZIP_COPY
ib::info() << "and extra copying"; #endif/* UNIV_ZIP_COPY */
/* Since InnoDB does not currently clean up all its internal data structuresinMySQLEmbeddedServerLibraryserver_end(),we printanerrormessageifsomeonetriestostartupInnoDBa
second time during the process lifetime. */
if (srv_start_has_been_called) {
ib::error() << "Startup called second time" " during the process lifetime." " In the MariaDB Embedded Server Library" " you cannot call server_init() more than" " once during the process lifetime.";
}
srv_start_has_been_called = true;
srv_is_being_started = true;
/* Register performance schema stages before any real work has been
started which may need to be instrumented. */
mysql_stage_register("innodb", srv_stages, static_cast<int>(UT_ARR_SIZE(srv_stages)));
srv_boot();
ib::info() << my_crc32c_implementation();
if (os_aio_init()) { return(srv_init_abort(DB_ERROR));
}
if (!srv_read_only_mode
&& !(lock_latest_err_file = os_file_create_tmpfile())) { return(srv_init_abort(DB_ERROR));
}
switch (err) { case DB_SUCCESS: break; case DB_CANNOT_OPEN_FILE:
ib::error()
<< "Could not open or create the system tablespace. If" " you tried to add new data files to the system" " tablespace, and it failed here, you should now" " edit innodb_data_file_path in my.cnf back to what" " it was, and remove the new ibdata files InnoDB" " created in this failed attempt. InnoDB only wrote" " those files full of zeros, but did not yet use" " them in any way. But be careful: do not remove" " old data files which contain your precious data!"; /* fall through */ default: /* Other errors might be flagged by
Datafile::validate_first_page() */ return srv_init_abort(err);
}
if (create_new_db) {
lsn_t flushed_lsn = log_sys.init_lsn();
log_sys.latch.wr_lock();
mysql_mutex_lock(&buf_pool.flush_list_mutex);
if (log_sys.archive) {
log_sys.file_size = srv_log_file_size;
log_sys.archive_set_size();
}
err = create_log_file(true, flushed_lsn);
if (err != DB_SUCCESS) { for (const Datafile &file: srv_sys_space) {
os_file_delete(innodb_data_file_key,
file.filepath());
} return srv_init_abort(err);
}
srv_undo_space_id_start = 1;
}
/* Open data files in the system tablespace: we keep
them open until database shutdown */
mysql_mutex_lock(&recv_sys.mutex);
ut_d(fil_system.sys_space->recv_size = srv_sys_space_size_debug);
err = fil_system.sys_space->open(create_new_db)
? DB_SUCCESS : DB_ERROR;
mysql_mutex_unlock(&recv_sys.mutex);
if (log_sys.resize_rename()) { return(srv_init_abort(DB_ERROR));
}
} else { /* We always try to do a recovery, even if the database had
been shut down normally: this is the normal startup path */
switch (srv_operation) { case SRV_OPERATION_NORMAL: case SRV_OPERATION_EXPORT_RESTORED: case SRV_OPERATION_RESTORE_EXPORT: if (err != DB_SUCCESS) { break;
}
if (err != DB_SUCCESS) { return srv_init_abort(err);
}
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { /* Apply the hashed log records to the respectivefilepages,forthelastbatchof recv_group_scan_log_recs(). Sinceitmaygeneratehugebatchofthreadpooltasks, forreadiotaskgroup,scaledownthreadcreationrate bytemporarilyrestrictingtpoolconcurrency.
*/
srv_thread_pool->set_concurrency(srv_n_read_io_threads);
/* Upgrade or resize or rebuild the redo logs before generatinganydirtypages,sothattheoldredolog
file will not be written to. */
if (srv_operation <= SRV_OPERATION_EXPORT_RESTORED) {
err = srv_log_rebuild_if_needed();
if (err != DB_SUCCESS) { return srv_init_abort(err);
}
}
recv_sys.debug_free();
if (log_sys.archive) log_sys.archive_set_size();
if (!recv_sys.rpo) { const uint32_t flags = FSP_FLAGS_PAGE_SSIZE(); for (uint32_t id = srv_undo_space_id_start;
id <= srv_undo_tablespaces; id++) { if (fil_space_t* space = fil_space_get(id)) {
fsp_flags_try_adjust(space, flags);
}
}
if (sum_of_new_sizes > 0) { /* New data file(s) were added */
mtr.start();
mtr.x_lock_space(fil_system.sys_space);
buf_block_t* block = buf_page_get(
page_id_t(0, 0), 0,
RW_SX_LATCH, &mtr); /* The first page of the system tablespace shouldalreadyhavebeensuccessfully
accessed earlier during startup. */
ut_a(block);
ulint size = mach_read_from_4(
FSP_HEADER_OFFSET + FSP_SIZE
+ block->page.frame);
ut_ad(size == fil_system.sys_space
->size_in_header);
size += sum_of_new_sizes;
mtr.write<4>(*block,
FSP_HEADER_OFFSET + FSP_SIZE
+ block->page.frame, size);
fil_system.sys_space->size_in_header
= uint32_t(size);
mtr.commit();
log_write_up_to(mtr.commit_lsn(), true);
}
}
#ifdef UNIV_DEBUG
{
mtr.start();
buf_block_t* block = buf_page_get(page_id_t(0, 0), 0,
RW_S_LATCH, &mtr);
ut_ad(mach_read_from_4(FSP_SIZE + FSP_HEADER_OFFSET
+ block->page.frame)
== fil_system.sys_space->size_in_header);
mtr.commit();
} #endif const ulint tablespace_size_in_header
= fil_system.sys_space->size_in_header; const ulint sum_of_data_file_sizes
= srv_sys_space.get_sum_of_sizes(); /* Compare the system tablespace file size to what is storedinFSP_SIZE.Insrv_sys_space.open_or_create() wealreadycheckedthatthefilesizesmatchthe
innodb_data_file_path specification. */ if (srv_read_only_mode
|| sum_of_data_file_sizes == tablespace_size_in_header) { /* Do not complain about the size. */
} elseif (!srv_sys_space.can_auto_extend_last_file()
|| sum_of_data_file_sizes
< tablespace_size_in_header) {
ib::error() << "Tablespace size stored in header is "
<< tablespace_size_in_header
<< " pages, but the sum of data file sizes is "
<< sum_of_data_file_sizes << " pages";
if (srv_force_recovery == 0
&& sum_of_data_file_sizes
< tablespace_size_in_header) {
ib::error() << "Cannot start InnoDB. The tail of" " the system tablespace is" " missing. Have you edited" " innodb_data_file_path in my.cnf" " in an inappropriate way, removing" " data files from there?" " You can set innodb_force_recovery=1" " in my.cnf to force" " a startup if you are trying to" " recover a badly corrupt database.";
/* Create the doublewrite buffer to a new tablespace */ if (!srv_read_only_mode && srv_force_recovery < SRV_FORCE_NO_TRX_UNDO
&& !buf_dblwr.create()) { return(srv_init_abort(DB_ERROR));
}
/* Recreate the undo tablespaces */ if (!high_level_read_only && !recv_sys.rpo) {
err = srv_undo_tablespaces_reinitialize(); if (err) { return srv_init_abort(err);
}
}
srv_undo_tablespaces = srv_undo_tablespaces_open;
/* Here the double write buffer has already been created and so anynewrollbacksegmentswillbeallocatedafterthedouble writebuffer.Thedefaultsegmentshouldalreadyexist. Wecreatethenewsegmentsonlyifit'sanewdatabaseor
the database was shutdown cleanly. */
/* Note: When creating the extra rollback segments during an upgrade weviolatethelatchingorder,evenifthechangebufferisempty. Itcannotcreateadeadlockbecausewearestill runninginsinglethreadedmodeessentially.OnlytheIOthreads
should be running at this stage. */
if (!trx_sys_create_rsegs()) { return(srv_init_abort(DB_ERROR));
}
if (!create_new_db) {
ut_ad(high_level_read_only
|| srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
/* Validate a few system page types that were left
uninitialized before MySQL or MariaDB 5.5. */ if (!high_level_read_only && !recv_sys.rpo
&& !fil_system.sys_space->full_crc32()) {
buf_block_t* block;
mtr.start(); /* Bitmap page types will be reset in
buf_dblwr_check_block() without redo logging. */
block = buf_page_get(
page_id_t(0, FSP_IBUF_HEADER_PAGE_NO), 0, RW_X_LATCH, &mtr); if (UNIV_UNLIKELY(!block)) {
corrupted_old_page:
mtr.commit(); return srv_init_abort(DB_CORRUPTION);
}
fil_block_check_type(*block, FIL_PAGE_TYPE_SYS, &mtr); /* Already MySQL 3.23.53 initialized FSP_IBUF_TREE_ROOT_PAGE_NOto
FIL_PAGE_INDEX. No need to reset that one. */
block = buf_page_get(
page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO), 0, RW_X_LATCH, &mtr); if (UNIV_UNLIKELY(!block)) { goto corrupted_old_page;
}
fil_block_check_type(*block, FIL_PAGE_TYPE_TRX_SYS,
&mtr);
block = buf_page_get(
page_id_t(TRX_SYS_SPACE,
FSP_FIRST_RSEG_PAGE_NO), 0, RW_X_LATCH, &mtr); if (UNIV_UNLIKELY(!block)) { goto corrupted_old_page;
}
fil_block_check_type(*block, FIL_PAGE_TYPE_SYS, &mtr);
block = buf_page_get(
page_id_t(TRX_SYS_SPACE, FSP_DICT_HDR_PAGE_NO), 0, RW_X_LATCH, &mtr); if (UNIV_UNLIKELY(!block)) { goto corrupted_old_page;
}
fil_block_check_type(*block, FIL_PAGE_TYPE_SYS, &mtr);
mtr.commit();
}
/* Roll back any recovered data dictionary transactions,sothatthedatadictionarytableswill befreeofanylocks.Thedatadictionarylatch shouldguaranteethatthereisatmostonedata
dictionary transaction active at a time. */ if (!high_level_read_only && !recv_sys.rpo
&& srv_force_recovery <= SRV_FORCE_NO_TRX_UNDO) { /* If the following call is ever removed, the first-timeha_innobase::open()musthold(or acquireandrelease)atablelockthat conflictswithtrx_resurrect_table_locks(),to ensurethatanyrecoveredincompleteALTER TABLEwillhavebeenrolledback.Otherwise, dict_table_t::instantcouldbeclearedby rollbackinvoking dict_index_t::clear_instant_alter()whileopen
table handles exist in client connections. */
trx_rollback_recovered(false);
}
if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
dict_load_tablespaces();
}
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO
&& !recv_sys.rpo) { /* Drop partially created indexes. */
row_merge_drop_temp_indexes(); #ifdef EMBEDDED_LIBRARY /* Rollback incomplete non-DDL transactions */
trx_rollback_is_active = true;
srv_thread_pool->submit_task(&rollback_all_recovered_task); #endif
}
}
srv_startup_is_before_trx_rollback_phase = false;
if (!srv_read_only_mode) {
DBUG_EXECUTE_IF("innodb_skip_monitors", goto skip_monitors;); /* Create the task which warns of long semaphore waits */
srv_start_periodic_timer(srv_monitor_timer, srv_monitor_task,
SRV_MONITOR_INTERVAL);
if (srv_force_recovery < SRV_FORCE_NO_BACKGROUND
&& !recv_sys.rpo) {
srv_undo_sources = true; /* Create the dict stats gathering task */
dict_stats_start(); /* Create the thread that will optimize the
FULLTEXT search index subsystem. */
fts_optimize_init();
}
}
err = dict_sys.create_or_check_sys_tables(); switch (err) { case DB_SUCCESS: break; case DB_READ_ONLY: if (srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO) { break;
}
ib::error() << "Cannot create system tables in read-only mode"; /* fall through */ default: return(srv_init_abort(err));
}
err= innodb_binlog_startup_init(); if (UNIV_UNLIKELY(err != DB_SUCCESS))
{
sql_print_error("InnoDB: Could not initialize the binlog in InnoDB, " "aborting"); return(srv_init_abort(DB_ERROR));
}
if (!srv_read_only_mode
&& srv_operation <= SRV_OPERATION_EXPORT_RESTORED) { /* Initialize the innodb_temporary tablespace and keep
it open until shutdown. */
err = srv_open_tmp_tablespace(create_new_db);
if (err != DB_SUCCESS) { return(srv_init_abort(err));
}
if (srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
srv_start_periodic_timer(srv_master_timer, srv_master_callback, 1000);
}
}
srv_is_being_started = false;
if (srv_print_verbose_log) {
sql_print_information("InnoDB: " "log sequence number " LSN_PF "%s" "; transaction id " TRX_ID_FMT,
recv_sys.lsn,
log_sys.is_mmap()
? " (memory-mapped)" : "",
trx_sys.get_max_trx_id());
}
ut_ad(!srv_read_only_mode || recv_sys.rpo);
if (!recv_sys.rpo) { if (create_new_db) {
srv_buffer_pool_load_at_startup = FALSE;
}
/* Start buffer pool dump/load task */
buf_load_at_startup();
#ifdef WITH_WSREP
} else {
ib::warn() << "Skipping buffer pool dump/restore during " "wsrep recovery.";
} #endif/* WITH_WSREP */
dict_stats_init();
/* Create thread(s) that handles key rotation. This is neededalreadyhereaslog_preflush_pool_modified_pages willflushdirtypagesandthatmightneede.g.
fil_crypt_threads_cond. */
fil_crypt_threads_init();
#ifndef EMBEDDED_LIBRARY if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO && srv_was_started &&
!trx_rollback_is_active && trx_sys.any_active_transaction_recovered())
{ /* Trx rollback thread may not be started yet, since error happened before innobase_tc_log_recovery_done(),thusitisstartedheretofinishthe normalshutdownprocess.
*/
trx_rollback_is_active= true;
srv_thread_pool->submit_task(&rollback_all_recovered_task);
} #endif
if (!srv_fast_shutdown && srv_operation <= SRV_OPERATION_EXPORT_RESTORED) if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO && srv_was_started) while (trx_sys.any_active_transactions())
std::this_thread::sleep_for(std::chrono::milliseconds(1));
srv_shutdown_bg_undo_sources();
srv_purge_shutdown();
if (srv_n_fil_crypt_threads)
fil_crypt_set_thread_cnt(0);
}
/** Get the meta-data filename from the table name for a single-tabletablespace. @param[in]tabletableobject @param[out]filenamefilename
@param[in] max_len filename max length */ void
srv_get_meta_data_filename(
dict_table_t* table, char* filename,
ulint max_len)
{
ulint len; char* path;
/* Make sure the data_dir_path is set. */
dict_get_and_save_data_dir_path(table);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.