summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/mysql_priv.h6
-rw-r--r--sql/sql_base.cc60
-rw-r--r--sql/sql_handler.cc2
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_partition.cc2
-rw-r--r--sql/sql_table.cc5
-rw-r--r--sql/sql_trigger.cc3
-rw-r--r--sql/table.h24
8 files changed, 35 insertions, 69 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index e96534bad15..1028c7d0d29 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1238,9 +1238,9 @@ bool fix_merge_after_open(TABLE_LIST *old_child_list, TABLE_LIST **old_last,
bool reopen_table(TABLE *table);
bool reopen_tables(THD *thd, bool get_locks);
thr_lock_type read_lock_type_for_table(THD *thd, TABLE *table);
-void close_data_files_and_morph_locks(THD *thd, const char *db,
- const char *table_name);
-void close_handle_and_leave_table_as_lock(TABLE *table);
+void close_data_files_and_leave_as_placeholders(THD *thd, const char *db,
+ const char *table_name);
+void close_handle_and_leave_table_as_placeholder(TABLE *table);
void unlock_locked_tables(THD *thd);
void execute_init_command(THD *thd, sys_var_str *init_command_var,
rw_lock_t *var_mutex);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 40377a99d21..b21a9f3b931 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -726,25 +726,23 @@ static void reference_table_share(TABLE_SHARE *share)
}
-/*
- Close file handle, but leave the table in the table cache
+/**
+ Close file handle, but leave the table in THD::open_tables list
+ to allow its future reopening.
- SYNOPSIS
- close_handle_and_leave_table_as_lock()
- table Table handler
+ @param table Table handler
- NOTES
- By leaving the table in the table cache, it disallows any other thread
- to open the table
+ @note THD::killed will be set if we run out of memory
- thd->killed will be set if we run out of memory
+ @note If closing a MERGE child, the calling function has to
+ take care for closing the parent too, if necessary.
- If closing a MERGE child, the calling function has to take care for
- closing the parent too, if necessary.
+ @todo Get rid of this function once we refactor LOCK TABLES
+ to keep around TABLE_LIST elements used for opening
+ of tables until UNLOCK TABLES.
*/
-
-void close_handle_and_leave_table_as_lock(TABLE *table)
+void close_handle_and_leave_table_as_placeholder(TABLE *table)
{
TABLE_SHARE *share, *old_share= table->s;
char *key_buff;
@@ -1048,8 +1046,8 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
char dbname[NAME_LEN+1];
char tname[NAME_LEN+1];
/*
- Since close_data_files_and_morph_locks() frees share's memroot
- we need to make copies of database and table names.
+ Since close_data_files_and_leave_as_placeholders() frees share's
+ memroot we need to make copies of database and table names.
*/
strmov(dbname, tab->s->db.str);
strmov(tname, tab->s->table_name.str);
@@ -1059,7 +1057,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
goto err_with_reopen;
}
pthread_mutex_lock(&LOCK_open);
- close_data_files_and_morph_locks(thd, dbname, tname);
+ close_data_files_and_leave_as_placeholders(thd, dbname, tname);
pthread_mutex_unlock(&LOCK_open);
}
}
@@ -1082,7 +1080,8 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
goto err_with_reopen;
}
pthread_mutex_lock(&LOCK_open);
- close_data_files_and_morph_locks(thd, table->db, table->table_name);
+ close_data_files_and_leave_as_placeholders(thd, table->db,
+ table->table_name);
pthread_mutex_unlock(&LOCK_open);
}
}
@@ -1529,7 +1528,7 @@ bool close_thread_table(THD *thd, TABLE **table_ptr)
detach_merge_children(table, TRUE);
table->mdl_lock= 0;
- if (table->needs_reopen_or_name_lock() ||
+ if (table->needs_reopen() ||
thd->version != refresh_version || !table->db_stat)
{
free_cache_entry(table);
@@ -1537,12 +1536,6 @@ bool close_thread_table(THD *thd, TABLE **table_ptr)
}
else
{
- /*
- Open placeholders have TABLE::db_stat set to 0, so they should be
- handled by the first alternative.
- */
- DBUG_ASSERT(!table->open_placeholder);
-
/* Assert that MERGE children are not attached in unused_tables. */
DBUG_ASSERT(!table->is_children_attached());
@@ -3244,7 +3237,7 @@ bool reopen_table(TABLE *table)
/**
Close all instances of a table open by this thread and replace
- them with exclusive name-locks.
+ them with placeholder in THD::open_tables list for future reopening.
@param thd Thread context
@param db Database name for the table to be closed
@@ -3259,11 +3252,11 @@ bool reopen_table(TABLE *table)
the strings are used in a loop even after the share may be freed.
*/
-void close_data_files_and_morph_locks(THD *thd, const char *db,
- const char *table_name)
+void close_data_files_and_leave_as_placeholders(THD *thd, const char *db,
+ const char *table_name)
{
TABLE *table;
- DBUG_ENTER("close_data_files_and_morph_locks");
+ DBUG_ENTER("close_data_files_and_leave_as_placeholders");
safe_mutex_assert_owner(&LOCK_open);
@@ -3277,11 +3270,6 @@ void close_data_files_and_morph_locks(THD *thd, const char *db,
thd->lock= 0;
}
- /*
- Note that open table list may contain a name-lock placeholder
- for target table name if we process ALTER TABLE ... RENAME.
- So loop below makes sense even if we are not under LOCK TABLES.
- */
for (table=thd->open_tables; table ; table=table->next)
{
if (!strcmp(table->s->table_name.str, table_name) &&
@@ -3298,15 +3286,13 @@ void close_data_files_and_morph_locks(THD *thd, const char *db,
won't have multiple children with the same db.table_name.
*/
mysql_lock_remove(thd, thd->locked_tables, table->parent, TRUE);
- table->parent->open_placeholder= 1;
- close_handle_and_leave_table_as_lock(table->parent);
+ close_handle_and_leave_table_as_placeholder(table->parent);
}
else
mysql_lock_remove(thd, thd->locked_tables, table, TRUE);
}
- table->open_placeholder= 1;
table->s->version= 0;
- close_handle_and_leave_table_as_lock(table);
+ close_handle_and_leave_table_as_placeholder(table);
}
}
DBUG_VOID_RETURN;
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 5c034a0452a..6087b0b7700 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -801,7 +801,7 @@ void mysql_ha_flush(THD *thd)
if (hash_tables->table &&
(hash_tables->table->mdl_lock &&
mdl_has_pending_conflicting_lock(hash_tables->table->mdl_lock) ||
- hash_tables->table->needs_reopen_or_name_lock()))
+ hash_tables->table->needs_reopen()))
mysql_ha_close_table(thd, hash_tables);
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 525f6b9a4d8..5da9f2e6bd4 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2638,7 +2638,7 @@ bool Delayed_insert::handle_inserts(void)
thd_proc_info(&thd, "insert");
max_rows= delayed_insert_limit;
- if (thd.killed || table->needs_reopen_or_name_lock())
+ if (thd.killed || table->needs_reopen())
{
thd.killed= THD::KILL_CONNECTION;
max_rows= ULONG_MAX; // Do as much as possible
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 48f33bf3295..3c67574d8c1 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -6262,7 +6262,7 @@ static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt)
and we set db_stat to zero to ensure we don't close twice.
*/
pthread_mutex_lock(&LOCK_open);
- close_data_files_and_morph_locks(thd, db, table_name);
+ close_data_files_and_leave_as_placeholders(thd, db, table_name);
pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(0);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 5dee7015bd4..649ba28bcac 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -7415,7 +7415,7 @@ view_err:
pthread_mutex_lock(&LOCK_open);
- close_data_files_and_morph_locks(thd, db, table_name);
+ close_data_files_and_leave_as_placeholders(thd, db, table_name);
error=0;
save_old_db_type= old_db_type;
@@ -7507,8 +7507,7 @@ view_err:
object to make it suitable for reopening.
*/
DBUG_ASSERT(t_table == table);
- table->open_placeholder= 1;
- close_handle_and_leave_table_as_lock(table);
+ close_handle_and_leave_table_as_placeholder(table);
}
else
{
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index a623b3c80f3..a7a4d48b593 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -487,7 +487,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
if (!result && thd->locked_tables)
{
/* Make table suitable for reopening */
- close_data_files_and_morph_locks(thd, tables->db, tables->table_name);
+ close_data_files_and_leave_as_placeholders(thd, tables->db,
+ tables->table_name);
thd->in_lock_tables= 1;
if (reopen_tables(thd, 1))
{
diff --git a/sql/table.h b/sql/table.h
index 60560029725..a31b96e0828 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -793,24 +793,6 @@ public:
*/
my_bool key_read;
my_bool no_keyread;
- /*
- Placeholder for an open table which prevents other connections
- from taking name-locks on this table. Typically used with
- TABLE_SHARE::version member to take an exclusive name-lock on
- this table name -- a name lock that not only prevents other
- threads from opening the table, but also blocks other name
- locks. This is achieved by:
- - setting open_placeholder to 1 - this will block other name
- locks, as wait_for_locked_table_name will be forced to wait,
- see table_is_used for details.
- - setting version to 0 - this will force other threads to close
- the instance of this table and wait (this is the same approach
- as used for usual name locks).
- An exclusively name-locked table currently can have no handler
- object associated with it (db_stat is always 0), but please do
- not rely on that.
- */
- my_bool open_placeholder;
my_bool locked_by_logger;
my_bool no_replicate;
my_bool locked_by_name;
@@ -874,12 +856,10 @@ public:
read_set= &def_read_set;
write_set= &def_write_set;
}
- /* Is table open or should be treated as such by name-locking? */
- inline bool is_name_opened() { return db_stat || open_placeholder; }
/*
- Is this instance of the table should be reopen or represents a name-lock?
+ Is this instance of the table should be reopen?
*/
- inline bool needs_reopen_or_name_lock()
+ inline bool needs_reopen()
{ return s->version != refresh_version; }
bool is_children_attached(void);
};