diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-06-26 11:16:40 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-06-26 11:16:40 +0300 |
commit | 759deaa0a22182353617c9fbff81f9f5fed25683 (patch) | |
tree | 6863b5373b55e2e795c219ee0b10ac3228b0d467 /storage/innobase/buf/buf0buf.cc | |
parent | 5f22511e35674ecc376f4c56217ee2d78f92c772 (diff) | |
download | mariadb-git-759deaa0a22182353617c9fbff81f9f5fed25683.tar.gz |
MDEV-26010 fixup: Use acquire/release memory order
In commit 5f22511e35674ecc376f4c56217ee2d78f92c772 we depend on
Total Store Ordering. For correct operation on ISAs that implement
weaker memory ordering, we must explicitly use release/acquire stores
and loads on buf_page_t::oldest_modification_ to prevent a race condition
when buf_page_t::list does not happen to be on the same cache line.
buf_page_t::clear_oldest_modification(): Assert that the block is
not in buf_pool.flush_list, and use std::memory_order_release.
buf_page_t::oldest_modification_acquire(): Read oldest_modification_
with std::memory_order_acquire. In this way, if the return value is 0,
the caller may safely assume that it will not observe the buf_page_t
as being in buf_pool.flush_list, even if it is not holding
buf_pool.flush_list_mutex.
buf_flush_relocate_on_flush_list(), buf_LRU_free_page():
Invoke buf_page_t::oldest_modification_acquire().
Diffstat (limited to 'storage/innobase/buf/buf0buf.cc')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 72dd2cdc4ab..bbbb67a69df 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1333,21 +1333,19 @@ inline const buf_block_t *buf_pool_t::chunk_t::not_freed() const /* Skip blocks that are not being used for file pages. */ break; case BUF_BLOCK_FILE_PAGE: + const lsn_t lsn= block->page.oldest_modification(); + if (srv_read_only_mode) { /* The page cleaner is disabled in read-only mode. No pages can be dirtied, so all of them must be clean. */ - ut_d(lsn_t oldest_modification= block->page.oldest_modification()); - ut_ad(oldest_modification == 0 || - oldest_modification == recv_sys.recovered_lsn || + ut_ad(lsn == 0 || lsn == recv_sys.recovered_lsn || srv_force_recovery == SRV_FORCE_NO_LOG_REDO); ut_ad(!block->page.buf_fix_count()); ut_ad(block->page.io_fix() == BUF_IO_NONE); break; } - const lsn_t lsn= block->page.oldest_modification(); - if (fsp_is_system_temporary(block->page.id().space())) { ut_ad(lsn == 0 || lsn == 2); |