diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-02 08:17:10 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-02 08:17:10 +0300 |
commit | 0d6d63e1505bbf9898d46fa641a7a0579a4ae460 (patch) | |
tree | 9b5f4b906455d1133f029cce8c7c68f1f3c01836 /storage/innobase/include/log0log.h | |
parent | 661ebd469997e42e6d5c831791d2c2e68f240a83 (diff) | |
download | mariadb-git-0d6d63e1505bbf9898d46fa641a7a0579a4ae460.tar.gz |
MDEV-22027 Assertion oldest_lsn >= log_sys.last_checkpoint_lsn failed
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 1a6f708ec594ac0ae2dd30db926ab07b100fa24b (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 a52c4820a30a69522c9876f06510662bf063bcc3 (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 fec844aca88e1c6b9c36bb0b811e92d9d023ffb9.
Diffstat (limited to 'storage/innobase/include/log0log.h')
-rw-r--r-- | storage/innobase/include/log0log.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index a2c23d0bd89..30c113dbd19 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -139,7 +139,7 @@ log_get_max_modified_age_async(void); /*================================*/ /** Calculate the recommended highest values for lsn - last_checkpoint_lsn -and lsn - buf_get_oldest_modification(). +and lsn - buf_pool.get_oldest_modification(). @param[in] file_size requested innodb_log_file_size @retval true on success @retval false if the smallest log is too small to @@ -667,13 +667,13 @@ public: lsn_t max_modified_age_async; /*!< when this recommended value for lsn - - buf_pool_get_oldest_modification() + buf_pool.get_oldest_modification() is exceeded, we start an asynchronous preflush of pool pages */ lsn_t max_modified_age_sync; /*!< when this recommended value for lsn - - buf_pool_get_oldest_modification() + buf_pool.get_oldest_modification() is exceeded, we start a synchronous preflush of pool pages */ lsn_t max_checkpoint_age_async; |