summaryrefslogtreecommitdiff
path: root/sql/lock.cc
diff options
context:
space:
mode:
authorunknown <evgen@moonbone.local>2006-04-25 13:04:39 +0400
committerunknown <evgen@moonbone.local>2006-04-25 13:04:39 +0400
commit08f930375b5b393362f744aacd29197bb7b6ea57 (patch)
tree3fec1af8e114a3cc4505bed53230c19ce5c41b70 /sql/lock.cc
parentc984135242752a2bac8b32bbafcd8a45b2423121 (diff)
parent6692dcf7185518743d9dabefd22ef569d90667e6 (diff)
downloadmariadb-git-08f930375b5b393362f744aacd29197bb7b6ea57.tar.gz
Manually merged
client/mysql.cc: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/func_gconcat.result: Auto merged mysql-test/t/rpl_relayrotate.test: Auto merged mysys/mf_keycache.c: Auto merged BitKeeper/deleted/.del-innodb_unsafe_binlog-master.opt~9cbe1bb3d8696c5b: Auto merged mysql-test/t/rpl_stm_until.test: Auto merged sql/item_func.cc: Auto merged sql/lock.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_union.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/unireg.h: Auto merged storage/ndb/src/kernel/SimBlockList.cpp: Auto merged storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp: Auto merged
Diffstat (limited to 'sql/lock.cc')
-rw-r--r--sql/lock.cc56
1 files changed, 54 insertions, 2 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index 24a6e23e7ad..5a6cd58dd56 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -78,6 +78,7 @@ extern HASH open_cache;
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
uint flags, TABLE **write_locked);
+static void reset_lock_data(MYSQL_LOCK *sql_lock);
static int lock_external(THD *thd, TABLE **table,uint count);
static int unlock_external(THD *thd, TABLE **table,uint count);
static void print_lock_error(int error, const char *);
@@ -135,12 +136,16 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
*/
if (wait_if_global_read_lock(thd, 1, 1))
{
+ /* Clear the lock type of all lock data to avoid reusage. */
+ reset_lock_data(sql_lock);
my_free((gptr) sql_lock,MYF(0));
sql_lock=0;
break;
- }
+ }
if (thd->version != refresh_version)
{
+ /* Clear the lock type of all lock data to avoid reusage. */
+ reset_lock_data(sql_lock);
my_free((gptr) sql_lock,MYF(0));
goto retry;
}
@@ -150,6 +155,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
if (lock_external(thd, tables, count))
{
+ /* Clear the lock type of all lock data to avoid reusage. */
+ reset_lock_data(sql_lock);
my_free((gptr) sql_lock,MYF(0));
sql_lock=0;
break;
@@ -720,7 +727,10 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
*write_lock_used=table;
if (table->db_stat & HA_READ_ONLY)
{
- my_error(ER_OPEN_AS_READONLY, MYF(0), table->alias);
+ my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias);
+ /* Clear the lock type of the lock data that are stored already. */
+ sql_lock->lock_count= locks - sql_lock->locks;
+ reset_lock_data(sql_lock);
my_free((gptr) sql_lock,MYF(0));
DBUG_RETURN(0);
}
@@ -745,6 +755,48 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
}
+/*
+ Reset lock type in lock data.
+
+ SYNOPSIS
+ reset_lock_data()
+ sql_lock The MySQL lock.
+
+ DESCRIPTION
+
+ After a locking error we want to quit the locking of the table(s).
+ The test case in the bug report for Bug #18544 has the following
+ cases: 1. Locking error in lock_external() due to InnoDB timeout.
+ 2. Locking error in get_lock_data() due to missing write permission.
+ 3. Locking error in wait_if_global_read_lock() due to lock conflict.
+
+ In all these cases we have already set the lock type into the lock
+ data of the open table(s). If the table(s) are in the open table
+ cache, they could be reused with the non-zero lock type set. This
+ could lead to ignoring a different lock type with the next lock.
+
+ Clear the lock type of all lock data. This ensures that the next
+ lock request will set its lock type properly.
+
+ RETURN
+ void
+*/
+
+static void reset_lock_data(MYSQL_LOCK *sql_lock)
+{
+ THR_LOCK_DATA **ldata;
+ THR_LOCK_DATA **ldata_end;
+
+ for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count;
+ ldata < ldata_end;
+ ldata++)
+ {
+ /* Reset lock type. */
+ (*ldata)->type= TL_UNLOCK;
+ }
+}
+
+
/*****************************************************************************
Lock table based on the name.
This is used when we need total access to a closed, not open table