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

cmd: add meta page related surgery commands #539

Merged
merged 1 commit into from
Oct 19, 2023
Merged

cmd: add meta page related surgery commands #539

merged 1 commit into from
Oct 19, 2023

Conversation

ahrtr
Copy link
Member

@ahrtr ahrtr commented Jul 18, 2023

What this PR fix

This PR provides two surgery commands to validate and update meta pages separately.

  • surgery meta validate
    It validates whether the meta pages have corrupted.
  • surgery meta update
    It supports updating fields: root, freelist, pageSize and pgid.

Exampe: how to fix #537 using this PR

In #537, the meta pages corrupted. The roots in both meta pages somehow point to a freelist. Obviously it isn't correct.

$ ./bbolt page ./influxd.bolt 0
Page ID:    0
Page Type:  meta
Total Size: 4096 bytes
Overflow pages: 0
Version:    2
Page Size:  4096 bytes
Flags:      00000000
Root:       <pgid=26>
Freelist:   <pgid=25>
HWM:        <pgid=64>
Txn ID:     125942
Checksum:   8375a94a36e83692

$ ./bbolt page ./influxd.bolt 1
Page ID:    1
Page Type:  meta
Total Size: 4096 bytes
Overflow pages: 0
Version:    2
Page Size:  4096 bytes
Flags:      00000000
Root:       <pgid=26>
Freelist:   <pgid=26>
HWM:        <pgid=64>
Txn ID:     125943
Checksum:   50f13350d738a66c

$ ./bbolt page ./influxd.bolt 26
Page ID:    26
Page Type:  freelist
Total Size: 4096 bytes
Overflow pages: 0
Item Count: 25
Overflow: 0

25
30
31
......

$ ./bbolt page ./influxd.bolt 25
Page ID:    25
Page Type:  freelist
Total Size: 4096 bytes
Overflow pages: 0
Item Count: 25
Overflow: 0

26
30
31
......

The possible correct root page should be one of 4, 23, 27 or 39 (Note the root page must contains buckets). Changing the root page ID in both meta pages to any one of them can fix the db. But I am not sure which one is the real root page, because I am not familiar with how influxd uses bbolt.

The command of changing the root page to 4 are as below. You can use the similar command to change the root page to 23, 27 or 39, you just need to replace 4 (after root:) with one of them.

$ ./bbolt surgery meta update ./influxd.bolt --output ./new.db --page-size 4096 --fields root:4
$ ./bbolt surgery freelist abandon ./new.db --output ./new1.db

I already generated 4 db files (each of them has one of the root pages) as attached,

Next step

We should provide more command to inspect the data inside each bucket, especially inline bucket. In this case, it can help users to identify which page is the real root page.

@ahrtr
Copy link
Member Author

ahrtr commented Jul 18, 2023

@ptabor @tjungblu @cenkalti

@ahrtr
Copy link
Member Author

ahrtr commented Jul 24, 2023

Linked to #370

@ahrtr ahrtr mentioned this pull request Jul 24, 2023
6 tasks
@ahrtr
Copy link
Member Author

ahrtr commented Aug 10, 2023

cc @fuweid

}
defer f.Close()

buf := make([]byte, 1024)
Copy link
Member

Choose a reason for hiding this comment

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

should it be page-size buf?

Copy link
Member Author

Choose a reason for hiding this comment

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

It should be fine, because the meta data is just about 52 bytes.

Copy link
Member

@serathius serathius Oct 18, 2023

Choose a reason for hiding this comment

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

It is fine from code correctness, but it's not great from readability perspective. It's confusing to have arbitrary high value set. Can you just use pagesize, or leave a comment why 1024?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a comment,

	// The meta page is just 64 bytes, and definitely less than 1024 bytes,
	// so it's fine to only read 1204 bytes. Note we don't care about the
	// pageSize when reading the first meta page, because we always read the
	// file starting from offset 0. Actually the passed pageSize is 0 when
	// reading the first meta page in the `surgery meta update` command.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ugh, there is typo in the comment. Changed "1204" to "1024"

cmd/bbolt/command_surgery_meta.go Outdated Show resolved Hide resolved
Copy link
Member

@fuweid fuweid left a comment

Choose a reason for hiding this comment

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

LGTM

cmd/bbolt/command_surgery_meta.go Outdated Show resolved Hide resolved
cmd/bbolt/command_surgery_meta.go Outdated Show resolved Hide resolved
cmd/bbolt/command_surgery_meta.go Show resolved Hide resolved
@ahrtr
Copy link
Member Author

ahrtr commented Aug 11, 2023

@ptabor Resolved all the comments, PTAL, thx

@ahrtr ahrtr modified the milestones: v1.3.8, v1.4.0 Aug 11, 2023
@ahrtr
Copy link
Member Author

ahrtr commented Oct 7, 2023

@ptabor @serathius @mitake @spzala PTAL

}

for _, field := range o.fields {
kv := strings.Split(field, ":")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
kv := strings.Split(field, ":")
kv := strings.SplitN(field, ":", 2)

Copy link
Member Author

Choose a reason for hiding this comment

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

updated.

Copy link
Member

Choose a reason for hiding this comment

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

Don't see the change.

Copy link
Member Author

Choose a reason for hiding this comment

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

I intentionally changed it back. Because I need to validate the format is exactly in the format of name:value; the slice returned by strings.Split should contain exactly two elements.

		kv := strings.Split(field, ":")
		if len(kv) != 2 {
			return fmt.Errorf("invalid key-value pair: %s", field)
		}

Copy link
Member

@spzala spzala 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 @ahrtr

Two command:
- surgery meta validate
- surgery meta update

Signed-off-by: Benjamin Wang <wachao@vmware.com>
@ahrtr
Copy link
Member Author

ahrtr commented Oct 19, 2023

thx all for the review. @fuweid @ptabor @serathius @spzala

merging...

@ahrtr ahrtr merged commit 233156a into etcd-io:master Oct 19, 2023
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

panic: invalid page type: 26: 10
5 participants