diff options
author | Konstantin Osipov <kostja@sun.com> | 2009-12-02 18:22:15 +0300 |
---|---|---|
committer | Konstantin Osipov <kostja@sun.com> | 2009-12-02 18:22:15 +0300 |
commit | 3104af49cdd1a3c041948b0da17558c49c3edb49 (patch) | |
tree | e25111d23124912ae062b22e9503051a57bb23c3 /sql/sql_trigger.cc | |
parent | e8a9191e646ab510e14082793fed2d828e6c8679 (diff) | |
download | mariadb-git-3104af49cdd1a3c041948b0da17558c49c3edb49.tar.gz |
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.
Diffstat (limited to 'sql/sql_trigger.cc')
-rw-r--r-- | sql/sql_trigger.cc | 75 |
1 files changed, 29 insertions, 46 deletions
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index c8f01a56a72..9a42dd189e7 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -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,71 +451,53 @@ 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)); + pthread_mutex_unlock(&LOCK_open); - /* 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; - } + if (result) + goto end; -end_unlock: - pthread_mutex_unlock(&LOCK_open); + 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); |