-
Notifications
You must be signed in to change notification settings - Fork 34
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
feat(restore): adds --dc-mapping flag to restore command #4213
base: master
Are you sure you want to change the base?
Conversation
This adds support for --dc-mapping flag to restore command. It specifies mapping between DCs from the backup and DCs in the restored(target) cluster. All DCs from the source cluster should be explicitly mapped to all DCs in the target cluster. The only exception is when source and target cluster has exact match: source dcs == target dcs. Only works with tables restoration (--restore-tables=true). Syntax: "source_dc1,source_dc2=>target_dc1,target_dc2" Multiple mappings are separated by semicolons (;). Exclamation mark (!) before a DC indicates that it should be ignored during restore. Examples: "dc1,dc2=>dc3" - data from dc1 and dc2 DCs should be restored to dc3 DC. "dc1,dc2=>dc3,!dc4" - data from dc1 and dc2 DCs should be restored to dc3 DC. Ignoring dc4 DC from target cluster. "dc1,!dc2=>dc2" - data from dc1 should be restored to dc2 DC. Ignoring dc2 from source cluster. Fixes: #3829
This introduces use of dc mappings when restoring tables. Now each dc is downloading only data from corresponding dc(s) accordingly to user provided mapping. Also some dcs can be explicitly ignored. Fixes: #3829
This adds another cluster to docker setup, so we can have integration tests for dc-mappings. Fixes: #3829
In terms of syntax:
I find it confusing that it's possible to specify both restored and skipped DCs in the same mapping key.
I would suggest to validate that positive and negative DC occurrences are not mixed in the mapping key and that negative DCs can't be mapped to anything, so that we avoid confusion and typing mistakes. EDIT: The same goes here:
The negative DC is placed in the mapping value alongside positive DC? But I'm still in favor of not mixing positive and negative DCs here.
On the other hand, if we allow no DCs on either side of
Alternative approach would be to add some special characters for distinguishing between src and dst DCs, but I guess that the relation to the |
@@ -72,3 +72,16 @@ dry-run: | | |||
show-tables: | | |||
Prints table names together with keyspace, used in combination with --dry-run. | |||
dc-mapping: | |
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.
The sctool command docs are actually also a part of the regular SM docs.
In order to include those changes in the docs, you should run make docs
from repo root dir. In order to see how the changes were rendered, you can run
make -C docs preview(or just
make previewfrom
docs` dir).
slices.EqualFunc(tc.expectedMappings, mappings, func(a, b dcMapping) bool { | ||
return slices.Equal(a.Source, b.Source) && | ||
slices.Equal(a.Target, b.Target) && | ||
slices.Equal(a.IgnoreSource, b.IgnoreSource) && | ||
slices.Equal(a.IgnoreTarget, b.IgnoreTarget) | ||
}) |
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 think that you forgot to check the result of the slices.EqualFunc
:)
input: "dc1, dc2=>dc1, dc2", | ||
expectedMappings: dcMappings{ | ||
{Source: []string{"dc1", "dc2"}, Target: []string{"dc1", "dc2"}}, | ||
}, |
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.
This test case does not pass when the result is validated.
I don't see any code handling white spaces during the parsing, but it would be nice to add it.
if cmd.Update() { | ||
return wrapper("dc-mapping") | ||
} | ||
props["dc-mapping"] = cmd.dcMapping |
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.
We are using the convention of naming json
fields with _
instead of -
, but we use -
in the flag names:)
It can cause confusion and name mismatchs, but I think that we should follow it since its present in all of the flag names.
dcsInLoc := locationDC[loc.StringWithoutDC()] | ||
hostAllDCs := hostDCs[h] | ||
hostDCAccess[h] = append(hostDCAccess[h], strset.Intersection(strset.New(dcsInLoc...), strset.New(hostAllDCs...)).List()...) |
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 don't think that we should just make an intersection here.
If someone specified that given DC should be restored by given DC, then all hosts from this DC should have access to the appropriate location. This should be done inside the GetTarget
initial validation.
DCMappings DCMappings `json:"dc-mapping"` | ||
|
||
// Cache for host with access to remote location | ||
locationHosts map[Location][]string `json:"-"` | ||
// Cache for host and their DC after applying DCMappings | ||
hostDCs map[string][]string | ||
// Cache for dcs that shouldn't be restored from location | ||
ignoredSourceDC []string |
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.
Wouldn't it be way simpler if we just had a single mapping map[string][string]
of dst DC -> src DC list?
It could replace all locationHosts, hostDCs, ignoredSourceDC
.
During batch dispatch we could/should have access to given hosts DC, so it would give us enough information for correctness.
Ignored DCs could be replaced with restored DCs which could be easily obtained from such mapping when needed for filtering.
The assumption is that we don't need to care for cases like: what if only a few hosts from this DC have access to this location. Even when making backup, the whole DC needs to be backed up to a single location and all hosts from given DC needs to have access to it.
// The only way to have a list of dcs from the source cluster is to | ||
// get them from backup locations. | ||
sourceDC, err := w.collectDCFromLocation(ctx, t.locationHosts) |
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.
Correct, but we are already going through all of the manifests in the GetTarget
(initUnits
), so we should probably get all of the interesting data within a single iteration.
@@ -115,6 +115,7 @@ INTEGRATION_TEST_ARGS := -cluster $(PUBLIC_NET)100 \ | |||
-managed-cluster $(PUBLIC_NET)11,$(PUBLIC_NET)12,$(PUBLIC_NET)13,$(PUBLIC_NET)21,$(PUBLIC_NET)22,$(PUBLIC_NET)23 \ | |||
-test-network $(PUBLIC_NET) \ | |||
-managed-second-cluster $(PUBLIC_NET)31,$(PUBLIC_NET)32 \ | |||
-managed-third-cluster $(PUBLIC_NET)41,$(PUBLIC_NET)42 \ |
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.
Having 3 clusters for the docker setup seems excessive.
You have written nice unit tests, so we don't need to cover all scenarios with integration tests.
Having said that, could we simply rename the DC in the second cluster (used just for the restore)?
We could even divide this cluster into 2 single nodes DCs if that could help.
@VAveryanov8 I made a general review, but I didn't dive into other details, because it would be better to first discuss the current comments (other things might not matter after that). |
Also, we should deprecate the datacenter from the |
This adds support for
--dc-mapping
flag to restore command.It specifies mapping between DCs from the backup and DCs in the restored(target) cluster.
All DCs from the source cluster should be explicitly mapped to all DCs in the target cluster. The only exception is when
source and target cluster has exact match: source dcs == target dcs.
Only works with tables restoration (
--restore-tables=true
).Also by default now each dc is downloading only data from corresponding dc(s)accordingly to user provided mapping.
Syntax:
"source_dc1,source_dc2=>target_dc1,target_dc2"
Multiple mappings are separated by semicolons (;). Exclamation mark (!) before a DC indicates that it should be ignored during restore.
Examples:
Fixes: #3829
Please make sure that: