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_partition.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_partition.cc')
-rw-r--r-- | sql/sql_partition.cc | 73 |
1 files changed, 36 insertions, 37 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 75ab9a73a5b..f4525db7def 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -4314,7 +4314,6 @@ set_engine_all_partitions(partition_info *part_info, static int fast_end_partition(THD *thd, ulonglong copied, ulonglong deleted, - TABLE *table, TABLE_LIST *table_list, bool is_empty, ALTER_PARTITION_PARAM_TYPE *lpt, bool written_bin_log) @@ -4333,11 +4332,7 @@ static int fast_end_partition(THD *thd, ulonglong copied, error= 1; if (error) - { - /* If error during commit, no need to rollback, it's done. */ - table->file->print_error(error, MYF(0)); - DBUG_RETURN(TRUE); - } + DBUG_RETURN(TRUE); /* The error has been reported */ if ((!is_empty) && (!written_bin_log) && (!thd->lex->no_write_to_binlog)) @@ -6215,30 +6210,13 @@ static void release_log_entries(partition_info *part_info) */ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) { - int err; - if (lpt->thd->locked_tables_mode) - { - /* - When we have the table locked, it is necessary to reopen the table - since all table objects were closed and removed as part of the - ALTER TABLE of partitioning structure. - */ - pthread_mutex_lock(&LOCK_open); - lpt->thd->in_lock_tables= 1; - err= reopen_tables(lpt->thd, 1); - lpt->thd->in_lock_tables= 0; - if (err) - { - /* - Issue a warning since we weren't able to regain the lock again. - We also need to unlink table from thread's open list and from - table_cache - */ - unlink_open_table(lpt->thd, lpt->table, FALSE); - sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE"); - } - pthread_mutex_unlock(&LOCK_open); - } + THD *thd= lpt->thd; + + close_all_tables_for_name(thd, lpt->table->s, FALSE); + lpt->table= 0; + lpt->table_list->table= 0; + if (thd->locked_tables_list.reopen_tables(thd)) + sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE"); } /* @@ -6252,17 +6230,37 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt) { + TABLE_SHARE *share= lpt->table->s; THD *thd= lpt->thd; - const char *db= lpt->db; - const char *table_name= lpt->table_name; + TABLE *table; DBUG_ENTER("alter_close_tables"); /* - We need to also unlock tables and close all handlers. - We set lock to zero to ensure we don't do this twice - and we set db_stat to zero to ensure we don't close twice. + We must keep LOCK_open while manipulating with thd->open_tables. + Another thread may be working on it. */ pthread_mutex_lock(&LOCK_open); - close_data_files_and_leave_as_placeholders(thd, db, table_name); + /* + We can safely remove locks for all tables with the same name: + later they will all be closed anyway in + alter_partition_lock_handling(). + */ + for (table= thd->open_tables; table ; table= table->next) + { + if (!strcmp(table->s->table_name.str, share->table_name.str) && + !strcmp(table->s->db.str, share->db.str)) + { + mysql_lock_remove(thd, thd->lock, table); + table->file->close(); + table->db_stat= 0; // Mark file closed + /* + Ensure that we won't end up with a crippled table instance + in the table cache if an error occurs before we reach + alter_partition_lock_handling() and the table is closed + by close_thread_tables() instead. + */ + table->s->version= 0; + } + } pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(0); } @@ -6429,6 +6427,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, DBUG_ENTER("fast_alter_partition_table"); lpt->thd= thd; + lpt->table_list= table_list; lpt->part_info= part_info; lpt->alter_info= alter_info; lpt->create_info= create_info; @@ -6745,7 +6744,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, user */ DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted, - table, table_list, FALSE, NULL, + table_list, FALSE, NULL, written_bin_log)); err: close_thread_tables(thd); |