mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MWL#116: After-review fixes.
Also implement the InnoDB changes for group commit into innodb_plugin.
This commit is contained in:
88
mysql-test/suite/innodb_plugin/t/binlog_consistent.test
Normal file
88
mysql-test/suite/innodb_plugin/t/binlog_consistent.test
Normal file
@ -0,0 +1,88 @@
|
||||
--source include/have_log_bin.inc
|
||||
--source include/have_binlog_format_mixed_or_statement.inc
|
||||
--source include/have_innodb_plugin.inc
|
||||
|
||||
RESET MASTER;
|
||||
|
||||
# Test that we get the correct binlog position from START TRANSACTION WITH
|
||||
# CONSISTENT SNAPSHOT even when other transactions are active.
|
||||
|
||||
connect(con1,localhost,root,,);
|
||||
connect(con2,localhost,root,,);
|
||||
connect(con3,localhost,root,,);
|
||||
connect(con4,localhost,root,,);
|
||||
|
||||
connection default;
|
||||
--echo # Connection default
|
||||
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(100), PRIMARY KEY (a,b)) ENGINE=innodb;
|
||||
SHOW MASTER STATUS;
|
||||
SHOW STATUS LIKE 'binlog_snapshot_%';
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (0, "");
|
||||
|
||||
connection con1;
|
||||
--echo # Connection con1
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (1, "");
|
||||
|
||||
connection con2;
|
||||
--echo # Connection con2
|
||||
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=myisam;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (2, "first");
|
||||
INSERT INTO t2 VALUES (2);
|
||||
INSERT INTO t1 VALUES (2, "second");
|
||||
|
||||
connection default;
|
||||
--echo # Connection default
|
||||
COMMIT;
|
||||
|
||||
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||
|
||||
connection con3;
|
||||
--echo # Connection con3
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (3, "");
|
||||
INSERT INTO t2 VALUES (3);
|
||||
|
||||
connection con4;
|
||||
--echo # Connection con4
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (4, "");
|
||||
COMMIT;
|
||||
|
||||
connection default;
|
||||
--echo # Connection default
|
||||
SELECT * FROM t1 ORDER BY a,b;
|
||||
SHOW STATUS LIKE 'binlog_snapshot_%';
|
||||
SHOW MASTER STATUS;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
|
||||
connection con1;
|
||||
--echo # Connection con1
|
||||
COMMIT;
|
||||
|
||||
connection con2;
|
||||
--echo # Connection con2
|
||||
COMMIT;
|
||||
|
||||
connection con3;
|
||||
--echo # Connection con3
|
||||
COMMIT;
|
||||
FLUSH LOGS;
|
||||
|
||||
connection default;
|
||||
--echo # Connection default
|
||||
SELECT * FROM t1 ORDER BY a,b;
|
||||
SHOW STATUS LIKE 'binlog_snapshot_%';
|
||||
SHOW MASTER STATUS;
|
||||
COMMIT;
|
||||
SHOW STATUS LIKE 'binlog_snapshot_%';
|
||||
SHOW MASTER STATUS;
|
||||
|
||||
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
|
||||
SHOW BINLOG EVENTS;
|
||||
|
||||
DROP TABLE t1,t2;
|
115
mysql-test/suite/innodb_plugin/t/group_commit.test
Normal file
115
mysql-test/suite/innodb_plugin/t/group_commit.test
Normal file
@ -0,0 +1,115 @@
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/have_innodb_plugin.inc
|
||||
--source include/have_log_bin.inc
|
||||
|
||||
# Test some group commit code paths by using debug_sync to do controlled
|
||||
# commits of 6 transactions: first 1 alone, then 3 as a group, then 2 as a
|
||||
# group.
|
||||
#
|
||||
# Group 3 is allowed to race as far as possible ahead before group 2 finishes
|
||||
# to check some edge case for concurrency control.
|
||||
|
||||
CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=innodb;
|
||||
|
||||
SELECT variable_value INTO @commits FROM information_schema.global_status
|
||||
WHERE variable_name = 'binlog_commits';
|
||||
SELECT variable_value INTO @group_commits FROM information_schema.global_status
|
||||
WHERE variable_name = 'binlog_group_commits';
|
||||
|
||||
connect(con1,localhost,root,,);
|
||||
connect(con2,localhost,root,,);
|
||||
connect(con3,localhost,root,,);
|
||||
connect(con4,localhost,root,,);
|
||||
connect(con5,localhost,root,,);
|
||||
connect(con6,localhost,root,,);
|
||||
|
||||
# Start group1 (with one thread) doing commit, waiting for
|
||||
# group2 to queue up before finishing.
|
||||
|
||||
connection con1;
|
||||
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group1_running WAIT_FOR group2_queued";
|
||||
send INSERT INTO t1 VALUES ("con1");
|
||||
|
||||
# Make group2 (with three threads) queue up.
|
||||
# Make sure con2 is the group commit leader for group2.
|
||||
# Make group2 wait with running commit_ordered() until group3 has committed.
|
||||
|
||||
connection con2;
|
||||
set DEBUG_SYNC= "now WAIT_FOR group1_running";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con2";
|
||||
SET DEBUG_SYNC= "commit_after_release_LOCK_log WAIT_FOR group3_committed";
|
||||
SET DEBUG_SYNC= "commit_after_group_run_commit_ordered SIGNAL group2_visible WAIT_FOR group2_checked";
|
||||
send INSERT INTO t1 VALUES ("con2");
|
||||
connection con3;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group2_con2";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con3";
|
||||
send INSERT INTO t1 VALUES ("con3");
|
||||
connection con4;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group2_con3";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con4";
|
||||
send INSERT INTO t1 VALUES ("con4");
|
||||
|
||||
# When group2 is queued, let group1 continue and queue group3.
|
||||
|
||||
connection default;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group2_con4";
|
||||
|
||||
# At this point, trasaction 1 is still not visible as commit_ordered() has not
|
||||
# been called yet.
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
SET DEBUG_SYNC= "now SIGNAL group2_queued";
|
||||
connection con1;
|
||||
reap;
|
||||
|
||||
# Now transaction 1 is visible.
|
||||
connection default;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
connection con5;
|
||||
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group3_con5";
|
||||
SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con5_leader WAIT_FOR con6_queued";
|
||||
send INSERT INTO t1 VALUES ("con5");
|
||||
|
||||
connection con6;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con5_leader";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con6_queued";
|
||||
send INSERT INTO t1 VALUES ("con6");
|
||||
|
||||
connection default;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group3_con5";
|
||||
# Still only transaction 1 visible, as group2 have not yet run commit_ordered().
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SET DEBUG_SYNC= "now SIGNAL group3_committed";
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group2_visible";
|
||||
# Now transactions 1-4 visible.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SET DEBUG_SYNC= "now SIGNAL group2_checked";
|
||||
|
||||
connection con2;
|
||||
reap;
|
||||
|
||||
connection con3;
|
||||
reap;
|
||||
|
||||
connection con4;
|
||||
reap;
|
||||
|
||||
connection con5;
|
||||
reap;
|
||||
|
||||
connection con6;
|
||||
reap;
|
||||
|
||||
connection default;
|
||||
# Check all transactions finally visible.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
SELECT variable_value - @commits FROM information_schema.global_status
|
||||
WHERE variable_name = 'binlog_commits';
|
||||
SELECT variable_value - @group_commits FROM information_schema.global_status
|
||||
WHERE variable_name = 'binlog_group_commits';
|
||||
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE t1;
|
@ -0,0 +1 @@
|
||||
--skip-stack-trace --skip-core-file
|
@ -0,0 +1,89 @@
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/have_innodb_plugin.inc
|
||||
--source include/have_log_bin.inc
|
||||
--source include/have_binlog_format_mixed_or_statement.inc
|
||||
|
||||
# Need DBUG to crash the server intentionally
|
||||
--source include/have_debug.inc
|
||||
# Don't test this under valgrind, memory leaks will occur as we crash
|
||||
--source include/not_valgrind.inc
|
||||
|
||||
# The test case currently uses grep and tail, which may be unavailable on
|
||||
# some windows systems. But see MWL#191 for how to remove the need for grep.
|
||||
--source include/not_windows.inc
|
||||
|
||||
# XtraDB stores the binlog position corresponding to the last commit, and
|
||||
# prints it during crash recovery.
|
||||
# Test that we get the correct position when we group commit several
|
||||
# transactions together.
|
||||
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
|
||||
INSERT INTO t1 VALUES (0);
|
||||
|
||||
connect(con1,localhost,root,,);
|
||||
connect(con2,localhost,root,,);
|
||||
connect(con3,localhost,root,,);
|
||||
|
||||
# Queue up three commits for group commit.
|
||||
|
||||
connection con1;
|
||||
SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con1_waiting WAIT_FOR con3_queued";
|
||||
SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont EXECUTE 3";
|
||||
send INSERT INTO t1 VALUES (1);
|
||||
|
||||
connection con2;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con1_waiting";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con2_queued";
|
||||
send INSERT INTO t1 VALUES (2);
|
||||
|
||||
connection con3;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con2_queued";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con3_queued";
|
||||
send INSERT INTO t1 VALUES (3);
|
||||
|
||||
connection default;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
||||
# At this point, no transactions are committed.
|
||||
SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
||||
# At this point, 1 transaction is committed.
|
||||
SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
||||
|
||||
# At this point, 2 transactions are committed.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
connection con2;
|
||||
reap;
|
||||
|
||||
# Now crash the server with 1+2 in-memory committed, 3 only prepared.
|
||||
connection default;
|
||||
system echo wait-group_commit_binlog_pos.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
||||
SET SESSION debug="+d,crash_dispatch_command_before";
|
||||
--error 2006,2013
|
||||
SELECT 1;
|
||||
|
||||
connection con1;
|
||||
--error 2006,2013
|
||||
reap;
|
||||
connection con3;
|
||||
--error 2006,2013
|
||||
reap;
|
||||
|
||||
system echo restart-group_commit_binlog_pos.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
||||
|
||||
connection default;
|
||||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
# Crash recovery should recover all three transactions.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
# Check that the binlog position reported by InnoDB is the correct one
|
||||
# for the end of the second transaction (as can be checked with
|
||||
# mysqlbinlog).
|
||||
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||
--exec grep 'InnoDB: Last MySQL binlog file position' $MYSQLD_DATADIR/../../log/mysqld.1.err | tail -1
|
||||
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE t1;
|
@ -0,0 +1 @@
|
||||
--binlog-optimize-thread-scheduling=0 --skip-stack-trace --skip-core-file
|
@ -0,0 +1,90 @@
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/have_innodb_plugin.inc
|
||||
--source include/have_log_bin.inc
|
||||
--source include/have_binlog_format_mixed_or_statement.inc
|
||||
|
||||
# Need DBUG to crash the server intentionally
|
||||
--source include/have_debug.inc
|
||||
# Don't test this under valgrind, memory leaks will occur as we crash
|
||||
--source include/not_valgrind.inc
|
||||
|
||||
# The test case currently uses grep and tail, which may be unavailable on
|
||||
# some windows systems. But see MWL#191 for how to remove the need for grep.
|
||||
--source include/not_windows.inc
|
||||
|
||||
# XtraDB stores the binlog position corresponding to the last commit, and
|
||||
# prints it during crash recovery.
|
||||
# Test that we get the correct position when we group commit several
|
||||
# transactions together.
|
||||
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
|
||||
INSERT INTO t1 VALUES (0);
|
||||
|
||||
connect(con1,localhost,root,,);
|
||||
connect(con2,localhost,root,,);
|
||||
connect(con3,localhost,root,,);
|
||||
|
||||
# Queue up three commits for group commit.
|
||||
|
||||
connection con1;
|
||||
SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con1_waiting WAIT_FOR con3_queued";
|
||||
SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
|
||||
send INSERT INTO t1 VALUES (1);
|
||||
|
||||
connection con2;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con1_waiting";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con2_queued";
|
||||
SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
|
||||
send INSERT INTO t1 VALUES (2);
|
||||
|
||||
connection con3;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con2_queued";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con3_queued";
|
||||
SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
|
||||
send INSERT INTO t1 VALUES (3);
|
||||
|
||||
connection default;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
||||
# At this point, no transactions are committed.
|
||||
SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
||||
# At this point, 1 transaction is committed.
|
||||
SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
||||
|
||||
# At this point, 2 transactions are committed.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
connection con1;
|
||||
reap;
|
||||
connection con2;
|
||||
reap;
|
||||
|
||||
# Now crash the server with 1+2 in-memory committed, 3 only prepared.
|
||||
connection default;
|
||||
system echo wait-group_commit_binlog_pos_no_optimize_thread.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
||||
SET SESSION debug="+d,crash_dispatch_command_before";
|
||||
--error 2006,2013
|
||||
SELECT 1;
|
||||
|
||||
connection con3;
|
||||
--error 2006,2013
|
||||
reap;
|
||||
|
||||
system echo restart-group_commit_binlog_pos_no_optimize_thread.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
||||
|
||||
connection default;
|
||||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
# Crash recovery should recover all three transactions.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
# Check that the binlog position reported by InnoDB is the correct one
|
||||
# for the end of the second transaction (as can be checked with
|
||||
# mysqlbinlog).
|
||||
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||
--exec grep 'InnoDB: Last MySQL binlog file position' $MYSQLD_DATADIR/../../log/mysqld.1.err | tail -1
|
||||
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE t1;
|
@ -0,0 +1 @@
|
||||
--skip-stack-trace --skip-core-file
|
82
mysql-test/suite/innodb_plugin/t/group_commit_crash.test
Normal file
82
mysql-test/suite/innodb_plugin/t/group_commit_crash.test
Normal file
@ -0,0 +1,82 @@
|
||||
# Testing group commit by crashing a few times.
|
||||
# Test adapted from the Facebook patch: lp:mysqlatfacebook
|
||||
--source include/not_embedded.inc
|
||||
# Don't test this under valgrind, memory leaks will occur
|
||||
--source include/not_valgrind.inc
|
||||
|
||||
# Binary must be compiled with debug for crash to occur
|
||||
--source include/have_debug.inc
|
||||
--source include/have_innodb_plugin.inc
|
||||
--source include/have_log_bin.inc
|
||||
|
||||
let $file_format_check=`SELECT @@innodb_file_format_check`;
|
||||
CREATE TABLE t1(a CHAR(255),
|
||||
b CHAR(255),
|
||||
c CHAR(255),
|
||||
d CHAR(255),
|
||||
id INT AUTO_INCREMENT,
|
||||
PRIMARY KEY(id)) ENGINE=InnoDB;
|
||||
create table t2 like t1;
|
||||
delimiter //;
|
||||
create procedure setcrash(IN i INT)
|
||||
begin
|
||||
CASE i
|
||||
WHEN 1 THEN SET SESSION debug="d,crash_commit_after_prepare";
|
||||
WHEN 2 THEN SET SESSION debug="d,crash_commit_after_log";
|
||||
WHEN 3 THEN SET SESSION debug="d,crash_commit_before_unlog";
|
||||
WHEN 4 THEN SET SESSION debug="d,crash_commit_after";
|
||||
WHEN 5 THEN SET SESSION debug="d,crash_commit_before";
|
||||
ELSE BEGIN END;
|
||||
END CASE;
|
||||
end //
|
||||
delimiter ;//
|
||||
# Avoid getting a crashed mysql.proc table.
|
||||
FLUSH TABLES;
|
||||
|
||||
let $numtests = 5;
|
||||
|
||||
let $numinserts = 10;
|
||||
while ($numinserts)
|
||||
{
|
||||
dec $numinserts;
|
||||
INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
|
||||
}
|
||||
|
||||
--enable_reconnect
|
||||
|
||||
while ($numtests)
|
||||
{
|
||||
SET binlog_format= mixed;
|
||||
RESET MASTER;
|
||||
|
||||
START TRANSACTION;
|
||||
insert into t1 select * from t2;
|
||||
# Write file to make mysql-test-run.pl expect crash
|
||||
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
|
||||
eval call setcrash($numtests);
|
||||
|
||||
# Run the crashing query
|
||||
--error 2006,2013
|
||||
COMMIT;
|
||||
|
||||
# Poll the server waiting for it to be back online again.
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
# table and binlog should be in sync.
|
||||
SELECT * FROM t1 ORDER BY id;
|
||||
--replace_column 2 # 5 #
|
||||
SHOW BINLOG EVENTS LIMIT 2,1;
|
||||
|
||||
delete from t1;
|
||||
|
||||
dec $numtests;
|
||||
}
|
||||
|
||||
# final cleanup
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP PROCEDURE setcrash;
|
||||
--disable_query_log
|
||||
eval SET GLOBAL innodb_file_format_check=$file_format_check;
|
||||
--enable_query_log
|
@ -0,0 +1 @@
|
||||
--binlog-optimize-thread-scheduling=0 --skip-stack-trace --skip-core-file
|
@ -0,0 +1,82 @@
|
||||
# Testing group commit by crashing a few times.
|
||||
# Test adapted from the Facebook patch: lp:mysqlatfacebook
|
||||
--source include/not_embedded.inc
|
||||
# Don't test this under valgrind, memory leaks will occur
|
||||
--source include/not_valgrind.inc
|
||||
|
||||
# Binary must be compiled with debug for crash to occur
|
||||
--source include/have_debug.inc
|
||||
--source include/have_innodb_plugin.inc
|
||||
--source include/have_log_bin.inc
|
||||
|
||||
let $file_format_check=`SELECT @@innodb_file_format_check`;
|
||||
CREATE TABLE t1(a CHAR(255),
|
||||
b CHAR(255),
|
||||
c CHAR(255),
|
||||
d CHAR(255),
|
||||
id INT AUTO_INCREMENT,
|
||||
PRIMARY KEY(id)) ENGINE=InnoDB;
|
||||
create table t2 like t1;
|
||||
delimiter //;
|
||||
create procedure setcrash(IN i INT)
|
||||
begin
|
||||
CASE i
|
||||
WHEN 1 THEN SET SESSION debug="d,crash_commit_after_prepare";
|
||||
WHEN 2 THEN SET SESSION debug="d,crash_commit_after_log";
|
||||
WHEN 3 THEN SET SESSION debug="d,crash_commit_before_unlog";
|
||||
WHEN 4 THEN SET SESSION debug="d,crash_commit_after";
|
||||
WHEN 5 THEN SET SESSION debug="d,crash_commit_before";
|
||||
ELSE BEGIN END;
|
||||
END CASE;
|
||||
end //
|
||||
delimiter ;//
|
||||
# Avoid getting a crashed mysql.proc table.
|
||||
FLUSH TABLES;
|
||||
|
||||
let $numtests = 5;
|
||||
|
||||
let $numinserts = 10;
|
||||
while ($numinserts)
|
||||
{
|
||||
dec $numinserts;
|
||||
INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
|
||||
}
|
||||
|
||||
--enable_reconnect
|
||||
|
||||
while ($numtests)
|
||||
{
|
||||
SET binlog_format= mixed;
|
||||
RESET MASTER;
|
||||
|
||||
START TRANSACTION;
|
||||
insert into t1 select * from t2;
|
||||
# Write file to make mysql-test-run.pl expect crash
|
||||
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
|
||||
eval call setcrash($numtests);
|
||||
|
||||
# Run the crashing query
|
||||
--error 2006,2013
|
||||
COMMIT;
|
||||
|
||||
# Poll the server waiting for it to be back online again.
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
# table and binlog should be in sync.
|
||||
SELECT * FROM t1 ORDER BY id;
|
||||
--replace_column 2 # 5 #
|
||||
SHOW BINLOG EVENTS LIMIT 2,1;
|
||||
|
||||
delete from t1;
|
||||
|
||||
dec $numtests;
|
||||
}
|
||||
|
||||
# final cleanup
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP PROCEDURE setcrash;
|
||||
--disable_query_log
|
||||
eval SET GLOBAL innodb_file_format_check=$file_format_check;
|
||||
--enable_query_log
|
@ -0,0 +1 @@
|
||||
--binlog-optimize-thread-scheduling=0
|
@ -0,0 +1,115 @@
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/have_innodb_plugin.inc
|
||||
--source include/have_log_bin.inc
|
||||
|
||||
# Test some group commit code paths by using debug_sync to do controlled
|
||||
# commits of 6 transactions: first 1 alone, then 3 as a group, then 2 as a
|
||||
# group.
|
||||
#
|
||||
# Group 3 is allowed to race as far as possible ahead before group 2 finishes
|
||||
# to check some edge case for concurrency control.
|
||||
|
||||
CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=innodb;
|
||||
|
||||
SELECT variable_value INTO @commits FROM information_schema.global_status
|
||||
WHERE variable_name = 'binlog_commits';
|
||||
SELECT variable_value INTO @group_commits FROM information_schema.global_status
|
||||
WHERE variable_name = 'binlog_group_commits';
|
||||
|
||||
connect(con1,localhost,root,,);
|
||||
connect(con2,localhost,root,,);
|
||||
connect(con3,localhost,root,,);
|
||||
connect(con4,localhost,root,,);
|
||||
connect(con5,localhost,root,,);
|
||||
connect(con6,localhost,root,,);
|
||||
|
||||
# Start group1 (with one thread) doing commit, waiting for
|
||||
# group2 to queue up before finishing.
|
||||
|
||||
connection con1;
|
||||
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group1_running WAIT_FOR group2_queued";
|
||||
send INSERT INTO t1 VALUES ("con1");
|
||||
|
||||
# Make group2 (with three threads) queue up.
|
||||
# Make sure con2 is the group commit leader for group2.
|
||||
# Make group2 wait with running commit_ordered() until group3 has committed.
|
||||
|
||||
connection con2;
|
||||
set DEBUG_SYNC= "now WAIT_FOR group1_running";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con2";
|
||||
SET DEBUG_SYNC= "commit_after_release_LOCK_log WAIT_FOR group3_committed";
|
||||
send INSERT INTO t1 VALUES ("con2");
|
||||
connection con3;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group2_con2";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con3";
|
||||
send INSERT INTO t1 VALUES ("con3");
|
||||
connection con4;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group2_con3";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con4";
|
||||
SET DEBUG_SYNC= "commit_after_group_run_commit_ordered SIGNAL group2_visible WAIT_FOR group2_checked";
|
||||
send INSERT INTO t1 VALUES ("con4");
|
||||
|
||||
# When group2 is queued, let group1 continue and queue group3.
|
||||
|
||||
connection default;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group2_con4";
|
||||
|
||||
# At this point, trasaction 1 is still not visible as commit_ordered() has not
|
||||
# been called yet.
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
SET DEBUG_SYNC= "now SIGNAL group2_queued";
|
||||
connection con1;
|
||||
reap;
|
||||
|
||||
# Now transaction 1 is visible.
|
||||
connection default;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
connection con5;
|
||||
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group3_con5";
|
||||
SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con5_leader WAIT_FOR con6_queued";
|
||||
send INSERT INTO t1 VALUES ("con5");
|
||||
|
||||
connection con6;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR con5_leader";
|
||||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con6_queued";
|
||||
send INSERT INTO t1 VALUES ("con6");
|
||||
|
||||
connection default;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group3_con5";
|
||||
# Still only transaction 1 visible, as group2 have not yet run commit_ordered().
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SET DEBUG_SYNC= "now SIGNAL group3_committed";
|
||||
SET DEBUG_SYNC= "now WAIT_FOR group2_visible";
|
||||
# Now transactions 1-4 visible.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SET DEBUG_SYNC= "now SIGNAL group2_checked";
|
||||
|
||||
connection con2;
|
||||
reap;
|
||||
|
||||
connection con3;
|
||||
reap;
|
||||
|
||||
connection con4;
|
||||
reap;
|
||||
|
||||
connection con5;
|
||||
reap;
|
||||
|
||||
connection con6;
|
||||
reap;
|
||||
|
||||
connection default;
|
||||
# Check all transactions finally visible.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
SELECT variable_value - @commits FROM information_schema.global_status
|
||||
WHERE variable_name = 'binlog_commits';
|
||||
SELECT variable_value - @group_commits FROM information_schema.global_status
|
||||
WHERE variable_name = 'binlog_group_commits';
|
||||
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE t1;
|
Reference in New Issue
Block a user