From 094a1f1e58c09a1df922aeff942712c2c8be9914 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 20 May 2010 10:39:02 +0300 Subject: [PATCH] Merge from mysql-trunk-innodb into mysql-5.1-innodb/storage/innobase: ------------------------------------------------------------ revno: 3094 revision-id: vasil.dimov@oracle.com-20100513074652-0cvlhgkesgbb2bfh parent: vasil.dimov@oracle.com-20100512173700-byf8xntxjur1hqov committer: Vasil Dimov branch nick: mysql-trunk-innodb timestamp: Thu 2010-05-13 10:46:52 +0300 message: Followup to Bug#51920, fix binlog.binlog_killed This is a followup to the fix of Bug#51920 Innodb connections in row lock wait ignore KILL until lock wait timeout in that fix (rb://279) the behavior was changed to honor when a trx is interrupted during lock wait, but the returned error code was still "lock wait timeout" when it should be "interrupted". This change fixes the non-deterministically failing test binlog.binlog_killed, that failed like this: binlog.binlog_killed 'stmt' [ fail ] Test ended at 2010-05-12 11:39:08 CURRENT_TEST: binlog.binlog_killed mysqltest: At line 208: query 'reap' failed with wrong errno 1205: 'Lock wait timeout exceeded; try restarting transaction', instead of 0... Approved by: Sunny Bains (rb://344) ------------------------------------------------------------ This merge is non-trivial since it has to introduce the DB_INTERRUPTED error code. Also revert vasil.dimov@oracle.com-20100408165555-9rpjh24o0sa9ad5y which adjusted the binlog.binlog_killed test to the new (wrong) behavior --- mysql-test/suite/binlog/t/binlog_killed.test | 2 +- storage/innobase/handler/ha_innodb.cc | 4 ++++ storage/innobase/include/db0err.h | 3 +++ storage/innobase/row/row0mysql.c | 1 + storage/innobase/srv/srv0srv.c | 10 +++++++--- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/binlog/t/binlog_killed.test b/mysql-test/suite/binlog/t/binlog_killed.test index ce6d344af32..e2db326129d 100644 --- a/mysql-test/suite/binlog/t/binlog_killed.test +++ b/mysql-test/suite/binlog/t/binlog_killed.test @@ -202,7 +202,7 @@ eval kill query $ID; rollback; connection con2; ---error 0,ER_QUERY_INTERRUPTED,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_QUERY_INTERRUPTED reap; # todo 1,2 above rollback; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f2a6c52ce7b..cf7ec4d6e6f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -759,6 +759,10 @@ convert_error_code_to_mysql( } else if (error == DB_UNSUPPORTED) { return(HA_ERR_UNSUPPORTED); + } else if (error == DB_INTERRUPTED) { + + my_error(ER_QUERY_INTERRUPTED, MYF(0)); + return(-1); } else { return(-1); // Unknown error } diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index ed7ce151718..b1461689d38 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -69,6 +69,9 @@ Created 5/24/1996 Heikki Tuuri a feature that it can't recoginize or work with e.g., FT indexes created by a later version of the engine. */ +#define DB_INTERRUPTED 49 /* the query has been interrupted with + "KILL QUERY N;" */ + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 20fb69499a1..b4ce31575c7 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -483,6 +483,7 @@ handle_new_error: } else if (err == DB_ROW_IS_REFERENCED || err == DB_NO_REFERENCED_ROW || err == DB_CANNOT_ADD_CONSTRAINT + || err == DB_INTERRUPTED || err == DB_TOO_MANY_CONCURRENT_TRXS) { if (savept) { /* Roll back the latest, possibly incomplete diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index a2eed3f171c..5b1184fb416 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1554,12 +1554,16 @@ srv_suspend_mysql_thread( mutex_exit(&kernel_mutex); - if (trx_is_interrupted(trx) - || (srv_lock_wait_timeout < 100000000 - && wait_time > (double)srv_lock_wait_timeout)) { + if (srv_lock_wait_timeout < 100000000 + && wait_time > (double)srv_lock_wait_timeout) { trx->error_state = DB_LOCK_WAIT_TIMEOUT; } + + if (trx_is_interrupted(trx)) { + + trx->error_state = DB_INTERRUPTED; + } #else /* UNIV_HOTBACKUP */ /* This function depends on MySQL code that is not included in InnoDB Hot Backup builds. Besides, this function should never