MDEV-41036 buf_page_peek_if_young() does not properly compute and wra… - #5678
Conversation
|
|
There was a problem hiding this comment.
🟡 Changes recommended
The wraparound and threshold boundaries need regression coverage.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Fixes InnoDB LRU youth detection across the 31-bit eviction-clock wraparound.
Changes:
- Computes page age using 31-bit modular subtraction.
- Preserves the existing young-window threshold.
File summaries
| File | Description |
|---|---|
storage/innobase/include/buf0buf.inl |
Corrects wraparound handling in buf_page_peek_if_young(). |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| buf_pool.freed_page_clock, so the age must be computed modulo 2^31. */ | ||
| constexpr uint32_t CLOCK_MASK= (1U << 31) - 1; | ||
| const uint32_t now= uint32_t(buf_pool.freed_page_clock) & CLOCK_MASK; | ||
| const uint32_t age= (now - uint32_t(bpage->freed_page_clock)) & CLOCK_MASK; |
…p page age in young calculation buf_page_t::freed_page_clock is a 31-bit bitfield holding the low bits of buf_pool.freed_page_clock. buf_page_peek_if_young() evaluated the condition now < stamp + window in size_t arithmetic, which failed to account for wraparound within the 31-bit clock space. When the global clock wrapped past a stamp (particularly when stamp was high, near 2^31), the comparison evaluated to true for an extended period even though the page was older than the window. During these wraparound windows, pages were falsely reported as young. Because returning true causes InnoDB to skip moving pages to the MRU head (to reduce lock contention), these falsely "young" pages were not promoted. As a result, active/hot pages could sink into the old portion of the LRU list and be evicted prematurely. Additionally, buf_read_ahead_random() over-counted recently accessed pages during wraparound intervals. Compute age as (now - stamp) & clock_mask using 31-bit modular arithmetic and compare age < window. A page then cleanly leaves the young window after the intended number of evictions regardless of clock wraparound.
09044e8 to
89f6bd1
Compare
|
We got a https://jira.mariadb.org/browse/MDEV-37189 failure in this run: https://buildbot.mariadb.org/#builders/536/builds/43237 This can be explained by the still missing merge of https://jira.mariadb.org/browse/MDEV-38056 into 11.8: |
…p page age in young calculation
buf_page_t::freed_page_clock is a 31-bit bitfield holding the low bits of buf_pool.freed_page_clock. buf_page_peek_if_young() evaluated the condition now < stamp + window in size_t arithmetic, which failed to account for wraparound within the 31-bit clock space.
When the global clock wrapped past a stamp (particularly when stamp was high, near 2^31), the comparison evaluated to true for an extended period even though the page was older than the window. During these wraparound windows, pages were falsely reported as young.
Because returning true causes InnoDB to skip moving pages to the MRU head (to reduce lock contention), these falsely "young" pages were not promoted.
As a result, active/hot pages could sink into the old portion of the LRU list and be evicted prematurely. Additionally, buf_read_ahead_random() over-counted recently accessed pages during wraparound intervals.
Compute age as (now - stamp) & clock_mask using 31-bit modular arithmetic and compare age < window. A page then cleanly leaves the young window after the intended number of evictions regardless of clock wraparound.