• Marko Mäkelä's avatar
    MDEV-22027 Assertion oldest_lsn >= log_sys.last_checkpoint_lsn failed · 0d6d63e1
    Marko Mäkelä authored
    log_buf_pool_get_oldest_modification(): Acquire
    log_sys_t::flush_order_mutex in order to prevent a race condition
    that was introduced in
    commit 1a6f708e (MDEV-15058).
    
    Before that change, log_buf_pool_get_oldest_modification()
    was protected by both log_sys.mutex and log_sys.flush_order_mutex
    like it was supposed to be ever since
    commit a52c4820 (MySQL 5.5.10).
    
    buf_pool_t::get_oldest_modification(): Replaces
    buf_pool_get_oldest_modification(), to emphasize that
    log_sys.flush_order_mutex must be acquired by the caller if needed.
    
    log_close(): Invoke log_buf_pool_get_oldest_modification()
    in order to ensure a clean shutdown.
    
    The scenario of the race condition is as follows:
    
    1. The buffer pool is clean (no writes are pending).
    2. mtr_add_dirtied_pages_to_flush_list() releases log_sys.mutex.
    3. log_buf_pool_get_oldest_modification() observes that the
    buffer pool is clean and returns log_sys.lsn.
    4. log_checkpoint() completes, writing a wrong checkpoint header
    according to which everything up to log_sys.lsn was clean.
    5. mtr_add_dirtied_pages_to_flush_list() completes the execution
    of mtr_memo_note_modifications(), releases the page latches and
    the flush_order_mutex.
    6. On a subsequent log_checkpoint(), the assertion could fail
    if the page modifications had not been flushed yet.
    
    The failing assertion (which is valid) was added in MySQL 5.7
    mysql/mysql-server@5c6c6ec69336369487dfc080a6980089b4e1a3c2
    and merged to MariaDB Server 10.2.2 in
    commit fec844ac.
    0d6d63e1
srv0mon.cc 70.1 KB