-
Sujatha Sivakumar authored
Problem: ======= Access to the following variables is protected by LOCK_log. binlog-transaction-dependency-tracking binlog-transaction-dependency-history-size 'LOCK_log' is held when these variables are being set or read. Holding 'LOCK_log' results in following Deadlock scenario. Analysis: ========= 1) SELECT * FROM performance_schema.session_variables WHERE VARIABLE_NAME LIKE 'binlog_transaction_dependency_tracking'; The above query acquires a lock on thread data and tries to read the values of 'binlog_transaction_dependency_tracking'. Inorder to read this variable 'LOCK_log' is required. Owns: THD::LOCK_thd_data (acquired in PFS_system_variable_cache::do_materialize_all ->PFS_variable_cache<Var_type>::get_THD -> Find_THD_variable::operator()) Waits for: MYSQL_BIN_LOG::LOCK_log 2) SHOW BINARY LOGS Above command acquires 'LOCK_log' to read current active binary log specific information and then goes on to acquire LOCK_index, so that it can list the rest of binary logs. Owns: MYSQL_BIN_LOG::LOCK_log (acquired in show_binlogs()) Waits for: MYSQL_BIN_LOG::LOCK_index 3) PURGE LOGS BEFORE date Above command acquires 'LOCK_index' and reads one log at a time from index. For each log it tries to identify how many threads are accessing this log. Inorder to do this it acquires a lock on global thread list and iterates through the entire thread list. For each thread it tries to acquire LOCK_thd_data and verify if the log is being used by the tread or not. Hence it waits for the lock. Owns: MYSQL_BIN_LOG::LOCK_index (acquired in MYSQL_BIN_LOG::purge_logs_before_date) Waits for: THD::LOCK_thd_data Fix: === Transaction dependency tracking information is updated based on 'max_committed_transaction' object contents. 'max_committed_transaction' holds the transaction sequence_number. This transaction_sequence number is updated during the flush stage of the commit and it is used to update the transaction dependency tracking through 'update_max_committed' function call. 'LOCK_log' needs to be held when the active binary log is being modified. Where as to protect concurrent access to set or read dependency tracking information a less granular lock should be sufficient. Hence a new lock named 'LOCK_slave_trans_dep_tracker' has been introduced to protect concurrent access to transaction dependency tracking information.
Sujatha Sivakumar authoredProblem: ======= Access to the following variables is protected by LOCK_log. binlog-transaction-dependency-tracking binlog-transaction-dependency-history-size 'LOCK_log' is held when these variables are being set or read. Holding 'LOCK_log' results in following Deadlock scenario. Analysis: ========= 1) SELECT * FROM performance_schema.session_variables WHERE VARIABLE_NAME LIKE 'binlog_transaction_dependency_tracking'; The above query acquires a lock on thread data and tries to read the values of 'binlog_transaction_dependency_tracking'. Inorder to read this variable 'LOCK_log' is required. Owns: THD::LOCK_thd_data (acquired in PFS_system_variable_cache::do_materialize_all ->PFS_variable_cache<Var_type>::get_THD -> Find_THD_variable::operator()) Waits for: MYSQL_BIN_LOG::LOCK_log 2) SHOW BINARY LOGS Above command acquires 'LOCK_log' to read current active binary log specific information and then goes on to acquire LOCK_index, so that it can list the rest of binary logs. Owns: MYSQL_BIN_LOG::LOCK_log (acquired in show_binlogs()) Waits for: MYSQL_BIN_LOG::LOCK_index 3) PURGE LOGS BEFORE date Above command acquires 'LOCK_index' and reads one log at a time from index. For each log it tries to identify how many threads are accessing this log. Inorder to do this it acquires a lock on global thread list and iterates through the entire thread list. For each thread it tries to acquire LOCK_thd_data and verify if the log is being used by the tread or not. Hence it waits for the lock. Owns: MYSQL_BIN_LOG::LOCK_index (acquired in MYSQL_BIN_LOG::purge_logs_before_date) Waits for: THD::LOCK_thd_data Fix: === Transaction dependency tracking information is updated based on 'max_committed_transaction' object contents. 'max_committed_transaction' holds the transaction sequence_number. This transaction_sequence number is updated during the flush stage of the commit and it is used to update the transaction dependency tracking through 'update_max_committed' function call. 'LOCK_log' needs to be held when the active binary log is being modified. Where as to protect concurrent access to set or read dependency tracking information a less granular lock should be sufficient. Hence a new lock named 'LOCK_slave_trans_dep_tracker' has been introduced to protect concurrent access to transaction dependency tracking information.
Loading