Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

io: add pager for append-only file abstraction #17084

Merged
merged 16 commits into from
Mar 27, 2024

Conversation

dotnwat
Copy link
Member

@dotnwat dotnwat commented Mar 14, 2024

Add io::pager which provides an append-only abstraction on top of the files using io::scheduler for the write-back process.

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v23.3.x
  • v23.2.x

Release Notes

  • none

@dotnwat
Copy link
Member Author

dotnwat commented Mar 14, 2024

src/v/io/page.h Outdated Show resolved Hide resolved
src/v/io/page.h Show resolved Hide resolved
src/v/io/page_cache.h Show resolved Hide resolved
src/v/io/pager.h Outdated Show resolved Hide resolved
src/v/io/pager.h Show resolved Hide resolved
page.signal_waiters();
} else if (page.test_flag(page::flags::dirty)) {
vassert(page.test_flag(page::flags::write), "Expected write page");
if (!page.test_flag(page::flags::queued)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it mean for handle_completion to be called but queued is not set? A write failure?

Copy link
Member Author

@dotnwat dotnwat Mar 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the io-queue clears the queued flag before write-back happens. normally the write finishes and the completion handler is called and the dirty flag is cleared.

but while the write was happening, the page may have been re-queued because new data arrived and was written into the page, in which case the queued flag will be set. this is also the case here in which we don't want to incorrectly clear the dirty flag.

now that i'm thinking about it, it might be simpler to only invoke the completion handler for writes when the page wasn't re-queued.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explaining, that's really helpful. I agree, it may make for easier reasoning to have the io-queue only call the completion callback when the page isn't requeued. Does this result in a meaningful behavioral change for users? Is it that writers now have to wait longer in the face of concurrent writers, before getting a page as we're appending? (I think that makes sense, if so)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this result in a meaningful behavioral change for users? Is it that writers now have to wait longer in the face of concurrent writers, before getting a page as we're appending? (I think that makes sense, if so)

For writers, there should be no change: new writes can always land into a dirty page as appends. That's true even if the page is queued for write-back.

For readers, there should be no change: dirty data in the cache is always readable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah makes sense. I saw us calling get_page() on the write path and assumed that that could lead us to waiting on the write path. But it makes sense that we could return a dirty page, in which case we aren't faulting (and not waiting!)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep. i think that there is a good argument for having a fast path for get_page that doesn't use co_await which would make it more clear.

src/v/io/pager.cc Show resolved Hide resolved
src/v/io/pager.cc Show resolved Hide resolved
src/v/io/tests/pager_test.cc Show resolved Hide resolved
@dotnwat
Copy link
Member Author

dotnwat commented Mar 24, 2024

@dotnwat dotnwat requested a review from andrwng March 24, 2024 23:21
Avoids terminal spam.

Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
A page is faulting when a read is occuring in response to a cache miss.
A page is dirty when it contains data not written to persistent storage.

Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Will be used by the page cache to clear release memory.

Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
These routines are marked as noexcept, and each of the bitset operations
throw if an invalid bit position is passed in.

Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Dirty and faulting are mutually exclusive.

Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
To avoid the pager needing to have knowledge about the internals of the
io queue to clear the dirty bit, the io queue now only delivers write
compeltions for writes that aren't requeued.

Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
@dotnwat
Copy link
Member Author

dotnwat commented Mar 27, 2024

Force pushed https://github.com/redpanda-data/redpanda/compare/f308e8a02052f3625a4bfd81ba9871515128b3d0..ae5efe90381fb29d1c0ad284f174ac805db8c228 to fix Git commit messages and add a note about the pager into the io/README

@vbotbuildovich
Copy link
Collaborator

new failures in https://buildkite.com/redpanda/redpanda/builds/46902#018e8115-18bc-4a5e-a666-84e734b6968e:

"rptest.tests.transactions_test.TxUpgradeTest.upgrade_does_not_change_tx_coordinator_assignment_test"

Copy link
Contributor

@andrwng andrwng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pretty much LGTM. Just a remaining clarifying question about the completion callback change

@dotnwat
Copy link
Member Author

dotnwat commented Mar 27, 2024

Failures unit test #16561

@dotnwat
Copy link
Member Author

dotnwat commented Mar 27, 2024

new failures in https://buildkite.com/redpanda/redpanda/builds/46902#018e8115-18bc-4a5e-a666-84e734b6968e:

"rptest.tests.transactions_test.TxUpgradeTest.upgrade_does_not_change_tx_coordinator_assignment_test"

This PR doesn't touch any code outside v/io

@dotnwat dotnwat merged commit f0879a5 into redpanda-data:dev Mar 27, 2024
12 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants