summaryrefslogtreecommitdiff
path: root/mysql-test/suite/innodb/t/innodb_force_recovery.test
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-10-11 17:28:15 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-10-11 17:28:15 +0300
commitb42294bc6409794bdbd2051b32fa079d81cea61d (patch)
tree8da23db6ced9e068134a51b95e80d5a8cb055691 /mysql-test/suite/innodb/t/innodb_force_recovery.test
parentb5fae7f743d2b2c71ee23b0daf51c2be294733eb (diff)
downloadmariadb-git-b42294bc6409794bdbd2051b32fa079d81cea61d.tar.gz
MDEV-19514 Defer change buffer merge until pages are requested
We will remove the InnoDB background operation of merging buffered changes to secondary index leaf pages. Changes will only be merged as a result of an operation that accesses a secondary index leaf page, such as a SQL statement that performs a lookup via that index, or is modifying the index. Also ROLLBACK and some background operations, such as purging the history of committed transactions, or computing index cardinality statistics, can cause change buffer merge. Encryption key rotation will not perform change buffer merge. The motivation of this change is to simplify the I/O logic and to allow crash recovery to happen in the background (MDEV-14481). We also hope that this will reduce the number of "mystery" crashes due to corrupted data. Because change buffer merge will typically take place as a result of executing SQL statements, there should be a clearer connection between the crash and the SQL statements that were executed when the server crashed. In many cases, a slight performance improvement was observed. This is joint work with Thirunarayanan Balathandayuthapani and was tested by Axel Schwenke and Matthias Leich. The InnoDB monitor counter innodb_ibuf_merge_usec will be removed. On slow shutdown (innodb_fast_shutdown=0), we will continue to merge all buffered changes (and purge all undo log history). Two InnoDB configuration parameters will be changed as follows: innodb_disable_background_merge: Removed. This parameter existed only in debug builds. All change buffer merges will use synchronous reads. innodb_force_recovery will be changed as follows: * innodb_force_recovery=4 will be the same as innodb_force_recovery=3 (the change buffer merge cannot be disabled; it can only happen as a result of an operation that accesses a secondary index leaf page). The option used to be capable of corrupting secondary index leaf pages. Now that capability is removed, and innodb_force_recovery=4 becomes 'safe'. * innodb_force_recovery=5 (which essentially hard-wires SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED) becomes safe to use. Bogus data can be returned to SQL, but persistent InnoDB data files will not be corrupted further. * innodb_force_recovery=6 (ignore the redo log files) will be the only option that can potentially cause persistent corruption of InnoDB data files. Code changes: buf_page_t::ibuf_exist: New flag, to indicate whether buffered changes exist for a buffer pool page. Pages with pending changes can be returned by buf_page_get_gen(). Previously, the changes were always merged inside buf_page_get_gen() if needed. ibuf_page_exists(const buf_page_t&): Check if a buffered changes exist for an X-latched or read-fixed page. buf_page_get_gen(): Add the parameter allow_ibuf_merge=false. All callers that know that they may be accessing a secondary index leaf page must pass this parameter as allow_ibuf_merge=true, unless it does not matter for that caller whether all buffered changes have been applied. Assert that whenever allow_ibuf_merge holds, the page actually is a leaf page. Attempt change buffer merge only to secondary B-tree index leaf pages. btr_block_get(): Add parameter 'bool merge'. All callers of btr_block_get() should know whether the page could be a secondary index leaf page. If it is not, we should avoid consulting the change buffer bitmap to even consider a merge. This is the main interface to requesting index pages from the buffer pool. ibuf_merge_or_delete_for_page(), recv_recover_page(): Replace buf_page_get_known_nowait() with much simpler logic, because it is now guaranteed that that the block is x-latched or read-fixed. mlog_init_t::mark_ibuf_exist(): Renamed from mlog_init_t::ibuf_merge(). On crash recovery, we will no longer merge any buffered changes for the pages that we read into the buffer pool during the last batch of applying log records. buf_page_get_gen_known_nowait(), BUF_MAKE_YOUNG, BUF_KEEP_OLD: Remove. btr_search_guess_on_hash(): Merge buf_page_get_gen_known_nowait() to its only remaining caller. buf_page_make_young_if_needed(): Define as an inline function. Add the parameter buf_pool. buf_page_peek_if_young(), buf_page_peek_if_too_old(): Add the parameter buf_pool. fil_space_validate_for_mtr_commit(): Remove a bogus comment about background merge of the change buffer. btr_cur_open_at_rnd_pos_func(), btr_cur_search_to_nth_level_func(), btr_cur_open_at_index_side_func(): Use narrower data types and scopes. ibuf_read_merge_pages(): Replaces buf_read_ibuf_merge_pages(). Merge the change buffer by invoking buf_page_get_gen().
Diffstat (limited to 'mysql-test/suite/innodb/t/innodb_force_recovery.test')
-rw-r--r--mysql-test/suite/innodb/t/innodb_force_recovery.test25
1 files changed, 4 insertions, 21 deletions
diff --git a/mysql-test/suite/innodb/t/innodb_force_recovery.test b/mysql-test/suite/innodb/t/innodb_force_recovery.test
index fe070100c08..bd9554e6b6e 100644
--- a/mysql-test/suite/innodb/t/innodb_force_recovery.test
+++ b/mysql-test/suite/innodb/t/innodb_force_recovery.test
@@ -17,47 +17,33 @@ insert into t2 values(1, 2);
SET GLOBAL innodb_fast_shutdown = 0;
---echo # Restart the server with innodb_force_recovery as 4.
--let $restart_parameters= --innodb-force-recovery=4
--source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
select * from t1;
---error ER_READ_ONLY_MODE
+begin;
insert into t1 values(2, 3);
+rollback;
---error ER_CANT_CREATE_TABLE
alter table t1 add f3 int not null, algorithm=copy;
---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
-alter table t1 add f3 int not null, algorithm=inplace;
+alter table t1 add f4 int not null, algorithm=inplace;
---error ER_CANT_CREATE_TABLE
drop index idx on t1;
---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
-alter table t1 drop index idx, algorithm=inplace;
---error ER_READ_ONLY_MODE
update t1 set f1=3 where f2=2;
---error ER_CANT_CREATE_TABLE
create table t3(f1 int not null)engine=innodb;
-
---error ER_BAD_TABLE_ERROR
drop table t3;
---error ER_ERROR_ON_RENAME
rename table t1 to t3;
-
---error ER_OPEN_AS_READONLY
+rename table t3 to t1;
truncate table t1;
---error ER_OPEN_AS_READONLY
-drop table t1;
show tables;
---echo # Restart the server with innodb_force_recovery as 5.
--let $restart_parameters= --innodb-force-recovery=5
--source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
@@ -98,7 +84,6 @@ create schema db;
drop schema db;
show tables;
---echo # Restart the server with innodb_force_recovery as 6.
--let $restart_parameters= --innodb-force-recovery=6
--source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
@@ -136,7 +121,6 @@ truncate table t2;
drop table t2;
show tables;
---echo # Restart the server with innodb_force_recovery=2
--let $restart_parameters= --innodb-force-recovery=2
--source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
@@ -154,7 +138,6 @@ disconnect con1;
connection default;
--source include/kill_mysqld.inc
---echo # Restart the server with innodb_force_recovery=3
--let $restart_parameters= --innodb-force-recovery=3
--source include/start_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;