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

Pages checksum verification #736

Merged
merged 8 commits into from Aug 28, 2020

Conversation

usernamedt
Copy link
Member

In this PR I propose the page checksums verification functionality for backup-push

I've adapted the Postgres page hash calculation (modified version of FNV-1a hash algorithm) from C origin:
https://github.com/postgres/postgres/blob/REL_12_STABLE/src/include/storage/checksum_impl.h

Also, I've also partially borrowed the logic of is_page_corrupted() from pg_page_verification tool: https://github.com/google/pg_page_verification/blob/master/pg_page_verification.c

Users can enable the page verification using --verify flag or by setting WALG_VERIFY_PAGE_CHECKSUMS env variable. If found any, corrupted block numbers (currently no more than 10 of them) will be recorded to the backup sentinel json, for example:

...
 "/base/13690/13535": {
      "IsSkipped": true,
      "MTime": "2020-08-20T21:02:56.690095409+05:00",
      "IsIncremented": false
    },
    "/base/16384/16397": {
      "CorruptBlocks": [
        1
      ],
      "IsIncremented": false,
      "IsSkipped": false,
      "MTime": "2020-08-21T19:09:52.966149937+05:00"
    },
...

}
fileReader, cfi.header.Size, err = ReadIncrementalFile(cfi.path, cfi.fileInfo.Size(), *p.incrementFromLsn, bitmap)
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've renamed fileReader to fileReadCloser because actually it is ReadCloser, not only reader

Copy link
Collaborator

@g0djan g0djan left a comment

Choose a reason for hiding this comment

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

Looks good


type BackupFileDescription struct {
IsIncremented bool // should never be both incremented and Skipped
IsSkipped bool
MTime time.Time
CorruptBlocks []uint32 `json:",omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add the actual number of corrupted blocks. Sometimes it helps to distinguish different bugs.

Copy link
Collaborator

Choose a reason for hiding this comment

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

And maybe a flag to keep all blocks.

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 in 50e27bd

func (m *MultiCloser) Close() error {
var err error
for _, c := range m.closers {
// still call Close on each, even if one returns an error
Copy link
Collaborator

Choose a reason for hiding this comment

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

hm, it will be better to save all error messages. You can combine it to a new error

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 4efeef1

"unsafe"
)

// This code is an adaptation of Postgres data page checksum calculation code written in Go.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I will trust that it has the same code.

}

// VerifyPagedFileIncrement verifies pages of an increment
func VerifyPagedFileIncrement(path string, fileInfo os.FileInfo, increment io.Reader) ([]uint32, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This part is OK

@g0djan g0djan merged commit 4547cba into wal-g:master Aug 28, 2020
@NikolayS
Copy link
Contributor

NikolayS commented Nov 5, 2020

@usernamedt awesome features! discovered by accident. Couldn't find anything in README or Postgres-related .md doc file. Could you please add info there? (I can help, but it would be good to have at least a draft)

@usernamedt
Copy link
Member Author

@usernamedt awesome features! discovered by accident. Couldn't find anything in README or Postgres-related .md doc file. Could you please add info there? (I can help, but it would be good to have at least a draft)

Hi, thanks for noting this, seems like I forgot to add documentation for this feature :) I'll fix this soon. As for now, I have a more or less detailed description here.

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.

None yet

3 participants