diff options
author | unknown <evgen@moonbone.local> | 2006-04-25 13:04:39 +0400 |
---|---|---|
committer | unknown <evgen@moonbone.local> | 2006-04-25 13:04:39 +0400 |
commit | 08f930375b5b393362f744aacd29197bb7b6ea57 (patch) | |
tree | 3fec1af8e114a3cc4505bed53230c19ce5c41b70 /sql/lock.cc | |
parent | c984135242752a2bac8b32bbafcd8a45b2423121 (diff) | |
parent | 6692dcf7185518743d9dabefd22ef569d90667e6 (diff) | |
download | mariadb-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.cc | 56 |
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 |