diff options
author | Nirbhay Choubey <nirbhay@mariadb.com> | 2016-06-10 16:19:59 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@mariadb.com> | 2016-06-10 18:39:43 -0400 |
commit | 7305be2f7e724e5e62961606794beab199d79045 (patch) | |
tree | 403bd132ee82a16946e3208f5d535de6e5945b80 /sql/rpl_rli.cc | |
parent | 547511153fb1f59688752aa5524ae411b5960c92 (diff) | |
download | mariadb-git-7305be2f7e724e5e62961606794beab199d79045.tar.gz |
MDEV-5535: Cannot reopen temporary table
mysqld maintains a list of TABLE objects for all temporary
tables created within a session in THD. Here each table is
represented by a TABLE object.
A query referencing a particular temporary table for more
than once, however, failed with ER_CANT_REOPEN_TABLE error
because a TABLE_SHARE was allocate together with the TABLE,
so temporary tables always had only one TABLE per TABLE_SHARE.
This patch lift this restriction by separating TABLE and
TABLE_SHARE objects and storing TABLE_SHAREs for temporary
tables in a list in THD, and TABLEs in a list within their
respective TABLE_SHAREs.
Diffstat (limited to 'sql/rpl_rli.cc')
-rw-r--r-- | sql/rpl_rli.cc | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index f9d0910a2a7..f8f06d613f4 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2006, 2013, Oracle and/or its affiliates. Copyright (c) 2010, 2013, Monty Program Ab + Copyright (c) 2016, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -52,8 +53,8 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery) no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id), info_fd(-1), cur_log_fd(-1), relay_log(&sync_relaylog_period), sync_counter(0), is_relay_log_recovery(is_slave_recovery), - save_temporary_tables(0), mi(0), - inuse_relaylog_list(0), last_inuse_relaylog(0), + save_temporary_tables(0), + mi(0), inuse_relaylog_list(0), last_inuse_relaylog(0), cur_log_old_open_count(0), group_relay_log_pos(0), event_relay_log_pos(0), #if HAVE_valgrind @@ -1062,24 +1063,53 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos, void Relay_log_info::close_temporary_tables() { - TABLE *table,*next; DBUG_ENTER("Relay_log_info::close_temporary_tables"); - for (table=save_temporary_tables ; table ; table=next) + TMP_TABLE_SHARE *share; + TABLE *table; + + if (!save_temporary_tables) { - next=table->next; + /* There are no temporary tables. */ + DBUG_VOID_RETURN; + } + + while ((share= save_temporary_tables->pop_front())) + { + /* + Iterate over the list of tables for this TABLE_SHARE and close them. + */ + while ((table= share->all_tmp_tables.pop_front())) + { + DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", + table->s->db.str, table->s->table_name.str)); + + /* Reset in_use as the table may have been created by another thd */ + table->in_use= 0; + /* + Lets not free TABLE_SHARE here as there could be multiple TABLEs opened + for the same table (TABLE_SHARE). + */ + closefrm(table); + my_free(table); + } - /* Reset in_use as the table may have been created by another thd */ - table->in_use=0; /* Don't ask for disk deletion. For now, anyway they will be deleted when slave restarts, but it is a better intention to not delete them. */ - DBUG_PRINT("info", ("table: 0x%lx", (long) table)); - close_temporary(table, 1, 0); + + free_table_share(share); + my_free(share); } - save_temporary_tables= 0; + + /* By now, there mustn't be any elements left in the list. */ + DBUG_ASSERT(save_temporary_tables->is_empty()); + + my_free(save_temporary_tables); + save_temporary_tables= NULL; slave_open_temp_tables= 0; + DBUG_VOID_RETURN; } @@ -1756,6 +1786,7 @@ void rpl_group_info::cleanup_context(THD *thd, bool error) } m_table_map.clear_tables(); slave_close_thread_tables(thd); + if (error) { thd->mdl_context.release_transactional_locks(); |