mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-5492 - Reduce usage of LOCK_open: TABLE::in_use
Move TABLE::in_use out of LOCK_open. This is done with assumtion that foreign threads accessing TABLE::in_use will only need consistent value _after_ marking table for flush and purging unused table instances. In this case TABLE::in_use will always point to a valid thread object. Previously FLUSH TABLES thread may wait for tables flushed subsequently by concurrent threads which breaks the above assumption, e.g.: open tables: t1 (version= 1) thr1 (FLUSH TABLES): refresh_version++ thr1 (FLUSH TABLES): purge table cache open tables: none thr2 (SELECT * FROM t1): open tables: t1 open tables: t1 (version= 2) thr2 (FLUSH TABLES): refresh_version++ thr2 (FLUSH TABLES): purge table cache thr1 (FLUSH TABLES): wait for old tables (including t1 with version 2) It is fixed so that FLUSH TABLES waits only for tables that were open heretofore.
This commit is contained in:
10
sql/table.cc
10
sql/table.cc
@@ -3805,7 +3805,7 @@ bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
|
||||
bool result= TRUE;
|
||||
|
||||
/*
|
||||
To protect used_tables list from being concurrently modified
|
||||
To protect all_tables list from being concurrently modified
|
||||
while we are iterating through it we acquire LOCK_open.
|
||||
This does not introduce deadlocks in the deadlock detector
|
||||
because we won't try to acquire LOCK_open while
|
||||
@@ -3832,7 +3832,8 @@ bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
|
||||
|
||||
while ((table= tables_it++))
|
||||
{
|
||||
if (table->in_use && gvisitor->inspect_edge(&table->in_use->mdl_context))
|
||||
DBUG_ASSERT(table->in_use && tdc.flushed);
|
||||
if (gvisitor->inspect_edge(&table->in_use->mdl_context))
|
||||
{
|
||||
goto end_leave_node;
|
||||
}
|
||||
@@ -3841,7 +3842,8 @@ bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
|
||||
tables_it.rewind();
|
||||
while ((table= tables_it++))
|
||||
{
|
||||
if (table->in_use && table->in_use->mdl_context.visit_subgraph(gvisitor))
|
||||
DBUG_ASSERT(table->in_use && tdc.flushed);
|
||||
if (table->in_use->mdl_context.visit_subgraph(gvisitor))
|
||||
{
|
||||
goto end_leave_node;
|
||||
}
|
||||
@@ -3890,7 +3892,7 @@ bool TABLE_SHARE::wait_for_old_version(THD *thd, struct timespec *abstime,
|
||||
MDL_wait::enum_wait_status wait_status;
|
||||
|
||||
mysql_mutex_assert_owner(&tdc.LOCK_table_share);
|
||||
DBUG_ASSERT(has_old_version());
|
||||
DBUG_ASSERT(tdc.flushed);
|
||||
|
||||
tdc.m_flush_tickets.push_front(&ticket);
|
||||
|
||||
|
Reference in New Issue
Block a user