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

libroach: prevent infinite loop in reverse-scan #35505

Merged
merged 1 commit into from
Mar 13, 2019

Conversation

ajkr
Copy link
Contributor

@ajkr ajkr commented Mar 7, 2019

Fixed and added a test case for infinite loop leading to OOM in reverse-scan
optimization to use SeekForPrev() after N Prev()s fail to find a new
key. It could happen when that optimization was used on a key that also
had a write intent.

Release note: None

@ajkr ajkr requested review from a team March 7, 2019 16:59
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Collaborator

@petermattis petermattis left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajkr)


c-deps/libroach/mvcc.h, line 552 at r1 (raw file):

    // Since the iterator we're using here has its upper-bound set to `key`,
    // this seeks to the last key that is strictly less than `key`.
    assert(key.compare(iter_->upper_bound) == 0);

I'm not sure if this is safe. We also call iterSeekReverse from prevKey.

@ajkr
Copy link
Contributor Author

ajkr commented Mar 7, 2019

I see. Does that usage also rely on SeekForPrev landing at a key strictly less than the seek key? It appears that way to me because the seek key is the current key with zero timestamp, which might be an actual key.

@petermattis
Copy link
Collaborator

I see. Does that usage also rely on SeekForPrev landing at a key strictly less than the seek key? It appears that way to me because the seek key is the current key with zero timestamp, which might be an actual key.

Yes, it does rely on SeekForPrev landing at a key strictly less than the seek key. Is there a bug here? When will SeekForPrev return a key equal to the seek key? I'm pretty sure I both tested this and looked at the source code when I wrote that comment.

@ajkr
Copy link
Contributor Author

ajkr commented Mar 7, 2019

I think it should land on the seek key if it exists in the DB and isn't excluded by iterate_upper_bound, e.g., https://github.com/facebook/rocksdb/blob/master/db/db_iter_test.cc#L2264-L2266

@petermattis
Copy link
Collaborator

I think it should land on the seek key if it exists in the DB and isn't excluded by iterate_upper_bound, e.g., https://github.com/facebook/rocksdb/blob/master/db/db_iter_test.cc#L2264-L2266

I'll look at the code in RocksDB later. Seems feasible to test this scenario and demonstrate a problem.

@ajkr
Copy link
Contributor Author

ajkr commented Mar 7, 2019

Got it. Will attempt to expose a problem in a test case in mvcc_test.go.

@ajkr ajkr force-pushed the fix-mvcc-scan-comment branch from c45b129 to 3ad5fbb Compare March 8, 2019 00:04
@ajkr
Copy link
Contributor Author

ajkr commented Mar 8, 2019

Fun investigation. I added a test case and reverted the change to iterSeekReverse.

EDIT: But I did not solve the actual problem yet.

@ajkr ajkr changed the title libroach: update comment on SeekForPrev usage libroach: prevent infinite loop in reverse-scan Mar 8, 2019
Fixed and added a test case for infinite loop leading to OOM in reverse-scan
optimization to use `SeekForPrev()` after N `Prev()`s fail to find a new
key. It could happen when that optimization was used on a key that also
had a write intent.

Release note: None
@petermattis
Copy link
Collaborator

Well, definitely a bug. I wonder if we've ever hit this in practice. It requires reverse scans, and a number of versions for a key, which might be a rare combination. Glad you found this, though.

@ajkr ajkr force-pushed the fix-mvcc-scan-comment branch from 3ad5fbb to 31a8193 Compare March 8, 2019 01:20
@ajkr
Copy link
Contributor Author

ajkr commented Mar 11, 2019

This is ready for review.

Copy link
Collaborator

@petermattis petermattis left a comment

Choose a reason for hiding this comment

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

:lgtm: Very glad you caught this.

Can you run the MVCCReverseScan benchmarks? I'm curious to see how this affected them, though I don't see an easy way to avoid this check.

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @ajkr)

@ajkr
Copy link
Contributor Author

ajkr commented Mar 13, 2019

Sure, the benchmark looks the same more or less (https://gist.github.com/ajkr/c7059d4dd38e111d91908d7d1eb244b0), so I think this should be safe to land.

@ajkr
Copy link
Contributor Author

ajkr commented Mar 13, 2019

bors r+

craig bot pushed a commit that referenced this pull request Mar 13, 2019
35505: libroach: prevent infinite loop in reverse-scan r=ajkr a=ajkr

Fixed and added a test case for infinite loop leading to OOM in reverse-scan
optimization to use `SeekForPrev()` after N `Prev()`s fail to find a new
key. It could happen when that optimization was used on a key that also
had a write intent.

Release note: None


Co-authored-by: Andrew Kryczka <[email protected]>
@craig
Copy link
Contributor

craig bot commented Mar 13, 2019

Build succeeded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants