1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-02 09:41:40 +03:00

Commit on behalf of Dmitry Lenev.

Merge his patch for Bug#52044 into 5.5, and apply 
review comments.
This commit is contained in:
Konstantin Osipov
2010-08-12 17:50:23 +04:00
27 changed files with 1264 additions and 366 deletions

View File

@@ -1756,6 +1756,7 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
{
Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
TABLE_LIST *table_list;
MDL_request_list mdl_requests;
/*
This is called from SQLCOM_FLUSH, the transaction has
@@ -1774,22 +1775,26 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
}
/*
@todo: Since lock_table_names() acquires a global IX
lock, this actually waits for a GRL in another connection.
We are thus introducing an incompatibility.
Do nothing for now, since not taking a global IX violates
current internal MDL asserts, fix after discussing with
Dmitry.
Acquire SNW locks on tables to be flushed. We can't use
lock_table_names() here as this call will also acquire global IX
and database-scope IX locks on the tables, and this will make
this statement incompatible with FLUSH TABLES WITH READ LOCK.
*/
if (lock_table_names(thd, all_tables, 0, thd->variables.lock_wait_timeout,
MYSQL_OPEN_SKIP_TEMPORARY))
for (table_list= all_tables; table_list;
table_list= table_list->next_global)
mdl_requests.push_front(&table_list->mdl_request);
if (thd->mdl_context.acquire_locks(&mdl_requests,
thd->variables.lock_wait_timeout))
goto error;
DEBUG_SYNC(thd,"flush_tables_with_read_lock_after_acquire_locks");
for (table_list= all_tables; table_list;
table_list= table_list->next_global)
{
/* Remove the table from cache. */
tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
/* Request removal of table from cache. */
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
table_list->db,
table_list->table_name, FALSE);
@@ -1798,6 +1803,11 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
table_list->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */
}
/*
Before opening and locking tables the below call also waits
for old shares to go away, so the fact that we don't pass
MYSQL_LOCK_IGNORE_FLUSH flag to it is important.
*/
if (open_and_lock_tables(thd, all_tables, FALSE,
MYSQL_OPEN_HAS_MDL_LOCK,
&lock_tables_prelocking_strategy) ||
@@ -1808,17 +1818,11 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
thd->variables.option_bits|= OPTION_TABLE_LOCK;
/*
Downgrade the exclusive locks.
Use MDL_SHARED_NO_WRITE as the intended
post effect of this call is identical
to LOCK TABLES <...> READ, and we didn't use
thd->in_lock_talbes and thd->sql_command= SQLCOM_LOCK_TABLES
hacks to enter the LTM.
@todo: release the global IX lock here!!!
We don't downgrade MDL_SHARED_NO_WRITE here as the intended
post effect of this call is identical to LOCK TABLES <...> READ,
and we didn't use thd->in_lock_talbes and
thd->sql_command= SQLCOM_LOCK_TABLES hacks to enter the LTM.
*/
for (table_list= all_tables; table_list;
table_list= table_list->next_global)
table_list->mdl_request.ticket->downgrade_exclusive_lock(MDL_SHARED_NO_WRITE);
return FALSE;
@@ -6852,10 +6856,11 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
tmp_write_to_binlog= 0;
if (thd->global_read_lock.lock_global_read_lock(thd))
return 1; // Killed
if (close_cached_tables(thd, tables, (options & REFRESH_FAST) ?
FALSE : TRUE))
result= 1;
if (close_cached_tables(thd, tables,
((options & REFRESH_FAST) ? FALSE : TRUE),
thd->variables.lock_wait_timeout))
result= 1;
if (thd->global_read_lock.make_global_read_lock_block_commit(thd)) // Killed
{
/* Don't leave things in a half-locked state */
@@ -6892,8 +6897,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
}
if (close_cached_tables(thd, tables, (options & REFRESH_FAST) ?
FALSE : TRUE))
if (close_cached_tables(thd, tables,
((options & REFRESH_FAST) ? FALSE : TRUE),
(thd ? thd->variables.lock_wait_timeout :
LONG_TIMEOUT)))
result= 1;
}
my_dbopt_cleanup();