Skip to content

Commit 951dde2

Browse files
Slawomir Maludzinskidahlerlend
authored andcommitted
Bug#35342521 Binary log purge should hold IX backup lock
Issue description ----------------- PURGE BINARY LOGS and ALTER TABLE SECONDARY_LOG cannot be executed concurrently. Analysis -------- PURGE BINARY LOGS calls is_instance_backup_locked() to check if any other process is holding BACKUP_LOCK and fails if it finds any. The lock is not acquired for the duration of the PURGE BINARY LOGS statement which is incorrect. As result it is possible that some other thread acquires BACKUP_LOCK after PURGE has returned from is_instance_backup_locked(). Proposed solution ----------------- PURGE BINARY LOG should acquire IX BACKUP_LOCK. Since IX locks are compatible with each other, it will not block concurrent DDLs or get blocked by them. Also, IX locks are not compatible with X locks, so PURGE acquiring IX BACKUP_LOCK would also prevent a concurrent BACKUP from executing. Change-Id: Ib0ccc8bea3fd0c2115246eb7fa50280f4292c3c4
1 parent c35d584 commit 951dde2

26 files changed

+1109
-123
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#
2+
# Initialization
3+
#
4+
RESET MASTER;
5+
CREATE TABLE t1 (c1 INT PRIMARY KEY) SECONDARY_ENGINE rapid;
6+
FLUSH BINARY LOGS;
7+
SHOW BINARY LOGS;
8+
Log_name File_size Encrypted
9+
binlog.000001 SIZE No
10+
binlog.000002 SIZE No
11+
#
12+
# Run PURGE BINARY LOGS in separate connection
13+
#
14+
[connection default]
15+
PURGE BINARY LOGS TO 'binlog.000001';
16+
[START] PURGE BINARY LOGS TO 'binlog.000001';
17+
#
18+
# Check ALTER TABLE statement can be executed
19+
#
20+
ALTER TABLE t1 SECONDARY_LOAD;
21+
#
22+
# Continue PURGE BINARY LOGS statement
23+
#
24+
[END] PURGE BINARY LOGS TO 'binlog.000001';
25+
#
26+
# Cleanup
27+
#
28+
DROP TABLE t1;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#
2+
# Initialization
3+
#
4+
CREATE TABLE t1 (c INT);
5+
FLUSH BINARY LOGS;
6+
#
7+
# Lock the instance for backup using con1
8+
#
9+
LOCK INSTANCE FOR BACKUP;
10+
#
11+
# Check errors for purge operations
12+
#
13+
[connection default]
14+
PURGE BINARY LOGS TO 'BINLOG_FILE';
15+
ERROR HY000: Could not purge binary logs since another session is executing LOCK INSTANCE FOR BACKUP. Wait for that session to release the lock.
16+
PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';
17+
ERROR HY000: Could not purge binary logs since another session is executing LOCK INSTANCE FOR BACKUP. Wait for that session to release the lock.
18+
#
19+
# Unlock the instance for backup using con1
20+
#
21+
[connection con1]
22+
UNLOCK INSTANCE;
23+
#
24+
# Check no errors for purge operations
25+
#
26+
[connection default]
27+
PURGE BINARY LOGS TO 'BINLOG_FILE';
28+
PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';
29+
#
30+
# Cleanup
31+
#
32+
[connection default]
33+
DROP TABLE t1;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#
2+
# Initialization
3+
#
4+
RESET MASTER;
5+
CREATE TABLE t1 (c INT);
6+
FLUSH BINARY LOGS;
7+
SHOW BINARY LOGS;
8+
Log_name File_size Encrypted
9+
binlog.000001 SIZE No
10+
binlog.000002 SIZE No
11+
#
12+
# Execute FLUSH BINARY LOGS but stop on 'at_purge_logs_before_date' sync point
13+
#
14+
[connection default]
15+
[START] FLUSH BINARY LOGS;
16+
#
17+
# Check errors for LOCK INSTANCE FOR BACKUP operation
18+
#
19+
SET SESSION lock_wait_timeout = 1;
20+
LOCK INSTANCE FOR BACKUP;
21+
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
22+
#
23+
# Continue FLUSH BINARY LOGS operation
24+
#
25+
[END] FLUSH BINARY LOGS;
26+
#
27+
# Check no errors for LOCK INSTANCE FOR BACKUP operation
28+
#
29+
LOCK INSTANCE FOR BACKUP;
30+
UNLOCK INSTANCE;
31+
#
32+
# Cleanup
33+
#
34+
[connection default]
35+
DROP TABLE t1;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#
2+
# Initialize
3+
#
4+
SET @@global.binlog_expire_logs_seconds = 1;
5+
RESET MASTER;
6+
FLUSH BINARY LOGS;
7+
FLUSH BINARY LOGS;
8+
#
9+
# Lock instance for backup
10+
#
11+
[connection con1]
12+
LOCK INSTANCE FOR BACKUP;
13+
#
14+
# Flush binary logs so binary logs are purged
15+
#
16+
[connection default]
17+
include/save_error_log_position.inc
18+
FLUSH BINARY LOGS;
19+
#
20+
# Check that binary logs have not been purged
21+
#
22+
include/assert_error_log.inc [server: 1, pattern: Could not purge binary logs since another session is executing LOCK INSTANCE FOR BACKUP. Wait for that session to release the lock.]
23+
#
24+
# Unlock instance
25+
#
26+
[connection con1]
27+
UNLOCK INSTANCE;
28+
#
29+
# Generate log purge
30+
#
31+
[connection default]
32+
include/save_error_log_position.inc
33+
FLUSH BINARY LOGS;
34+
#
35+
# Check relay logs have been purged
36+
#
37+
include/assert_error_log.inc [server: 1, pattern: NONE]
38+
#
39+
# Cleanup
40+
#
41+
SET @@global.binlog_expire_logs_seconds = BINLOG_EXPIRE_LOGS_SECONDS_SAVED;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#
2+
# Initialization
3+
#
4+
RESET MASTER;
5+
CREATE TABLE t1 (c INT);
6+
FLUSH BINARY LOGS;
7+
SHOW BINARY LOGS;
8+
Log_name File_size Encrypted
9+
binlog.000001 SIZE No
10+
binlog.000002 SIZE No
11+
#
12+
# Execute PURGE BINARY LOGS but stop on a sync point
13+
#
14+
[connection default]
15+
PURGE BINARY LOGS TO 'binlog.000001';
16+
[START] PURGE BINARY LOGS TO 'binlog.000001';
17+
#
18+
# Check errors for LOCK INSTANCE FOR BACKUP operation
19+
#
20+
SET SESSION lock_wait_timeout = 1;
21+
LOCK INSTANCE FOR BACKUP;
22+
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
23+
#
24+
# Continue PURGE BINARY LOGS operation
25+
#
26+
[END] PURGE BINARY LOGS TO 'binlog.000001';
27+
#
28+
# Check no errors for LOCK INSTANCE FOR BACKUP operation
29+
#
30+
LOCK INSTANCE FOR BACKUP;
31+
UNLOCK INSTANCE;
32+
#
33+
# Cleanup
34+
#
35+
[connection default]
36+
DROP TABLE t1;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#
2+
# Initialization
3+
#
4+
RESET MASTER;
5+
CREATE TABLE t1 (c1 INT PRIMARY KEY) SECONDARY_ENGINE rapid;
6+
FLUSH BINARY LOGS;
7+
SHOW BINARY LOGS;
8+
Log_name File_size Encrypted
9+
binlog.000001 SIZE No
10+
binlog.000002 SIZE No
11+
#
12+
# Run ALTER TABLE in separate connection
13+
#
14+
[connection default]
15+
[START] ALTER TABLE t1 SECONDARY_LOAD;
16+
#
17+
# Check PURGE BINARY LOGS can be executed
18+
#
19+
PURGE BINARY LOGS TO 'BINLOG_FILE';
20+
#
21+
# Continue ALTER TABLE statement
22+
#
23+
[END] ALTER TABLE t1 SECONDARY_LOAD;
24+
#
25+
# Cleanup
26+
#
27+
DROP TABLE t1;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# === Purpose ===
2+
# Check ALTER TABLE operation can be executed with PURGE BINARY LOGS.
3+
#
4+
# === Requirements ===
5+
# R1. ALTER TABLE can be executed with PURGE BINARY LOGS statement.
6+
#
7+
# === Implementation ===
8+
# 1. Create table
9+
# 2. Run PURGE BINARY LOGS statement but stop on a sync point
10+
# 3. Check ALTER TABLE statement can be executed
11+
# 4. Cleanup
12+
#
13+
# === References ===
14+
#
15+
# Bug#35342521 Binary log purge should hold IX backup lock
16+
#
17+
--source include/have_debug_sync.inc
18+
--source include/have_binlog_format_row.inc
19+
20+
--echo #
21+
--echo # Initialization
22+
--echo #
23+
24+
RESET MASTER;
25+
CREATE TABLE t1 (c1 INT PRIMARY KEY) SECONDARY_ENGINE rapid;
26+
27+
--let $binlog_file = query_get_value(SHOW MASTER STATUS, File, 1)
28+
FLUSH BINARY LOGS;
29+
--replace_column 2 SIZE
30+
SHOW BINARY LOGS;
31+
32+
--echo #
33+
--echo # Run PURGE BINARY LOGS in separate connection
34+
--echo #
35+
36+
--connect (con1, localhost, root,,)
37+
38+
--let $rpl_connection_name = default
39+
--source include/rpl_connection.inc
40+
41+
--eval PURGE BINARY LOGS TO '$binlog_file'
42+
--let $statement_connection = con1
43+
--let $statement = PURGE BINARY LOGS TO '$binlog_file'
44+
--let $sync_point = before_purge_logs
45+
--source include/execute_to_sync_point.inc
46+
47+
--echo #
48+
--echo # Check ALTER TABLE statement can be executed
49+
--echo #
50+
51+
--disable_warnings
52+
ALTER TABLE t1 SECONDARY_LOAD;
53+
--enable_warnings
54+
55+
--echo #
56+
--echo # Continue PURGE BINARY LOGS statement
57+
--echo #
58+
59+
--source include/execute_from_sync_point.inc
60+
61+
--echo #
62+
--echo # Cleanup
63+
--echo #
64+
65+
DROP TABLE t1;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# === Purpose ===
2+
# Check PURGE BINARY LOGS operation is mutually exclusive with BACKUP lock.
3+
#
4+
# === Requirements ===
5+
# R1. PURGE BINARY LOGS must be mutually exclusive with BACKUP operation.
6+
#
7+
# === Implementation ===
8+
#
9+
# 1. Create database and tables
10+
# 2. Create second connection
11+
# 2.1. LOCK INSTANCE FOR BACKUP
12+
# 3. Use first connection
13+
# 3.1. Check PURGE BINARY LOGS TO/BEFORE cannot proceed
14+
# 4. Use second connection
15+
# 4.1. UNLOCK INSTANCE
16+
# 5. Check PURGE BINARY LOGS TO/BEFORE can proceed
17+
# 6. Cleanup
18+
#
19+
# === References ===
20+
#
21+
# Bug#35342521 Binary log purge should hold IX backup lock
22+
#
23+
--source include/have_debug.inc
24+
--source include/have_binlog_format_row.inc
25+
26+
--echo #
27+
--echo # Initialization
28+
--echo #
29+
30+
CREATE TABLE t1 (c INT);
31+
--let $binlog_file = query_get_value(SHOW MASTER STATUS, File, 1)
32+
FLUSH BINARY LOGS;
33+
34+
--echo #
35+
--echo # Lock the instance for backup using con1
36+
--echo #
37+
38+
--connect (con1, localhost, root,,)
39+
LOCK INSTANCE FOR BACKUP;
40+
41+
--echo #
42+
--echo # Check errors for purge operations
43+
--echo #
44+
45+
--let $rpl_connection_name = default
46+
--source include/rpl_connection.inc
47+
48+
--replace_result $binlog_file BINLOG_FILE
49+
--error ER_CANNOT_PURGE_BINLOG_WITH_BACKUP_LOCK
50+
--eval PURGE BINARY LOGS TO '$binlog_file'
51+
52+
--error ER_CANNOT_PURGE_BINLOG_WITH_BACKUP_LOCK
53+
PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';
54+
55+
--echo #
56+
--echo # Unlock the instance for backup using con1
57+
--echo #
58+
59+
--let $rpl_connection_name = con1
60+
--source include/rpl_connection.inc
61+
UNLOCK INSTANCE;
62+
63+
--echo #
64+
--echo # Check no errors for purge operations
65+
--echo #
66+
67+
--let $rpl_connection_name = default
68+
--source include/rpl_connection.inc
69+
70+
--replace_result $binlog_file BINLOG_FILE
71+
--eval PURGE BINARY LOGS TO '$binlog_file'
72+
73+
PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';
74+
75+
--echo #
76+
--echo # Cleanup
77+
--echo #
78+
79+
--let $rpl_connection_name = default
80+
--source include/rpl_connection.inc
81+
82+
DROP TABLE t1;

0 commit comments

Comments
 (0)