summaryrefslogtreecommitdiff
path: root/sql/lock.cc
diff options
context:
space:
mode:
authorunknown <mikael@c-870ae253.1238-1-64736c10.cust.bredbandsbolaget.se>2006-05-26 18:44:52 -0400
committerunknown <mikael@c-870ae253.1238-1-64736c10.cust.bredbandsbolaget.se>2006-05-26 18:44:52 -0400
commita29e59e00c772f08995d74978a7ded2e8d05c3e9 (patch)
tree4d641081368bfaa5b0730e596ca4f260d3739a47 /sql/lock.cc
parenteeea858c874ab563229e0ad3e49747d5a2c648a1 (diff)
downloadmariadb-git-a29e59e00c772f08995d74978a7ded2e8d05c3e9.tar.gz
BUG#19122: MySQL Server crashes when ALTER TABLE t1 REBUILD PARTITION on InnoDB table
mysql-test/r/partition.result: New test case sql/lock.cc: Added new flag to lock_table_name to ensure we get proper name lock even when we already have lock on table. sql/mysql_priv.h: Added new flag to lock_table_name to ensure we get proper name lock even when we already have lock on table. Added table_list to ALTER_PARTITION_PARAM_TYPE and changed some const char * to char* sql/sql_base.cc: Added new flag to lock_table_name to ensure we get proper name lock even when we already have lock on table. Added table_list to ALTER_PARTITION_PARAM_TYPE and changed some const char * to char* sql/sql_partition.cc: New methods to 1) Get a name lock even when we already have one 2) New method that unlocks table and closes the handlers. 3) Release name lock Integrated those new methods to ensure that handlers are unlocked and closed when drop or rename is called on them. There is still some work to update the comments to reflect the last changes.
Diffstat (limited to 'sql/lock.cc')
-rw-r--r--sql/lock.cc45
1 files changed, 29 insertions, 16 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index 5a6cd58dd56..3a0aa99218f 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -828,7 +828,7 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
if (wait_if_global_read_lock(thd, 0, 1))
DBUG_RETURN(1);
VOID(pthread_mutex_lock(&LOCK_open));
- if ((lock_retcode = lock_table_name(thd, table_list)) < 0)
+ if ((lock_retcode = lock_table_name(thd, table_list, TRUE)) < 0)
goto end;
if (lock_retcode && wait_for_locked_table_names(thd, table_list))
{
@@ -851,6 +851,7 @@ end:
lock_table_name()
thd Thread handler
table_list Lock first table in this list
+ check_in_use Do we need to check if table already in use by us
WARNING
If you are going to update the table, you should use
@@ -870,7 +871,7 @@ end:
> 0 table locked, but someone is using it
*/
-int lock_table_name(THD *thd, TABLE_LIST *table_list)
+int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
{
TABLE *table;
char key[MAX_DBKEY_LENGTH];
@@ -882,17 +883,22 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
key_length= create_table_def_key(thd, key, table_list, 0);
- /* Only insert the table if we haven't insert it already */
- for (table=(TABLE*) hash_first(&open_cache, (byte*)key, key_length, &state);
- table ;
- table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length, &state))
+ if (check_in_use)
{
- if (table->in_use == thd)
+ /* Only insert the table if we haven't insert it already */
+ for (table=(TABLE*) hash_first(&open_cache, (byte*)key,
+ key_length, &state);
+ table ;
+ table = (TABLE*) hash_next(&open_cache,(byte*) key,
+ key_length, &state))
{
- DBUG_PRINT("info", ("Table is in use"));
- table->s->version= 0; // Ensure no one can use this
- table->locked_by_name= 1;
- DBUG_RETURN(0);
+ if (table->in_use == thd)
+ {
+ DBUG_PRINT("info", ("Table is in use"));
+ table->s->version= 0; // Ensure no one can use this
+ table->locked_by_name= 1;
+ DBUG_RETURN(0);
+ }
}
}
/*
@@ -917,10 +923,17 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
my_free((gptr) table,MYF(0));
DBUG_RETURN(-1);
}
-
- /* Return 1 if table is in use */
- DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
- RTFC_NO_FLAG)));
+
+ if (!check_in_use)
+ {
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ /* Return 1 if table is in use */
+ DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
+ RTFC_NO_FLAG)));
+ }
}
@@ -1003,7 +1016,7 @@ bool lock_table_names(THD *thd, TABLE_LIST *table_list)
for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
{
int got_lock;
- if ((got_lock=lock_table_name(thd,lock_table)) < 0)
+ if ((got_lock=lock_table_name(thd,lock_table, TRUE)) < 0)
goto end; // Fatal error
if (got_lock)
got_all_locks=0; // Someone is using table