summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-04-25 09:26:01 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-04-26 23:03:28 +0300
commitce3ffefc454f1e6eea987e47c52796af48585380 (patch)
tree1c09d9290b5ba428bbd71fad5934b3fe22e0bb13
parentd1bcc1f49f8080e9549d29e74b0676875b9ca96b (diff)
downloadmariadb-git-ce3ffefc454f1e6eea987e47c52796af48585380.tar.gz
Adapt the innodb_undo tests from MySQL 5.7
Simplify the tests that are present in MySQL 5.7. Make the table smaller while generating enough undo log. Do not unnecessarily drop tables. trx_purge_initiate_truncate(): Remove two crash injection points (before and after normal redo log checkpoint), because they are not adding any value. Clarify some messages. trx_sys_create_rsegs(): Display the number of active undo tablespaces. srv_undo_tablespaces_init(): When initializing the data files, do not leave srv_undo_tablespaces_active at 0. Do not display that number; let trx_sys_create_rsegs() display it once the final number is known. innodb_params_adjust(): Adjust parameters after startup. innobase_init(): Do not allow innodb_max_undo_size to be less than SRV_UNDO_TABLESPACE_SIZE_IN_PAGES. This avoids unnecessary repeated truncation of undo tablespaces when using innodb_page_size=32k or innodb_page_size=64k.
-rw-r--r--mysql-test/include/have_innodb_max_16k.inc4
-rw-r--r--mysql-test/suite/innodb_undo/include/have_undo_tablespaces.inc4
-rw-r--r--mysql-test/suite/innodb_undo/include/truncate_recover.inc8
-rw-r--r--mysql-test/suite/innodb_undo/r/truncate.result11
-rw-r--r--mysql-test/suite/innodb_undo/r/truncate_multi_client.result51
-rw-r--r--mysql-test/suite/innodb_undo/r/truncate_recover.result15
-rw-r--r--mysql-test/suite/innodb_undo/t/truncate.test72
-rw-r--r--mysql-test/suite/innodb_undo/t/truncate_multi_client.test77
-rw-r--r--mysql-test/suite/innodb_undo/t/truncate_recover.test50
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_max_undo_log_size_basic.result12
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result8
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_max_undo_log_size_basic.test8
-rw-r--r--storage/innobase/handler/ha_innodb.cc52
-rw-r--r--storage/innobase/srv/srv0start.cc7
-rw-r--r--storage/innobase/trx/trx0purge.cc57
-rw-r--r--storage/innobase/trx/trx0sys.cc10
16 files changed, 363 insertions, 83 deletions
diff --git a/mysql-test/include/have_innodb_max_16k.inc b/mysql-test/include/have_innodb_max_16k.inc
new file mode 100644
index 00000000000..f8346666299
--- /dev/null
+++ b/mysql-test/include/have_innodb_max_16k.inc
@@ -0,0 +1,4 @@
+if (`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE LOWER(variable_name) = 'innodb_page_size' AND variable_value <= 16384`)
+{
+ --skip Test requires InnoDB with page size not greater than 16k.
+}
diff --git a/mysql-test/suite/innodb_undo/include/have_undo_tablespaces.inc b/mysql-test/suite/innodb_undo/include/have_undo_tablespaces.inc
new file mode 100644
index 00000000000..87830a4a5f0
--- /dev/null
+++ b/mysql-test/suite/innodb_undo/include/have_undo_tablespaces.inc
@@ -0,0 +1,4 @@
+if (`select count(*) = 0 from information_schema.global_variables where variable_name like 'innodb_undo_tablespaces' and variable_value >= 2`)
+{
+ --skip Test requires InnoDB with at-least 2 undo tablespaces.
+}
diff --git a/mysql-test/suite/innodb_undo/include/truncate_recover.inc b/mysql-test/suite/innodb_undo/include/truncate_recover.inc
new file mode 100644
index 00000000000..fe068afa6e3
--- /dev/null
+++ b/mysql-test/suite/innodb_undo/include/truncate_recover.inc
@@ -0,0 +1,8 @@
+begin;
+update t1 set c = 'MariaDB';
+update t1 set c = 'InnoDB';
+eval set global debug_dbug = '+d,$SEARCH_PATTERN';
+commit;
+--source include/shutdown_mysqld.inc
+--source include/search_pattern_in_file.inc
+--source include/start_mysqld.inc
diff --git a/mysql-test/suite/innodb_undo/r/truncate.result b/mysql-test/suite/innodb_undo/r/truncate.result
new file mode 100644
index 00000000000..4f62d85e08a
--- /dev/null
+++ b/mysql-test/suite/innodb_undo/r/truncate.result
@@ -0,0 +1,11 @@
+SET GLOBAL innodb_fast_shutdown=0;
+create table t1(keyc int primary key, c1 char(100)) engine = innodb;
+begin;
+update t1 set c1 = 'mysql';
+update t1 set c1 = 'oracle';
+delete from t1;
+commit;
+drop table t1;
+SET GLOBAL innodb_fast_shutdown=0;
+SET GLOBAL innodb_undo_log_truncate=1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
diff --git a/mysql-test/suite/innodb_undo/r/truncate_multi_client.result b/mysql-test/suite/innodb_undo/r/truncate_multi_client.result
new file mode 100644
index 00000000000..c1ce2845996
--- /dev/null
+++ b/mysql-test/suite/innodb_undo/r/truncate_multi_client.result
@@ -0,0 +1,51 @@
+SET GLOBAL innodb_fast_shutdown=0;
+create table t1(keyc int primary key, c char(100)) engine = innodb;
+create table t2(keyc int primary key, c char(100)) engine = innodb;
+CREATE PROCEDURE populate_t1()
+BEGIN
+DECLARE i INT DEFAULT 1;
+while (i <= 20000) DO
+insert into t1 values (i, 'a');
+SET i = i + 1;
+END WHILE;
+END |
+CREATE PROCEDURE populate_t2()
+BEGIN
+DECLARE i INT DEFAULT 1;
+while (i <= 20000) DO
+insert into t2 values (i, 'a');
+SET i = i + 1;
+END WHILE;
+END |
+connect con1,localhost,root,,;
+begin;
+call populate_t1();
+connect con2,localhost,root,,;
+begin;
+call populate_t2();
+connection con1;
+update t1 set c = 'mysql';
+connection con2;
+update t2 set c = 'mysql';
+connection con1;
+update t1 set c = 'oracle';
+connection con2;
+update t2 set c = 'oracle';
+connection con1;
+delete from t1;
+connection con2;
+delete from t2;
+connection con1;
+commit;
+disconnect con1;
+connection con2;
+commit;
+disconnect con2;
+connection default;
+drop table t1, t2;
+drop PROCEDURE populate_t1;
+drop PROCEDURE populate_t2;
+SET GLOBAL innodb_fast_shutdown=0;
+SET GLOBAL innodb_undo_log_truncate=1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
+FOUND 1 /Truncating UNDO tablespace 1/ in mysqld.1.err
diff --git a/mysql-test/suite/innodb_undo/r/truncate_recover.result b/mysql-test/suite/innodb_undo/r/truncate_recover.result
new file mode 100644
index 00000000000..f89bc0a9e47
--- /dev/null
+++ b/mysql-test/suite/innodb_undo/r/truncate_recover.result
@@ -0,0 +1,15 @@
+create table t1(keyc int primary key, c char(100)) engine = innodb;
+begin;
+commit;
+begin;
+update t1 set c = 'MariaDB';
+update t1 set c = 'InnoDB';
+set global debug_dbug = '+d,ib_undo_trunc_before_truncate';
+commit;
+FOUND 1 /ib_undo_trunc_before_truncate/ in mysqld.1.err
+begin;
+update t1 set c = 'MariaDB';
+update t1 set c = 'InnoDB';
+set global debug_dbug = '+d,ib_undo_trunc_before_ddl_log_end';
+commit;
+FOUND 1 /ib_undo_trunc_before_ddl_log_end/ in mysqld.1.err
diff --git a/mysql-test/suite/innodb_undo/t/truncate.test b/mysql-test/suite/innodb_undo/t/truncate.test
new file mode 100644
index 00000000000..2c612478929
--- /dev/null
+++ b/mysql-test/suite/innodb_undo/t/truncate.test
@@ -0,0 +1,72 @@
+#
+# WL#6965: Truncate UNDO logs.
+#
+
+--source include/have_innodb.inc
+--source include/have_innodb_max_16k.inc
+--source include/have_undo_tablespaces.inc
+
+# The test is restarting the server to force undo truncation.
+--source include/not_embedded.inc
+
+SET GLOBAL innodb_fast_shutdown=0;
+--let $restart_parameters=--innodb_undo_tablespaces=2 --innodb_undo_logs=4
+--source include/restart_mysqld.inc
+
+let MYSQLD_DATADIR = `select @@datadir`;
+
+#-----------------------------------------------------------------------------
+#
+# 1. Perform enough DML action so that undo tablespace size grows beyond
+# set threshold and then wait and see if it is being truncated.
+#
+create table t1(keyc int primary key, c1 char(100)) engine = innodb;
+begin;
+--disable_query_log
+let $i=30000;
+while ($i) {
+ eval insert into t1 values(30000-$i, '');
+ dec $i;
+}
+--enable_query_log
+update t1 set c1 = 'mysql';
+update t1 set c1 = 'oracle';
+delete from t1;
+commit;
+drop table t1;
+
+let CHECKFILE = $MYSQL_TMP_DIR/check.txt;
+perl;
+($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size1)
+ = stat("$ENV{MYSQLD_DATADIR}/undo001");
+($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size2)
+ = stat("$ENV{MYSQLD_DATADIR}/undo002");
+open(OUT, ">$ENV{CHECKFILE}") || die;
+print OUT "let \$size1='$size1,$size2';\n";
+close(OUT);
+EOF
+SET GLOBAL innodb_fast_shutdown=0;
+SET GLOBAL innodb_undo_log_truncate=1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
+--source include/shutdown_mysqld.inc
+--source $CHECKFILE
+perl;
+($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size1)
+ = stat("$ENV{MYSQLD_DATADIR}/undo001");
+($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size2)
+ = stat("$ENV{MYSQLD_DATADIR}/undo002");
+open(OUT, ">$ENV{CHECKFILE}") || die;
+print OUT "let \$size2='$size1,$size2';\n";
+close(OUT);
+EOF
+
+--source $CHECKFILE
+--remove_file $CHECKFILE
+
+if ($size1 == $size2)
+{
+ echo Truncation did not happen: $size1 == $size2;
+}
+
+--let $restart_parameters=
+--source include/start_mysqld.inc
diff --git a/mysql-test/suite/innodb_undo/t/truncate_multi_client.test b/mysql-test/suite/innodb_undo/t/truncate_multi_client.test
new file mode 100644
index 00000000000..ac4ead00b51
--- /dev/null
+++ b/mysql-test/suite/innodb_undo/t/truncate_multi_client.test
@@ -0,0 +1,77 @@
+#
+# WL#6965: Truncate UNDO logs.
+#
+
+--source include/have_innodb.inc
+# This test is restarting the server.
+--source include/not_embedded.inc
+# With larger innodb_page_size, the undo log tablespaces do not grow enough.
+--source include/have_innodb_max_16k.inc
+--source include/have_undo_tablespaces.inc
+
+SET GLOBAL innodb_fast_shutdown=0;
+--let $restart_parameters=--innodb_undo_tablespaces=2 --innodb_undo_logs=4
+--source include/restart_mysqld.inc
+
+#-----------------------------------------------------------------------------
+#
+# Perform DML action using multiple clients and multiple undo tablespace.
+#
+#
+create table t1(keyc int primary key, c char(100)) engine = innodb;
+create table t2(keyc int primary key, c char(100)) engine = innodb;
+#
+delimiter |;
+CREATE PROCEDURE populate_t1()
+BEGIN
+ DECLARE i INT DEFAULT 1;
+ while (i <= 20000) DO
+ insert into t1 values (i, 'a');
+ SET i = i + 1;
+ END WHILE;
+END |
+delimiter ;|
+#
+delimiter |;
+CREATE PROCEDURE populate_t2()
+BEGIN
+ DECLARE i INT DEFAULT 1;
+ while (i <= 20000) DO
+ insert into t2 values (i, 'a');
+ SET i = i + 1;
+ END WHILE;
+END |
+delimiter ;|
+#
+#
+connect (con1,localhost,root,,);
+begin;
+send call populate_t1();
+
+connect (con2,localhost,root,,);
+begin;
+send call populate_t2();
+
+connection con1; reap; send update t1 set c = 'mysql';
+connection con2; reap; send update t2 set c = 'mysql';
+connection con1; reap; send update t1 set c = 'oracle';
+connection con2; reap; send update t2 set c = 'oracle';
+connection con1; reap; send delete from t1;
+connection con2; reap; send delete from t2;
+connection con1; reap; commit; disconnect con1;
+connection con2; reap; commit; disconnect con2;
+
+connection default;
+drop table t1, t2;
+drop PROCEDURE populate_t1;
+drop PROCEDURE populate_t2;
+
+SET GLOBAL innodb_fast_shutdown=0;
+SET GLOBAL innodb_undo_log_truncate=1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
+
+--source include/restart_mysqld.inc
+
+let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err;
+let SEARCH_PATTERN = Truncating UNDO tablespace 1;
+--source include/search_pattern_in_file.inc
diff --git a/mysql-test/suite/innodb_undo/t/truncate_recover.test b/mysql-test/suite/innodb_undo/t/truncate_recover.test
new file mode 100644
index 00000000000..8087d191f1e
--- /dev/null
+++ b/mysql-test/suite/innodb_undo/t/truncate_recover.test
@@ -0,0 +1,50 @@
+#
+# WL#6965: Truncate UNDO logs.
+#
+
+--source include/have_innodb.inc
+--source include/have_debug.inc
+# With larger innodb_page_size, the undo log tablespaces do not grow enough.
+--source include/have_innodb_max_16k.inc
+--source include/have_undo_tablespaces.inc
+
+# Valgrind would complain about memory leaks when we crash on purpose.
+--source include/not_valgrind.inc
+# Embedded server does not support crashing
+--source include/not_embedded.inc
+# Avoid CrashReporter popup on Mac
+--source include/not_crashrep.inc
+
+--disable_query_log
+# FIXME: The doublewrite buffer should not issue these warnings.
+# FIXME: Maybe buf_dblwr_process() should empty the buffer at the end?
+call mtr.add_suppression("InnoDB: A copy of page.*in the doublewrite buffer slot.*is not within space bounds");
+FLUSH TABLES;
+--enable_query_log
+
+--let $restart_parameters=--innodb-undo-logs=4 --innodb-undo-tablespaces=2 --innodb-undo-log-truncate=1 --innodb-max-undo-log-size=10485760 --innodb-purge-rseg-truncate-frequency=1 --innodb-fast-shutdown=0
+--source include/restart_mysqld.inc
+
+let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err;
+
+create table t1(keyc int primary key, c char(100)) engine = innodb;
+begin;
+--disable_query_log
+let $i=30000;
+while ($i) {
+ eval insert into t1 values(30000-$i, '');
+ dec $i;
+}
+--enable_query_log
+commit;
+
+let SEARCH_PATTERN = ib_undo_trunc_before_truncate;
+--source include/truncate_recover.inc
+
+let SEARCH_PATTERN = ib_undo_trunc_before_ddl_log_end;
+--source include/truncate_recover.inc
+
+let SEARCH_PATTERN = ib_undo_trunc_trunc_done;
+let $restart_parameters=
+--source include/truncate_recover.inc
+drop table t1;
diff --git a/mysql-test/suite/sys_vars/r/innodb_max_undo_log_size_basic.result b/mysql-test/suite/sys_vars/r/innodb_max_undo_log_size_basic.result
index 3854060b33b..47565ac40ad 100644
--- a/mysql-test/suite/sys_vars/r/innodb_max_undo_log_size_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_max_undo_log_size_basic.result
@@ -4,17 +4,21 @@ COUNT(@@GLOBAL.innodb_max_undo_log_size)
1
1 Expected
'#---------------------BS_STVARS_035_02----------------------#'
+SET @save = @@GLOBAL.innodb_max_undo_log_size;
SET @@GLOBAL.innodb_max_undo_log_size=1073741824;
SELECT COUNT(@@GLOBAL.innodb_max_undo_log_size);
COUNT(@@GLOBAL.innodb_max_undo_log_size)
1
1 Expected
SET @@GLOBAL.innodb_max_undo_log_size=18446744073709551615;
-SELECT @@GLOBAL.innodb_max_undo_log_size;
-@@GLOBAL.innodb_max_undo_log_size
-18446744073709551615
-18446744073709551615 Expected
+Warnings:
+Warning 1292 Truncated incorrect innodb_max_undo_log_size value: '18446744073709551615'
+SELECT FLOOR(@@GLOBAL.innodb_max_undo_log_size / @@GLOBAL.innodb_page_size);
+FLOOR(@@GLOBAL.innodb_max_undo_log_size / @@GLOBAL.innodb_page_size)
+4294967296
+4294967296 Expected
SET @@GLOBAL.innodb_max_undo_log_size=1073741824;
+SET GLOBAL innodb_max_undo_log_size = @save;
'#---------------------BS_STVARS_035_03----------------------#'
SELECT @@GLOBAL.innodb_max_undo_log_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index 70ba7371334..4822f43fbb2 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -1618,14 +1618,14 @@ READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_MAX_UNDO_LOG_SIZE
SESSION_VALUE NULL
-GLOBAL_VALUE 1073741824
+GLOBAL_VALUE 10485760
GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE 1073741824
+DEFAULT_VALUE 10485760
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
-VARIABLE_COMMENT Maximum size of UNDO tablespace in MB (If UNDO tablespace grows beyond this size it will be truncated in due course).
+VARIABLE_COMMENT Desired maximum UNDO tablespace size in bytes
NUMERIC_MIN_VALUE 10485760
-NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_MAX_VALUE 281474976710656
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY NO
diff --git a/mysql-test/suite/sys_vars/t/innodb_max_undo_log_size_basic.test b/mysql-test/suite/sys_vars/t/innodb_max_undo_log_size_basic.test
index 9882578923e..e311d6fb873 100644
--- a/mysql-test/suite/sys_vars/t/innodb_max_undo_log_size_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_max_undo_log_size_basic.test
@@ -37,17 +37,21 @@ SELECT COUNT(@@GLOBAL.innodb_max_undo_log_size);
# Check if Value can set #
####################################################################
+SET @save = @@GLOBAL.innodb_max_undo_log_size;
+
SET @@GLOBAL.innodb_max_undo_log_size=1073741824;
SELECT COUNT(@@GLOBAL.innodb_max_undo_log_size);
--echo 1 Expected
SET @@GLOBAL.innodb_max_undo_log_size=18446744073709551615;
-SELECT @@GLOBAL.innodb_max_undo_log_size;
---echo 18446744073709551615 Expected
+SELECT FLOOR(@@GLOBAL.innodb_max_undo_log_size / @@GLOBAL.innodb_page_size);
+--echo 4294967296 Expected
SET @@GLOBAL.innodb_max_undo_log_size=1073741824;
+SET GLOBAL innodb_max_undo_log_size = @save;
+
--echo '#---------------------BS_STVARS_035_03----------------------#'
#################################################################
# Check if the value in GLOBAL Table matches value in variable #
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index e2be027b8e9..c1c7330943e 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1359,15 +1359,11 @@ void
innobase_commit_concurrency_init_default();
/*=======================================*/
-/** @brief Initialize the default and max value of innodb_undo_logs.
-
-Once InnoDB is running, the default value and the max value of
-innodb_undo_logs must be equal to the available undo logs,
-given by srv_available_undo_logs. */
+/** @brief Adjust some InnoDB startup parameters based on file contents
+or innodb_page_size. */
static
void
-innobase_undo_logs_init_default_max();
-/*==================================*/
+innodb_params_adjust();
/************************************************************//**
Validate the file format name and return its corresponding id.
@@ -4291,6 +4287,11 @@ innobase_change_buffering_inited_ok:
if (UNIV_PAGE_SIZE_DEF != srv_page_size) {
ib::info() << "innodb_page_size=" << srv_page_size;
+
+ srv_max_undo_log_size = std::max(
+ srv_max_undo_log_size,
+ ulonglong(SRV_UNDO_TABLESPACE_SIZE_IN_PAGES)
+ * srv_page_size);
}
if (srv_log_write_ahead_size > srv_page_size) {
@@ -4457,12 +4458,6 @@ innobase_change_buffering_inited_ok:
}
*/
- /* Since we in this module access directly the fields of a trx
- struct, and due to different headers and flags it might happen that
- ib_mutex_t has a different size in this module and in InnoDB
- modules, we check at run time that the size is the same in
- these compilation modules. */
-
err = innobase_start_or_create_for_mysql();
if (srv_buf_pool_size_org != 0) {
@@ -4488,8 +4483,7 @@ innobase_change_buffering_inited_ok:
}
srv_was_started = true;
- /* Adjust the innodb_undo_logs config object */
- innobase_undo_logs_init_default_max();
+ innodb_params_adjust();
innobase_old_blocks_pct = static_cast<uint>(
buf_LRU_old_ratio_update(innobase_old_blocks_pct, TRUE));
@@ -21493,12 +21487,10 @@ static MYSQL_SYSVAR_ULONG(undo_logs, srv_undo_logs,
static MYSQL_SYSVAR_ULONGLONG(max_undo_log_size, srv_max_undo_log_size,
PLUGIN_VAR_OPCMDARG,
- "Maximum size of UNDO tablespace in MB (If UNDO tablespace grows"
- " beyond this size it will be truncated in due course). ",
+ "Desired maximum UNDO tablespace size in bytes",
NULL, NULL,
- 1024 * 1024 * 1024L,
- 10 * 1024 * 1024L,
- ~0ULL, 0);
+ 10 << 20, 10 << 20,
+ 1ULL << (32 + UNIV_PAGE_SIZE_SHIFT_MAX), 0);
static MYSQL_SYSVAR_ULONG(purge_rseg_truncate_frequency,
srv_purge_rseg_truncate_frequency,
@@ -22222,19 +22214,25 @@ innobase_commit_concurrency_init_default()
= innobase_commit_concurrency;
}
-/** @brief Initialize the default and max value of innodb_undo_logs.
-
-Once InnoDB is running, the default value and the max value of
-innodb_undo_logs must be equal to the available undo logs,
-given by srv_available_undo_logs. */
+/** @brief Adjust some InnoDB startup parameters based on file contents
+or innodb_page_size. */
static
void
-innobase_undo_logs_init_default_max()
-/*=================================*/
+innodb_params_adjust()
{
+ /* The default value and the max value of
+ innodb_undo_logs must be equal to the available undo logs. */
MYSQL_SYSVAR_NAME(undo_logs).max_val
= MYSQL_SYSVAR_NAME(undo_logs).def_val
= srv_available_undo_logs;
+ MYSQL_SYSVAR_NAME(max_undo_log_size).max_val
+ = 1ULL << (32 + UNIV_PAGE_SIZE_SHIFT);
+ MYSQL_SYSVAR_NAME(max_undo_log_size).min_val
+ = MYSQL_SYSVAR_NAME(max_undo_log_size).def_val
+ = ulonglong(SRV_UNDO_TABLESPACE_SIZE_IN_PAGES)
+ * srv_page_size;
+ MYSQL_SYSVAR_NAME(max_undo_log_size).max_val
+ = 1ULL << (32 + UNIV_PAGE_SIZE_SHIFT);
}
/****************************************************************************
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index ef0d88b4316..3ef937c303d 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -894,6 +894,7 @@ srv_undo_tablespaces_init(bool create_new_db)
}
}
} else {
+ srv_undo_tablespaces_active = srv_undo_tablespaces;
n_undo_tablespaces = srv_undo_tablespaces;
for (i = 1; i <= n_undo_tablespaces; ++i) {
@@ -975,12 +976,10 @@ srv_undo_tablespaces_init(bool create_new_db)
return(err != DB_SUCCESS ? err : DB_ERROR);
- } else if (n_undo_tablespaces > 0) {
+ } else if (n_undo_tablespaces > 0) {
ib::info() << "Opened " << n_undo_tablespaces
- << " undo tablespaces ("
- << srv_undo_tablespaces_active
- << " active)";
+ << " undo tablespaces";
if (srv_undo_tablespaces == 0) {
ib::warn() << "innodb_undo_tablespaces=0 disables"
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index f83d9377852..42ae4890cab 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, 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
@@ -987,27 +987,20 @@ trx_purge_initiate_truncate(
initiate truncate.
d. Execute actual truncate
e. Remove the DDL log. */
- DBUG_EXECUTE_IF("ib_undo_trunc_before_checkpoint",
- ib::info() << "ib_undo_trunc_before_checkpoint";
- DBUG_SUICIDE(););
/* After truncate if server crashes then redo logging done for this
undo tablespace might not stand valid as tablespace has been
truncated. */
log_make_checkpoint_at(LSN_MAX, TRUE);
- ib::info() << "Truncating UNDO tablespace with space identifier "
- << undo_trunc->get_marked_space_id();
+ const ulint space_id = undo_trunc->get_marked_space_id();
- DBUG_EXECUTE_IF("ib_undo_trunc_before_ddl_log_start",
- ib::info() << "ib_undo_trunc_before_ddl_log_start";
- DBUG_SUICIDE(););
+ ib::info() << "Truncating UNDO tablespace " << space_id;
#ifdef UNIV_DEBUG
dberr_t err =
#endif /* UNIV_DEBUG */
- undo_trunc->start_logging(
- undo_trunc->get_marked_space_id());
+ undo_trunc->start_logging(space_id);
ut_ad(err == DB_SUCCESS);
DBUG_EXECUTE_IF("ib_undo_trunc_before_truncate",
@@ -1016,14 +1009,12 @@ trx_purge_initiate_truncate(
trx_purge_cleanse_purge_queue(undo_trunc);
- bool success = trx_undo_truncate_tablespace(undo_trunc);
- if (!success) {
+ if (!trx_undo_truncate_tablespace(undo_trunc)) {
/* Note: In case of error we don't enable the rsegs
and neither unmark the tablespace so the tablespace
continue to remain inactive. */
- ib::error() << "Failed to truncate UNDO tablespace with"
- " space identifier "
- << undo_trunc->get_marked_space_id();
+ ib::error() << "Failed to truncate UNDO tablespace "
+ << space_id;
return;
}
@@ -1046,7 +1037,7 @@ trx_purge_initiate_truncate(
log_make_checkpoint_at(LSN_MAX, TRUE);
- undo_trunc->done_logging(undo_trunc->get_marked_space_id());
+ undo_trunc->done_logging(space_id);
/* Completed truncate. Now it is safe to re-use the tablespace. */
for (ulint i = 0; i < undo_trunc->rsegs_size(); ++i) {
@@ -1054,8 +1045,7 @@ trx_purge_initiate_truncate(
rseg->skip_allocation = false;
}
- ib::info() << "Completed truncate of UNDO tablespace with space"
- " identifier " << undo_trunc->get_marked_space_id();
+ ib::info() << "Truncated UNDO tablespace " << space_id;
undo_trunc->reset();
undo::Truncate::clear_trunc_list();
@@ -1075,7 +1065,7 @@ trx_purge_truncate_history(
purge_iter_t* limit, /*!< in: truncate limit */
const ReadView* view) /*!< in: purge view */
{
- ulint i;
+ ut_ad(trx_purge_check_limit());
/* We play safe and set the truncate limit at most to the purge view
low_limit number, though this is not necessary */
@@ -1088,7 +1078,7 @@ trx_purge_truncate_history(
ut_ad(limit->trx_no <= purge_sys->view.low_limit_no());
- for (i = 0; i < TRX_SYS_N_RSEGS; ++i) {
+ for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) {
trx_rseg_t* rseg = trx_sys->rseg_array[i];
if (rseg != NULL) {
@@ -1100,8 +1090,7 @@ trx_purge_truncate_history(
/* UNDO tablespace truncate. We will try to truncate as much as we
can (greedy approach). This will ensure when the server is idle we
try and truncate all the UNDO tablespaces. */
- ulint nchances = srv_undo_tablespaces_active;
- for (i = 0; i < nchances; i++) {
+ for (ulint i = srv_undo_tablespaces_active; i--; ) {
trx_purge_mark_undo_for_truncate(&purge_sys->undo_trunc);
trx_purge_initiate_truncate(limit, &purge_sys->undo_trunc);
}
@@ -1638,22 +1627,6 @@ trx_purge_wait_for_workers_to_complete(
ut_a(srv_get_task_queue_length() == 0);
}
-/******************************************************************//**
-Remove old historical changes from the rollback segments. */
-static
-void
-trx_purge_truncate(void)
-/*====================*/
-{
- ut_ad(trx_purge_check_limit());
-
- if (purge_sys->limit.trx_no == 0) {
- trx_purge_truncate_history(&purge_sys->iter, &purge_sys->view);
- } else {
- trx_purge_truncate_history(&purge_sys->limit, &purge_sys->view);
- }
-}
-
/*******************************************************************//**
This function runs a purge batch.
@return number of undo log pages handled in the batch */
@@ -1742,7 +1715,11 @@ run_synchronously:
#endif /* UNIV_DEBUG */
if (truncate) {
- trx_purge_truncate();
+ trx_purge_truncate_history(
+ purge_sys->limit.trx_no
+ ? &purge_sys->limit
+ : &purge_sys->iter,
+ &purge_sys->view);
}
MONITOR_INC_VALUE(MONITOR_PURGE_INVOKED, 1);
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 09719b40a46..47f30138ceb 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -935,8 +935,14 @@ trx_sys_create_rsegs()
ut_ad(srv_undo_logs <= srv_available_undo_logs);
- ib::info() << srv_undo_logs << " out of " << srv_available_undo_logs
- << " rollback segments are active.";
+ ib::info info;
+ info << srv_undo_logs << " out of " << srv_available_undo_logs;
+ if (srv_undo_tablespaces_active) {
+ info << " rollback segments in " << srv_undo_tablespaces_active
+ << " undo tablespaces are active.";
+ } else {
+ info << " rollback segments are active.";
+ }
return(true);
}