• Marko Mäkelä's avatar
    MDEV-12674 Innodb_row_lock_current_waits has overflow · ff166093
    Marko Mäkelä authored
    There is a race condition related to the variable
    srv_stats.n_lock_wait_current_count, which is only
    incremented and decremented by the function lock_wait_suspend_thread(),
    
    The incrementing is protected by lock_sys->wait_mutex, but the
    decrementing does not appear to be protected by anything.
    This mismatch could allow the counter to be corrupted when a
    transactional InnoDB table or record lock wait is terminating
    roughly at the same time with the start of a wait on a
    (possibly different) lock.
    
    ib_counter_t: Remove some unused methods. Prevent instantiation for N=1.
    Add an inc() method that takes a slot index as a parameter.
    
    single_indexer_t: Remove.
    
    simple_counter<typename Type, bool atomic=false>: A new counter wrapper.
    Optionally use atomic memory operations for modifying the counter.
    Aligned to the cache line size.
    
    lsn_ctr_1_t, ulint_ctr_1_t, int64_ctr_1_t: Define as simple_counter<Type>.
    These counters are either only incremented (and we do not care about
    losing some increment operations), or the increment/decrement operations
    are protected by some mutex.
    
    srv_stats_t::os_log_pending_writes: Document that the number is protected
    by log_sys->mutex.
    
    srv_stats_t::n_lock_wait_current_count: Use simple_counter<ulint, true>,
    that is, atomic inc() and dec() operations.
    
    lock_wait_suspend_thread(): Release the mutexes before incrementing
    the counters. Avoid acquiring the lock mutex if the lock wait has
    already been resolved. Atomically increment and decrement
    srv_stats.n_lock_wait_current_count.
    
    row_insert_for_mysql(), row_update_for_mysql(),
    row_update_cascade_for_mysql(): Use the inc() method with the trx->id
    as the slot index. This is a non-functional change, just using
    inc() instead of add(1).
    
    buf_LRU_get_free_block(): Replace the method add(index, n) with inc().
    There is no slot index in the simple_counter.
    ff166093
row0mysql.cc 151 KB