From 7768ccbb54114e8ca35287fbcb14615f81a88783 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 4 Mar 2010 10:18:06 +0000 Subject: BUG#51055: Replication failure on duplicate key + traditional SQL mode When the master was executing in sql_mode='traditional' (which implies that really_abort_on_warning returns TRUE - because of MODE_STRICT_ALL_TABLES), the error code (ER_DUP_ENTRY in the reported case) was not being set in the Query_log_event. Therefore, even if a failure was to be expected when replaying the statement on the slave, a failure would occur, because the Query_log_event was not transporting the expected error code, but 0 instead. This was because when the master was getting the error code to set it in the Query_log_event, the executing thread would be assumed to have been killed: THD::killed==THD::KILL_BAD_DATA. This would make the error code fetch routine not to check thd->main_da.sql_errno(), but instead the thd->killed value. What's more, is that the server would thd->killed value if thd->killed == THD::KILL_BAD_DATA and return 0 instead. So this is a double inconsistency, as the we should not even check thd->killed but rather thd->main_da.sql_errno(). We fix this by extending the condition used to choose whether to check the thd->main_da.sql_errno() or thd->killed, so that it takes into consideration the case when: thd->killed==THD::KILL_BAD_DATA. --- sql/log.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index b7313a988c4..b75650cfec7 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4679,7 +4679,7 @@ int query_error_code(THD *thd, bool not_killed) { int error; - if (not_killed) + if (not_killed || (thd->killed == THD::KILL_BAD_DATA)) { error= thd->is_error() ? thd->main_da.sql_errno() : 0; -- cgit v1.2.1