1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +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.
This commit is contained in:
Konstantin Osipov
2009-12-08 12:57:07 +03:00
parent 4a8a1c568d
commit a66a2608ae
30 changed files with 566 additions and 733 deletions

View File

@ -1100,7 +1100,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
TABLE *table;
bool error;
uint path_length;
MDL_request *mdl_request= NULL;
MDL_request mdl_request;
bool has_mdl_lock= FALSE;
DBUG_ENTER("mysql_truncate");
bzero((char*) &create_info,sizeof(create_info));
@ -1145,6 +1146,12 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
if (!dont_send_ok)
{
enum legacy_db_type table_type;
/*
FIXME: Code of TRUNCATE breaks the meta-data
locking protocol since it tries to find out the table storage
engine and therefore accesses table in some way without holding
any kind of meta-data lock.
*/
mysql_frm_type(thd, path, &table_type);
if (table_type == DB_TYPE_UNKNOWN)
{
@ -1170,20 +1177,12 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION)
goto trunc_by_del;
/*
FIXME: Actually code of TRUNCATE breaks meta-data locking protocol since
tries to get table enging and therefore accesses table in some way
without holding any kind of meta-data lock.
*/
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);
mdl_request.init(0, table_list->db, table_list->table_name, MDL_EXCLUSIVE);
if (thd->mdl_context.acquire_exclusive_lock(&mdl_request))
DBUG_RETURN(TRUE);
}
has_mdl_lock= TRUE;
pthread_mutex_lock(&LOCK_open);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
table_list->table_name);
@ -1212,19 +1211,13 @@ end:
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd); // This should return record count
}
if (mdl_request)
{
thd->mdl_context.release_lock(mdl_request->ticket);
thd->mdl_context.remove_request(mdl_request);
}
if (has_mdl_lock)
thd->mdl_context.release_lock(mdl_request.ticket);
}
else if (error)
{
if (mdl_request)
{
thd->mdl_context.release_lock(mdl_request->ticket);
thd->mdl_context.remove_request(mdl_request);
}
if (has_mdl_lock)
thd->mdl_context.release_lock(mdl_request.ticket);
}
DBUG_RETURN(error);