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

db: fix iterator error propagation, NextPrefix violation #3593

Merged
merged 2 commits into from
May 7, 2024

Conversation

jbowens
Copy link
Collaborator

@jbowens jbowens commented May 6, 2024

This commit fixes a few issues surrounding NextPrefix and iterator errors. Previously, under some circumstances, an error propagated by the underlying iterator would not immediately be propagated up. Instead the Iterator could in some circumstances call Next or NextPrefix on an already exhausted, errored iterator, resulting in undefined behavior.

Similarly, the results of calling NextPrefix on an exhausted top-level pebble.Iterator are not defined. This commit adapts the implementation to early exit in this case. The metamorphic test may generate such operations.

Fix #3592.

This commit fixes a few issues surrounding NextPrefix and iterator errors.
Previously, under some circumstances, an error propagated by the underlying
iterator would not immediately be propagated up. Instead the Iterator could in
some circumstances call Next or NextPrefix on an already exhausted, errored
iterator, resulting in undefined behavior.

Similarly, the results of calling NextPrefix on an exhausted top-level
pebble.Iterator are not defined. This commit adapts the implementation to early
exit in this case. The metamorphic test may generate such operations.

Fix cockroachdb#3592.
@jbowens jbowens requested a review from a team as a code owner May 6, 2024 19:28
@jbowens jbowens requested a review from aadityasondhi May 6, 2024 19:28
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Member

@RaduBerinde RaduBerinde left a comment

Choose a reason for hiding this comment

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

:lgtm:

Just one thing. this does not fix the original violates upper bound issue in #3592.

Reviewable status: 0 of 1 files reviewed, all discussions resolved (waiting on @aadityasondhi)

Copy link
Collaborator Author

@jbowens jbowens left a comment

Choose a reason for hiding this comment

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

Pushed a second commit to fix the violates upper bound issue 😅

Reviewable status: 0 of 3 files reviewed, all discussions resolved (waiting on @aadityasondhi)

Copy link
Member

@RaduBerinde RaduBerinde left a comment

Choose a reason for hiding this comment

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

Nice!! :lgtm:

Reviewable status: 0 of 3 files reviewed, 1 unresolved discussion (waiting on @aadityasondhi and @jbowens)


internal/keyspan/keyspanimpl/level_iter.go line 158 at r2 (raw file):

		return noFileLoaded
	}
	l.iter, l.err = l.newIter(file, l.tableOpts)

[nit] maybe do iter, err := and only set l.iter in the no error case, so we don't rely on newIter returning nil

When an ingested flushable creates a range deletion iterator, it uses the
keyspanimpl.LevelIter to expose a unified view of all the range deletions
across the files of the atomically ingested sstables. When loading a sstable's
range deletion iterator failed, it returned a non-nil iterator to work around
idiosyncroncies of the keyspanimpl.LevelIter. This could cause the LevelIter to
mistakenly think it had already loaded a file's range deletions. This commit
fixes ingestedFlushable.constructRangeDelIter to return a nil FragmentIterator
if there's an error, and refactors (keyspanimpl.LevelIter).loadFile.

Fix cockroachdb#3592.
@jbowens jbowens force-pushed the iter-err-nextprefix branch from 7498751 to 925a3db Compare May 7, 2024 19:45
Copy link
Collaborator Author

@jbowens jbowens 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: 0 of 3 files reviewed, 1 unresolved discussion (waiting on @aadityasondhi and @RaduBerinde)


internal/keyspan/keyspanimpl/level_iter.go line 158 at r2 (raw file):

Previously, RaduBerinde wrote…

[nit] maybe do iter, err := and only set l.iter in the no error case, so we don't rely on newIter returning nil

Good call

@jbowens jbowens merged commit 98cadc9 into cockroachdb:master May 7, 2024
11 checks passed
@jbowens jbowens deleted the iter-err-nextprefix branch May 7, 2024 20:07
@RaduBerinde
Copy link
Member

iterator.go line 1743 at r1 (raw file):

		i.rangeKey.updated = i.rangeKey.hasRangeKey && !i.Valid() && i.opts.rangeKeys()
	}
	// NextPrefix from an exhausted position is undefined. We keep the exhausted

Iterator.NextPrefix says you can't call it in IterAtLimit state but doesn't say anything about an exhausted iterator. If it's exhausted in the backward direction, isn't NextPrefix valid?

Copy link
Collaborator Author

@jbowens jbowens 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: 0 of 3 files reviewed, 2 unresolved discussions


iterator.go line 1743 at r1 (raw file):

Previously, RaduBerinde wrote…

Iterator.NextPrefix says you can't call it in IterAtLimit state but doesn't say anything about an exhausted iterator. If it's exhausted in the backward direction, isn't NextPrefix valid?

Hrm yeah it seems like we could allow it as an operation semantically equivalent to a plain Next, but I also don't think we require it. Maybe this implementation should literally call Iterator.Next if exhausted.

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.

TestIteratorErrors fails with SeekLT violates upper bound panic
3 participants