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

Steps toward deprecating implicit prefix seek, related fixes #13026

Closed
wants to merge 8 commits into from

Conversation

pdillinger
Copy link
Contributor

@pdillinger pdillinger commented Sep 20, 2024

Summary: With some new use cases onboarding to prefix extractors/seek/filters, one of the risks is existing iterator code, e.g. for maintenance tasks, being unintentionally subject to prefix seek semantics. This is a longstanding known design flaw with prefix seek, and prefix_same_as_start and auto_prefix_mode were steps in the direction of making that obsolete. However, we can't just immediately set total_order_seek to true by default, because that would impact so much code instantly.

Here we add a new DB option, prefix_seek_opt_in_only that basically allows users to transition to the future behavior when they are ready. When set to true, all iterators will be treated as if total_order_seek=true and then the only ways to get prefix seek semantics are with prefix_same_as_start or auto_prefix_mode.

Related fixes / changes:

  • Make sure that prefix_same_as_start and auto_prefix_mode are compatible with (or override) total_order_seek (depending on your interpretation).
  • Fix a bug in which a new iterator after dynamically changing the prefix extractor might mix different prefix semantics between memtable and SSTs. Both should use the latest extractor semantics, which means iterators ignoring memtable prefix filters with an old extractor. And that means passing the latest prefix extractor to new memtable iterators that might use prefix seek. (Without the fix, the test added for this fails in many ways.)

Suggested follow-up:

  • Investigate a FIXME where a MergeIteratorBuilder is created in db_impl.cc. No unit test detects a change in value that should impact correctness.
  • Make memtable prefix bloom compatible with auto_prefix_mode, which might require involving the memtablereps because we don't know at iterator creation time (only seek time) whether an auto_prefix_mode seek will be a prefix seek.
  • Add prefix_same_as_start testing to db_stress

Test Plan: tests updated, added. Add combination of total_order_seek=true and auto_prefix_mode=true to stress test. Ran make blackbox_crash_test for a long while.

Manually ran tests with prefix_seek_opt_in_only=true as default, looking for unexpected issues. I inspected most of the results and migrated many tests to be ready for such a change (but not all).

@pdillinger pdillinger force-pushed the prefix_seek_opt_in_only branch 2 times, most recently from 4ad0388 to a8d741e Compare September 20, 2024 15:39
@pdillinger pdillinger changed the title WIP Steps toward deprecating implicit prefix seek, related fixes Sep 20, 2024
Summary:

Test Plan:

Reviewers:

Subscribers:

Tasks:

Tags:
@pdillinger pdillinger marked this pull request as ready for review September 20, 2024 16:22
@ltamasi
Copy link
Contributor

ltamasi commented Sep 20, 2024

@pdillinger Heads up, the mini stress test failure might be legit (or the stress test framework might need some work)

@pdillinger
Copy link
Contributor Author

@pdillinger Heads up, the mini stress test failure might be legit (or the stress test framework might need some work)

Yeah, looks like a bug or mismatched expectations. Investigating.

@pdillinger
Copy link
Contributor Author

It looks like my memtable support for auto_prefix_mode is incomplete/insufficient, so I'll rip that back out.

/*prefix_extractor=*/nullptr));
super_version->imm->AddIterators(
read_opts, /*seqno_to_time_mapping=*/nullptr,
super_version->mutable_cf_options.prefix_extractor.get(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: Do we have to pass the prefix extractor here? We don't pass it to the memtable iterator, and MergeIteratorBuilder is in non-prefix mode

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixing

ropts.prefix_same_as_start = true;
}
std::unique_ptr<Iterator> iter(db_->NewIterator(ropts));
// Out of domain
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: just to clarify, for out-of-domain queries, the expectation is that the prefix extractor (and any prefix blooms) will be ignored, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct

ASSERT_OK(Put("goat1", "g1"));
ASSERT_OK(Put("goat2", "g2"));

iter.reset(db_->NewIterator(ropts));
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe toss in some Gets too like above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do

Comment on lines 3814 to 3816
read_options.total_order_seek |=
immutable_db_options_.prefix_seek_opt_in_only;

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the best (or only) place to do this? We also have NewIterators as well as some other features like transactions which call NewIteratorImpl directly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixing. I'll have an assertion in DBIter::DBIter that prefix_seek_opt_in_only has been applied to total_order_seek

@@ -1592,7 +1592,7 @@ Status StressTest::TestIterateImpl(ThreadState* thread,
ro.total_order_seek = true;
expect_total_order = true;
} else if (thread->rand.OneIn(4)) {
ro.total_order_seek = false;
ro.total_order_seek = thread->rand.OneIn(2);
Copy link
Contributor

Choose a reason for hiding this comment

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

We would want to add the new option to the stress/crash test framework as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It looks tricky to add because there's a surprising lot of stress test code doing prefix iteration. prefix_seek_opt_in_only is not unlocking any new functionality. It's just a cosmetic shortcut for forcing total_order_seek.

@hx235 hx235 self-requested a review September 20, 2024 20:02
@facebook-github-bot
Copy link
Contributor

@pdillinger has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@pdillinger
Copy link
Contributor Author

This PR is not really showing the follow-up commits main...pdillinger:rocksdb:prefix_seek_opt_in_only

Copy link
Contributor

@ltamasi ltamasi left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@facebook-github-bot
Copy link
Contributor

@pdillinger merged this pull request in a1a102f.

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.

3 participants