mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
5c46751f23
The aim of the InnoDB change buffer is to avoid delays when a leaf page of a secondary index is not present in the buffer pool, and a record needs to be inserted, delete-marked, or purged. Instead of reading the page into the buffer pool for making such a modification, we may insert a record to the change buffer (a special index tree in the InnoDB system tablespace). The buffered changes are guaranteed to be merged if the index page actually needs to be read later. The change buffer could be useful when the database is stored on a rotational medium (hard disk) where random seeks are slower than sequential reads or writes. Obviously, the change buffer will cause write amplification, due to potentially large amount of metadata that is being written to the change buffer. We will have to write redo log records for modifying the change buffer tree as well as the user tablespace. Furthermore, in the user tablespace, we must maintain a change buffer bitmap page that uses 2 bits for estimating the amount of free space in pages, and 1 bit to specify whether buffered changes exist. This bitmap needs to be updated on every operation, which could reduce performance. Even if the change buffer were free of bugs such as MDEV-24449 (potentially causing the corruption of any page in the system tablespace) or MDEV-26977 (corruption of secondary indexes due to a currently unknown reason), it will make diagnosis of other data corruption harder. Because of all this, it is best to disable the change buffer by default.
82 lines
2.8 KiB
Text
82 lines
2.8 KiB
Text
--echo #
|
|
--echo # Bug#69122 - INNODB DOESN'T REDO-LOG INSERT BUFFER MERGE
|
|
--echo # OPERATION IF IT IS DONE IN-PLACE
|
|
--echo #
|
|
--source include/have_innodb.inc
|
|
# innodb_change_buffering_debug option is debug only
|
|
--source include/have_debug.inc
|
|
# Embedded server does not support crashing
|
|
--source include/not_embedded.inc
|
|
# DBUG_SUICIDE() hangs under valgrind
|
|
--source include/not_valgrind.inc
|
|
# This test is slow on buildbot.
|
|
--source include/big_test.inc
|
|
--source include/have_sequence.inc
|
|
|
|
call mtr.add_suppression("InnoDB: innodb_read_only prevents crash recovery");
|
|
call mtr.add_suppression("Plugin initialization aborted at srv0start\\.cc");
|
|
call mtr.add_suppression("Plugin 'InnoDB'");
|
|
FLUSH TABLES;
|
|
|
|
CREATE TABLE t1(
|
|
a INT AUTO_INCREMENT PRIMARY KEY,
|
|
b CHAR(1),
|
|
c INT,
|
|
INDEX(b))
|
|
ENGINE=InnoDB STATS_PERSISTENT=0;
|
|
|
|
--let $_server_id= `SELECT @@server_id`
|
|
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
|
|
|
|
# The flag innodb_change_buffering_debug is only available in debug builds.
|
|
# It instructs InnoDB to try to evict pages from the buffer pool when
|
|
# change buffering is possible, so that the change buffer will be used
|
|
# whenever possible.
|
|
SET GLOBAL innodb_change_buffering_debug = 1;
|
|
SET GLOBAL innodb_change_buffering = all;
|
|
let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
|
|
|
# Create enough rows for the table, so that the change buffer will be
|
|
# used for modifying the secondary index page. There must be multiple
|
|
# index pages, because changes to the root page are never buffered.
|
|
INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_8192;
|
|
|
|
BEGIN;
|
|
SELECT b FROM t1 LIMIT 3;
|
|
|
|
connect (con1,localhost,root,,);
|
|
BEGIN;
|
|
DELETE FROM t1 WHERE a=1;
|
|
# This should be buffered, if innodb_change_buffering_debug = 1 is in effect.
|
|
INSERT INTO t1 VALUES(1,'X',1);
|
|
|
|
SET DEBUG_DBUG='+d,crash_after_log_ibuf_upd_inplace';
|
|
--exec echo "wait" > $_expect_file_name
|
|
--error 2013
|
|
# This should force a change buffer merge
|
|
SELECT b FROM t1 LIMIT 3;
|
|
disconnect con1;
|
|
connection default;
|
|
let SEARCH_PATTERN=Wrote log record for ibuf update in place operation;
|
|
--source include/search_pattern_in_file.inc
|
|
|
|
--let $restart_parameters= --innodb-read-only
|
|
--source include/start_mysqld.inc
|
|
CHECK TABLE t1;
|
|
--source include/shutdown_mysqld.inc
|
|
let SEARCH_PATTERN=innodb_read_only prevents crash recovery;
|
|
--source include/search_pattern_in_file.inc
|
|
|
|
--let $restart_parameters= --innodb-force-recovery=5
|
|
--source include/start_mysqld.inc
|
|
SELECT * FROM t1 LIMIT 1;
|
|
replace_regex /.*operations:.* (insert.*), delete \d.*discarded .*/\1/;
|
|
SHOW ENGINE INNODB STATUS;
|
|
# Slow shutdown will not merge the changes due to innodb_force_recovery=5.
|
|
SET GLOBAL innodb_fast_shutdown=0;
|
|
--let $restart_parameters=
|
|
--source include/restart_mysqld.inc
|
|
CHECK TABLE t1;
|
|
replace_regex /.*operations:.* insert [1-9][0-9]*, delete mark [1-9][0-9]*, delete \d.*discarded .*//;
|
|
SHOW ENGINE INNODB STATUS;
|
|
DROP TABLE t1;
|