Browse Source
MWL#116: Efficient group commit for binary log
MWL#116: Efficient group commit for binary log
Preliminary commit for testingpull/374/head
16 changed files with 1806 additions and 452 deletions
-
63mysql-test/r/group_commit.result
-
28mysql-test/suite/binlog/r/binlog_ioerr.result
-
29mysql-test/suite/binlog/t/binlog_ioerr.test
-
115mysql-test/t/group_commit.test
-
210sql/handler.cc
-
89sql/handler.h
-
1276sql/log.cc
-
209sql/log.h
-
5sql/log_event.h
-
3sql/mysqld.cc
-
6sql/sql_class.cc
-
4sql/sql_class.h
-
2sql/sql_load.cc
-
10sql/table.cc
-
1sql/table.h
-
208storage/xtradb/handler/ha_innodb.cc
@ -0,0 +1,63 @@ |
|||
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'; |
|||
SET DEBUG_SYNC= "commit_after_group_log_xid SIGNAL group1_running WAIT_FOR group2_queued"; |
|||
INSERT INTO t1 VALUES ("con1"); |
|||
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_group_commit WAIT_FOR group3_committed"; |
|||
SET DEBUG_SYNC= "commit_after_group_run_commit_ordered SIGNAL group2_visible WAIT_FOR group2_checked"; |
|||
INSERT INTO t1 VALUES ("con2"); |
|||
SET DEBUG_SYNC= "now WAIT_FOR group2_con2"; |
|||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con3"; |
|||
INSERT INTO t1 VALUES ("con3"); |
|||
SET DEBUG_SYNC= "now WAIT_FOR group2_con3"; |
|||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con4"; |
|||
INSERT INTO t1 VALUES ("con4"); |
|||
SET DEBUG_SYNC= "now WAIT_FOR group2_con4"; |
|||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; |
|||
SELECT * FROM t1 ORDER BY a; |
|||
a |
|||
SET DEBUG_SYNC= "now SIGNAL group2_queued"; |
|||
SELECT * FROM t1 ORDER BY a; |
|||
a |
|||
con1 |
|||
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group3_con5"; |
|||
SET DEBUG_SYNC= "commit_after_get_LOCK_group_commit SIGNAL con5_leader WAIT_FOR con6_queued"; |
|||
INSERT INTO t1 VALUES ("con5"); |
|||
SET DEBUG_SYNC= "now WAIT_FOR con5_leader"; |
|||
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con6_queued"; |
|||
INSERT INTO t1 VALUES ("con6"); |
|||
SET DEBUG_SYNC= "now WAIT_FOR group3_con5"; |
|||
SELECT * FROM t1 ORDER BY a; |
|||
a |
|||
con1 |
|||
SET DEBUG_SYNC= "now SIGNAL group3_committed"; |
|||
SET DEBUG_SYNC= "now WAIT_FOR group2_visible"; |
|||
SELECT * FROM t1 ORDER BY a; |
|||
a |
|||
con1 |
|||
con2 |
|||
con3 |
|||
con4 |
|||
SET DEBUG_SYNC= "now SIGNAL group2_checked"; |
|||
SELECT * FROM t1 ORDER BY a; |
|||
a |
|||
con1 |
|||
con2 |
|||
con3 |
|||
con4 |
|||
con5 |
|||
con6 |
|||
SELECT variable_value - @commits FROM information_schema.global_status |
|||
WHERE variable_name = 'binlog_commits'; |
|||
variable_value - @commits |
|||
6 |
|||
SELECT variable_value - @group_commits FROM information_schema.global_status |
|||
WHERE variable_name = 'binlog_group_commits'; |
|||
variable_value - @group_commits |
|||
3 |
|||
SET DEBUG_SYNC= 'RESET'; |
|||
DROP TABLE t1; |
|||
@ -0,0 +1,28 @@ |
|||
CALL mtr.add_suppression("Error writing file 'master-bin'"); |
|||
RESET MASTER; |
|||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb; |
|||
INSERT INTO t1 VALUES(0); |
|||
SET SESSION debug='+d,fail_binlog_write_1'; |
|||
INSERT INTO t1 VALUES(1); |
|||
ERROR HY000: Error writing file 'master-bin' (errno: 22) |
|||
INSERT INTO t1 VALUES(2); |
|||
ERROR HY000: Error writing file 'master-bin' (errno: 22) |
|||
SET SESSION debug=''; |
|||
INSERT INTO t1 VALUES(3); |
|||
SELECT * FROM t1; |
|||
a |
|||
0 |
|||
3 |
|||
SHOW BINLOG EVENTS; |
|||
Log_name Pos Event_type Server_id End_log_pos Info |
|||
BINLOG POS Format_desc 1 ENDPOS Server ver: #, Binlog ver: # |
|||
BINLOG POS Query 1 ENDPOS use `test`; CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb |
|||
BINLOG POS Query 1 ENDPOS BEGIN |
|||
BINLOG POS Query 1 ENDPOS use `test`; INSERT INTO t1 VALUES(0) |
|||
BINLOG POS Xid 1 ENDPOS COMMIT /* XID */ |
|||
BINLOG POS Query 1 ENDPOS BEGIN |
|||
BINLOG POS Query 1 ENDPOS BEGIN |
|||
BINLOG POS Query 1 ENDPOS BEGIN |
|||
BINLOG POS Query 1 ENDPOS use `test`; INSERT INTO t1 VALUES(3) |
|||
BINLOG POS Xid 1 ENDPOS COMMIT /* XID */ |
|||
DROP TABLE t1; |
|||
@ -0,0 +1,29 @@ |
|||
source include/have_debug.inc; |
|||
source include/have_innodb.inc; |
|||
source include/have_log_bin.inc; |
|||
source include/have_binlog_format_mixed_or_statement.inc; |
|||
|
|||
CALL mtr.add_suppression("Error writing file 'master-bin'"); |
|||
|
|||
RESET MASTER; |
|||
|
|||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb; |
|||
INSERT INTO t1 VALUES(0); |
|||
SET SESSION debug='+d,fail_binlog_write_1'; |
|||
--error ER_ERROR_ON_WRITE |
|||
INSERT INTO t1 VALUES(1); |
|||
--error ER_ERROR_ON_WRITE |
|||
INSERT INTO t1 VALUES(2); |
|||
SET SESSION debug=''; |
|||
INSERT INTO t1 VALUES(3); |
|||
SELECT * FROM t1; |
|||
|
|||
# Actually the output from this currently shows a bug. |
|||
# The injected IO error leaves partially written transactions in the binlog in |
|||
# the form of stray "BEGIN" events. |
|||
# These should disappear from the output if binlog error handling is improved. |
|||
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/ |
|||
--replace_column 1 BINLOG 2 POS 5 ENDPOS |
|||
SHOW BINLOG EVENTS; |
|||
|
|||
DROP TABLE t1; |
|||
@ -0,0 +1,115 @@ |
|||
--source include/have_debug_sync.inc |
|||
--source include/have_innodb.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_after_group_log_xid 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_group_commit 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_group_commit 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; |
|||
1276
sql/log.cc
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue