Skip to content

Commit 8d54cbc

Browse files
Joao Gramachobjornmu
Joao Gramacho
authored andcommitted
Merge branch 'mysql-5.6' into mysql-5.7
(cherry picked from commit fc05b1f101098bc30de2f8cba133a9d750cc9e9b)
1 parent 8c2edd0 commit 8d54cbc

File tree

3 files changed

+156
-1
lines changed

3 files changed

+156
-1
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[connection conn1]
2+
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
3+
SET DEBUG_SYNC= 'before_sync_binlog_file SIGNAL holding_before_bgc_sync_binlog_file WAIT_FOR continue_bgc_sync_binlog_file';
4+
INSERT INTO t1 VALUES (1);
5+
[connection conn2]
6+
SET DEBUG_SYNC= 'NOW WAIT_FOR holding_before_bgc_sync_binlog_file';
7+
SET DEBUG_SYNC= 'before_rotate_binlog_file SIGNAL holding_before_rotate_binlog_file WAIT_FOR continue_rotate_binlog_file';
8+
FLUSH LOGS;
9+
[connection default]
10+
SET DEBUG_SYNC= 'now WAIT_FOR holding_before_rotate_binlog_file TIMEOUT 3';
11+
SET DEBUG_SYNC= 'now SIGNAL continue_bgc_sync_binlog_file';
12+
SET DEBUG_SYNC= 'before_rotate_binlog_file CLEAR';
13+
SET DEBUG_SYNC = 'now SIGNAL continue_rotate_binlog_file';
14+
[connection conn1]
15+
[connection conn2]
16+
[connection default]
17+
DROP TABLE t1;
18+
SET DEBUG_SYNC= 'RESET';
19+
[connection conn1]
20+
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
21+
SET DEBUG_SYNC= 'before_sync_binlog_file SIGNAL holding_before_bgc_sync_binlog_file WAIT_FOR continue_bgc_sync_binlog_file';
22+
INSERT INTO t1 VALUES (1);
23+
[connection conn2]
24+
SET DEBUG_SYNC= 'NOW WAIT_FOR holding_before_bgc_sync_binlog_file';
25+
SET DEBUG_SYNC= 'before_rotate_binlog_file SIGNAL holding_before_rotate_binlog_file WAIT_FOR continue_rotate_binlog_file';
26+
FLUSH LOGS;
27+
[connection default]
28+
SET DEBUG_SYNC= 'now WAIT_FOR holding_before_rotate_binlog_file TIMEOUT 3';
29+
SET DEBUG_SYNC= 'now SIGNAL continue_bgc_sync_binlog_file';
30+
SET DEBUG_SYNC= 'before_rotate_binlog_file CLEAR';
31+
SET DEBUG_SYNC = 'now SIGNAL continue_rotate_binlog_file';
32+
[connection conn1]
33+
[connection conn2]
34+
[connection default]
35+
DROP TABLE t1;
36+
SET DEBUG_SYNC= 'RESET';
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# ==== Purpose ====
2+
#
3+
# This test will try to rotate the binary log of the server while binary log
4+
# group commit sync stage tries to sync the recently flushed binary log group.
5+
#
6+
# As binary log group commit releases the binary log's LOCK_log right after
7+
# finishing the flush stage and entering the sync stage, the rotate procedure
8+
# (executed by MYSQL_BIN_LOG::new_file_impl) will be able take LOCK_log, but
9+
# it will delay the binary log rotation until the amount of prepared
10+
# transactions not yet committed be zero or the binary log group commit sync
11+
# stage has finished.
12+
#
13+
# ==== Related Bugs and Worklogs ====
14+
#
15+
# BUG#22245619 SERVER ABORT AFTER SYNC STAGE OF THE COMMIT FAILS
16+
#
17+
18+
# This test case is binary log format agnostic
19+
--source include/have_binlog_format_row.inc
20+
--source include/have_debug_sync.inc
21+
--source include/have_myisam.inc
22+
--source include/have_innodb.inc
23+
24+
# Create two additional connections
25+
# conn1 will do the binary log group commit
26+
# conn2 will rotate the binary log
27+
# the default connection will coordinate the test case activity
28+
--connect(conn1,localhost,root,,test)
29+
--connect(conn2,localhost,root,,test)
30+
31+
--let $engine= MyISAM
32+
33+
while ($engine)
34+
{
35+
--let $rpl_connection_name= conn1
36+
--source include/rpl_connection.inc
37+
# Create a new table
38+
--eval CREATE TABLE t1 (c1 INT) ENGINE=$engine
39+
40+
# Make the server to hold before syncing the binary log group
41+
SET DEBUG_SYNC= 'before_sync_binlog_file SIGNAL holding_before_bgc_sync_binlog_file WAIT_FOR continue_bgc_sync_binlog_file';
42+
--send INSERT INTO t1 VALUES (1)
43+
44+
--let $rpl_connection_name= conn2
45+
--source include/rpl_connection.inc
46+
# Wait until it reached the sync binary log group
47+
SET DEBUG_SYNC= 'NOW WAIT_FOR holding_before_bgc_sync_binlog_file';
48+
49+
# Make the server to hold while rotating the binary log
50+
# It can hold in two places:
51+
# a) waiting before all flushed transactions with Xid to be committed;
52+
# b) after closing the old and before opening the new binary log file;
53+
#
54+
# The debug sync will happen at (a) if there are transactions for a
55+
# transactional storage engine or at (b) if there are no transactions
56+
# for a transactional storage engine in the group to be committed.
57+
SET DEBUG_SYNC= 'before_rotate_binlog_file SIGNAL holding_before_rotate_binlog_file WAIT_FOR continue_rotate_binlog_file';
58+
# Rotate the binary log
59+
--send FLUSH LOGS
60+
61+
# Wait until the server reaches the debug sync point while rotating the
62+
# binary log
63+
--let $rpl_connection_name= default
64+
--source include/rpl_connection.inc
65+
--disable_warnings
66+
SET DEBUG_SYNC= 'now WAIT_FOR holding_before_rotate_binlog_file TIMEOUT 3';
67+
--enable_warnings
68+
69+
# Let the binary log group commit to sync and continue
70+
SET DEBUG_SYNC= 'now SIGNAL continue_bgc_sync_binlog_file';
71+
# Clear the binary log rotate debug sync point to avoid it to stop twice
72+
SET DEBUG_SYNC= 'before_rotate_binlog_file CLEAR';
73+
# Let the binary log rotate to continue
74+
SET DEBUG_SYNC = 'now SIGNAL continue_rotate_binlog_file';
75+
76+
--let $rpl_connection_name= conn1
77+
--source include/rpl_connection.inc
78+
--reap
79+
80+
--let $rpl_connection_name= conn2
81+
--source include/rpl_connection.inc
82+
--reap
83+
84+
--let $rpl_connection_name= default
85+
--source include/rpl_connection.inc
86+
87+
# Cleanup
88+
DROP TABLE t1;
89+
SET DEBUG_SYNC= 'RESET';
90+
91+
if ($engine == InnoDB)
92+
{
93+
--let $engine=
94+
}
95+
if ($engine == MyISAM)
96+
{
97+
--let $engine= InnoDB
98+
}
99+
}
100+
101+
# Disconnect the additional connections
102+
--disconnect conn1
103+
--disconnect conn2

