Skip to content

Commit 0abf8b3

Browse files
Dmitry LenevDmitry Lenev
authored andcommitted
Reverted a temporary workaround for bug #56405 "Deadlock
in the MDL deadlock detector". It is no longer needed as a better fix for this bug has been pushed. --BZR-- revision-id: [email protected] property-branch-nick: mysql-5.5-rt-mrg testament3-sha1: fdc2eff54b5f4a4388e5a7b1968949d7c5e329ff
1 parent 28077bf commit 0abf8b3

6 files changed

Lines changed: 14 additions & 83 deletions

File tree

mysql-test/suite/perfschema/r/dml_setup_instruments.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ wait/synch/mutex/sql/LOCK_active_mi YES YES
1313
wait/synch/mutex/sql/LOCK_audit_mask YES YES
1414
wait/synch/mutex/sql/LOCK_connection_count YES YES
1515
wait/synch/mutex/sql/LOCK_crypt YES YES
16-
wait/synch/mutex/sql/LOCK_dd_owns_lock_open YES YES
16+
wait/synch/mutex/sql/LOCK_delayed_create YES YES
1717
select * from performance_schema.SETUP_INSTRUMENTS
1818
where name like 'Wait/Synch/Rwlock/sql/%'
1919
and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock')

sql/mdl.cc

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class Deadlock_detection_visitor: public MDL_wait_for_graph_visitor
124124
Deadlock_detection_visitor(MDL_context *start_node_arg)
125125
: m_start_node(start_node_arg),
126126
m_victim(NULL),
127+
m_current_search_depth(0),
127128
m_found_deadlock(FALSE)
128129
{}
129130
virtual bool enter_node(MDL_context *node);
@@ -132,8 +133,6 @@ class Deadlock_detection_visitor: public MDL_wait_for_graph_visitor
132133
virtual bool inspect_edge(MDL_context *dest);
133134

134135
MDL_context *get_victim() const { return m_victim; }
135-
136-
void abort_traversal(MDL_context *node);
137136
private:
138137
/**
139138
Change the deadlock victim to a new one if it has lower deadlock
@@ -148,6 +147,13 @@ class Deadlock_detection_visitor: public MDL_wait_for_graph_visitor
148147
MDL_context *m_start_node;
149148
/** If a deadlock is found, the context that identifies the victim. */
150149
MDL_context *m_victim;
150+
/** Set to the 0 at start. Increased whenever
151+
we descend into another MDL context (aka traverse to the next
152+
wait-for graph node). When MAX_SEARCH_DEPTH is reached, we
153+
assume that a deadlock is found, even if we have not found a
154+
loop.
155+
*/
156+
uint m_current_search_depth;
151157
/** TRUE if we found a deadlock. */
152158
bool m_found_deadlock;
153159
/**
@@ -181,7 +187,7 @@ class Deadlock_detection_visitor: public MDL_wait_for_graph_visitor
181187

182188
bool Deadlock_detection_visitor::enter_node(MDL_context *node)
183189
{
184-
m_found_deadlock= m_current_search_depth >= MAX_SEARCH_DEPTH;
190+
m_found_deadlock= ++m_current_search_depth >= MAX_SEARCH_DEPTH;
185191
if (m_found_deadlock)
186192
{
187193
DBUG_ASSERT(! m_victim);
@@ -201,6 +207,7 @@ bool Deadlock_detection_visitor::enter_node(MDL_context *node)
201207

202208
void Deadlock_detection_visitor::leave_node(MDL_context *node)
203209
{
210+
--m_current_search_depth;
204211
if (m_found_deadlock)
205212
opt_change_victim_to(node);
206213
}
@@ -244,21 +251,6 @@ Deadlock_detection_visitor::opt_change_victim_to(MDL_context *new_victim)
244251
}
245252

246253

247-
/**
248-
Abort traversal of a wait-for graph and report a deadlock.
249-
250-
@param node Node which we were about to visit when abort
251-
was initiated.
252-
*/
253-
254-
void Deadlock_detection_visitor::abort_traversal(MDL_context *node)
255-
{
256-
DBUG_ASSERT(! m_victim);
257-
m_found_deadlock= TRUE;
258-
opt_change_victim_to(node);
259-
}
260-
261-
262254
/**
263255
Get a bit corresponding to enum_mdl_type value in a granted/waiting bitmaps
264256
and compatibility matrices.
@@ -2064,13 +2056,8 @@ bool MDL_lock::visit_subgraph(MDL_ticket *waiting_ticket,
20642056
are visiting it but this is OK: in the worst case we might do some
20652057
extra work and one more context might be chosen as a victim.
20662058
*/
2067-
++gvisitor->m_current_search_depth;
2068-
20692059
if (gvisitor->enter_node(src_ctx))
2070-
{
2071-
--gvisitor->m_current_search_depth;
20722060
goto end;
2073-
}
20742061

20752062
/*
20762063
We do a breadth-first search first -- that is, inspect all
@@ -2127,7 +2114,6 @@ bool MDL_lock::visit_subgraph(MDL_ticket *waiting_ticket,
21272114

21282115
end_leave_node:
21292116
gvisitor->leave_node(src_ctx);
2130-
--gvisitor->m_current_search_depth;
21312117

21322118
end:
21332119
mysql_prlock_unlock(&m_rwlock);

sql/mdl.h

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,7 @@ class MDL_wait_for_graph_visitor
385385

386386
virtual bool inspect_edge(MDL_context *dest) = 0;
387387
virtual ~MDL_wait_for_graph_visitor();
388-
MDL_wait_for_graph_visitor() :m_lock_open_count(0),
389-
m_current_search_depth(0)
390-
{ }
391-
virtual void abort_traversal(MDL_context *node) = 0;
388+
MDL_wait_for_graph_visitor() :m_lock_open_count(0) {}
392389
public:
393390
/**
394391
XXX, hack: During deadlock search, we may need to
@@ -399,17 +396,6 @@ class MDL_wait_for_graph_visitor
399396
LOCK_open since it has significant performance impacts.
400397
*/
401398
uint m_lock_open_count;
402-
/**
403-
Set to the 0 at start. Increased whenever
404-
we descend into another MDL context (aka traverse to the next
405-
wait-for graph node). When MAX_SEARCH_DEPTH is reached, we
406-
assume that a deadlock is found, even if we have not found a
407-
loop.
408-
409-
XXX: This member belongs to this class only temporarily until
410-
bug #56405 is fixed.
411-
*/
412-
uint m_current_search_depth;
413399
};
414400

415401
/**

sql/sql_base.cc

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,11 @@ bool No_such_table_error_handler::safely_trapped_errors()
100100
TABLE_SHAREs, refresh_version and the table id counter.
101101
*/
102102
mysql_mutex_t LOCK_open;
103-
mysql_mutex_t LOCK_dd_owns_lock_open;
104-
uint dd_owns_lock_open= 0;
105103

106104
#ifdef HAVE_PSI_INTERFACE
107-
static PSI_mutex_key key_LOCK_open, key_LOCK_dd_owns_lock_open;
105+
static PSI_mutex_key key_LOCK_open;
108106
static PSI_mutex_info all_tdc_mutexes[]= {
109-
{ &key_LOCK_open, "LOCK_open", PSI_FLAG_GLOBAL },
110-
{ &key_LOCK_dd_owns_lock_open, "LOCK_dd_owns_lock_open", PSI_FLAG_GLOBAL }
107+
{ &key_LOCK_open, "LOCK_open", PSI_FLAG_GLOBAL }
111108
};
112109

113110
/**
@@ -302,8 +299,6 @@ bool table_def_init(void)
302299
init_tdc_psi_keys();
303300
#endif
304301
mysql_mutex_init(key_LOCK_open, &LOCK_open, MY_MUTEX_INIT_FAST);
305-
mysql_mutex_init(key_LOCK_dd_owns_lock_open, &LOCK_dd_owns_lock_open,
306-
MY_MUTEX_INIT_FAST);
307302
oldest_unused_share= &end_of_unused_share;
308303
end_of_unused_share.prev= &oldest_unused_share;
309304

@@ -347,7 +342,6 @@ void table_def_free(void)
347342
table_def_inited= 0;
348343
/* Free table definitions. */
349344
my_hash_free(&table_def_cache);
350-
mysql_mutex_destroy(&LOCK_dd_owns_lock_open);
351345
mysql_mutex_destroy(&LOCK_open);
352346
}
353347
DBUG_VOID_RETURN;

sql/sql_base.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
7070

7171
bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
7272
extern mysql_mutex_t LOCK_open;
73-
extern mysql_mutex_t LOCK_dd_owns_lock_open;
74-
extern uint dd_owns_lock_open;
7573
bool table_cache_init(void);
7674
void table_cache_free(void);
7775
bool table_def_init(void);

sql/table.cc

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3085,30 +3085,7 @@ bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
30853085
holding a write-lock on MDL_lock::m_rwlock.
30863086
*/
30873087
if (gvisitor->m_lock_open_count++ == 0)
3088-
{
3089-
/*
3090-
To circumvent bug #56405 "Deadlock in the MDL deadlock detector"
3091-
we don't try to lock LOCK_open mutex if some thread doing
3092-
deadlock detection already owns it and current search depth is
3093-
greater than 0. Instead we report a deadlock.
3094-
3095-
TODO/FIXME: The proper fix for this bug is to use rwlocks for
3096-
protection of table shares/instead of LOCK_open.
3097-
Unfortunately it requires more effort/has significant
3098-
performance effect.
3099-
*/
3100-
mysql_mutex_lock(&LOCK_dd_owns_lock_open);
3101-
if (gvisitor->m_current_search_depth > 0 && dd_owns_lock_open > 0)
3102-
{
3103-
mysql_mutex_unlock(&LOCK_dd_owns_lock_open);
3104-
--gvisitor->m_lock_open_count;
3105-
gvisitor->abort_traversal(src_ctx);
3106-
return TRUE;
3107-
}
3108-
++dd_owns_lock_open;
3109-
mysql_mutex_unlock(&LOCK_dd_owns_lock_open);
31103088
mysql_mutex_lock(&LOCK_open);
3111-
}
31123089

31133090
I_P_List_iterator <TABLE, TABLE_share> tables_it(used_tables);
31143091

@@ -3123,12 +3100,8 @@ bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
31233100
goto end;
31243101
}
31253102

3126-
++gvisitor->m_current_search_depth;
31273103
if (gvisitor->enter_node(src_ctx))
3128-
{
3129-
--gvisitor->m_current_search_depth;
31303104
goto end;
3131-
}
31323105

31333106
while ((table= tables_it++))
31343107
{
@@ -3151,16 +3124,10 @@ bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
31513124

31523125
end_leave_node:
31533126
gvisitor->leave_node(src_ctx);
3154-
--gvisitor->m_current_search_depth;
31553127

31563128
end:
31573129
if (gvisitor->m_lock_open_count-- == 1)
3158-
{
31593130
mysql_mutex_unlock(&LOCK_open);
3160-
mysql_mutex_lock(&LOCK_dd_owns_lock_open);
3161-
--dd_owns_lock_open;
3162-
mysql_mutex_unlock(&LOCK_dd_owns_lock_open);
3163-
}
31643131

31653132
return result;
31663133
}

0 commit comments

Comments
 (0)