1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Patch changing how ALTER TABLE implementation handles table locking

and invalidation in the most general case (non-temporary table and
not simple RENAME or ENABLE/DISABLE KEYS or partitioning command).

See comment for sql/sql_table.cc for more information.

These changes are prerequisite for 5.1 version of fix for bug #23667
"CREATE TABLE LIKE is not isolated from alteration by other connections"
This commit is contained in:
dlenev@mockturtle.local
2007-05-19 10:49:56 +04:00
parent e4a3189c4f
commit b0dfdc2b83
9 changed files with 399 additions and 173 deletions

View File

@ -99,7 +99,6 @@ static bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
TABLE_LIST *table_desc, MEM_ROOT *mem_root);
static void close_old_data_files(THD *thd, TABLE *table, bool morph_locks,
bool send_refresh);
static bool reopen_table(TABLE *table);
static bool
has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables);
@ -681,7 +680,7 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
*/
static void close_handle_and_leave_table_as_lock(TABLE *table)
void close_handle_and_leave_table_as_lock(TABLE *table)
{
TABLE_SHARE *share, *old_share= table->s;
char *key_buff;
@ -2705,7 +2704,7 @@ TABLE *find_locked_table(THD *thd, const char *db,const char *table_name)
1 error. The old table object is not changed.
*/
static bool reopen_table(TABLE *table)
bool reopen_table(TABLE *table)
{
TABLE tmp;
bool error= 1;
@ -2788,27 +2787,55 @@ static bool reopen_table(TABLE *table)
}
/*
Used with ALTER TABLE:
Close all instanses of table when LOCK TABLES is in used;
Close first all instances of table and then reopen them
/**
@brief Close all instances of a table open by this thread and replace
them with exclusive name-locks.
@param thd Thread context
@param db Database name for the table to be closed
@param table_name Name of the table to be closed
@note This function assumes that if we are not under LOCK TABLES,
then there is only one table open and locked. This means that
the function probably has to be adjusted before it can be used
anywhere outside ALTER TABLE.
*/
bool close_data_tables(THD *thd,const char *db, const char *table_name)
void close_data_files_and_morph_locks(THD *thd, const char *db,
const char *table_name)
{
TABLE *table;
DBUG_ENTER("close_data_tables");
DBUG_ENTER("close_data_files_and_morph_locks");
safe_mutex_assert_owner(&LOCK_open);
if (thd->lock)
{
/*
If we are not under LOCK TABLES we should have only one table
open and locked so it makes sense to remove the lock at once.
*/
mysql_unlock_tables(thd, thd->lock);
thd->lock= 0;
}
/*
Note that open table list may contain a name-lock placeholder
for target table name if we process ALTER TABLE ... RENAME.
So loop below makes sense even if we are not under LOCK TABLES.
*/
for (table=thd->open_tables; table ; table=table->next)
{
if (!strcmp(table->s->table_name.str, table_name) &&
!strcmp(table->s->db.str, db))
{
mysql_lock_remove(thd, thd->locked_tables,table);
if (thd->locked_tables)
mysql_lock_remove(thd, thd->locked_tables, table);
table->open_placeholder= 1;
close_handle_and_leave_table_as_lock(table);
}
}
DBUG_RETURN(0); // For the future
DBUG_VOID_RETURN;
}