mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Bug #35675 reset master finds assert if a binlog file can not be deleted
If a binlog file is manually replaced with a namesake directory the internal purging did not handle the error of deleting the file so that eventually a post-execution guards fires an assert. Fixed with reusing a snippet of code for bug@18199 to tolerate lack of the file but no other error at an attempt to delete it. The same applied to the index file deletion. The cset carries pieces of manual merging. mysql-test/r/binlog_index.result: new results mysql-test/r/ctype_big5.result: results changed mysql-test/suite/binlog/r/binlog_auto_increment_bug33029.result: new results mysql-test/suite/binlog/r/binlog_stm_blackhole.result: new results mysql-test/suite/binlog/t/binlog_auto_increment_bug33029.test: cleanup. still todo: to let the test run multiple times w/o restarting the server (just ./mtr test) mysql-test/suite/rpl/r/rpl_stm_auto_increment_bug33029.result: results changed mysql-test/suite/rpl/t/rpl_stm_auto_increment_bug33029.test: guarding the test with statement format condition as the logics of the test requires sql/log.cc: two changes. One for the bug, other manual merge. The bug change needs MYF(0) to pass to my_delete because not all error out of the function are critical. The finer check is done on the caller of my_delete similarly how it was implemented for bug@18199 fixes. Non-existance of a file is not a critical error. sql/sql_class.cc: manual merge, removing extra automatically brought hunk.
This commit is contained in:
parent
6630d2e18c
commit
2a001d5389
9 changed files with 81 additions and 34 deletions
|
@ -9,7 +9,7 @@ master-bin.000003 #
|
|||
master-bin.000004 #
|
||||
purge binary logs TO 'master-bin.000004';
|
||||
Warnings:
|
||||
Warning 1476 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found
|
||||
Warning 1611 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found
|
||||
*** must show a list starting from the 'TO' argument of PURGE ***
|
||||
show binary logs;
|
||||
Log_name File_size
|
||||
|
@ -20,7 +20,7 @@ flush logs;
|
|||
flush logs;
|
||||
*** must be a warning master-bin.000001 was not found ***
|
||||
Warnings:
|
||||
Warning 1476 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found
|
||||
Warning 1611 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found
|
||||
*** must show one record, of the active binlog, left in the index file after PURGE ***
|
||||
show binary logs;
|
||||
Log_name File_size
|
||||
|
|
|
@ -78,8 +78,8 @@ level smallint unsigned);
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`name` varchar(10) default NULL,
|
||||
`level` smallint(5) unsigned default NULL
|
||||
`name` varchar(10) DEFAULT NULL,
|
||||
`level` smallint(5) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=big5
|
||||
insert into t1 values ('string',1);
|
||||
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
|
||||
|
|
|
@ -36,3 +36,4 @@ DROP PROCEDURE IF EXISTS p1;
|
|||
DROP PROCEDURE IF EXISTS p2;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP TRIGGER IF EXISTS tr1;
|
||||
stop slave sql_thread;
|
||||
|
|
|
@ -172,6 +172,7 @@ master-bin.000001 # Query # # use `test`; BEGIN
|
|||
master-bin.000001 # Query # # use `test`; insert into t1 values(1)
|
||||
master-bin.000001 # Query # # use `test`; COMMIT
|
||||
drop table if exists t1;
|
||||
reset master;
|
||||
create table t1 (a int auto_increment, primary key (a)) engine=blackhole;
|
||||
insert into t1 values (11), (NULL), (NULL), (NULL);
|
||||
set insert_id= 3;
|
||||
|
@ -181,10 +182,16 @@ insert into t1 values (55), (NULL);
|
|||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # use `test`; create table t1 (a int auto_increment, primary key (a)) engine=blackhole
|
||||
master-bin.000001 # Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 # Intvar 1 # INSERT_ID=1
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values (11), (NULL), (NULL), (NULL)
|
||||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 # Intvar 1 # INSERT_ID=3
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL), (33), (NULL)
|
||||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 # Intvar 1 # INSERT_ID=5
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values (55), (NULL)
|
||||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
drop table t1;
|
||||
|
|
|
@ -45,3 +45,10 @@ DROP PROCEDURE IF EXISTS p2;
|
|||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP TRIGGER IF EXISTS tr1;
|
||||
enable_warnings;
|
||||
|
||||
remove_file $MYSQLTEST_VARDIR/master-data/slave-relay-bin.000001;
|
||||
remove_file $MYSQLTEST_VARDIR/master-data/slave-relay-bin.index;
|
||||
stop slave sql_thread;
|
||||
let $keep_connection=1;
|
||||
source include/wait_for_slave_sql_to_stop.inc;
|
||||
|
||||
|
|
|
@ -64,7 +64,9 @@ master-bin.000001 # Intvar # # INSERT_ID=9
|
|||
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (NULL)
|
||||
master-bin.000001 # Intvar # # INSERT_ID=10
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (NULL)
|
||||
master-bin.000001 # Intvar # # INSERT_ID=1
|
||||
master-bin.000001 # Query # # use `test`; DELETE FROM t1 WHERE id = 1
|
||||
master-bin.000001 # Intvar # # INSERT_ID=2
|
||||
master-bin.000001 # Query # # use `test`; DELETE FROM t1 WHERE id = 2
|
||||
master-bin.000001 # Query # # use `test`; DELETE FROM t2 WHERE id = 1
|
||||
master-bin.000001 # Query # # use `test`; DELETE FROM t2 WHERE id = 2
|
||||
|
@ -100,7 +102,9 @@ show binlog events from <binlog_start>;
|
|||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Intvar # # INSERT_ID=11
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (NULL)
|
||||
master-bin.000001 # Intvar # # INSERT_ID=3
|
||||
master-bin.000001 # Query # # use `test`; DELETE FROM t1 WHERE id = f1(3)
|
||||
master-bin.000001 # Intvar # # INSERT_ID=12
|
||||
master-bin.000001 # Query # # use `test`; DELETE FROM t1 WHERE id = f1(4)
|
||||
master-bin.000001 # Query # # use `test`; DELETE FROM t2 WHERE id = 3
|
||||
master-bin.000001 # Query # # use `test`; DELETE FROM t2 WHERE id = 4
|
|
@ -8,6 +8,7 @@
|
|||
# value might be associated with these statement, which could cause
|
||||
# duplicate entry error and stop the slave.
|
||||
|
||||
source include/have_binlog_format_statement.inc;
|
||||
source include/master-slave.inc;
|
||||
|
||||
--disable_warnings
|
74
sql/log.cc
74
sql/log.cc
|
@ -2746,14 +2746,62 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
my_delete_allow_opened(linfo.log_file_name, MYF(MY_WME));
|
||||
if ((error= my_delete_allow_opened(linfo.log_file_name, MYF(0))) != 0)
|
||||
{
|
||||
if (my_errno == ENOENT)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
|
||||
linfo.log_file_name);
|
||||
sql_print_information("Failed to delete file '%s'",
|
||||
linfo.log_file_name);
|
||||
my_errno= 0;
|
||||
error= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
ER_BINLOG_PURGE_FATAL_ERR,
|
||||
"a problem with deleting %s; "
|
||||
"consider examining correspondence "
|
||||
"of your binlog index file "
|
||||
"to the actual binlog files",
|
||||
linfo.log_file_name);
|
||||
error= 1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (find_next_log(&linfo, 0))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Start logging with a new file */
|
||||
close(LOG_CLOSE_INDEX);
|
||||
my_delete_allow_opened(index_file_name, MYF(MY_WME)); // Reset (open will update)
|
||||
if ((error= my_delete_allow_opened(index_file_name, MYF(0)))) // Reset (open will update)
|
||||
{
|
||||
if (my_errno == ENOENT)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
|
||||
index_file_name);
|
||||
sql_print_information("Failed to delete file '%s'",
|
||||
index_file_name);
|
||||
my_errno= 0;
|
||||
error= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
ER_BINLOG_PURGE_FATAL_ERR,
|
||||
"a problem with deleting %s; "
|
||||
"consider examining correspondence "
|
||||
"of your binlog index file "
|
||||
"to the actual binlog files",
|
||||
index_file_name);
|
||||
error= 1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!thd->slave_thread)
|
||||
need_start_event=1;
|
||||
if (!open_index_file(index_file_name, 0))
|
||||
|
@ -2913,6 +2961,7 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
|
|||
0 ok
|
||||
@retval
|
||||
LOG_INFO_EOF to_log not found
|
||||
LOG_INFO_EMFILE too many files opened
|
||||
LOG_INFO_FATAL if any other than ENOENT error from
|
||||
my_stat() or my_delete()
|
||||
*/
|
||||
|
@ -3004,28 +3053,19 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
|
|||
"of your binlog index file "
|
||||
"to the actual binlog files",
|
||||
log_info.log_file_name);
|
||||
if (my_errno == EMFILE)
|
||||
{
|
||||
DBUG_PRINT("info",
|
||||
("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
|
||||
error= LOG_INFO_EMFILE;
|
||||
}
|
||||
error= LOG_INFO_FATAL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
It's not fatal if we can't delete a log file ;
|
||||
if we could delete it, take its size into account
|
||||
*/
|
||||
DBUG_PRINT("info",("purging %s",log_info.log_file_name));
|
||||
if (!my_delete(log_info.log_file_name, MYF(0)) && decrease_log_space)
|
||||
*decrease_log_space-= file_size;
|
||||
|
||||
ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
|
||||
if (current_thd->is_slave_error) {
|
||||
DBUG_PRINT("info",("slave error: %d", current_thd->is_slave_error));
|
||||
if (my_errno == EMFILE) {
|
||||
DBUG_PRINT("info",("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
|
||||
ret = LOG_INFO_EMFILE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (find_next_log(&log_info, 0) || exit_loop)
|
||||
break;
|
||||
|
|
|
@ -1069,19 +1069,6 @@ bool THD::store_globals()
|
|||
|
||||
void THD::cleanup_after_query()
|
||||
{
|
||||
last_insert_id_used= FALSE;
|
||||
if (clear_next_insert_id)
|
||||
{
|
||||
clear_next_insert_id= 0;
|
||||
next_insert_id= 0;
|
||||
|
||||
/*
|
||||
BUG#33029, if one statement in a SP set this member to 1, all
|
||||
statment after this statement in the SP would be considered used
|
||||
INSERT_ID value, reset this member after each query to fix this.
|
||||
*/
|
||||
insert_id_used= 0;
|
||||
}
|
||||
/*
|
||||
Reset rand_used so that detection of calls to rand() will save random
|
||||
seeds if needed by the slave.
|
||||
|
|
Loading…
Reference in a new issue