diff options
-rw-r--r-- | sql/mysql_priv.h | 6 | ||||
-rw-r--r-- | sql/sql_base.cc | 60 | ||||
-rw-r--r-- | sql/sql_handler.cc | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_partition.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 5 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 3 | ||||
-rw-r--r-- | sql/table.h | 24 |
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); }; |