mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-41214: PURGE BINARY LOGS does not delete non-active binlog files
Make the binlog-in-engine code path ignore @@slave_connections_needed_for_purge for interactive PURGE BINARY LOGS. Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
@@ -36,16 +36,22 @@ RESET MASTER;
|
||||
--echo #
|
||||
FLUSH BINARY LOGS;
|
||||
FLUSH BINARY LOGS;
|
||||
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
FLUSH BINARY LOGS;
|
||||
if ($binlog_in_engine) {
|
||||
--let $binlog_name= binlog-000004.ibb
|
||||
--let $binlog_size= 262144
|
||||
--source include/wait_for_engine_binlog.inc
|
||||
}
|
||||
--source include/show_binary_logs.inc
|
||||
PURGE BINARY LOGS TO 'master-bin.000003';
|
||||
eval PURGE BINARY LOGS TO '$binlog_file';
|
||||
SHOW WARNINGS;
|
||||
--source include/show_binary_logs.inc
|
||||
|
||||
--let $first= query_get_value(SHOW BINARY LOGS, Log_name, 1)
|
||||
if ($first != master-bin.000003)
|
||||
if ($first != $binlog_file)
|
||||
{
|
||||
--echo # Control failed: expected master-bin.000003 first, got $first
|
||||
--echo # Control failed: expected $binlog_file first, got $first
|
||||
--die Interactive purge did not work even with no cached refusal
|
||||
}
|
||||
|
||||
@@ -55,7 +61,12 @@ if ($first != master-bin.000003)
|
||||
--echo #
|
||||
FLUSH BINARY LOGS;
|
||||
FLUSH BINARY LOGS;
|
||||
--let $binlog_file2= query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
FLUSH BINARY LOGS;
|
||||
if ($binlog_in_engine) {
|
||||
--let $binlog_name= binlog-000007.ibb
|
||||
--source include/wait_for_engine_binlog.inc
|
||||
}
|
||||
--source include/show_binary_logs.inc
|
||||
|
||||
--echo # Let the files age past binlog_expire_logs_seconds: purge_logs_before_date
|
||||
@@ -65,23 +76,30 @@ SET @@global.binlog_expire_logs_seconds= 1;
|
||||
--echo # Rotating attempts an automatic purge, which the guard refuses. That
|
||||
--echo # refusal is what populates the cache.
|
||||
FLUSH BINARY LOGS;
|
||||
--let $binlog_file3= query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
|
||||
--let $first= query_get_value(SHOW BINARY LOGS, Log_name, 1)
|
||||
if ($first != master-bin.000003)
|
||||
if ($first != $binlog_file)
|
||||
{
|
||||
--echo # Setup failed: expected the automatic purge to delete nothing.
|
||||
--die The automatic purge was not refused, so nothing was cached
|
||||
}
|
||||
--echo # The automatic refusal states the correct reason in the error log:
|
||||
--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let SEARCH_PATTERN= Binary log .master-bin.000003. is not purged because less than .slave_connections_needed_for_purge. slaves have processed it
|
||||
--source include/search_pattern_in_file.inc
|
||||
if (!$binlog_in_engine) {
|
||||
--echo # The automatic refusal states the correct reason in the error log:
|
||||
--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let SEARCH_PATTERN= Binary log .$binlog_file. is not purged because less than .slave_connections_needed_for_purge. slaves have processed it
|
||||
--source include/search_pattern_in_file.inc
|
||||
}
|
||||
|
||||
--echo # Now the interactive purge. It should behave exactly as in part 1.
|
||||
PURGE BINARY LOGS TO 'master-bin.000006';
|
||||
--echo # On affected versions this reports master-bin.000003 as the current active
|
||||
--echo # binlog, while master-bin.000008 is active:
|
||||
eval PURGE BINARY LOGS TO '$binlog_file2';
|
||||
--echo # On affected versions this reports $binlog_file as the current active
|
||||
--echo # binlog, while $binlog_file3 is active:
|
||||
SHOW WARNINGS;
|
||||
if ($binlog_in_engine) {
|
||||
--let $binlog_name= binlog-000008.ibb
|
||||
--source include/wait_for_engine_binlog.inc
|
||||
}
|
||||
--source include/show_binary_logs.inc
|
||||
|
||||
--evalp SET @@global.binlog_expire_logs_seconds = $save_binlog_expire_logs_seconds
|
||||
|
||||
@@ -36,14 +36,6 @@ INSERT INTO t1 VALUES (100);
|
||||
INSERT INTO t2 VALUES (100, 'xyzzy');
|
||||
DROP TABLE t1, t2;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(2048)) ENGINE=InnoDB;
|
||||
SET @old_min_slaves= @@GLOBAL.slave_connections_needed_for_purge;
|
||||
SET GLOBAL slave_connections_needed_for_purge= 1;
|
||||
PURGE BINARY LOGS TO 'binlog-000001.ibb';
|
||||
ERROR HY000: A purgeable log is in use, will not purge
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Note 1375 Binary log 'binlog-000000.ibb' is not purged because less than 'slave_connections_needed_for_purge' slaves have processed it
|
||||
Error 1378 A purgeable log is in use, will not purge
|
||||
SET GLOBAL slave_connections_needed_for_purge= 0;
|
||||
PURGE BINARY LOGS TO 'binlog-000001.ibb';
|
||||
ERROR HY000: A purgeable log is in use, will not purge
|
||||
|
||||
@@ -65,11 +65,6 @@ DROP TABLE t1, t2;
|
||||
# Test purge by size
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(2048)) ENGINE=InnoDB;
|
||||
|
||||
SET @old_min_slaves= @@GLOBAL.slave_connections_needed_for_purge;
|
||||
SET GLOBAL slave_connections_needed_for_purge= 1;
|
||||
--error ER_LOG_IN_USE
|
||||
PURGE BINARY LOGS TO 'binlog-000001.ibb';
|
||||
SHOW WARNINGS;
|
||||
SET GLOBAL slave_connections_needed_for_purge= 0;
|
||||
--error ER_LOG_IN_USE
|
||||
PURGE BINARY LOGS TO 'binlog-000001.ibb';
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
SET @@global.binlog_expire_logs_seconds= 0;
|
||||
SET @@global.max_binlog_total_size= 0;
|
||||
SET @@global.slave_connections_needed_for_purge= 1;
|
||||
SELECT @@global.slave_connections_needed_for_purge;
|
||||
@@global.slave_connections_needed_for_purge
|
||||
1
|
||||
SELECT @@global.binlog_expire_logs_seconds, @@global.max_binlog_total_size;
|
||||
@@global.binlog_expire_logs_seconds @@global.max_binlog_total_size
|
||||
0 0
|
||||
# No replica has ever connected:
|
||||
SELECT COUNT(*) AS dump_threads FROM information_schema.PROCESSLIST
|
||||
WHERE COMMAND = 'Binlog Dump';
|
||||
dump_threads
|
||||
0
|
||||
RESET MASTER;
|
||||
#
|
||||
# Part 1 (control). Nothing has attempted a purge yet, so no refusal is
|
||||
# cached, and the interactive purge correctly ignores the slave's guard.
|
||||
#
|
||||
FLUSH BINARY LOGS;
|
||||
FLUSH BINARY LOGS;
|
||||
FLUSH BINARY LOGS;
|
||||
show binary logs;
|
||||
Log_name File_size
|
||||
binlog-000000.ibb #
|
||||
binlog-000001.ibb #
|
||||
binlog-000002.ibb #
|
||||
binlog-000003.ibb #
|
||||
binlog-000004.ibb #
|
||||
PURGE BINARY LOGS TO 'binlog-000002.ibb';
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
show binary logs;
|
||||
Log_name File_size
|
||||
binlog-000002.ibb #
|
||||
binlog-000003.ibb #
|
||||
binlog-000004.ibb #
|
||||
#
|
||||
# Part 2. Let one automatic purge be refused, then try PURGE that must
|
||||
# be effective on the fixed server.
|
||||
#
|
||||
FLUSH BINARY LOGS;
|
||||
FLUSH BINARY LOGS;
|
||||
FLUSH BINARY LOGS;
|
||||
show binary logs;
|
||||
Log_name File_size
|
||||
binlog-000002.ibb #
|
||||
binlog-000003.ibb #
|
||||
binlog-000004.ibb #
|
||||
binlog-000005.ibb #
|
||||
binlog-000006.ibb #
|
||||
binlog-000007.ibb #
|
||||
# Let the files age past binlog_expire_logs_seconds: purge_logs_before_date
|
||||
# skips can_purge_log() for any file whose mtime is not older than that.
|
||||
SET @@global.binlog_expire_logs_seconds= 1;
|
||||
# Rotating attempts an automatic purge, which the guard refuses. That
|
||||
# refusal is what populates the cache.
|
||||
FLUSH BINARY LOGS;
|
||||
# Now the interactive purge. It should behave exactly as in part 1.
|
||||
PURGE BINARY LOGS TO 'binlog-000005.ibb';
|
||||
# On affected versions this reports binlog-000002.ibb as the current active
|
||||
# binlog, while binlog-000007.ibb is active:
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
show binary logs;
|
||||
Log_name File_size
|
||||
binlog-000005.ibb #
|
||||
binlog-000006.ibb #
|
||||
binlog-000007.ibb #
|
||||
binlog-000008.ibb #
|
||||
SET @@global.binlog_expire_logs_seconds = $save_binlog_expire_logs_seconds;
|
||||
SET @@global.max_binlog_total_size= $save_max_binlog_total_size;
|
||||
SET @@global.slave_connections_needed_for_purge= $save_slave_connections_needed_for_purge;
|
||||
RESET MASTER;
|
||||
@@ -0,0 +1,4 @@
|
||||
--let $binlog_in_engine= 1
|
||||
--source suite/binlog/t/binlog_purge_stale_refusal_cache.test
|
||||
# This is last so we override the --log-bin server option correctly.
|
||||
--source include/have_innodb_binlog.inc
|
||||
@@ -838,22 +838,9 @@ bool purge_master_logs(THD* thd, const char* to_log)
|
||||
handler_binlog_purge_info purge_info;
|
||||
auto p= engine_binlog_in_use();
|
||||
purge_info.limit_file_no= p.first;
|
||||
uint num_dump_threads= p.second;
|
||||
if (num_dump_threads < slave_connections_needed_for_purge)
|
||||
{
|
||||
/*
|
||||
Prevent purging any file.
|
||||
We need to do it this way, since we have to call into the engine to let
|
||||
it check if there are any files to potentially purge. If there are, we
|
||||
want to give an error that purge was not possible. But if there were no
|
||||
files to purge in any case, we do not want to give any error.
|
||||
*/
|
||||
purge_info.limit_file_no= 0;
|
||||
purge_info.nonpurge_reason= "less than "
|
||||
"'slave_connections_needed_for_purge' slaves have processed it";
|
||||
}
|
||||
else
|
||||
purge_info.nonpurge_reason= nullptr;
|
||||
uint num_dump_threads __attribute__((unused))= p.second;
|
||||
/* Interactive purge ignores slave_connections_needed_for_purge */
|
||||
purge_info.nonpurge_reason= nullptr;
|
||||
purge_info.nonpurge_filename[0]= '\0';
|
||||
purge_info.purge_by_date= false;
|
||||
purge_info.limit_date= (time_t)0;
|
||||
@@ -901,15 +888,9 @@ bool purge_master_logs_before_date(THD* thd, time_t purge_time)
|
||||
handler_binlog_purge_info purge_info;
|
||||
auto p= engine_binlog_in_use();
|
||||
purge_info.limit_file_no= p.first;
|
||||
uint num_dump_threads= p.second;
|
||||
if (num_dump_threads < slave_connections_needed_for_purge)
|
||||
{
|
||||
purge_info.limit_file_no= 0;
|
||||
purge_info.nonpurge_reason= "less than "
|
||||
"'slave_connections_needed_for_purge' slaves have processed it";
|
||||
}
|
||||
else
|
||||
purge_info.nonpurge_reason= nullptr;
|
||||
uint num_dump_threads __attribute__((unused))= p.second;
|
||||
/* Interactive purge ignores slave_connections_needed_for_purge */
|
||||
purge_info.nonpurge_reason= nullptr;
|
||||
purge_info.nonpurge_filename[0]= '\0';
|
||||
purge_info.purge_by_date= true;
|
||||
purge_info.limit_date= purge_time;
|
||||
|
||||
Reference in New Issue
Block a user