summaryrefslogtreecommitdiff
path: root/storage/innobase/buf/buf0buf.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-06-26 11:16:40 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-06-26 11:16:40 +0300
commit759deaa0a22182353617c9fbff81f9f5fed25683 (patch)
tree6863b5373b55e2e795c219ee0b10ac3228b0d467 /storage/innobase/buf/buf0buf.cc
parent5f22511e35674ecc376f4c56217ee2d78f92c772 (diff)
downloadmariadb-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.cc8
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);