Backport of:

----------------------------------------------------------
revno: 2630.10.1
committer: Konstantin Osipov <konstantin@mysql.com>
branch nick: mysql-6.0-lock-tables-tidyup
timestamp: Wed 2008-06-11 15:49:58 +0400
message:
  WL#3726, review fixes.
  Now that we have metadata locks, we don't need to keep a crippled
  TABLE instance in the table cache to indicate that a table is locked.
  Remove all code that used this technique. Instead, rely on metadata
  locks and use the standard open_table() and close_thread_table()
  to manipulate with the table cache tables.
  Removes a list of functions that have become unused (see the comment
  for sql_base.cc for details).
  Under LOCK TABLES, keep a TABLE_LIST instance for each table
  that may be temporarily closed. For that, implement an own class for
  LOCK TABLES mode, Locked_tables_list.

This is a pre-requisite patch for WL#4144.
This is not exactly a backport: there is no new 
online ALTER table in Celosia, so the old alter table
code was changed to work with the new table cache API.


mysql-test/r/lock.result:
  Update results (WL#3726 post-review patch).
mysql-test/r/trigger-compat.result:
  We take the table from the table cache now, thus no warning.
mysql-test/suite/rpl/r/rpl_trigger.result:
  We take the table from the table cache now, thus no warning.
mysql-test/t/lock.test:
  Additional tests for LOCK TABLES mode (previously not covered by
  the test suite (WL#3726).
sql/field.h:
  Remove reopen_table().
sql/lock.cc:
  Remove an obsolete parameter of mysql_lock_remove().
  It's not used anywhere now either.
sql/mysql_priv.h:
  Add 4 new open_table() flags.
  Remove declarations of removed functions.
sql/sp_head.cc:
  Rename thd->mdl_el_root to thd->locked_tables_root.
sql/sql_acl.cc:
  Use the new implementation of unlock_locked_tables().
sql/sql_base.cc:
  Implement class Locked_tables_list.
  Implement close_all_tables_for_name().
  Rewrite close_cached_tables() to use the new reopen_tables().
  Remove reopen_table(), reopen_tables(), reopen_table_entry() 
  (ex. open_unireg_entry()), close_data_files_and_leave_as_placeholders(),
  close_handle_and_leave_table_as_placeholder(), close_cached_table(),
  table_def_change_share(), reattach_merge(), reopen_name_locked_table(),
  unlink_open_table().
  
  Move acquisition of a metadata lock into an own function
  - open_table_get_mdl_lock().
sql/sql_class.cc:
  Deploy class Locked_tables_list.
sql/sql_class.h:
  Declare class Locked_tables_list.
  Keep one instance of this class in class THD.
  Rename mdl_el_root to locked_tables_root.
sql/sql_db.cc:
  Update a comment.
sql/sql_insert.cc:
  Use the plain open_table() to open a just created table in
  CREATE TABLE .. SELECT.
sql/sql_parse.cc:
  Use thd->locked_tables_list to enter and leave LTM_LOCK_TABLES mode.
sql/sql_partition.cc:
  Deploy the new method of working with partitioned table locks.
sql/sql_servers.cc:
  Update to the new signature of unlock_locked_tables().
sql/sql_table.cc:
  In mysql_rm_table_part2(), the branch that removes a table under
  LOCK TABLES, make sure that the table being dropped
  is also removed from THD::locked_tables_list.
  Update ALTER TABLE and CREATE TABLE LIKE implementation to use
  open_table() and close_all_tables_for_name() instead of 
  reopen_tables().
sql/sql_trigger.cc:
  Use the new locking way.
sql/table.h:
  Add TABLE::pos_in_locked_tables, which is used only under
  LOCK TABLES.
This commit is contained in:
Konstantin Osipov 2009-12-02 18:22:15 +03:00
commit 3104af49cd
20 changed files with 763 additions and 1195 deletions

View file

@ -328,6 +328,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
bool result= TRUE;
String stmt_query;
bool need_start_waiting= FALSE;
bool lock_upgrade_done= FALSE;
DBUG_ENTER("mysql_create_or_drop_trigger");
@ -450,72 +451,54 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
if (!(tables->table= find_write_locked_table(thd->open_tables, tables->db,
tables->table_name)))
goto end;
/*
Ensure that table is opened only by this thread and that no other
statement will open this table.
*/
if (wait_while_table_is_used(thd, tables->table, HA_EXTRA_FORCE_REOPEN))
goto end;
pthread_mutex_lock(&LOCK_open);
/* Later on we will need it to downgrade the lock */
tables->mdl_lock_data= tables->table->mdl_lock_data;
}
else
{
/*
Obtain exlusive meta-data lock on the table and remove TABLE
instances from cache.
*/
if (lock_table_names(thd, tables))
tables->table= open_n_lock_single_table(thd, tables,
TL_WRITE_ALLOW_READ,
MYSQL_OPEN_TAKE_UPGRADABLE_MDL);
if (! tables->table)
goto end;
pthread_mutex_lock(&LOCK_open);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, tables->db, tables->table_name);
if (reopen_name_locked_table(thd, tables))
goto end_unlock;
tables->table->use_all_columns();
}
table= tables->table;
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
goto end;
lock_upgrade_done= TRUE;
if (!table->triggers)
{
if (!create)
{
my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
goto end_unlock;
goto end;
}
if (!(table->triggers= new (&table->mem_root) Table_triggers_list(table)))
goto end_unlock;
goto end;
}
pthread_mutex_lock(&LOCK_open);
result= (create ?
table->triggers->create_trigger(thd, tables, &stmt_query):
table->triggers->drop_trigger(thd, tables, &stmt_query));
/* Under LOCK TABLES we must reopen the table to activate the trigger. */
if (!result && thd->locked_tables_mode)
{
/* Make table suitable for reopening */
close_data_files_and_leave_as_placeholders(thd, tables->db,
tables->table_name);
thd->in_lock_tables= 1;
if (reopen_tables(thd, 1))
{
/* To be safe remove this table from the set of LOCKED TABLES */
unlink_open_table(thd, tables->table, FALSE);
/*
Ignore reopen_tables errors for now. It's better not leave master/slave
in a inconsistent state.
*/
thd->clear_error();
}
thd->in_lock_tables= 0;
}
end_unlock:
pthread_mutex_unlock(&LOCK_open);
if (result)
goto end;
close_all_tables_for_name(thd, table->s, FALSE);
/*
Reopen the table if we were under LOCK TABLES.
Ignore the return value for now. It's better to
keep master/slave in consistent state.
*/
thd->locked_tables_list.reopen_tables(thd);
end:
if (!result)
{
@ -525,11 +508,11 @@ end:
/*
If we are under LOCK TABLES we should restore original state of meta-data
locks. Otherwise call to close_thread_tables() will take care about both
TABLE instance created by reopen_name_locked_table() and metadata lock.
TABLE instance created by open_n_lock_single_table() and metadata lock.
*/
if (thd->locked_tables_mode && tables && tables->table)
if (thd->locked_tables_mode && tables && lock_upgrade_done)
mdl_downgrade_exclusive_lock(&thd->mdl_context,
tables->table->mdl_lock_data);
tables->mdl_lock_data);
if (need_start_waiting)
start_waiting_global_read_lock(thd);