Backport of:
------------------------------------------------------------ revno: 2630.4.14 committer: Dmitry Lenev <dlenev@mysql.com> branch nick: mysql-6.0-3726-w timestamp: Wed 2008-05-28 12:16:03 +0400 message: WL#3726 "DDL locking for all metadata objects". After review fixes in progress. Removed unused code and adjusted names of functions/methods to better reflect their current function.
This commit is contained in:
parent
af4ee7432a
commit
3d19fdad34
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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))
|
||||
{
|
||||
|
24
sql/table.h
24
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);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user