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

storage/storageccl: Add an option to break export mid key #68102

Merged
merged 2 commits into from Aug 12, 2021

Conversation

aliher1911
Copy link
Contributor

@aliher1911 aliher1911 commented Jul 27, 2021

Previously when exporting ranges with very large number of versions
export could hit the situation where single key export would exceed
maximum export byte limit. To resolve this, safety threshold has to
be raised which could cause nodes going out of memory.

To address this, this patch adds an ability to stop and resume on
the arbitrary key timestamp so that it could be stopped mid key and
resumed later.

Release note: None

Fixes #68231

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@aliher1911 aliher1911 force-pushed the limit-export-requests branch 3 times, most recently from 0ea6cfc to f68a75b Compare August 2, 2021 11:57
@aliher1911 aliher1911 changed the title storage: Add an option to break export mid key storage/storageccl: Add an option to break export mid key Aug 2, 2021
@aliher1911 aliher1911 requested review from a team, pbardea and sumeerbhola and removed request for a team August 2, 2021 12:09
@aliher1911
Copy link
Contributor Author

Want to get feedback on this before I add any client side code from backup_processor to the mix.
Currently split into 2 commits, one on the pebble side and another on request/response for export.

Copy link
Contributor

@pbardea pbardea left a comment

Choose a reason for hiding this comment

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

Reviewed 2 of 9 files at r1.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @aliher1911 and @sumeerbhola)


pkg/ccl/storageccl/export.go, line 183 at r2 (raw file):

	// Only use resume timestamp if splitting mid key is enabled.
	resumeKeyTs := hlc.Timestamp{}
	if args.SplitMidKey {

Can we only permit SplitMidKey be set if args.ReturnSST is set? Backup/restore's accounting of these SSTs treats them as covering a complete span, so if we do split and ExportRequest mid SST, the backup processor should have a chance to stitch it together at the callsite. (We don't want to add a timestamp field to BackupManifest_File.)

We'll soon want to move to all requests setting args.ReturnSST to true so I don't think that this is a big limitation.


pkg/roachpb/api.proto, line 1368 at r2 (raw file):

  // different from start_time.
  util.hlc.Timestamp resume_key_ts = 12 [(gogoproto.nullable) = false];
  util.hlc.Timestamp start_time = 3 [(gogoproto.nullable) = false];

With serveral timestamps in the request, perhaps it'd be worthwhile to add a comment saying that StartTime is meaningful only with MVCCFilter set to all revisions, and that it is the lower bound on MVCCVersions of exported keys?


pkg/roachpb/api.proto, line 1445 at r2 (raw file):

  message File {
    Span span = 1 [(gogoproto.nullable) = false];
    util.hlc.Timestamp resume_key_ts = 9 [(gogoproto.nullable) = false];

Does resumeKeyTS semantically make sense to describe the contents of the file? Perhaps something like endKeyTS?

Also nit: (gogoproto.customname) = "ResumeKeyTS" (for here and the change to exportrequest above)


pkg/storage/pebble_batch.go, line 136 at r1 (raw file):

	startKey, endKey roachpb.Key,
	startTS, endTS hlc.Timestamp,
	firstKeyTs hlc.Timestamp,

nit: s/firstKeyTs/firstKeyTS/g and s/resumeTs/resumeTS/g

Copy link
Contributor Author

@aliher1911 aliher1911 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: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @aliher1911, @pbardea, and @sumeerbhola)


pkg/ccl/storageccl/export.go, line 183 at r2 (raw file):

Previously, pbardea (Paul Bardea) wrote…

Can we only permit SplitMidKey be set if args.ReturnSST is set? Backup/restore's accounting of these SSTs treats them as covering a complete span, so if we do split and ExportRequest mid SST, the backup processor should have a chance to stitch it together at the callsite. (We don't want to add a timestamp field to BackupManifest_File.)

We'll soon want to move to all requests setting args.ReturnSST to true so I don't think that this is a big limitation.

I think we can't just remove the option because of mixed version clusters to retain ability to still do non-split exports, but we can check that this option can't be set if ReturnSST is false and fail.
Does that make sense?

Copy link
Contributor

@pbardea pbardea 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: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @aliher1911 and @sumeerbhola)


pkg/ccl/storageccl/export.go, line 183 at r2 (raw file):

but we can check that this option can't be set if ReturnSST is false and fail

Yes, that sounds good

Sorry, I didn't meant to remove any option, just that we expect almost all requests (the exception being mixed-version requests) to set args.ReturnSST to true.

Copy link
Collaborator

@sumeerbhola sumeerbhola left a comment

Choose a reason for hiding this comment

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

The storage changes look fine.

  • MVCCIncrementalIterator.SeekGE has a code comment that says "startKey should be a metadata key to ensure ..." that needs tweaking.
  • is the logic inpebbleExportToSst adequately tested using export_test.go -- could you look at the code coverage?

:lgtm:

Reviewed 8 of 9 files at r1, 1 of 3 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @aliher1911 and @sumeerbhola)


pkg/storage/engine.go, line 410 at r1 (raw file):

	//
	// This function looks at MVCC versions and intents, and returns an error if an
	// intent is found.

can you add stuff to the function comment about firstKeyTs and stopMidKey.

Copy link
Contributor Author

@aliher1911 aliher1911 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: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @aliher1911, @pbardea, and @sumeerbhola)


pkg/ccl/storageccl/export.go, line 183 at r2 (raw file):

Previously, pbardea (Paul Bardea) wrote…

but we can check that this option can't be set if ReturnSST is false and fail

Yes, that sounds good

Sorry, I didn't meant to remove any option, just that we expect almost all requests (the exception being mixed-version requests) to set args.ReturnSST to true.

Done.


