1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +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:
Konstantin Osipov
2009-12-08 12:57:07 +03:00
parent 478e09609c
commit ce5c87a3d3
30 changed files with 566 additions and 733 deletions

View File

@@ -2399,7 +2399,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->lex->set_stmt_unsafe();
thd->set_current_stmt_binlog_row_based_if_mixed();
alloc_mdl_requests(&di->table_list, thd->mem_root);
init_mdl_requests(&di->table_list);
if (di->open_and_lock_table())
goto err;
@@ -3464,7 +3464,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
Item *item;
Field *tmp_field;
bool not_used;
enum_open_table_action not_used2;
DBUG_ENTER("create_table_from_items");
tmp_table.alias= 0;
@@ -3543,13 +3542,13 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
{
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
an exclusive metadata lock.
*/
if (open_table(thd, create_table, thd->mem_root,
&ot_action_unused, MYSQL_OPEN_REOPEN))
&ot_ctx_unused, MYSQL_OPEN_REOPEN))
{
pthread_mutex_lock(&LOCK_open);
quick_rm_table(create_info->db_type, create_table->db,
@@ -3562,7 +3561,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
}
else
{
if (open_table(thd, create_table, thd->mem_root, &not_used2,
Open_table_context ot_ctx_unused(thd);
if (open_table(thd, create_table, thd->mem_root, &ot_ctx_unused,
MYSQL_OPEN_TEMPORARY_ONLY) &&
!create_info->table_existed)
{
@@ -3637,18 +3637,28 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/
class MY_HOOKS : public TABLEOP_HOOKS {
public:
MY_HOOKS(select_create *x, TABLE_LIST *create_table,
TABLE_LIST *select_tables)
: ptr(x), all_tables(*create_table)
MY_HOOKS(select_create *x, TABLE_LIST *create_table_arg,
TABLE_LIST *select_tables_arg)
: ptr(x),
create_table(create_table_arg),
select_tables(select_tables_arg)
{
all_tables.next_global= select_tables;
}
private:
virtual int do_postlock(TABLE **tables, uint count)
{
int error;
THD *thd= const_cast<THD*>(ptr->get_thd());
if (int error= decide_logging_format(thd, &all_tables))
TABLE_LIST *save_next_global= create_table->next_global;
create_table->next_global= select_tables;
error= decide_logging_format(thd, create_table);
create_table->next_global= save_next_global;
if (error)
return error;
TABLE const *const table = *tables;
@@ -3662,7 +3672,8 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
}
select_create *ptr;
TABLE_LIST all_tables;
TABLE_LIST *create_table;
TABLE_LIST *select_tables;
};
MY_HOOKS hooks(this, create_table, select_tables);