#At file:///C:/source/bzr/mysql-6.0-bug-39924/ based on revid:jorgen.loland@stripped
2703 Chuck Bell 2009-04-30
BUG#39924 : Not possible to use backup logs after BACKUP has been interrupted
This patch corrects the problem of not being able to write
to the backup logs when a backup or restore is killed.
modified:
mysql-test/suite/backup/r/backup_logs.result
mysql-test/suite/backup/t/backup_logs.test
sql/backup/kernel.cc
sql/log.cc
per-file messages:
mysql-test/suite/backup/r/backup_logs.result
New result file.
mysql-test/suite/backup/t/backup_logs.test
New test case to show that backup logs complete writing
of error condition after operation is killed.
sql/backup/kernel.cc
Added debug insertion to simulate killing a backup
or restore operation.
sql/log.cc
Added override code to allow backup log to continue writing
if the backup or restore operation is killed.
=== modified file 'mysql-test/suite/backup/r/backup_logs.result'
--- a/mysql-test/suite/backup/r/backup_logs.result 2009-02-26 22:19:09 +0000
+++ b/mysql-test/suite/backup/r/backup_logs.result 2009-05-01 00:16:39 +0000
@@ -397,6 +397,53 @@ SET @@global.backup_history_log_file = r
ERROR HY000: The path specified for backup_history_log_file is too long.
SET @@global.backup_history_log_file = DEFAULT;
SET global max_allowed_packet=DEFAULT;
+#
+# Test to see if logs successfully written after command is
+# killed.
+#
+SET SESSION debug="+d,kill_backup";
+The backup id for this command should be 506.
+BACKUP DATABASE backup_logs to 'backup_logs_orig_intr.bak';
+ERROR 70100: Query execution was interrupted
+FLUSH BACKUP LOGS;
+Turn off debugging session.
+SET SESSION debug="-d";
+Show error state.
+SELECT backup_id, backup_state FROM mysql.backup_history WHERE backup_id = 506;
+backup_id 506
+backup_state error
+Show error state.
+SELECT backup_id, notes FROM mysql.backup_progress WHERE backup_id = 506;
+backup_id 506
+notes starting
+backup_id 506
+notes running
+backup_id 506
+notes cancel
+backup_id 506
+notes error
+# Now try restore.
+SET SESSION debug="+d,kill_restore";
+The backup id for this command should be 507.
+RESTORE FROM 'backup_logs_orig.bak' OVERWRITE;
+ERROR 70100: Query execution was interrupted
+FLUSH BACKUP LOGS;
+Turn off debugging session.
+SET SESSION debug="-d";
+Show error state.
+SELECT backup_id, backup_state FROM mysql.backup_history WHERE backup_id = 507;
+backup_id 507
+backup_state error
+Show error state.
+SELECT backup_id, notes FROM mysql.backup_progress WHERE backup_id = 507;
+backup_id 507
+notes starting
+backup_id 507
+notes running
+backup_id 507
+notes cancel
+backup_id 507
+notes error
SET @@global.log_backup_output = 'TABLE';
DROP USER 'tom'@'localhost';
SET DEBUG_SYNC= 'reset';
=== modified file 'mysql-test/suite/backup/t/backup_logs.test'
--- a/mysql-test/suite/backup/t/backup_logs.test 2009-03-09 14:00:03 +0000
+++ b/mysql-test/suite/backup/t/backup_logs.test 2009-05-01 00:16:39 +0000
@@ -516,6 +516,46 @@ SET @@global.backup_history_log_file = D
SET global max_allowed_packet=DEFAULT;
+--echo #
+--echo # Test to see if logs successfully written after command is
+--echo # killed.
+--echo #
+SET SESSION debug="+d,kill_backup";
+
+--echo The backup id for this command should be 506.
+--error ER_QUERY_INTERRUPTED
+BACKUP DATABASE backup_logs to 'backup_logs_orig_intr.bak';
+
+FLUSH BACKUP LOGS;
+
+--echo Turn off debugging session.
+SET SESSION debug="-d";
+
+--echo Show error state.
+--query_vertical SELECT backup_id, backup_state FROM mysql.backup_history WHERE backup_id = 506
+
+--echo Show error state.
+--query_vertical SELECT backup_id, notes FROM mysql.backup_progress WHERE backup_id = 506
+
+--echo # Now try restore.
+
+SET SESSION debug="+d,kill_restore";
+
+--echo The backup id for this command should be 507.
+--error ER_QUERY_INTERRUPTED
+RESTORE FROM 'backup_logs_orig.bak' OVERWRITE;
+
+FLUSH BACKUP LOGS;
+
+--echo Turn off debugging session.
+SET SESSION debug="-d";
+
+--echo Show error state.
+--query_vertical SELECT backup_id, backup_state FROM mysql.backup_history WHERE backup_id = 507
+
+--echo Show error state.
+--query_vertical SELECT backup_id, notes FROM mysql.backup_progress WHERE backup_id = 507
+
#
# Cleanup.
#
=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc 2009-04-08 12:33:46 +0000
+++ b/sql/backup/kernel.cc 2009-05-01 00:16:39 +0000
@@ -194,6 +194,8 @@ execute_backup_command(THD *thd,
info->close(); // close catalogue after filling it with objects to backup
+ DBUG_EXECUTE_IF("kill_backup", thd->killed= THD::KILL_QUERY;);
+
if (res || !info->is_valid())
DBUG_RETURN(send_error(context, ER_BACKUP_BACKUP_PREPARE));
@@ -227,6 +229,8 @@ execute_backup_command(THD *thd,
DEBUG_SYNC(thd, "after_backup_start_restore");
+ DBUG_EXECUTE_IF("kill_restore", thd->killed= THD::KILL_QUERY;);
+
res= context.do_restore(overwrite);
DEBUG_SYNC(thd, "restore_before_end");
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2009-04-22 22:12:25 +0000
+++ b/sql/log.cc 2009-05-01 00:16:39 +0000
@@ -794,6 +794,7 @@ bool Log_to_csv_event_handler::
bool save_time_zone_used;
char *host= current_thd->security_ctx->host; // host name
char *user= current_thd->security_ctx->user; // user name
+ THD::killed_state saved_killed_state= THD::NOT_KILLED;
/*
Turn the binlog off and don't replicate the
@@ -812,10 +813,22 @@ bool Log_to_csv_event_handler::
table_list.db= MYSQL_SCHEMA_NAME.str;
table_list.db_length= MYSQL_SCHEMA_NAME.length;
+ /*
+ We need to override the check for a killed thread in the
+ open_performance_schema_table() to allow the backup log
+ to be written even if backup is killed in the middle of
+ execution.
+ */
+ saved_killed_state= thd->killed;
+ if (thd->killed)
+ thd->killed= THD::NOT_KILLED;
+
if (!(table= open_performance_schema_table(thd, & table_list,
& open_tables_backup)))
goto err;
+ thd->killed= saved_killed_state;
+
need_close= TRUE;
if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) ||
@@ -1025,6 +1038,7 @@ bool Log_to_csv_event_handler::
bool need_rnd_end= FALSE;
Open_tables_state open_tables_backup;
bool save_time_zone_used;
+ THD::killed_state saved_killed_state= THD::NOT_KILLED;
save_time_zone_used= thd->time_zone_used;
@@ -1037,10 +1051,22 @@ bool Log_to_csv_event_handler::
table_list.db= MYSQL_SCHEMA_NAME.str;
table_list.db_length= MYSQL_SCHEMA_NAME.length;
+ /*
+ We need to override the check for a killed thread in the
+ open_performance_schema_table() to allow the backup log
+ to be written even if backup is killed in the middle of
+ execution.
+ */
+ saved_killed_state= thd->killed;
+ if (thd->killed)
+ thd->killed= THD::NOT_KILLED;
+
if (!(table= open_performance_schema_table(thd, & table_list,
& open_tables_backup)))
goto err;
+ thd->killed= saved_killed_state;
+
need_close= TRUE;
if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) ||