pkg/roachpb/api.proto, line 1368 at r2 (raw file):

Previously, pbardea (Paul Bardea) wrote…

With serveral timestamps in the request, perhaps it'd be worthwhile to add a comment saying that StartTime is meaningful only with MVCCFilter set to all revisions, and that it is the lower bound on MVCCVersions of exported keys?

Done.


pkg/roachpb/api.proto, line 1445 at r2 (raw file):

resumeKeyTS
Yeah you are absolutely right! endKeyTS would be more consistent with how it is named in the Span where we have start and end keys.

@pbardea pbardea self-requested a review August 5, 2021 15:53
Copy link
Contributor Author

@aliher1911 aliher1911 left a comment

Choose a reason for hiding this comment

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

@sumeerbhola can you elaborate on SeekGE, is it no longer the case that we can seek intents and keys separately because of how we store them now? Our current resume usage didn't change much here.

Test coverage look fine, I just added new tests there and wrapped that as a table test to cover different cases.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @pbardea and @sumeerbhola)


pkg/storage/engine.go, line 410 at r1 (raw file):

Previously, sumeerbhola wrote…

can you add stuff to the function comment about firstKeyTs and stopMidKey.

Seems like comment went a bit out of date since writer was added. Does it also make sense to wrap it in a struct later, since not all of them are always applicable.

Copy link
Collaborator

@sumeerbhola sumeerbhola left a comment

Choose a reason for hiding this comment

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

The fact that they are separate is hidden from the user of MVCCIncrementalIterator, so I didn't mean to refer to the separated intents stuff. The comment currently says

startKey should be a metadata key to ensure that the iterator has a chance to observe any intents on the key if they are there.

and now we are not necessarily passing in a metadata key because we may have already observed the intent and are resuming from a particular version.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @pbardea and @sumeerbhola)

@aliher1911 aliher1911 marked this pull request as ready for review August 6, 2021 08:52
@aliher1911 aliher1911 requested a review from a team August 6, 2021 08:52
@aliher1911 aliher1911 requested review from a team as code owners August 6, 2021 08:52
@aliher1911 aliher1911 force-pushed the limit-export-requests branch 2 times, most recently from 55e0ca4 to 0fc4ce2 Compare August 6, 2021 09:24
Copy link
Contributor Author

@aliher1911 aliher1911 left a comment

Choose a reason for hiding this comment

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

Updated comments on MVCCIncrementalIterator!

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @pbardea and @sumeerbhola)

Copy link
Collaborator

@sumeerbhola sumeerbhola left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 4 files at r8.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @aliher1911, @pbardea, and @sumeerbhola)


pkg/storage/engine.go, line 410 at r1 (raw file):

Previously, aliher1911 (Oleg) wrote…

Seems like comment went a bit out of date since writer was added. Does it also make sense to wrap it in a struct later, since not all of them are always applicable.

wrapping in an options struct sounds good.


pkg/storage/engine.go, line 394 at r8 (raw file):

	// If stopMidKey is used, firstKeyTS would serve as the timestamp for export to
	// resume together with a startKey. firstKeyTs doesn't necessarily need to be
	// between startTS and endTS.

what is the case in which it won't be in (startTS, endTS]?
also, it looks like firstKeyTS is unilaterally used. Maybe say that:
firstKeyTS is either empty, which represents starting from the potential intent and continuing to the versions, or non-empty, which represents starting from a particular version. firstKeyTS will always be empty when !stopMidKey.

Copy link
Contributor Author

@aliher1911 aliher1911 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: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @aliher1911, @pbardea, and @sumeerbhola)


pkg/storage/engine.go, line 394 at r8 (raw file):

Previously, sumeerbhola wrote…

what is the case in which it won't be in (startTS, endTS]?
also, it looks like firstKeyTS is unilaterally used. Maybe say that:
firstKeyTS is either empty, which represents starting from the potential intent and continuing to the versions, or non-empty, which represents starting from a particular version. firstKeyTS will always be empty when !stopMidKey.

Currently it is always empty or within (startTS, endTS] but there's another PR that would break this assumption if that change sounds feasible. Idea is to stop iterating after we hit certain underlying iteration limits #68467. In that case iterator could stop while skipping outside the (startTS, endTS] range and resuming it from that point will either bring us to start of interval or next key depending on where we stopped.

@aliher1911 aliher1911 force-pushed the limit-export-requests branch 2 times, most recently from 405ce1f to 7f6fb0a Compare August 6, 2021 15:41
Copy link
Contributor Author

@aliher1911 aliher1911 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: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @pbardea and @sumeerbhola)


pkg/storage/engine.go, line 410 at r1 (raw file):

Previously, sumeerbhola wrote…

wrapping in an options struct sounds good.

I'll do that with separate PR

Copy link
Contributor

@pbardea pbardea 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 to me

@aliher1911
Copy link
Contributor Author

@sumeerbhola just checking if you have any more comments on that beside what was addressed. Before I rebase past breakages and merge that.

Previously when exporting ranges with very large number of versions
export could hit the situation where single key export would exceed
maximum export byte limit. To resolve this, safety threshold has to
be raised which could cause nodes going out of memory.
To address this, this patch adds an ability to stop and resume on
the arbitrary key timestamp so that it could be stopped mid key and
resumed later.

Release note: None
Add ability to request exports that would use resume span starting
from arbitrary key timestamp and return resume timestamp for
continuation to use new storage export capability.

Release note: None
@aliher1911
Copy link
Contributor Author

bors r=pbardea,sumeerbhola

@craig craig bot merged commit ab15e5f into cockroachdb:master Aug 12, 2021
@craig
Copy link
Contributor

craig bot commented Aug 12, 2021

Build succeeded:

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.

Allow ExportRequest to resume exports on timestamp boundary
4 participants