Skip to content

memory_pages evicts mapped pages, which gives back no anonymous memory and costs a pread #759

Description

@tamnd

memory_pages is a promise about anonymous bytes. Once #757's map_settled is on, a settled page is a mapping of the file, and a mapping costs no anonymous bytes at all. Evicting one therefore gives back nothing the kernel was not already free to take, and it buys a pread on the next read of that page. The bound is doing work against itself.

2e61a2b fixed the worst version of this, which was an ordering accident: evict_settled ran the remap before the eviction, so on a bulk load, where the flusher settles pages in bursts and a whole burst lands below the floor at once, every settled page was mapped by one half of the call and unmapped by the other half of the same call. Two syscalls a page for a mapping that never served a read.

What that fix does not touch is the steady state. The floor sits at tail - memory_pages and the read-only boundary sits at tail - mutable_pages, so there is a band of memory_pages - mutable_pages pages between them where a page is settled and still above the floor. Every page transits that band as the log grows. So on a sustained write with both options set, each page is still mapped once and unmapped once, and with a tight bound the band is a page or two wide and the mapping's whole life is the time the tail takes to move two pages. That is churn with a real cost and no benefit.

The shape of the answer looks like this, and it needs deciding rather than guessing:

  • memory_pages counts anonymous pages only, and a mapped page is out of scope for it. evict_behind would skip a mapped victim instead of unmapping it, which means head has to be able to move past a page whose slot is still populated. Today everything below head is assumed not resident, so this is not a one line change and the invariant needs restating first.
  • Or the two options are declared mutually exclusive, Options::validate refuses a database with both set, and the documentation says a mapped tail is the bound. That is honest and cheap and it gives up the case where somebody wants a hard ceiling on total resident bytes and not just anonymous ones.
  • Or eviction unmaps but only under memory pressure it can observe, which is the virtual memory assisted buffer management direction from Leis and colleagues (SIGMOD 2023) and is a much larger piece of work.

There is a measurement that decides which of the first two is right, and it is not taken yet: whether a mapped read that faults is cheaper or dearer than the pread it replaces. That is the #757 A/B, queued on server3. If the mapping wins, the bound should stop evicting mapped pages and the first option is worth its cost. If the mapping loses, map_settled is not becoming the default anyway and the second option costs nothing.

So this is blocked on #757's numbers and should not be picked up before them. Filing it now because the interaction is live in the code today for anybody who sets both options, and the only thing standing between a user and the churn is that map_settled defaults to off.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    perfPerformance and resource budgetsstorageStorage engines and file formats

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions