Skip to content
  • Sujatha Sivakumar's avatar
    38a6d1d0
    Bug#28511326: DEADLOCK DURING PURGE_LOGS_BEFORE_DATE · 38a6d1d0
    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.
    38a6d1d0
    Bug#28511326: DEADLOCK DURING PURGE_LOGS_BEFORE_DATE
    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.
Loading