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

fix(scrubber): more robust metadata consistency checks #8344

Merged
merged 17 commits into from
Jul 22, 2024

Conversation

yliang412
Copy link
Contributor

@yliang412 yliang412 commented Jul 10, 2024

Part of #8128.

Problem

Scrubber uses scan_metadata command to flag metadata inconsistencies. To trust it at scale, we need to make sure the errors we emit is a reflection of real scenario. One check performed in the scrubber is to see whether layers listed in the latest index_part.json is present in object listing. Currently, the scrubber does not robustly handle the case where objects are uploaded/deleted during the scan. Below is some traces on possible race conditions that produces false positives.

Case 1: Layer insertion

RemoteTimelineClient Scrubber S3 Ground Truth After Step
    indexed_layers: [A], layers_present: [A]
  read tenant_objects [A]  
insert B    
upload index to include B   indexed_layers: [A, B], layers_present: [A, B]
  download index [A, B]  
  check B is in tenant_objects → false, error  

In the above example, B is actually present on S3. To resolve this, we can issue a HeadObject to the missing layers and see if they are actually present.

Case 2: Layer deletion (impossible)

RemoteTimelineClient Scrubber S3 Ground Truth After Step
    indexed_layers: [A, B], layers_present: [A, B]
  download index, indexed_layers = [A, B]  
delete A from index   indexed_layers: [A], layers_present: [A, B]
delete A   indexed_layers: [B], layers_present: [B]
  read B, tenant_objects = [B], indexed_layers = [A, B]  
  check if A is present in tenant objects, nope, → error (this is a false positive)  

This case is made impossible by always read the tenant objects listing first before downloading the index.

Case 3: Fast L0 replacement

RemoteTimelineClient Scrubber S3 Ground Truth After Step
    indexed_layers: [], layers_present: []
  read tenant_objects []  
insert L0    
upload index to include L0   indexed_layers: [L0], layers_present: [L0]
  read index [L0]  
  check L0 is in tenant_objects → false  
upload L1; upload index, delete L0   indexed_layers: [L1], layers_present: [L1]
  head_object(L0) → fail  

This is very unlikely but theoretically possible. Instead of rescanning the index, the implementation will emit the error with a caveat indicating the missing layer is L0.

Summary of changes

Condition for success: An object in the index is (1) in the object listing we acquire from S3 or (2) found in a HeadObject request (new object).

  • Add in the HeadObject requests for the layers missing from the object listing.
  • Keep the order of first getting the object listing and then downloading the layers.
  • Update check to only consider shards with highest shard count.
  • Skip analyzing a timeline if deleted_at tombstone is marked in index_part.json.
  • Add new test to see if scrubber actually detect the metadata inconsistency.

Misc

  • A timeline with no ancestor should always have some layers.
  • Removed experimental histograms

Caveat

Checklist before requesting a review

  • I have performed a self-review of my code.
  • If it is a core feature, I have added thorough tests.
  • Do we need to implement analytics? if so did you add the relevant metrics to the dashboard?
  • If this PR requires public announcement, mark it with /release-notes label and add several sentences in this section.

Checklist before merging

  • Do not forget to reformat commit message to not include the above checklist

Copy link

github-actions bot commented Jul 10, 2024

3126 tests run: 3005 passed, 0 failed, 121 skipped (full report)


Flaky tests (1)

Postgres 15

Code coverage* (full report)

  • functions: 32.6% (7003 of 21459 functions)
  • lines: 50.0% (55263 of 110539 lines)

* collected from Rust tests only


The comment gets automatically updated with the latest test results
a6cfed9 at 2024-07-22T13:48:58.375Z :recycle:

@yliang412 yliang412 self-assigned this Jul 15, 2024
@yliang412 yliang412 added the c/storage/scrubber Component: s3_scrubber label Jul 15, 2024
Signed-off-by: Yuchen Liang <yuchen@neon.tech>
@yliang412 yliang412 force-pushed the yuchen/scrubber-robust-metadata-check branch from 53c814c to 455c5d6 Compare July 15, 2024 18:52
Signed-off-by: Yuchen Liang <yuchen@neon.tech>
@yliang412 yliang412 force-pushed the yuchen/scrubber-robust-metadata-check branch from 7c988e0 to eaf3a3b Compare July 15, 2024 23:48
Signed-off-by: Yuchen Liang <yuchen@neon.tech>
Signed-off-by: Yuchen Liang <yuchen@neon.tech>
Signed-off-by: Yuchen Liang <yuchen@neon.tech>
@yliang412 yliang412 marked this pull request as ready for review July 16, 2024 16:09
@yliang412 yliang412 requested a review from a team as a code owner July 16, 2024 16:09
@yliang412 yliang412 requested a review from jcsp July 16, 2024 16:09
@yliang412 yliang412 changed the title [WIP] fix(scrubber): more robust metadata consistency checks fix(scrubber): more robust metadata consistency checks Jul 16, 2024
@yliang412 yliang412 requested a review from skyzh July 16, 2024 17:37
Copy link
Member

@skyzh skyzh left a comment

Choose a reason for hiding this comment

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

did a quick review, have you tried running this with staging pageserver? I assume this process is read-only and it should be safe to run it.

pageserver/src/tenant/storage_layer/layer_name.rs Outdated Show resolved Hide resolved
storage_scrubber/src/checks.rs Show resolved Hide resolved
storage_scrubber/src/checks.rs Show resolved Hide resolved
storage_scrubber/src/checks.rs Outdated Show resolved Hide resolved
@yliang412
Copy link
Contributor Author

Tested on staging, logged warnings and errors as expected.

Copy link
Contributor

@jcsp jcsp left a comment

Choose a reason for hiding this comment

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

This looks good, couple of minor comments.

yliang412 and others added 5 commits July 18, 2024 12:20
Signed-off-by: Yuchen Liang <yuchen@neon.tech>
Signed-off-by: Yuchen Liang <yuchen@neon.tech>
Signed-off-by: Yuchen Liang <yuchen@neon.tech>
The histograms in the metadata summary were added experimentally. We
will remove them since we can get most of the insights from prometheus
stats. Also reduce noise when maximum value go out of the range.

---------

Signed-off-by: Yuchen Liang <yuchen@neon.tech>
@yliang412 yliang412 enabled auto-merge (squash) July 22, 2024 13:04
@yliang412 yliang412 disabled auto-merge July 22, 2024 13:11
@yliang412 yliang412 enabled auto-merge (squash) July 22, 2024 13:12
@yliang412 yliang412 merged commit 595c450 into main Jul 22, 2024
65 checks passed
@yliang412 yliang412 deleted the yuchen/scrubber-robust-metadata-check branch July 22, 2024 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c/storage/scrubber Component: s3_scrubber
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants