-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
backup: allow restricting backup coordination by region #95791
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, it is pretty pleasing how small the implementation is for this feature.
I left some questions and comments, but most are style related, so take them or leave them.
One question I have is whether the errors produced during a relocation contain enough information to not confuse users into thinking something is wrong.
id jobspb.JobID, | ||
destID base.SQLInstanceID, | ||
destSession sqlliveness.SessionID, | ||
) (sentinel error, failure error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤷 I can't decide if a function that returns two errors is more or less weird than a function that always returns an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, right? I went back and forth on this and decided I liked this best: I want to indicate failure vs success separately since e.g. callers are encouraged to Wrapf() their failures with contextual info or log them or clean up differently. I thought about making the first have a different type that just happened to implement Error() but I eventually decided error
made it most obvious that you return this thing from Resume() and don't go make your own.
destID base.SQLInstanceID, | ||
destSession sqlliveness.SessionID, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this function take a sqlinstance.InstanceInfo (or some other type that bundles the instance id and session ID)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
InstanceInfo has a lot more going on than I need/have. I don't know if we have anything that is just the pair of id and session. I'm not sure I feel like they need to be paired, conceptually? I guess I read ID as the destination, and session as a way to make sure it doesn't get dropped in transit but they're not obviously more linked than the other individual args?
// Check that a node will currently be able to run this before we create it. | ||
if coordinatorLocality.NonEmpty() { | ||
if _, err := p.DistSQLPlanner().GetAllInstancesByLocality(ctx, coordinatorLocality); err != nil { | ||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this error end up looking like? I'm wondering if we should wrap it, mentioning the COORDINATOR_LOCALITY option so the user knows what they might need to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like pq: no instances found matching locality filter %s
. It includes the filter that didn't match, which seems more useful than the field they put that filter in?
SQL changes LGTM. |
ed49d93
to
5951f80
Compare
Release note: none. Epic: none.
Release note: none. Epic: none.
The coordinator of a backup job needs to access the 'default' locality to read and write metadata including the backup checkpoint files and manifest. Prior to this change, this meant that every node in the cluster needed to be able to access this default locality storage location, since any node could become the coordinator. This change introduces a new locality filter option that can be specified when the backup job is created. If set, this new option will cause any node which attempts to execute the backup job to check if it meets the locality requirements and, if not, move the execution of the job to a node which does meet them, or fail if not such node can be found. A locality requirement is specified as any number of key=value pairs, each of which a node must match to be eligible to execute the job, for example, a job run with BACKUP ... WITH coordinator_locality = 'region=east,cloud=azure' would require a node have both 'region=east' and 'cloud=azure', however the order is not significant, only that each specified filter is met. Jobs typically begin executing directly on the node on which they are created so if that node has matching localities, it will execute the job, or relocate it if it does not. Relocated executions may take some amount of time to resume on the new node to which they were relocated, similar to the delay seen when a paused job is resumed, typically between a few seconds to a minute. Note that this only restricts the *coordination* of the backup job -- reading the row data from individual ranges and exporting that data to the destination storage location or locations is still performed by many nodes, typically the leaseholders for each range. Release note (enterprise change): coordination of BACKUP jobs and thus writing of BACKUP metadata can be restricted to nodes within designated localities using the new 'coordinator_locality' option. Epic: CRDB-9547.
Nice work here. I'm good with this as a step. Let's be sure not to forget the alter and create schedule changes before shipping it. |
TFTRs! bors r+ |
Build failed (retrying...): |
Build succeeded: |
The coordinator of a backup job needs to access the 'default' locality
to read and write metadata including the backup checkpoint files and
manifest. Prior to this change, this meant that every node in the
cluster needed to be able to access this default locality storage
location, since any node could become the coordinator.
This change introduces a new locality filter option that can be
specified when the backup job is created. If set, this new option will
cause any node which attempts to execute the backup job to check if it
meets the locality requirements and, if not, move the execution of the
job to a node which does meet them, or fail if not such node can be
found.
A locality requirement is specified as any number of key=value pairs,
each of which a node must match to be eligible to execute the job, for
example, a job run with BACKUP ... WITH coordinator_locality =
'region=east,cloud=azure' would require a node have both 'region=east'
and 'cloud=azure', however the order is not significant, only that each
specified filter is met.
Jobs typically begin executing directly on the node on which they are
created so if that node has matching localities, it will execute the
job, or relocate it if it does not.
Relocated executions may take some amount of time to resume on the new
node to which they were relocated, similar to the delay seen when a
paused job is resumed, typically between a few seconds to a minute.
Note that this only restricts the coordination of the backup job --
reading the row data from individual ranges and exporting that data to
the destination storage location or locations is still performed by many
nodes, typically the leaseholders for each range.
Release note (enterprise change): coordination of BACKUP jobs and thus
writing of BACKUP metadata can be restricted to nodes within designated
localities using the new 'coordinator_locality' option.
Epic: CRDB-9547.