polardbxengine/mysql-test/suite/innodb/t/log_first_rec_group.test

215 lines
6.2 KiB
Plaintext

# Test adjusted to 16k pages.
--source include/have_innodb_16k.inc
# We use DBUG_EXECUTE_IF.
--source include/have_debug.inc
# Required for the crash just after COMMIT resulting in recovery without rows.
--source include/not_log_bin.inc
# Currently valgrind has issues with DBUG_SUICIDE().
--source include/not_valgrind.inc
--disable_query_log
--disable_result_log
let $MYSQLD_DATADIR= `SELECT @@datadir`;
let $MYSQLD_SOCKET= `SELECT @@socket`;
let $MYSQLD_PORT= `SELECT @@port`;
--echo # Initialization - create table.
CREATE TABLE t (a INT NOT NULL PRIMARY KEY) ENGINE = InnoDB;
let $debug_test = 0;
--echo #
--echo # Scenario 1. Crash during recovery crash, when recovery ends in the same block as checkpoint_lsn.
--echo #
let $pass = 0;
while ($pass != 2) {
--echo Pass: $pass
DELETE FROM t;
INSERT INTO t (a) VALUES (100);
# Enable all METRICS within log module
SET GLOBAL innodb_monitor_enable = module_log;
# Disable background threads that could modify pages
SET GLOBAL innodb_dict_stats_disabled_debug = 1;
SET GLOBAL innodb_master_thread_disabled_debug = 1;
SET GLOBAL innodb_purge_stop_now = 1;
# Execute sharp checkpoint (flush all pages)
SET GLOBAL innodb_log_checkpoint_now = 1;
--echo # 0. Move to the next log block.
let $log_fill_block_sql = INSERT INTO t(a) VALUES (101);
let $log_fill_block_and_crash = 0;
--source ../include/log_fill_block.inc
let $start_lsn = $end_lsn;
--echo # 1. Execute tiny mini transaction in the current block [only pass 0]
if ($pass == 0) {
SET AUTOCOMMIT = 0;
INSERT INTO t (a) VALUES(102);
if ($debug_test) {
--source ../include/log_read_current_lsn.inc
--echo State: after writing first mtr to the block
--echo LSN: $current_lsn
}
}
--echo # 2. Create checkpoint at the current lsn and block further checkpoints
SET GLOBAL innodb_log_checkpoint_now = 1;
SET GLOBAL innodb_page_cleaner_disabled_debug = 1;
SET GLOBAL innodb_checkpoint_disabled = 1;
if ($debug_test) {
--source ../include/log_read_current_lsn.inc
--source ../include/log_read_checkpoint_lsn.inc
--echo State: after checkpoint write
--echo LSN: $current_lsn
--echo Checkpoint LSN: $checkpoint_lsn
}
--echo # 3. Execute transaction to force non-trivial crash recovery: 103.
INSERT INTO t (a) VALUES (103);
COMMIT;
--source ../include/log_read_current_lsn.inc
--let $end_lsn = $current_lsn
if ($debug_test) {
--echo State: after writing 103
--echo LSN: $end_lsn
}
--let $assert_text = All must happen within the single log block (this was required for the bug)
--let $assert_cond = [SELECT $start_lsn DIV 512] = [SELECT ($end_lsn + 50) DIV 512]
--source include/assert.inc
--echo # 5. Crash when trying to insert B.
SET GLOBAL DEBUG="+d,mtr_commit_crash";
--source include/expect_crash.inc
--error 2013
INSERT INTO t (a) VALUES (105);
--echo # 6. Recover 103, write new redo record X during recovery and crash just before flushing page with 103
--error 137
--exec $MYSQLD --no-defaults --datadir=$MYSQLD_DATADIR --socket=$MYSQLD_SOCKET --port=$MYSQLD_PORT --skip-ssl --secure-file-priv="" --skip-mysqlx --debug="+d,log_first_rec_group_test"
--echo # 7. Start recovery and ensure all is recovered - we must recover 103.
--echo # If first_rec_group was pointing to X we would skip 103.
--source include/start_mysqld.inc
--enable_query_log
--enable_result_log
SELECT * FROM t;
--disable_query_log
--disable_result_log
inc $pass;
}
# Note that all global settings (disabled purge, dict_stats etc) are reset because
# we have restarted mysqld.
--echo #
--echo # Scenario 2. Restart after writing full log block with record ending at boundary,
--echo # recovery should start in middle of the last written block (pass 0, 2)
--echo # or at the beginning of that block (pass 1, 3) and end before the next
--echo # block (pass 0, 1) or just 12 bytes after its beginning (pass 2, 3).
--echo #
let $pass = 0;
while ($pass != 4) {
--echo Pass: $pass
DELETE FROM t;
INSERT INTO t (a) VALUES (200);
# Enable all METRICS within log module
SET GLOBAL innodb_monitor_enable = module_log;
# Disable background threads that could modify pages
SET GLOBAL innodb_dict_stats_disabled_debug = 1;
SET GLOBAL innodb_master_thread_disabled_debug = 1;
SET GLOBAL innodb_purge_stop_now = 1;
# Execute sharp checkpoint (flush all pages)
SET GLOBAL innodb_log_checkpoint_now = 1;
--echo # 0. Move to the next log block
let $log_fill_block_sql = INSERT INTO t(a) VALUES (201);
let $log_fill_block_and_crash = 0;
--source ../include/log_fill_block.inc
--echo # 1. Execute tiny mini transaction in the current block [pass 0, 2]
let $insert_202 = 0;
if ($pass == 0) {
let $insert_202 = 1;
}
if ($pass == 2) {
let $insert_202 = 1;
}
if ($insert_202 == 1) {
SET AUTOCOMMIT = 0;
INSERT INTO t (a) VALUES (202);
}
# Execute sharp checkpoint (flush all pages) and block further checkpoints
SET GLOBAL innodb_log_checkpoint_now = 1;
SET GLOBAL innodb_page_cleaner_disabled_debug = 1;
SET GLOBAL innodb_checkpoint_disabled = 1;
--echo # 2. Write up to the end of the block.
let $crash_at_203 = 0;
if ($pass == 0) {
let $crash_at_203 = 1;
}
if ($pass == 1) {
let $crash_at_203 = 1;
}
--echo # 3. Crash on writing next 12 bytes of incomplete block [pass 0, 1].
let $log_fill_block_and_crash = $crash_at_203;
let $log_fill_block_sql = INSERT INTO t(a) VALUES (203);
--source ../include/log_fill_block.inc
let $log_fill_block_and_crash = 0;
--echo # 4. If we still haven't crashed, force mtr to crash.
if ($crash_at_203 == 0) {
SET GLOBAL DEBUG = "+d,mtr_commit_crash";
--source include/expect_crash.inc
--error 2013
INSERT INTO t (a) VALUES (204);
}
--echo # 5. Start MySQL after crash to see how it takes care of recovery
--source include/start_mysqld.inc
--enable_query_log
--enable_result_log
SELECT * FROM t;
--disable_query_log
--disable_result_log
inc $pass;
}
# Note that all global settings (disabled purge, dict_stats etc) are reset because
# we have restarted mysqld.
--echo # Cleanup...
DROP TABLE t;
--enable_query_log
--enable_result_log