summaryrefslogtreecommitdiff
path: root/sql/lock.cc
diff options
context:
space:
mode:
authorunknown <svoj@mysql.com/april.(none)>2007-07-25 19:56:17 +0500
committerunknown <svoj@mysql.com/april.(none)>2007-07-25 19:56:17 +0500
commit4537a0c9e97e19b34bd4cc1969ce388f4ac48ccc (patch)
tree3d9b4b3023946a2cde552f86f3b6f13275eb21d6 /sql/lock.cc
parent363a2f765c044e9442423692208d12635ec63eb0 (diff)
downloadmariadb-git-4537a0c9e97e19b34bd4cc1969ce388f4ac48ccc.tar.gz
BUG#29806 - binlog_innodb.test creates a server log
Stopping mysql server could result in an entry in mysql error file: "InnoDB: Error: MySQL is freeing a thd". This happened because InnoDB assumes that the server will never call external_lock(F_UNLCK) in case external_lock(READ/WRITE) failed. Prior to this patch we haven't had strict definition whether external_lock(F_UNLCK) must be called in case external_lock(READ/WRITE) fails. This patch states that we never call external_lock(F_UNLCK) in case external_lock(READ/WRITE) fails. mysql-test/suite/binlog/t/disabled.def: Re-enabled binlog_innodb and binlog_killed tests. sql/ha_ndbcluster.cc: Restore handler state in case external_lock() failed. sql/ha_partition.cc: Do not call external_lock(F_UNLCK) in case external_lock(READ/WRITE) failed. sql/lock.cc: Do not call external_lock(F_UNLCK) in case external_lock(READ/WRITE) failed. storage/myisammrg/myrg_locking.c: Restore handler state in case external_lock() failed.
Diffstat (limited to 'sql/lock.cc')
-rw-r--r--sql/lock.cc8
1 files changed, 7 insertions, 1 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index 50922a682a2..a1985f0b217 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -60,6 +60,11 @@
- When calling UNLOCK TABLES we call mysql_unlock_tables() for all
tables used in LOCK TABLES
+ If table_handler->external_lock(thd, locktype) fails, we call
+ table_handler->external_lock(thd, F_UNLCK) for each table that was locked,
+ excluding one that caused failure. That means handler must cleanup itself
+ in case external_lock() fails.
+
TODO:
Change to use my_malloc() ONLY when using LOCK TABLES command or when
we are forced to use mysql_lock_merge.
@@ -269,8 +274,9 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
if ((error=(*tables)->file->ha_external_lock(thd,lock_type)))
{
print_lock_error(error, (*tables)->file->table_type());
- for (; i-- ; tables--)
+ while (--i)
{
+ tables--;
(*tables)->file->ha_external_lock(thd, F_UNLCK);
(*tables)->current_lock=F_UNLCK;
}