mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Backport of:
---------------------------------------------------------- revno: 2617.69.20 committer: Konstantin Osipov <kostja@sun.com> branch nick: 5.4-4284-1-assert timestamp: Thu 2009-08-13 18:29:55 +0400 message: WL#4284 "Transactional DDL locking" A review fix. Since WL#4284 implementation separated MDL_request and MDL_ticket, MDL_request becamse a utility object necessary only to get a ticket. Store it by-value in TABLE_LIST with the intent to merge MDL_request::key with table_list->table_name and table_list->db in future. Change the MDL subsystem to not require MDL_requests to stay around till close_thread_tables(). Remove the list of requests from the MDL context. Requests for shared metadata locks acquired in open_tables() are only used as a list in recover_from_failed_open_table_attempt(), which calls mdl_context.wait_for_locks() for this list. To keep such list for recover_from_failed_open_table_attempt(), introduce a context class (Open_table_context), that collects all requests. A lot of minor cleanups and simplications that became possible with this change. sql/event_db_repository.cc: Remove alloc_mdl_requests(). Now MDL_request instance is a member of TABLE_LIST, and init_one_table() initializes it. sql/ha_ndbcluster_binlog.cc: Remove now unnecessary declaration and initialization of binlog_mdl_request. sql/lock.cc: No need to allocate MDL requests in lock_table_names() now. sql/log.cc: Use init_one_table() method, remove alloc_mdl_requests(), which is now unnecessary. sql/log_event.cc: No need to allocate mdl_request separately now. Use init_one_table() method. sql/log_event_old.cc: Update to the new signature of close_tables_for_reopen(). sql/mdl.cc: Update try_acquire_exclusive_lock() to be more easy to use. Function lock_table_name_if_not_cached() has been removed. Make acquire_shared_lock() signature consistent with try_acquire_exclusive_lock() signature. Remove methods that are no longer used. Update comments. sql/mdl.h: Implement an assignment operator that doesn't copy MDL_key (MDL_key::operator= is private and should remain private). This is a hack to work-around assignment of TABLE_LIST by value in several places. Such assignments violate encapsulation, since only perform a shallow copy. In most cases these assignments are a hack on their own. sql/mysql_priv.h: Update signatures of close_thread_tables() and close_tables_for_reopen(). sql/sp.cc: Allocate TABLE_LIST in thd->mem_root. Use init_one_table(). sql/sp_head.cc: Use init_one_table(). Remove thd->locked_tables_root, it's no longer needed. sql/sql_acl.cc: Use init_mdl_requests() and init_one_table(). sql/sql_base.cc: Update to new signatures of try_acquire_shared_lock() and try_acquire_exclusive_lock(). Remove lock_table_name_if_not_cached(). Fix a bug in open_ltable() that would not return ER_LOCK_DEADLOCK in case of a failed lock_tables() and a multi-statement transaction. Fix a bug in open_and_lock_tables_derived() that would not return ER_LOCK_DEADLOCK in case of a multi-statement transaction and a failure of lock_tables(). Move assignment of enum_open_table_action to a method of Open_table_context, a new class that maintains information for backoff actions. Minor rearrangements of the code. Remove alloc_mdl_requests() in functions that work with system tables: instead the patch ensures that callers always initialize TABLE_LIST argument. sql/sql_class.cc: THD::locked_tables_root is no more. sql/sql_class.h: THD::locked_tables_root is no more. Add a declaration for Open_table_context class. sql/sql_delete.cc: Update to use the simplified MDL API. sql/sql_handler.cc: TABLE_LIST::mdl_request is stored by-value now. Ensure that mdl_request.ticket is NULL for every request that is passed into MDL, to satisfy MDL asserts. @ sql/sql_help.cc Function open_system_tables_for_read() no longer initializes mdl_requests. Move TABLE_LIST::mdl_request initialization closer to TABLE_LIST initialization. sql/sql_help.cc: Function open_system_tables_for_read() no longer initializes mdl_requests. Move TABLE_LIST::mdl_request initialization closer to TABLE_LIST initialization. sql/sql_insert.cc: Remove assignment by-value of TABLE_LIST in TABLEOP_HOOKS. We can't carry over a granted MDL ticket from one table list to another. sql/sql_parse.cc: Change alloc_mdl_requests() -> init_mdl_requests(). @todo We can remove init_mdl_requests() altogether in some places: all places that call add_table_to_list() already have mdl requests initialized. sql/sql_plugin.cc: Use init_one_table(). THD::locked_tables_root is no more. sql/sql_servers.cc: Use init_one_table(). sql/sql_show.cc: Update acquire_high_priority_shared_lock() to use TABLE_LIST::mdl_request rather than allocate an own. Fix get_trigger_table_impl() to use init_one_table(), check for out of memory, follow the coding style. sql/sql_table.cc: Update to work with TABLE_LIST::mdl_request by-value. Remove lock_table_name_if_not_cached(). The code that used to delegate to it is quite simple and concise without it now. sql/sql_udf.cc: Use init_one_table(). sql/sql_update.cc: Update to use the new signature of close_tables_for_reopen(). sql/table.cc: Move re-setting of mdl_requests for prepared statements and stored procedures from close_thread_tables() to reinit_stmt_before_use(). Change alloc_mdl_requests() to init_mdl_requests(). init_mdl_requests() is a hack that can't be deleted until we don't have a list-aware TABLE_LIST constructor. Hopefully its use will be minimal sql/table.h: Change alloc_mdl_requests() to init_mdl_requests() TABLE_LIST::mdl_request is stored by value. sql/tztime.cc: We no longer initialize mdl requests in open_system_tables_for*() functions. Move this initialization closer to initialization of the rest of TABLE_LIST members. storage/myisammrg/ha_myisammrg.cc: Simplify mdl_request initialization.
This commit is contained in:
204
sql/sql_table.cc
204
sql/sql_table.cc
@ -16,6 +16,7 @@
|
||||
/* drop and alter of tables */
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include "debug_sync.h"
|
||||
#include <hash.h>
|
||||
#include <myisam.h>
|
||||
#include <my_dir.h>
|
||||
@ -1907,14 +1908,25 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
if (find_temporary_table(thd, table->db, table->table_name))
|
||||
{
|
||||
/*
|
||||
Since we don't acquire metadata lock if we have found temporary
|
||||
table, we should do something to avoid releasing it at the end.
|
||||
A temporary table.
|
||||
|
||||
Don't try to find a corresponding MDL lock or assign it
|
||||
to table->mdl_request.ticket. There can't be metadata
|
||||
locks for temporary tables: they are local to the session.
|
||||
|
||||
Later in this function we release the MDL lock only if
|
||||
table->mdl_requeset.ticket is not NULL. Thus here we
|
||||
ensure that we won't release the metadata lock on the base
|
||||
table locked with LOCK TABLES as a side effect of temporary
|
||||
table drop.
|
||||
*/
|
||||
table->mdl_request= NULL;
|
||||
DBUG_ASSERT(table->mdl_request.ticket == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Not a temporary table.
|
||||
|
||||
Since 'tables' list can't contain duplicates (this is ensured
|
||||
by parser) it is safe to cache pointer to the TABLE instances
|
||||
in its elements.
|
||||
@ -1923,7 +1935,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
table->table_name);
|
||||
if (!table->table)
|
||||
DBUG_RETURN(1);
|
||||
table->mdl_request->ticket= table->table->mdl_ticket;
|
||||
table->mdl_request.ticket= table->table->mdl_ticket;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2188,7 +2200,7 @@ err:
|
||||
Under LOCK TABLES we should release meta-data locks on the tables
|
||||
which were dropped. Otherwise we can rely on close_thread_tables()
|
||||
doing this. Unfortunately in this case we are likely to get more
|
||||
false positives in lock_table_name_if_not_cached() function. So
|
||||
false positives in try_acquire_exclusive_lock() function. So
|
||||
it makes sense to remove exclusive meta-data locks in all cases.
|
||||
|
||||
Leave LOCK TABLES mode if we managed to drop all tables which were
|
||||
@ -2203,14 +2215,14 @@ err:
|
||||
}
|
||||
for (table= tables; table; table= table->next_local)
|
||||
{
|
||||
if (table->mdl_request)
|
||||
if (table->mdl_request.ticket)
|
||||
{
|
||||
/*
|
||||
Under LOCK TABLES we may have several instances of table open
|
||||
and locked and therefore have to remove several metadata lock
|
||||
requests associated with them.
|
||||
*/
|
||||
thd->mdl_context.release_all_locks_for_name(table->mdl_request->ticket);
|
||||
thd->mdl_context.release_all_locks_for_name(table->mdl_request.ticket);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4094,47 +4106,6 @@ warn:
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Auxiliary function which obtains exclusive meta-data lock on the
|
||||
table if there are no shared or exclusive on it already.
|
||||
|
||||
See mdl_try_acquire_exclusive_lock() function for more info.
|
||||
|
||||
TODO: This function is here mostly to simplify current patch
|
||||
and probably should be removed.
|
||||
TODO: Investigate if it is kosher to leave lock request in the
|
||||
context in the case when we fail to obtain the lock.
|
||||
*/
|
||||
|
||||
static bool lock_table_name_if_not_cached(THD *thd, const char *db,
|
||||
const char *table_name,
|
||||
MDL_request **mdl_request)
|
||||
{
|
||||
bool conflict;
|
||||
|
||||
if (!(*mdl_request= MDL_request::create(0, db, table_name, thd->mem_root)))
|
||||
return TRUE;
|
||||
(*mdl_request)->set_type(MDL_EXCLUSIVE);
|
||||
thd->mdl_context.add_request(*mdl_request);
|
||||
if (thd->mdl_context.try_acquire_exclusive_lock(*mdl_request, &conflict))
|
||||
{
|
||||
/*
|
||||
To simplify our life under LOCK TABLES we remove unsatisfied
|
||||
lock request from the context.
|
||||
*/
|
||||
thd->mdl_context.remove_request(*mdl_request);
|
||||
if (!conflict)
|
||||
{
|
||||
/* Probably OOM. */
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
*mdl_request= NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Database and name-locking aware wrapper for mysql_create_table_no_lock(),
|
||||
*/
|
||||
@ -4145,7 +4116,8 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name,
|
||||
bool internal_tmp_table,
|
||||
uint select_field_count)
|
||||
{
|
||||
MDL_request *target_mdl_request= NULL;
|
||||
MDL_request target_mdl_request;
|
||||
bool has_target_mdl_lock= FALSE;
|
||||
bool result;
|
||||
DBUG_ENTER("mysql_create_table");
|
||||
|
||||
@ -4168,13 +4140,15 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name,
|
||||
|
||||
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
|
||||
{
|
||||
if (lock_table_name_if_not_cached(thd, db, table_name, &target_mdl_request))
|
||||
target_mdl_request.init(0, db, table_name, MDL_EXCLUSIVE);
|
||||
if (thd->mdl_context.try_acquire_exclusive_lock(&target_mdl_request))
|
||||
{
|
||||
result= TRUE;
|
||||
goto unlock;
|
||||
}
|
||||
if (!target_mdl_request)
|
||||
if (target_mdl_request.ticket == NULL)
|
||||
{
|
||||
/* Table exists and is locked by some other thread. */
|
||||
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
@ -4191,6 +4165,9 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name,
|
||||
}
|
||||
goto unlock;
|
||||
}
|
||||
/* Got lock. */
|
||||
DEBUG_SYNC(thd, "locked_table_name");
|
||||
has_target_mdl_lock= TRUE;
|
||||
}
|
||||
|
||||
result= mysql_create_table_no_lock(thd, db, table_name, create_info,
|
||||
@ -4199,11 +4176,9 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name,
|
||||
select_field_count);
|
||||
|
||||
unlock:
|
||||
if (target_mdl_request)
|
||||
{
|
||||
thd->mdl_context.release_lock(target_mdl_request->ticket);
|
||||
thd->mdl_context.remove_request(target_mdl_request);
|
||||
}
|
||||
if (has_target_mdl_lock)
|
||||
thd->mdl_context.release_lock(target_mdl_request.ticket);
|
||||
|
||||
pthread_mutex_lock(&LOCK_lock_db);
|
||||
if (!--creating_table && creating_database)
|
||||
pthread_cond_signal(&COND_refresh);
|
||||
@ -4364,11 +4339,11 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
int error= 0;
|
||||
TABLE tmp_table, *table;
|
||||
TABLE_SHARE *share;
|
||||
bool has_mdl_lock= FALSE;
|
||||
char from[FN_REFLEN],tmp[FN_REFLEN+32];
|
||||
const char **ext;
|
||||
MY_STAT stat_info;
|
||||
MDL_request *mdl_request= NULL;
|
||||
enum enum_open_table_action ot_action_unused;
|
||||
Open_table_context ot_ctx_unused(thd);
|
||||
DBUG_ENTER("prepare_for_repair");
|
||||
uint reopen_for_repair_flags= (MYSQL_LOCK_IGNORE_FLUSH |
|
||||
MYSQL_OPEN_HAS_MDL_LOCK);
|
||||
@ -4386,15 +4361,11 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
uint key_length;
|
||||
|
||||
key_length= create_table_def_key(thd, key, table_list, 0);
|
||||
mdl_request= MDL_request::create(0, table_list->db,
|
||||
table_list->table_name, thd->mem_root);
|
||||
mdl_request->set_type(MDL_EXCLUSIVE);
|
||||
thd->mdl_context.add_request(mdl_request);
|
||||
if (thd->mdl_context.acquire_exclusive_locks())
|
||||
{
|
||||
thd->mdl_context.remove_request(mdl_request);
|
||||
table_list->mdl_request.init(0, table_list->db, table_list->table_name,
|
||||
MDL_EXCLUSIVE);
|
||||
if (thd->mdl_context.acquire_exclusive_lock(&table_list->mdl_request))
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
has_mdl_lock= TRUE;
|
||||
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
|
||||
@ -4412,7 +4383,6 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
table= &tmp_table;
|
||||
table_list->mdl_request= mdl_request;
|
||||
}
|
||||
|
||||
/* A MERGE table must not come here. */
|
||||
@ -4507,7 +4477,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
to finish the repair in the handler later on.
|
||||
*/
|
||||
if (open_table(thd, table_list, thd->mem_root,
|
||||
&ot_action_unused, reopen_for_repair_flags))
|
||||
&ot_ctx_unused, reopen_for_repair_flags))
|
||||
{
|
||||
error= send_check_errmsg(thd, table_list, "repair",
|
||||
"Failed to open partially repaired table");
|
||||
@ -4523,11 +4493,9 @@ end:
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
}
|
||||
/* In case of a temporary table there will be no metadata lock. */
|
||||
if (error && mdl_request)
|
||||
{
|
||||
thd->mdl_context.release_lock(mdl_request->ticket);
|
||||
thd->mdl_context.remove_request(mdl_request);
|
||||
}
|
||||
if (error && has_mdl_lock)
|
||||
thd->mdl_context.release_lock(table_list->mdl_request.ticket);
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@ -4938,6 +4906,8 @@ send_result_message:
|
||||
thd->mdl_context.release_all_locks();
|
||||
if (!result_code) // recreation went ok
|
||||
{
|
||||
/* Clear the ticket released in close_thread_tables(). */
|
||||
table->mdl_request.ticket= NULL;
|
||||
if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
|
||||
((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
|
||||
result_code= 0; // analyze went ok
|
||||
@ -5241,9 +5211,9 @@ bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
|
||||
bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||
HA_CREATE_INFO *create_info)
|
||||
{
|
||||
MDL_request *target_mdl_request= NULL;
|
||||
char src_path[FN_REFLEN], dst_path[FN_REFLEN + 1];
|
||||
char src_path[FN_REFLEN + 1], dst_path[FN_REFLEN + 1];
|
||||
uint dst_path_length;
|
||||
bool has_mdl_lock= FALSE;
|
||||
char *db= table->db;
|
||||
char *table_name= table->table_name;
|
||||
int err;
|
||||
@ -5298,19 +5268,20 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lock_table_name_if_not_cached(thd, db, table_name, &target_mdl_request))
|
||||
goto err;
|
||||
if (!target_mdl_request)
|
||||
table->mdl_request.init(0, db, table_name, MDL_EXCLUSIVE);
|
||||
if (thd->mdl_context.try_acquire_exclusive_lock(&table->mdl_request))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (table->mdl_request.ticket == NULL)
|
||||
goto table_exists;
|
||||
|
||||
DEBUG_SYNC(thd, "locked_table_name");
|
||||
has_mdl_lock= TRUE;
|
||||
|
||||
dst_path_length= build_table_filename(dst_path, sizeof(dst_path) - 1,
|
||||
db, table_name, reg_ext, 0);
|
||||
if (!access(dst_path, F_OK))
|
||||
goto table_exists;
|
||||
/*
|
||||
Make the metadata lock available to open_table() called to
|
||||
reopen the table down the road.
|
||||
*/
|
||||
table->mdl_request= target_mdl_request;
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
|
||||
@ -5440,14 +5411,14 @@ binlog:
|
||||
char buf[2048];
|
||||
String query(buf, sizeof(buf), system_charset_info);
|
||||
query.length(0); // Have to zero it since constructor doesn't
|
||||
enum enum_open_table_action ot_action_unused;
|
||||
Open_table_context ot_ctx_unused(thd);
|
||||
/*
|
||||
Here we open the destination table, on which we already have
|
||||
exclusive metadata lock. This is needed for store_create_info()
|
||||
to work. The table will be closed by close_thread_table() at
|
||||
the end of this branch.
|
||||
*/
|
||||
if (open_table(thd, table, thd->mem_root, &ot_action_unused,
|
||||
if (open_table(thd, table, thd->mem_root, &ot_ctx_unused,
|
||||
MYSQL_OPEN_REOPEN))
|
||||
goto err;
|
||||
|
||||
@ -5481,11 +5452,9 @@ binlog:
|
||||
res= FALSE;
|
||||
|
||||
err:
|
||||
if (target_mdl_request)
|
||||
{
|
||||
thd->mdl_context.release_lock(target_mdl_request->ticket);
|
||||
thd->mdl_context.remove_request(target_mdl_request);
|
||||
}
|
||||
if (has_mdl_lock)
|
||||
thd->mdl_context.release_lock(table->mdl_request.ticket);
|
||||
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
@ -5969,7 +5938,6 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
|
||||
|
||||
@ -6424,7 +6392,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
{
|
||||
TABLE *table, *new_table= 0;
|
||||
MDL_ticket *mdl_ticket;
|
||||
MDL_request *target_mdl_request= NULL;
|
||||
MDL_request target_mdl_request;
|
||||
bool has_target_mdl_lock= FALSE;
|
||||
int error= 0;
|
||||
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1];
|
||||
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
|
||||
@ -6647,15 +6616,21 @@ view_err:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lock_table_name_if_not_cached(thd, new_db, new_name,
|
||||
&target_mdl_request))
|
||||
target_mdl_request.init(0, new_db, new_name, MDL_EXCLUSIVE);
|
||||
if (thd->mdl_context.try_acquire_exclusive_lock(&target_mdl_request))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (!target_mdl_request)
|
||||
if (target_mdl_request.ticket == NULL)
|
||||
{
|
||||
/* Table exists and is locked by some thread. */
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
DEBUG_SYNC(thd, "locked_table_name");
|
||||
has_target_mdl_lock= TRUE;
|
||||
/*
|
||||
Table maybe does not exist, but we got an exclusive lock
|
||||
on the name, now we can safely try to find out for sure.
|
||||
*/
|
||||
build_table_filename(new_name_buff, sizeof(new_name_buff) - 1,
|
||||
new_db, new_name_buff, reg_ext, 0);
|
||||
if (!access(new_name_buff, F_OK))
|
||||
@ -6843,8 +6818,7 @@ view_err:
|
||||
*/
|
||||
if (new_name != table_name || new_db != db)
|
||||
{
|
||||
thd->mdl_context.release_lock(target_mdl_request->ticket);
|
||||
thd->mdl_context.remove_request(target_mdl_request);
|
||||
thd->mdl_context.release_lock(target_mdl_request.ticket);
|
||||
thd->mdl_context.release_all_locks_for_name(mdl_ticket);
|
||||
}
|
||||
else
|
||||
@ -7081,7 +7055,6 @@ view_err:
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if (fast_alter_partition)
|
||||
{
|
||||
DBUG_ASSERT(!target_mdl_request);
|
||||
DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
|
||||
create_info, table_list,
|
||||
db, table_name,
|
||||
@ -7161,13 +7134,13 @@ view_err:
|
||||
{
|
||||
if (table->s->tmp_table)
|
||||
{
|
||||
enum_open_table_action not_used;
|
||||
Open_table_context ot_ctx_unused(thd);
|
||||
TABLE_LIST tbl;
|
||||
bzero((void*) &tbl, sizeof(tbl));
|
||||
tbl.db= new_db;
|
||||
tbl.table_name= tbl.alias= tmp_name;
|
||||
/* Table is in thd->temporary_tables */
|
||||
(void) open_table(thd, &tbl, thd->mem_root, ¬_used,
|
||||
(void) open_table(thd, &tbl, thd->mem_root, &ot_ctx_unused,
|
||||
MYSQL_LOCK_IGNORE_FLUSH);
|
||||
new_table= tbl.table;
|
||||
}
|
||||
@ -7439,7 +7412,7 @@ view_err:
|
||||
To do this we need to obtain a handler object for it.
|
||||
NO need to tamper with MERGE tables. The real open is done later.
|
||||
*/
|
||||
enum enum_open_table_action ot_action_unused;
|
||||
Open_table_context ot_ctx_unused(thd);
|
||||
TABLE *t_table;
|
||||
if (new_name != table_name || new_db != db)
|
||||
{
|
||||
@ -7448,7 +7421,7 @@ view_err:
|
||||
table_list->table_name_length= strlen(new_name);
|
||||
table_list->db= new_db;
|
||||
table_list->db_length= strlen(new_db);
|
||||
table_list->mdl_request= target_mdl_request;
|
||||
table_list->mdl_request.ticket= target_mdl_request.ticket;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -7457,10 +7430,10 @@ view_err:
|
||||
points to a different instance than the one set initially
|
||||
to request the lock.
|
||||
*/
|
||||
table_list->mdl_request->ticket= mdl_ticket;
|
||||
table_list->mdl_request.ticket= mdl_ticket;
|
||||
}
|
||||
if (open_table(thd, table_list, thd->mem_root,
|
||||
&ot_action_unused, MYSQL_OPEN_REOPEN))
|
||||
&ot_ctx_unused, MYSQL_OPEN_REOPEN))
|
||||
{
|
||||
goto err_with_mdl;
|
||||
}
|
||||
@ -7523,8 +7496,7 @@ view_err:
|
||||
{
|
||||
if ((new_name != table_name || new_db != db))
|
||||
{
|
||||
thd->mdl_context.release_lock(target_mdl_request->ticket);
|
||||
thd->mdl_context.remove_request(target_mdl_request);
|
||||
thd->mdl_context.release_lock(target_mdl_request.ticket);
|
||||
thd->mdl_context.release_all_locks_for_name(mdl_ticket);
|
||||
}
|
||||
else
|
||||
@ -7583,11 +7555,9 @@ err:
|
||||
alter_info->datetime_field->field_name);
|
||||
thd->abort_on_warning= save_abort_on_warning;
|
||||
}
|
||||
if (target_mdl_request)
|
||||
{
|
||||
thd->mdl_context.release_lock(target_mdl_request->ticket);
|
||||
thd->mdl_context.remove_request(target_mdl_request);
|
||||
}
|
||||
if (has_target_mdl_lock)
|
||||
thd->mdl_context.release_lock(target_mdl_request.ticket);
|
||||
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
err_with_mdl:
|
||||
@ -7598,11 +7568,9 @@ err_with_mdl:
|
||||
tables and release the exclusive metadata lock.
|
||||
*/
|
||||
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
||||
if (target_mdl_request)
|
||||
{
|
||||
thd->mdl_context.release_lock(target_mdl_request->ticket);
|
||||
thd->mdl_context.remove_request(target_mdl_request);
|
||||
}
|
||||
if (has_target_mdl_lock)
|
||||
thd->mdl_context.release_lock(target_mdl_request.ticket);
|
||||
|
||||
thd->mdl_context.release_all_locks_for_name(mdl_ticket);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
@ -7851,6 +7819,8 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
|
||||
uninitialized data. open_tables() could fail.
|
||||
*/
|
||||
table_list->table= NULL;
|
||||
/* Same applies to MDL ticket. */
|
||||
table_list->mdl_request.ticket= NULL;
|
||||
|
||||
bzero((char*) &create_info, sizeof(create_info));
|
||||
create_info.row_type=ROW_TYPE_NOT_USED;
|
||||
|
Reference in New Issue
Block a user