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

Ensure bitValuePointer flag is cleared for LSM entry values written to LSM #1313

Merged
merged 4 commits into from
May 11, 2020

Conversation

ou05020
Copy link
Contributor

@ou05020 ou05020 commented Apr 19, 2020

When restoring a backup that was written with a lower ValueThreshold to a DB instance with a higher ValueThreshold, some entry values originally written to the value log in the backup DB will be written to the LSM along with the key when restored to the new DB.

The meta field for those entries is not updated to reflect the correct value storage state. Those entries still have the bitValuePointer flag set.

That causes iterator.prefetch to fail while looking up the value for those entries.

This fix ensures the meta bitValuePointer is cleared when entry values are stored in the LSM.

The original error can be reproduced by running the included TestLSMVPClear test after reverting the line 687 db.go change to clear the bitValuePointer flag.


This change is Reviewable

@ou05020 ou05020 requested a review from a team April 19, 2020 20:49
Copy link
Contributor

@jarifibrahim jarifibrahim left a comment

Choose a reason for hiding this comment

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

Thank you for fixing this PR @ou05020 . We really appreciate it. I have one small comment. Please address it and we can merge this PR.

Reviewable status: 0 of 2 files reviewed, 2 unresolved discussions (waiting on @ashish-goswami, @jarifibrahim, @manishrjain, and @ou05020)


backup_test.go, line 127 at r1 (raw file):

// with:
// 			Meta: entry.meta,
func TestLSMVPClear(t *testing.T) {

Thank you for adding a test. It's very easy to review a PR that has a test. I have written a similar test that looks simpler to me.

https://gist.github.com/jarifibrahim/aa134b1f8b35ddc1749ee24eb3198c23

I'll leave it up to you to decide which one looks simpler to you. :)


db.go, line 687 at r1 (raw file):

					// known to be set in write to LSM when the entry is loaded from a backup
					// with lower ValueThreshold and its value was stored in the value log.
					Meta:      entry.meta &^ bitValuePointer,

This will fix the issue but the actual issue is on line https://github.com/dgraph-io/badger/blob/5d19cc727d879fbab828b5299c47d53d23c3af7d/backup.go#L74

This is where we store the bits in the backup. Ideally, we should remove all the unnecessary bits from here so when restore happens, the bits will be stored correctly.
what do you think?

Copy link
Contributor Author

@ou05020 ou05020 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 2 files reviewed, 2 unresolved discussions (waiting on @ashish-goswami, @jarifibrahim, and @manishrjain)


backup_test.go, line 127 at r1 (raw file):

Previously, jarifibrahim (Ibrahim Jarif) wrote…

Thank you for adding a test. It's very easy to review a PR that has a test. I have written a similar test that looks simpler to me.

https://gist.github.com/jarifibrahim/aa134b1f8b35ddc1749ee24eb3198c23

I'll leave it up to you to decide which one looks simpler to you. :)

Thank you, I like your test better.


db.go, line 687 at r1 (raw file):

Previously, jarifibrahim (Ibrahim Jarif) wrote…

This will fix the issue but the actual issue is on line https://github.com/dgraph-io/badger/blob/5d19cc727d879fbab828b5299c47d53d23c3af7d/backup.go#L74

This is where we store the bits in the backup. Ideally, we should remove all the unnecessary bits from here so when restore happens, the bits will be stored correctly.
what do you think?

I originally modified backup.go to clear the value pointer bit. However, that did not address restoring from backups already created with the bit set.

Explicitly setting/clearing the value pointer bit based on how it will be stored at the time it is written is safest.

It resolves restoring from older backups with the problem and it prevents future errors that may occur if entries are copied/reused but the value is updated in such a way the ValueThreshold evaluation is different from the previous value.

Copy link
Contributor

@manishrjain manishrjain left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewed 1 of 2 files at r1, 1 of 1 files at r2.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @ashish-goswami and @jarifibrahim)

@cedricfung
Copy link

Will this fix #1139, without RunValueLogGC our data are increasing so fast.

@jarifibrahim
Copy link
Contributor

@cedricfung, the issue with #1139 was that you had some entries with invalid bitPointerValue set. This PR fixes the bits on invalid entries.

Did you take a backup and restore it with different ValueThreshold value?

@jarifibrahim jarifibrahim merged commit 9459a24 into hypermodeinc:master May 11, 2020
@jarifibrahim
Copy link
Contributor

Thank you for fixing this @ou05020 🎉

@cedricfung
Copy link

@jarifibrahim sorry I don't understand this, what could I do to fix this?

@jarifibrahim
Copy link
Contributor

@cedricfung Take a backup of your badger directory and restore it. (Keep the original one around). Do you run badger with default options?

NamanJain8 pushed a commit that referenced this pull request Sep 8, 2020
… to LSM (#1313)

When restoring a backup that was written with a lower `ValueThreshold`
to a DB instance with a higher `ValueThreshold`, some entry values
originally written to the value log in the backup DB will be written
to the LSM along with the key when restored to the new DB.

The `meta` field for those entries is not updated to reflect the
correct value storage state. Those entries still have the
`bitValuePointer` flag set.

That causes `iterator.prefetch` to fail while looking up the value
for those entries. This fix ensures the `meta` `bitValuePointer`
is cleared when entry values are stored in the LSM.

The original error can be reproduced by running the included
`TestLSMVPClear` test after reverting the line 687 `db.go` change
to clear the `bitValuePointer` flag.

(cherry picked from commit 9459a24)
NamanJain8 added a commit that referenced this pull request Sep 9, 2020
… to LSM (#1313) (#1501)

When restoring a backup that was written with a lower `ValueThreshold`
to a DB instance with a higher `ValueThreshold`, some entry values
originally written to the value log in the backup DB will be written
to the LSM along with the key when restored to the new DB.

The `meta` field for those entries is not updated to reflect the
correct value storage state. Those entries still have the
`bitValuePointer` flag set.

That causes `iterator.prefetch` to fail while looking up the value
for those entries. This fix ensures the `meta` `bitValuePointer`
is cleared when entry values are stored in the LSM.

The original error can be reproduced by running the included
`TestLSMVPClear` test after reverting the line 687 `db.go` change
to clear the `bitValuePointer` flag.

(cherry picked from commit 9459a24)

Co-authored-by: Julian Hegler <[email protected]>
avinashparchuri added a commit to neevaco/badger that referenced this pull request Jun 11, 2022
avinashparchuri added a commit to neevaco/badger that referenced this pull request Jun 13, 2022
mYmNeo pushed a commit to mYmNeo/badger that referenced this pull request Jan 16, 2023
… to LSM (hypermodeinc#1313) (hypermodeinc#1501)

When restoring a backup that was written with a lower `ValueThreshold`
to a DB instance with a higher `ValueThreshold`, some entry values
originally written to the value log in the backup DB will be written
to the LSM along with the key when restored to the new DB.

The `meta` field for those entries is not updated to reflect the
correct value storage state. Those entries still have the
`bitValuePointer` flag set.

That causes `iterator.prefetch` to fail while looking up the value
for those entries. This fix ensures the `meta` `bitValuePointer`
is cleared when entry values are stored in the LSM.

The original error can be reproduced by running the included
`TestLSMVPClear` test after reverting the line 687 `db.go` change
to clear the `bitValuePointer` flag.

(cherry picked from commit 9459a24)

Co-authored-by: Julian Hegler <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants