Skip to content

Instantly share code, notes, and snippets.

@nirbhayc
Created May 20, 2016 13:50
Show Gist options
  • Save nirbhayc/21501c99c91bbfc7202daed6a620f804 to your computer and use it in GitHub Desktop.
Save nirbhayc/21501c99c91bbfc7202daed6a620f804 to your computer and use it in GitHub Desktop.
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 20e1836..da55889 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -274,7 +274,7 @@ static my_bool list_open_tables_callback(TDC_element *element,
(*arg->start_list)->in_use= 0;
mysql_mutex_lock(&element->LOCK_table_share);
- TDC_element::All_share_tables_list::Iterator it(element->all_tables);
+ TABLE_SHARE::All_share_tables_list::Iterator it(element->share->all_tables);
TABLE *table;
while ((table= it++))
if (table->in_use)
@@ -355,7 +355,7 @@ void free_io_cache(TABLE *table)
void kill_delayed_threads_for_table(TDC_element *element)
{
- TDC_element::All_share_tables_list::Iterator it(element->all_tables);
+ TABLE_SHARE::All_share_tables_list::Iterator it(element->share->all_tables);
TABLE *tab;
mysql_mutex_assert_owner(&element->LOCK_table_share);
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 8e75258..fbf7085 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -82,7 +82,7 @@ static my_bool print_cached_tables_callback(TDC_element *element,
TABLE *entry;
mysql_mutex_lock(&element->LOCK_table_share);
- TDC_element::All_share_tables_list::Iterator it(element->all_tables);
+ TABLE_SHARE::All_share_tables_list::Iterator it(element->share->all_tables);
while ((entry= it++))
{
THD *in_use= entry->in_use;
diff --git a/sql/table.cc b/sql/table.cc
index 84f70cd..6b7519d 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -3933,7 +3933,7 @@ bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
tdc->all_tables_refs++;
mysql_mutex_unlock(&tdc->LOCK_table_share);
- TDC_element::All_share_tables_list::Iterator tables_it(tdc->all_tables);
+ TABLE_SHARE::All_share_tables_list::Iterator tables_it(tdc->share->all_tables);
/*
In case of multiple searches running in parallel, avoid going
diff --git a/sql/table.h b/sql/table.h
index 8b7c665..5d7f951 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -601,7 +601,16 @@ struct TABLE_STATISTICS_CB
struct TABLE_SHARE
{
TABLE_SHARE() {} /* Remove gcc warning */
- TABLE_SHARE *next, *prev;
+
+ /* Link to unused shares. */
+ TABLE_SHARE *next, **prev;
+
+ typedef I_P_List <TABLE, All_share_tables> All_share_tables_list;
+ /*
+ Doubly-linked (back-linked) lists of used and unused TABLE objects
+ for this share.
+ */
+ All_share_tables_list all_tables;
/** Category of this table. */
TABLE_CATEGORY table_category;
diff --git a/sql/table_cache.cc b/sql/table_cache.cc
index b307841..8eace22 100644
--- a/sql/table_cache.cc
+++ b/sql/table_cache.cc
@@ -61,10 +61,10 @@
/** Data collections. */
static LF_HASH tdc_hash; /**< Collection of TABLE_SHARE objects. */
/** Collection of unused TABLE_SHARE objects. */
-I_P_List <TDC_element,
- I_P_List_adapter<TDC_element, &TDC_element::next, &TDC_element::prev>,
+I_P_List <TABLE_SHARE,
+ I_P_List_adapter<TABLE_SHARE, &TABLE_SHARE::next, &TABLE_SHARE::prev>,
I_P_List_null_counter,
- I_P_List_fast_push_back<TDC_element> > unused_shares;
+ I_P_List_fast_push_back<TABLE_SHARE> > unused_shares;
static int64 tdc_version; /* Increments on each reload */
static int64 last_table_id;
@@ -143,13 +143,13 @@ uint tc_records(void)
Remove TABLE object from table cache.
- decrement tc_count
- - remove object from TABLE_SHARE::tdc.all_tables
+ - remove object from TABLE_SHARE::all_tables
*/
static void tc_remove_table(TABLE *table)
{
my_atomic_add32_explicit(&tc_count, -1, MY_MEMORY_ORDER_RELAXED);
- table->s->tdc->all_tables.remove(table);
+ table->s->all_tables.remove(table);
}
@@ -158,7 +158,7 @@ static void tc_remove_table(TABLE *table)
While locked:
- remove unused objects from TABLE_SHARE::tdc.free_tables and
- TABLE_SHARE::tdc.all_tables
+ TABLE_SHARE::all_tables
- decrement tc_count
While unlocked:
@@ -213,7 +213,7 @@ void tc_purge(bool mark_flushed)
Added object cannot be evicted or acquired.
While locked:
- - add object to TABLE_SHARE::tdc.all_tables
+ - add object to TABLE_SHARE::all_tables
- increment tc_count
- evict LRU object from table cache if we reached threshold
@@ -251,7 +251,7 @@ void tc_add_table(THD *thd, TABLE *table)
DBUG_ASSERT(table->in_use == thd);
mysql_mutex_lock(&table->s->tdc->LOCK_table_share);
table->s->tdc->wait_for_mdl_deadlock_detector();
- table->s->tdc->all_tables.push_front(table);
+ table->s->all_tables.push_front(table);
mysql_mutex_unlock(&table->s->tdc->LOCK_table_share);
/* If we have too many TABLE instances around, try to get rid of them */
@@ -497,18 +497,20 @@ void tdc_purge(bool all)
DBUG_ENTER("tdc_purge");
while (all || tdc_records() > tdc_size)
{
+ TABLE_SHARE *share;
TDC_element *element;
mysql_mutex_lock(&LOCK_unused_shares);
- if (!(element= unused_shares.pop_front()))
+ if (!(share= unused_shares.pop_front()))
{
mysql_mutex_unlock(&LOCK_unused_shares);
break;
}
/* Concurrent thread may start using share again, reset prev and next. */
- element->prev= 0;
- element->next= 0;
+ share->prev= 0;
+ share->next= 0;
+ element= share->tdc;
mysql_mutex_lock(&element->LOCK_table_share);
if (element->ref_count)
{
@@ -713,16 +715,16 @@ TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db, const char *table_name,
if (was_unused)
{
mysql_mutex_lock(&LOCK_unused_shares);
- if (element->prev)
+ if (element->share->prev)
{
/*
Share was not used before and it was in the old_unused_share list
Unlink share from this list
*/
DBUG_PRINT("info", ("Unlinking from not used list"));
- unused_shares.remove(element);
- element->next= 0;
- element->prev= 0;
+ unused_shares.remove(element->share);
+ element->share->next= 0;
+ element->share->prev= 0;
}
mysql_mutex_unlock(&LOCK_unused_shares);
}
@@ -791,8 +793,8 @@ void tdc_release_share(TABLE_SHARE *share)
}
/* Link share last in used_table_share list */
DBUG_PRINT("info", ("moving share to unused list"));
- DBUG_ASSERT(share->tdc->next == 0);
- unused_shares.push_back(share->tdc);
+ DBUG_ASSERT(share->next == 0);
+ unused_shares.push_back(share);
mysql_mutex_unlock(&share->tdc->LOCK_table_share);
mysql_mutex_unlock(&LOCK_unused_shares);
DBUG_VOID_RETURN;
@@ -866,11 +868,11 @@ bool tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
if (!element->ref_count)
{
- if (element->prev)
+ if (element->share->prev)
{
- unused_shares.remove(element);
- element->prev= 0;
- element->next= 0;
+ unused_shares.remove(element->share);
+ element->share->prev= 0;
+ element->share->next= 0;
}
mysql_mutex_unlock(&LOCK_unused_shares);
@@ -904,14 +906,15 @@ bool tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
if (remove_type == TDC_RT_REMOVE_NOT_OWN ||
remove_type == TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE)
{
- TDC_element::All_share_tables_list::Iterator it(element->all_tables);
+ TABLE_SHARE::All_share_tables_list::Iterator it(element->share->all_tables);
while ((table= it++))
{
my_refs++;
DBUG_ASSERT(table->in_use == thd);
}
}
- DBUG_ASSERT(element->all_tables.is_empty() || remove_type != TDC_RT_REMOVE_ALL);
+ DBUG_ASSERT(element->share->all_tables.is_empty() ||
+ remove_type != TDC_RT_REMOVE_ALL);
mysql_mutex_unlock(&element->LOCK_table_share);
while ((table= purge_tables.pop_front()))
@@ -924,7 +927,7 @@ bool tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
(asserted above), concurrent FLUSH TABLES threads may be in process of
closing unused table instances belonging to this share. E.g.:
thr1 (FLUSH TABLES): table= share->tdc.free_tables.pop_front();
- thr1 (FLUSH TABLES): share->tdc.all_tables.remove(table);
+ thr1 (FLUSH TABLES): share->all_tables.remove(table);
thr2 (ALTER TABLE): tdc_remove_table();
thr1 (FLUSH TABLES): intern_close_table(table);
diff --git a/sql/table_cache.h b/sql/table_cache.h
index ac36269..8948535 100644
--- a/sql/table_cache.h
+++ b/sql/table_cache.h
@@ -33,25 +33,18 @@ class TDC_element
TABLE_SHARE *share;
typedef I_P_List <TABLE, TABLE_share> TABLE_list;
- typedef I_P_List <TABLE, All_share_tables> All_share_tables_list;
/**
Protects ref_count, m_flush_tickets, all_tables, free_tables, flushed,
all_tables_refs.
*/
mysql_mutex_t LOCK_table_share;
mysql_cond_t COND_release;
- TDC_element *next, **prev; /* Link to unused shares */
uint ref_count; /* How many TABLE objects uses this */
uint all_tables_refs; /* Number of refs to all_tables */
/**
List of tickets representing threads waiting for the share to be flushed.
*/
Wait_for_flush_list m_flush_tickets;
- /*
- Doubly-linked (back-linked) lists of used and unused TABLE objects
- for this share.
- */
- All_share_tables_list all_tables;
TABLE_list free_tables;
TDC_element() {}
@@ -67,11 +60,8 @@ class TDC_element
DBUG_ASSERT(share == 0);
DBUG_ASSERT(ref_count == 0);
DBUG_ASSERT(m_flush_tickets.is_empty());
- DBUG_ASSERT(all_tables.is_empty());
DBUG_ASSERT(free_tables.is_empty());
DBUG_ASSERT(all_tables_refs == 0);
- DBUG_ASSERT(next == 0);
- DBUG_ASSERT(prev == 0);
}
@@ -120,9 +110,10 @@ class TDC_element
/**
- Wait for MDL deadlock detector to complete traversing tdc.all_tables.
+ Wait for MDL deadlock detector to complete traversing
+ TABLE_SHARE::all_tables.
- Must be called before updating TABLE_SHARE::tdc.all_tables.
+ Must be called before updating TABLE_SHARE::all_tables.
*/
void wait_for_mdl_deadlock_detector()
@@ -144,13 +135,10 @@ class TDC_element
&element->LOCK_table_share, MY_MUTEX_INIT_FAST);
mysql_cond_init(key_TABLE_SHARE_COND_release, &element->COND_release, 0);
element->m_flush_tickets.empty();
- element->all_tables.empty();
element->free_tables.empty();
element->all_tables_refs= 0;
element->share= 0;
element->ref_count= 0;
- element->next= 0;
- element->prev= 0;
DBUG_VOID_RETURN;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment