mariadb/sql
Venkatesh Duggirala 2870bd7423 Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS,
SHOW PROCESSLIST, SHOW BINLOGS

Problem:  A deadlock was occurring when 4 threads were
involved in acquiring locks in the following way
Thread 1: Dump thread ( Slave is reconnecting, so on
              Master, a new dump thread is trying kill
              zombie dump threads. It acquired thread's
              LOCK_thd_data and it is about to acquire
              mysys_var->current_mutex ( which LOCK_log)
Thread 2: Application thread is executing show binlogs and
               acquired LOCK_log and it is about to acquire
               LOCK_index.
Thread 3: Application thread is executing Purge binary logs
               and acquired LOCK_index and it is about to
               acquire LOCK_thread_count.
Thread 4: Application thread is executing show processlist
               and acquired LOCK_thread_count and it is
               about to acquire zombie dump thread's
               LOCK_thd_data.
Deadlock Cycle:
     Thread 1 -> Thread 2 -> Thread 3-> Thread 4 ->Thread 1

The same above deadlock was observed even when thread 4 is
executing 'SELECT * FROM information_schema.processlist' command and
acquired LOCK_thread_count and it is about to acquire zombie
dump thread's LOCK_thd_data.

Analysis:
There are four locks involved in the deadlock.  LOCK_log,
LOCK_thread_count, LOCK_index and LOCK_thd_data.
LOCK_log, LOCK_thread_count, LOCK_index are global mutexes
where as LOCK_thd_data is local to a thread.
We can divide these four locks in two groups.
Group 1 consists of LOCK_log and LOCK_index and the order
should be LOCK_log followed by LOCK_index.
Group 2 consists of other two mutexes
LOCK_thread_count, LOCK_thd_data and the order should
be LOCK_thread_count followed by LOCK_thd_data.
Unfortunately, there is no specific predefined lock order defined
to follow in the MySQL system when it comes to locks across these
two groups. In the above problematic example,
there is no problem in the way we are acquiring the locks
if you see each thread individually.
But If you combine all 4 threads, they end up in a deadlock.

Fix: 
Since everything seems to be fine in the way threads are taking locks,
In this patch We are changing the duration of the locks in Thread 4
to break the deadlock. i.e., before the patch, Thread 4
('show processlist' command) mysqld_list_processes()
function acquires LOCK_thread_count for the complete duration
of the function and it also acquires/releases
each thread's LOCK_thd_data.

LOCK_thread_count is used to protect addition and
deletion of threads in global threads list. While show
process list is looping through all the existing threads,
it will be a problem if a thread is exited but there is no problem
if a new thread is added to the system. Hence a new mutex is
introduced "LOCK_thd_remove" which will protect deletion
of a thread from global threads list. All threads which are
getting exited should acquire LOCK_thd_remove
followed by LOCK_thread_count. (It should take LOCK_thread_count
also because other places of the code still thinks that exit thread
is protected with LOCK_thread_count. In this fix, we are changing
only 'show process list' query logic )
(Eg: unlink_thd logic will be protected with
LOCK_thd_remove).

Logic of mysqld_list_processes(or file_schema_processlist)
will now be protected with 'LOCK_thd_remove' instead of
'LOCK_thread_count'.

Now the new locking order after this patch is:
LOCK_thd_remove -> LOCK_thd_data -> LOCK_log ->
LOCK_index -> LOCK_thread_count
2014-05-08 18:13:01 +05:30
..
examples
share
add_errmsg
authors.h
client_settings.h
CMakeLists.txt
contributors.h
custom_conf.h
datadict.cc
datadict.h
db.opt
debug_sync.cc
debug_sync.h
derror.cc
derror.h
des_key_file.cc
des_key_file.h
discover.cc
discover.h
event_data_objects.cc
event_data_objects.h
event_db_repository.cc
event_db_repository.h
event_parse_data.cc
event_parse_data.h
event_queue.cc
event_queue.h
event_scheduler.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
event_scheduler.h
events.cc
events.h
field.cc Addendum #1 to the fix for bug #18359924 2014-04-11 10:42:30 +03:00
field.h
field_conv.cc
filesort.cc
filesort.h
frm_crypt.cc
frm_crypt.h
gen_lex_hash.cc
gstream.cc
gstream.h
ha_ndbcluster.cc
ha_ndbcluster.h
ha_ndbcluster_binlog.cc
ha_ndbcluster_binlog.h
ha_ndbcluster_cond.cc
ha_ndbcluster_cond.h
ha_ndbcluster_tables.h
ha_partition.cc
ha_partition.h
handler.cc
handler.h
hash_filo.cc
hash_filo.h
hostname.cc
hostname.h
init.cc
init.h
item.cc
item.h
item_buff.cc
item_cmpfunc.cc
item_cmpfunc.h
item_create.cc
item_create.h
item_func.cc BUG#17994219: CREATE TABLE .. SELECT PRODUCES INVALID STRUCTURE, 2014-04-28 16:28:09 +05:30
item_func.h
item_geofunc.cc
item_geofunc.h
item_row.cc
item_row.h
item_strfunc.cc
item_strfunc.h
item_subselect.cc
item_subselect.h
item_sum.cc
item_sum.h
item_timefunc.cc
item_timefunc.h
item_xmlfunc.cc
item_xmlfunc.h
key.cc
key.h
keycaches.cc
keycaches.h
lex.h
lex_symbol.h
lock.cc
lock.h
log.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
log.h
log_event.cc
log_event.h
log_event_old.cc
log_event_old.h
main.cc
mdl.cc
mdl.h
mem_root_array.h
message.h
message.mc
message.rc
mf_iocache.cc
MSG00001.bin
my_decimal.cc
my_decimal.h
mysqld.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
mysqld.h Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
mysqld_suffix.h
net_serv.cc
nt_servc.cc
nt_servc.h
opt_range.cc Fixing compilation error. Post push fix for Bug#17909656 2014-05-07 16:55:03 +05:30
opt_range.h
opt_sum.cc
parse_file.cc
parse_file.h
partition_element.h
partition_info.cc
partition_info.h
password.c
procedure.cc
procedure.h
protocol.cc
protocol.h
records.cc
records.h
repl_failsafe.cc
repl_failsafe.h
replication.h
rpl_constants.h
rpl_filter.cc
rpl_filter.h
rpl_handler.cc
rpl_handler.h
rpl_injector.cc
rpl_injector.h
rpl_mi.cc
rpl_mi.h
rpl_record.cc
rpl_record.h
rpl_record_old.cc
rpl_record_old.h
rpl_reporting.cc
rpl_reporting.h
rpl_rli.cc
rpl_rli.h
rpl_tblmap.cc
rpl_tblmap.h
rpl_utility.cc
rpl_utility.h
scheduler.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
scheduler.h
set_var.cc
set_var.h
sha2.cc
signal_handler.cc
slave.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
slave.h
sp.cc
sp.h
sp_cache.cc
sp_cache.h
sp_head.cc
sp_head.h
sp_pcontext.cc
sp_pcontext.h
sp_rcontext.cc
sp_rcontext.h
spatial.cc
spatial.h
sql_acl.cc
sql_acl.h
sql_admin.cc
sql_admin.h
sql_alter.cc
sql_alter.h
sql_analyse.cc
sql_analyse.h
sql_array.h
sql_audit.cc
sql_audit.h
sql_base.cc
sql_base.h
sql_binlog.cc
sql_binlog.h
sql_bitmap.h
sql_builtin.cc.in
sql_cache.cc
sql_cache.h
sql_callback.h
sql_class.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
sql_class.h
sql_client.cc
sql_connect.cc
sql_connect.h
sql_const.h
sql_crypt.cc
sql_crypt.h
sql_cursor.cc
sql_cursor.h
sql_db.cc
sql_db.h
sql_delete.cc
sql_delete.h
sql_derived.cc
sql_derived.h
sql_do.cc
sql_do.h
sql_error.cc
sql_error.h
sql_handler.cc
sql_handler.h
sql_help.cc
sql_help.h
sql_hset.h
sql_insert.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
sql_insert.h
sql_lex.cc
sql_lex.h
sql_list.cc
sql_list.h
sql_load.cc Backport from trunk: 2014-04-23 17:01:35 +02:00
sql_load.h
sql_locale.cc
sql_locale.h
sql_manager.cc
sql_manager.h
sql_parse.cc
sql_parse.h
sql_partition.cc Bug#17909699: WRONG RESULTS WITH PARTITION BY LIST COLUMNS() 2014-05-06 11:05:37 +02:00
sql_partition.h
sql_partition_admin.cc
sql_partition_admin.h
sql_plist.h
sql_plugin.cc Bug#17638477 UNINSTALL AND INSTALL SEMI-SYNC PLUGIN CAUSES SLAVES TO BREAK 2014-05-05 22:22:15 +05:30
sql_plugin.h
sql_plugin_services.h
sql_prepare.cc
sql_prepare.h
sql_priv.h
sql_profile.cc
sql_profile.h
sql_reload.cc
sql_reload.h
sql_rename.cc
sql_rename.h
sql_repl.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
sql_repl.h
sql_select.cc Bug #18167356: EXPLAIN W/ EXISTS(SELECT* UNION SELECT*) 2014-04-28 21:07:27 +05:30
sql_select.h
sql_servers.cc
sql_servers.h
sql_show.cc Bug#17283409 4-WAY DEADLOCK: ZOMBIES, PURGING BINLOGS, 2014-05-08 18:13:01 +05:30
sql_show.h Bug#17638477 UNINSTALL AND INSTALL SEMI-SYNC PLUGIN CAUSES SLAVES TO BREAK 2014-05-05 22:22:15 +05:30
sql_signal.cc
sql_signal.h
sql_sort.h
sql_state.c
sql_string.cc Addendum #1 to the fix for bug #18359924 2014-04-11 10:42:30 +03:00
sql_string.h
sql_table.cc
sql_table.h
sql_tablespace.cc
sql_tablespace.h
sql_test.cc
sql_test.h
sql_time.cc
sql_time.h
sql_trigger.cc
sql_trigger.h
sql_truncate.cc Bug#17942050:KILL OF TRUNCATE TABLE WILL LEAD TO BINARY LOG 2014-04-15 15:17:25 +05:30
sql_truncate.h Bug#17942050:KILL OF TRUNCATE TABLE WILL LEAD TO BINARY LOG 2014-04-15 15:17:25 +05:30
sql_udf.cc
sql_udf.h
sql_union.cc Bug #17059925: UNIONS COMPUTES ROWS_EXAMINED INCORRECTLY 2014-05-08 14:49:53 +05:30
sql_union.h
sql_update.cc
sql_update.h
sql_view.cc
sql_view.h
sql_yacc.yy
strfunc.cc
strfunc.h
structs.h
sys_vars.cc
sys_vars.h
sys_vars_shared.h
table.cc
table.h
thr_malloc.cc
thr_malloc.h
transaction.cc
transaction.h
tzfile.h
tztime.cc
tztime.h
udf_example.c
udf_example.def
uniques.cc
unireg.cc
unireg.h