summaryrefslogtreecommitdiffstats
path: root/storage/innobase/srv
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/srv')
-rw-r--r--storage/innobase/srv/srv0mon.cc112
-rw-r--r--storage/innobase/srv/srv0srv.cc99
-rw-r--r--storage/innobase/srv/srv0start.cc316
3 files changed, 191 insertions, 336 deletions
diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc
index 62229842..2a22403e 100644
--- a/storage/innobase/srv/srv0mon.cc
+++ b/storage/innobase/srv/srv0mon.cc
@@ -2,7 +2,7 @@
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2022, MariaDB Corporation.
+Copyright (c) 2013, 2023, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -27,7 +27,6 @@ Created 12/9/2009 Jimmy Yang
#include "buf0flu.h"
#include "dict0mem.h"
-#include "ibuf0ibuf.h"
#include "lock0lock.h"
#include "mach0data.h"
#include "os0file.h"
@@ -517,23 +516,10 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_BUF_PAGE_READ("index_non_leaf","Index Non-leaf",
INDEX_NON_LEAF),
- MONITOR_BUF_PAGE_READ("index_ibuf_leaf", "Insert Buffer Index Leaf",
- INDEX_IBUF_LEAF),
-
- MONITOR_BUF_PAGE_READ("index_ibuf_non_leaf",
- "Insert Buffer Index Non-Leaf",
- INDEX_IBUF_NON_LEAF),
-
MONITOR_BUF_PAGE_READ("undo_log", "Undo Log", UNDO_LOG),
MONITOR_BUF_PAGE_READ("index_inode", "Index Inode", INODE),
- MONITOR_BUF_PAGE_READ("ibuf_free_list", "Insert Buffer Free List",
- IBUF_FREELIST),
-
- MONITOR_BUF_PAGE_READ("ibuf_bitmap", "Insert Buffer Bitmap",
- IBUF_BITMAP),
-
MONITOR_BUF_PAGE_READ("system_page", "System", SYSTEM),
MONITOR_BUF_PAGE_READ("trx_system", "Transaction System", TRX_SYSTEM),
@@ -556,23 +542,10 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_BUF_PAGE_WRITTEN("index_non_leaf","Index Non-leaf",
INDEX_NON_LEAF),
- MONITOR_BUF_PAGE_WRITTEN("index_ibuf_leaf", "Insert Buffer Index Leaf",
- INDEX_IBUF_LEAF),
-
- MONITOR_BUF_PAGE_WRITTEN("index_ibuf_non_leaf",
- "Insert Buffer Index Non-Leaf",
- INDEX_IBUF_NON_LEAF),
-
MONITOR_BUF_PAGE_WRITTEN("undo_log", "Undo Log", UNDO_LOG),
MONITOR_BUF_PAGE_WRITTEN("index_inode", "Index Inode", INODE),
- MONITOR_BUF_PAGE_WRITTEN("ibuf_free_list", "Insert Buffer Free List",
- IBUF_FREELIST),
-
- MONITOR_BUF_PAGE_WRITTEN("ibuf_bitmap", "Insert Buffer Bitmap",
- IBUF_BITMAP),
-
MONITOR_BUF_PAGE_WRITTEN("system_page", "System", SYSTEM),
MONITOR_BUF_PAGE_WRITTEN("trx_system", "Transaction System",
@@ -941,57 +914,6 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT | MONITOR_DEFAULT_ON),
MONITOR_DEFAULT_START, MONITOR_OVLD_N_FILE_OPENED},
- /* ========== Counters for Change Buffer ========== */
- {"module_ibuf_system", "change_buffer", "InnoDB Change Buffer",
- MONITOR_MODULE,
- MONITOR_DEFAULT_START, MONITOR_MODULE_IBUF_SYSTEM},
-
- {"ibuf_merges_insert", "change_buffer",
- "Number of inserted records merged by change buffering",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_OVLD_IBUF_MERGE_INSERT},
-
- {"ibuf_merges_delete_mark", "change_buffer",
- "Number of deleted records merged by change buffering",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_OVLD_IBUF_MERGE_DELETE},
-
- {"ibuf_merges_delete", "change_buffer",
- "Number of purge records merged by change buffering",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_OVLD_IBUF_MERGE_PURGE},
-
- {"ibuf_merges_discard_insert", "change_buffer",
- "Number of insert merged operations discarded",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_OVLD_IBUF_MERGE_DISCARD_INSERT},
-
- {"ibuf_merges_discard_delete_mark", "change_buffer",
- "Number of deleted merged operations discarded",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_OVLD_IBUF_MERGE_DISCARD_DELETE},
-
- {"ibuf_merges_discard_delete", "change_buffer",
- "Number of purge merged operations discarded",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_OVLD_IBUF_MERGE_DISCARD_PURGE},
-
- {"ibuf_merges", "change_buffer", "Number of change buffer merges",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_OVLD_IBUF_MERGES},
-
- {"ibuf_size", "change_buffer", "Change buffer size in pages",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_OVLD_IBUF_SIZE},
-
/* ========== Counters for server operations ========== */
{"module_innodb", "innodb",
"Counter for general InnoDB server wide operations and properties",
@@ -1549,38 +1471,6 @@ srv_mon_process_existing_counter(
value = fil_system.n_open;
break;
- case MONITOR_OVLD_IBUF_MERGE_INSERT:
- value = ibuf.n_merged_ops[IBUF_OP_INSERT];
- break;
-
- case MONITOR_OVLD_IBUF_MERGE_DELETE:
- value = ibuf.n_merged_ops[IBUF_OP_DELETE_MARK];
- break;
-
- case MONITOR_OVLD_IBUF_MERGE_PURGE:
- value = ibuf.n_merged_ops[IBUF_OP_DELETE];
- break;
-
- case MONITOR_OVLD_IBUF_MERGE_DISCARD_INSERT:
- value = ibuf.n_discarded_ops[IBUF_OP_INSERT];
- break;
-
- case MONITOR_OVLD_IBUF_MERGE_DISCARD_DELETE:
- value = ibuf.n_discarded_ops[IBUF_OP_DELETE_MARK];
- break;
-
- case MONITOR_OVLD_IBUF_MERGE_DISCARD_PURGE:
- value = ibuf.n_discarded_ops[IBUF_OP_DELETE];
- break;
-
- case MONITOR_OVLD_IBUF_MERGES:
- value = ibuf.n_merges;
- break;
-
- case MONITOR_OVLD_IBUF_SIZE:
- value = ibuf.size;
- break;
-
case MONITOR_OVLD_SERVER_ACTIVITY:
value = srv_get_activity_count();
break;
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 7c0c4b92..7d2a6072 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -3,7 +3,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2022, MariaDB Corporation.
+Copyright (c) 2013, 2023, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -48,7 +48,6 @@ Created 10/8/1995 Heikki Tuuri
#include "buf0lru.h"
#include "dict0boot.h"
#include "dict0load.h"
-#include "ibuf0ibuf.h"
#include "lock0lock.h"
#include "log0recv.h"
#include "mem0mem.h"
@@ -61,7 +60,6 @@ Created 10/8/1995 Heikki Tuuri
#include "srv0start.h"
#include "trx0i_s.h"
#include "trx0purge.h"
-#include "btr0defragment.h"
#include "ut0mem.h"
#include "fil0fil.h"
#include "fil0crypt.h"
@@ -123,9 +121,9 @@ my_bool srv_read_only_mode;
/** store to its own file each table created by an user; data
dictionary tables are in the system tablespace 0 */
my_bool srv_file_per_table;
-/** Set if InnoDB operates in read-only mode or innodb-force-recovery
-is greater than SRV_FORCE_NO_TRX_UNDO. */
-my_bool high_level_read_only;
+/** Set if innodb_read_only is set or innodb_force_recovery
+is SRV_FORCE_NO_UNDO_LOG_SCAN or greater. */
+bool high_level_read_only;
/** Sort buffer size in index creation */
ulong srv_sort_buf_size;
@@ -216,13 +214,6 @@ in the buffer cache and accessed sequentially for InnoDB to trigger a
readahead request. */
ulong srv_read_ahead_threshold;
-/** innodb_change_buffer_max_size; maximum on-disk size of change
-buffer in terms of percentage of the buffer pool. */
-uint srv_change_buffer_max_size;
-
-ulong srv_file_flush_method;
-
-
/** copy of innodb_open_files; @see innodb_init_params() */
ulint srv_max_n_open_files;
@@ -279,7 +270,7 @@ my_bool srv_print_all_deadlocks;
INFORMATION_SCHEMA.innodb_cmp_per_index */
my_bool srv_cmp_per_index_enabled;
-/** innodb_fast_shutdown=1 skips purge and change buffer merge.
+/** innodb_fast_shutdown=1 skips the purge of transaction history.
innodb_fast_shutdown=2 effectively crashes the server (no log checkpoint).
innodb_fast_shutdown=3 is a clean shutdown that skips the rollback
of active transaction (to be done on restart). */
@@ -313,8 +304,6 @@ unsigned long long srv_stats_modified_counter;
based on number of configured pages */
my_bool srv_stats_sample_traditional;
-my_bool srv_use_doublewrite_buf;
-
/** innodb_sync_spin_loops */
ulong srv_n_spin_wait_rounds;
/** innodb_spin_wait_delay */
@@ -323,21 +312,6 @@ uint srv_spin_wait_delay;
/** Number of initialized rollback segments for persistent undo log */
ulong srv_available_undo_logs;
-/* Defragmentation */
-my_bool srv_defragment;
-/** innodb_defragment_n_pages */
-uint srv_defragment_n_pages;
-uint srv_defragment_stats_accuracy;
-/** innodb_defragment_fill_factor_n_recs */
-uint srv_defragment_fill_factor_n_recs;
-/** innodb_defragment_fill_factor */
-double srv_defragment_fill_factor;
-/** innodb_defragment_frequency */
-uint srv_defragment_frequency;
-/** derived from innodb_defragment_frequency;
-@see innodb_defragment_frequency_update() */
-ulonglong srv_defragment_interval;
-
/** Current mode of operation */
enum srv_operation_mode srv_operation;
@@ -381,8 +355,6 @@ FILE* srv_misc_tmpfile;
ulint srv_main_active_loops;
/** Iterations of the loop bounded by the 'srv_idle' label. */
ulint srv_main_idle_loops;
-/** Iterations of the loop bounded by the 'srv_shutdown' label. */
-static ulint srv_main_shutdown_loops;
/** Log writes involving flush. */
ulint srv_log_writes_and_flush;
@@ -548,10 +520,9 @@ srv_print_master_thread_info(
FILE *file) /* in: output stream */
{
fprintf(file, "srv_master_thread loops: " ULINTPF " srv_active, "
- ULINTPF " srv_shutdown, " ULINTPF " srv_idle\n"
+ ULINTPF " srv_idle\n"
"srv_master_thread log flush and writes: " ULINTPF "\n",
srv_main_active_loops,
- srv_main_shutdown_loops,
srv_main_idle_loops,
srv_log_writes_and_flush);
}
@@ -770,8 +741,6 @@ srv_printf_innodb_monitor(
"--------\n", file);
os_aio_print(file);
- ibuf_print(file);
-
#ifdef BTR_CUR_HASH_ADAPT
if (btr_search_enabled) {
fputs("-------------------\n"
@@ -953,11 +922,6 @@ srv_export_innodb_status(void)
export_vars.innodb_n_temp_blocks_decrypted =
srv_stats.n_temp_blocks_decrypted;
- export_vars.innodb_defragment_compression_failures =
- btr_defragment_compression_failures;
- export_vars.innodb_defragment_failures = btr_defragment_failures;
- export_vars.innodb_defragment_count = btr_defragment_count;
-
export_vars.innodb_onlineddl_rowlog_rows = onlineddl_rowlog_rows;
export_vars.innodb_onlineddl_rowlog_pct_used = onlineddl_rowlog_pct_used;
export_vars.innodb_onlineddl_pct_progress = onlineddl_pct_progress;
@@ -1272,31 +1236,6 @@ static void srv_sync_log_buffer_in_background()
}
}
-/** Report progress during shutdown.
-@param last time of last output
-@param n_read number of page reads initiated for change buffer merge */
-static void srv_shutdown_print(time_t &last, ulint n_read)
-{
- time_t now= time(nullptr);
- if (now - last >= 15)
- {
- last= now;
-
- const ulint ibuf_size= ibuf.size;
- sql_print_information("Completing change buffer merge;"
- " %zu page reads initiated;"
- " %zu change buffer pages remain",
- n_read, ibuf_size);
-#if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY
- service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
- "Completing change buffer merge;"
- " %zu page reads initiated;"
- " %zu change buffer pages remain",
- n_read, ibuf_size);
-#endif
- }
-}
-
/** Perform periodic tasks whenever the server is active.
@param counter_time microsecond_interval_timer() */
static void srv_master_do_active_tasks(ulonglong counter_time)
@@ -1334,32 +1273,6 @@ static void srv_master_do_idle_tasks(ulonglong counter_time)
MONITOR_SRV_DICT_LRU_MICROSECOND, counter_time);
}
-/**
-Complete the shutdown tasks such as background DROP TABLE,
-and optionally change buffer merge (on innodb_fast_shutdown=0). */
-void srv_shutdown(bool ibuf_merge)
-{
- ulint n_read = 0;
- time_t now = time(NULL);
-
- do {
- ut_ad(!srv_read_only_mode);
- ut_ad(srv_shutdown_state == SRV_SHUTDOWN_CLEANUP);
- ++srv_main_shutdown_loops;
-
- if (ibuf_merge) {
- srv_main_thread_op_info = "doing insert buffer merge";
- /* Disallow the use of change buffer to
- avoid a race condition with
- ibuf_read_merge_pages() */
- ibuf_max_size_update(0);
- log_free_check();
- n_read = ibuf_contract();
- srv_shutdown_print(now, n_read);
- }
- } while (n_read);
-}
-
/** The periodic master task controlling the server. */
void srv_master_callback(void*)
{
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index fc557673..e13bc77d 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2022, MariaDB Corporation.
+Copyright (c) 2013, 2023, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
@@ -62,10 +62,8 @@ Created 2/16/1996 Heikki Tuuri
#include "btr0btr.h"
#include "btr0cur.h"
#include "rem0rec.h"
-#include "ibuf0ibuf.h"
#include "srv0start.h"
#include "srv0srv.h"
-#include "btr0defragment.h"
#include "mysql/service_wsrep.h" /* wsrep_recovery */
#include "trx0rseg.h"
#include "buf0flu.h"
@@ -88,6 +86,7 @@ Created 2/16/1996 Heikki Tuuri
#include "row0row.h"
#include "row0mysql.h"
#include "btr0pcur.h"
+#include "ibuf0ibuf.h"
#include "zlib.h"
#include "log.h"
@@ -370,6 +369,11 @@ inline dberr_t trx_sys_t::reset_page(mtr_t *mtr)
sys_header->page.frame + TRX_SYS_DOUBLEWRITE
+ FSEG_HEADER_SIZE + TRX_SYS_DOUBLEWRITE_REPEAT,
sys_header->page.frame + TRX_SYS_DOUBLEWRITE + FSEG_HEADER_SIZE, 12);
+ mtr->write<4>(
+ *sys_header,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED +
+ sys_header->page.frame,
+ TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N);
}
return DB_SUCCESS;
@@ -592,7 +596,8 @@ static uint32_t trx_rseg_get_n_undo_tablespaces()
mtr_t mtr;
mtr.start();
- if (const buf_block_t *sys_header= trx_sysf_get(&mtr, false))
+ 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))
@@ -822,7 +827,7 @@ unused_undo:
{
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(create_new_undo, name, 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++)
@@ -1034,7 +1039,7 @@ srv_init_abort_low(
/** Prepare to delete the redo log file. Flush the dirty pages from all the
buffer pools. Flush the redo log buffer to the redo log file.
@return lsn upto which data pages have been flushed. */
-static lsn_t srv_prepare_to_delete_redo_log_file()
+ATTRIBUTE_COLD static lsn_t srv_prepare_to_delete_redo_log_file()
{
DBUG_ENTER("srv_prepare_to_delete_redo_log_file");
@@ -1105,6 +1110,77 @@ same_size:
DBUG_RETURN(flushed_lsn);
}
+/** 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()
+{
+ /* Prepare to delete the old redo log file */
+ const lsn_t lsn{srv_prepare_to_delete_redo_log_file()};
+
+ DBUG_EXECUTE_IF("innodb_log_abort_1", return DB_ERROR;);
+ /* 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());
+ ut_d(mysql_mutex_lock(&buf_pool.flush_list_mutex));
+ ut_ad(!buf_pool.get_oldest_modification(0));
+ ut_d(mysql_mutex_unlock(&buf_pool.flush_list_mutex));
+ /* os_aio_pending_writes() may hold here if some write_io_callback()
+ did not release the slot yet. However, the page write itself must
+ have completed, because the buf_pool.flush_list is empty. In debug
+ builds, we wait for this to happen, hoping to get a hung process if
+ this assumption does not hold. */
+ ut_d(os_aio_wait_until_no_pending_writes(false));
+
+ /* Close the redo log file, so that we can replace it */
+ log_sys.close_file();
+
+ DBUG_EXECUTE_IF("innodb_log_abort_5", return DB_ERROR;);
+
+ 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()
+{
+ if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO)
+ /* Completely ignore the redo log. */
+ return DB_SUCCESS;
+ if (srv_read_only_mode)
+ /* Leave the redo log alone. */
+ return DB_SUCCESS;
+
+ if (log_sys.file_size == srv_log_file_size &&
+ log_sys.format ==
+ (srv_encrypt_log ? log_t::FORMAT_ENC_10_8 : log_t::FORMAT_10_8))
+ {
+ /* No need to add or remove encryption, upgrade, or resize. */
+ delete_log_files();
+ return DB_SUCCESS;
+ }
+
+ return srv_log_rebuild();
+}
+
+ATTRIBUTE_COLD static dberr_t ibuf_log_rebuild_if_needed()
+{
+ mysql_mutex_lock(&recv_sys.mutex);
+ recv_sys.apply(true);
+ mysql_mutex_unlock(&recv_sys.mutex);
+
+ if (recv_sys.is_corrupt_log() || recv_sys.is_corrupt_fs())
+ return DB_CORRUPTION;
+
+ dberr_t err= srv_log_rebuild_if_needed();
+ recv_sys.debug_free();
+ return err;
+}
+
static tpool::task_group rollback_all_recovered_group(1);
static tpool::task rollback_all_recovered_task(trx_rollback_all_recovered,
nullptr,
@@ -1132,7 +1208,7 @@ dberr_t srv_start(bool create_new_db)
if (srv_read_only_mode) {
sql_print_information("InnoDB: Started in read only mode");
- srv_use_doublewrite_buf = false;
+ buf_dblwr.use = buf_dblwr.USE_NO;
}
high_level_read_only = srv_read_only_mode
@@ -1147,10 +1223,6 @@ dberr_t srv_start(bool create_new_db)
ib::info() << "!!!!!!!! UNIV_DEBUG switched on !!!!!!!!!";
#endif
-#ifdef UNIV_IBUF_DEBUG
- ib::info() << "!!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!";
-#endif
-
ib::info() << "Compressed tables use zlib " ZLIB_VERSION
#ifdef UNIV_ZIP_DEBUG
" with validation"
@@ -1240,11 +1312,6 @@ dberr_t srv_start(bool create_new_db)
return(srv_init_abort(err));
}
- if (srv_read_only_mode) {
- ib::info() << "Disabling background log and ibuf IO write"
- << " threads.";
- }
-
if (os_aio_init()) {
ib::error() << "Cannot initialize AIO sub-system";
@@ -1399,31 +1466,41 @@ dberr_t srv_start(bool create_new_db)
if (create_new_db) {
ut_ad(!srv_read_only_mode);
- mtr_start(&mtr);
+ mtr.start();
ut_ad(fil_system.sys_space->id == 0);
compile_time_assert(TRX_SYS_SPACE == 0);
- compile_time_assert(IBUF_SPACE_ID == 0);
- ut_a(fsp_header_init(fil_system.sys_space,
- uint32_t(sum_of_new_sizes), &mtr)
- == DB_SUCCESS);
-
- ulint ibuf_root = btr_create(
- DICT_CLUSTERED | DICT_IBUF, fil_system.sys_space,
- DICT_IBUF_ID_MIN, nullptr, &mtr, &err);
-
- mtr_commit(&mtr);
-
- if (ibuf_root == FIL_NULL) {
- return srv_init_abort(err);
+ err = fsp_header_init(fil_system.sys_space,
+ uint32_t(sum_of_new_sizes), &mtr);
+ /* Allocate dummy change buffer pages for backward
+ compatibility and to prevent a downgrade. */
+ if (err != DB_SUCCESS) {
+ } else if (buf_block_t *b =
+ fseg_create(fil_system.sys_space, PAGE_DATA, &mtr,
+ &err)) {
+ ut_ad(b->page.id()
+ == page_id_t(0, FSP_IBUF_HEADER_PAGE_NO));
+ b = fseg_alloc_free_page_general(
+ b->page.frame + PAGE_DATA,
+ FSP_IBUF_TREE_ROOT_PAGE_NO, FSP_UP, false,
+ &mtr, &mtr, &err);
+ if (b) {
+ ut_ad(b->page.id() == page_id_t
+ (0, FSP_IBUF_TREE_ROOT_PAGE_NO));
+ mtr.set_modified(*b);
+ fsp_init_file_page(fil_system.sys_space, b,
+ &mtr);
+ } else {
+ ut_ad(err != DB_SUCCESS);
+ }
}
-
- 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,
after the double write buffer has been created. */
- err = trx_sys_create_sys_pages(&mtr);
+ if (err == DB_SUCCESS) {
+ err = trx_sys_create_sys_pages(&mtr);
+ }
+ mtr.commit();
if (err != DB_SUCCESS) {
return(srv_init_abort(err));
@@ -1457,39 +1534,45 @@ dberr_t srv_start(bool create_new_db)
recv_sys.dblwr.pages.clear();
- if (err != DB_SUCCESS) {
- return(srv_init_abort(err));
- }
+ bool must_upgrade_ibuf = false;
switch (srv_operation) {
case SRV_OPERATION_NORMAL:
case SRV_OPERATION_EXPORT_RESTORED:
case SRV_OPERATION_RESTORE_EXPORT:
- /* Initialize the change buffer. */
- err = dict_boot();
if (err != DB_SUCCESS) {
- return(srv_init_abort(err));
+ break;
}
- /* fall through */
- case SRV_OPERATION_RESTORE:
- /* This must precede recv_sys.apply(true). */
- srv_undo_tablespaces_active
- = trx_rseg_get_n_undo_tablespaces();
- if (srv_operation != SRV_OPERATION_RESTORE) {
- dict_sys.load_sys_tables();
+ err = ibuf_upgrade_needed();
+
+ if (UNIV_UNLIKELY(err == DB_FAIL)) {
+ must_upgrade_ibuf = true;
+ err = ibuf_log_rebuild_if_needed();
+ }
+
+ if (err != DB_SUCCESS) {
+ break;
}
- err = trx_lists_init_at_db_start();
+
+ err = dict_boot();
+ /* fall through */
+ case SRV_OPERATION_RESTORE:
if (err != DB_SUCCESS) {
- return srv_init_abort(err);
+ break;
}
+
+ srv_undo_tablespaces_active
+ = trx_rseg_get_n_undo_tablespaces();
break;
- case SRV_OPERATION_RESTORE_DELTA:
- case SRV_OPERATION_BACKUP:
- case SRV_OPERATION_BACKUP_NO_DEFER:
+ default:
ut_ad("wrong mariabackup mode" == 0);
}
+ 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
respective file pages, for the last batch of
@@ -1511,9 +1594,45 @@ dberr_t srv_start(bool create_new_db)
return(srv_init_abort(DB_CORRUPTION));
}
+ if (srv_operation != SRV_OPERATION_RESTORE
+ || recv_needed_recovery) {
+ }
+
DBUG_PRINT("ib_log", ("apply completed"));
- if (recv_needed_recovery) {
+ if (srv_operation != SRV_OPERATION_RESTORE) {
+ dict_sys.lock(SRW_LOCK_CALL);
+ dict_load_sys_table(dict_sys.sys_tables);
+ dict_sys.unlock();
+
+ if (UNIV_UNLIKELY(must_upgrade_ibuf)) {
+ dict_load_tablespaces(nullptr, true);
+ err = ibuf_upgrade();
+ if (err != DB_SUCCESS) {
+ return srv_init_abort(err);
+ }
+ }
+
+ dict_sys.lock(SRW_LOCK_CALL);
+ dict_load_sys_table(dict_sys.sys_columns);
+ dict_load_sys_table(dict_sys.sys_indexes);
+ dict_load_sys_table(dict_sys.sys_fields);
+ dict_sys.unlock();
+ dict_sys.load_sys_tables();
+
+ err = trx_lists_init_at_db_start();
+ if (err != DB_SUCCESS) {
+ return srv_init_abort(err);
+ }
+
+ if (recv_needed_recovery) {
+ trx_sys_print_mysql_binlog_offset();
+ }
+ } else if (recv_needed_recovery) {
+ err = trx_lists_init_at_db_start();
+ if (err != DB_SUCCESS) {
+ return srv_init_abort(err);
+ }
trx_sys_print_mysql_binlog_offset();
}
}
@@ -1530,57 +1649,10 @@ dberr_t srv_start(bool create_new_db)
generating any dirty pages, so that the old redo log
file will not be written to. */
- if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
- /* Completely ignore the redo log. */
- } else if (srv_read_only_mode) {
- /* Leave the redo log alone. */
- } else if (log_sys.file_size == srv_log_file_size
- && log_sys.format
- == (srv_encrypt_log
- ? log_t::FORMAT_ENC_10_8
- : log_t::FORMAT_10_8)) {
- /* No need to add or remove encryption,
- upgrade, or resize. */
- delete_log_files();
- } else {
- /* Prepare to delete the old redo log file */
- const lsn_t lsn{srv_prepare_to_delete_redo_log_file()};
-
- DBUG_EXECUTE_IF("innodb_log_abort_1",
- return(srv_init_abort(DB_ERROR)););
- /* 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());
- ut_d(mysql_mutex_lock(&buf_pool.flush_list_mutex));
- ut_ad(!buf_pool.get_oldest_modification(0));
- ut_d(mysql_mutex_unlock(&buf_pool.flush_list_mutex));
- /* os_aio_pending_writes() may hold here if
- some write_io_callback() did not release the
- slot yet. However, the page write itself must
- have completed, because the buf_pool.flush_list
- is empty. In debug builds, we wait for this to
- happen, hoping to get a hung process if this
- assumption does not hold. */
- ut_d(os_aio_wait_until_no_pending_writes(false));
-
- /* Close the redo log file, so that we can replace it */
- log_sys.close_file();
-
- DBUG_EXECUTE_IF("innodb_log_abort_5",
- return(srv_init_abort(DB_ERROR)););
- DBUG_PRINT("ib_log", ("After innodb_log_abort_5"));
-
- err = create_log_file(false, lsn);
-
- if (err == DB_SUCCESS && log_sys.resize_rename()) {
- err = DB_ERROR;
- }
+ err = srv_log_rebuild_if_needed();
- if (err != DB_SUCCESS) {
- return(srv_init_abort(err));
- }
+ if (err != DB_SUCCESS) {
+ return srv_init_abort(err);
}
recv_sys.debug_free();
@@ -1710,6 +1782,13 @@ dberr_t srv_start(bool create_new_db)
ut_ad(high_level_read_only
|| srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
+ if (!high_level_read_only
+ && srv_sys_space.can_auto_shrink()) {
+ fsp_system_tablespace_truncate();
+ DBUG_EXECUTE_IF("crash_after_sys_truncate",
+ return srv_init_abort(DB_ERROR););
+ }
+
/* Validate a few system page types that were left
uninitialized before MySQL or MariaDB 5.5. */
if (!high_level_read_only
@@ -1719,8 +1798,7 @@ dberr_t srv_start(bool create_new_db)
/* Bitmap page types will be reset in
buf_dblwr_check_block() without redo logging. */
block = buf_page_get(
- page_id_t(IBUF_SPACE_ID,
- FSP_IBUF_HEADER_PAGE_NO),
+ page_id_t(0, FSP_IBUF_HEADER_PAGE_NO),
0, RW_X_LATCH, &mtr);
if (UNIV_UNLIKELY(!block)) {
corrupted_old_page:
@@ -1778,13 +1856,7 @@ dberr_t srv_start(bool create_new_db)
}
if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
- /* The following call is necessary for the change
- buffer to work with multiple tablespaces. We must
- know the mapping between space id's and .ibd file
- names.
-
- We also determine the maximum tablespace id used. */
- dict_check_tablespaces_and_store_max_id(nullptr);
+ dict_load_tablespaces();
}
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO
@@ -1867,13 +1939,6 @@ skip_monitors:
trx_sys.get_max_trx_id());
}
- if (srv_force_recovery == 0) {
- /* In the change buffer we may have even bigger tablespace
- id's, because we may have dropped those tablespaces, but
- the buffered records have not been cleaned yet. */
- ibuf_update_max_tablespace_id();
- }
-
if (!srv_read_only_mode) {
if (create_new_db) {
srv_buffer_pool_load_at_startup = FALSE;
@@ -1904,9 +1969,6 @@ skip_monitors:
fil_crypt_threads_cond. */
fil_crypt_threads_init();
- /* Initialize online defragmentation. */
- btr_defragment_init();
-
srv_started_redo = true;
}
@@ -1927,15 +1989,9 @@ void innodb_preshutdown()
if (srv_read_only_mode)
return;
if (!srv_fast_shutdown && srv_operation <= SRV_OPERATION_EXPORT_RESTORED)
- {
- /* Because a slow shutdown must empty the change buffer, we had
- better prevent any further changes from being buffered. */
- innodb_change_buffering= 0;
-
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();
@@ -1998,8 +2054,6 @@ void innodb_shutdown()
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
ut_ad(lock_sys.is_initialised() || !srv_was_started);
ut_ad(log_sys.is_initialised() || !srv_was_started);
- ut_ad(ibuf.index || !innodb_change_buffering || !srv_was_started
- || srv_force_recovery >= SRV_FORCE_NO_DDL_UNDO);
dict_stats_deinit();
@@ -2009,7 +2063,6 @@ void innodb_shutdown()
fts_optimize_shutdown(); dict_stats_shutdown(); */
fil_crypt_threads_cleanup();
- btr_defragment_shutdown();
}
/* This must be disabled before closing the buffer pool
@@ -2020,7 +2073,6 @@ void innodb_shutdown()
btr_search_disable();
}
#endif /* BTR_CUR_HASH_ADAPT */
- ibuf_close();
log_sys.close();
purge_sys.close();
trx_sys.close();