sql/binlog.cc

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6400,7 +6400,10 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
64006400
written to the binary log.
64016401
*/
64026402
while (get_prep_xids() > 0)
6403+
{
6404+
DEBUG_SYNC(current_thd, "before_rotate_binlog_file");
64036405
mysql_cond_wait(&m_prep_xids_cond, &LOCK_xids);
6406+
}
64046407
mysql_mutex_unlock(&LOCK_xids);
64056408

64066409
mysql_mutex_lock(&LOCK_index);
@@ -6489,6 +6492,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
64896492
Note that at this point, log_state != LOG_CLOSED (important for is_open()).
64906493
*/
64916494

6495+
DEBUG_SYNC(current_thd, "before_rotate_binlog_file");
64926496
/*
64936497
new_file() is only used for rotation (in FLUSH LOGS or because size >
64946498
max_binlog_size or max_relay_log_size).
@@ -8752,6 +8756,7 @@ int MYSQL_BIN_LOG::ordered_commit(THD *thd, bool all, bool skip_commit)
87528756
mysql_mutex_t *leave_mutex_before_commit_stage= NULL;
87538757
my_off_t flush_end_pos= 0;
87548758
bool update_binlog_end_pos_after_sync;
8759+
bool need_LOCK_log;
87558760
if (unlikely(!is_open()))
87568761
{
87578762
final_queue= stage_manager.fetch_queue_for(Stage_manager::FLUSH_STAGE);
@@ -8809,8 +8814,16 @@ int MYSQL_BIN_LOG::ordered_commit(THD *thd, bool all, bool skip_commit)
88098814
/*
88108815
Stage #2: Syncing binary log file to disk
88118816
*/
8817+
need_LOCK_log= sync_counter + 1 >= get_sync_period() && get_prep_xids() == 0;
88128818

8813-
if (change_stage(thd, Stage_manager::SYNC_STAGE, wait_queue, &LOCK_log, &LOCK_sync))
8819+
/*
8820+
LOCK_log is not released also when we are about to sync the binary log and
8821+
there is no transactional storage engine prepared transactions. This will
8822+
guarantee that the binary log rotation will not take place before syncing
8823+
the binary log file.
8824+
*/
8825+
if (change_stage(thd, Stage_manager::SYNC_STAGE, wait_queue,
8826+
need_LOCK_log ? NULL : &LOCK_log, &LOCK_sync))
88148827
{
88158828
DBUG_PRINT("return", ("Thread ID: %u, commit_error: %d",
88168829
thd->thread_id(), thd->commit_error));
@@ -8841,6 +8854,9 @@ int MYSQL_BIN_LOG::ordered_commit(THD *thd, bool all, bool skip_commit)
88418854
update_binlog_end_pos(tmp_thd->get_trans_pos());
88428855
}
88438856

8857+
if (need_LOCK_log)
8858+
mysql_mutex_unlock(&LOCK_log);
8859+
88448860
DEBUG_SYNC(thd, "bgc_after_sync_stage_before_commit_stage");
88458861

88468862
leave_mutex_before_commit_stage= &LOCK_sync;

0 commit comments

Comments
 (0)