You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(design): address Claude round-3 review on logical backup proposal
Round-2 carry-overs:
- Move NewBackupScanner from *ShardedCoordinator to *ShardStore.
ShardedCoordinator (kv/sharded_coordinator.go:124) has no *ShardStore
field; ShardStore is the natural home for ScanAt-adjacent code.
- Add a Phase-1 note that ScanAt's doc comment must be updated to
reflect that BeginBackup's applied_index fence makes cross-shard
ScanAt globally consistent.
- Add pin_token to ListAdaptersAndScopesRequest so the scope scan is
bounded to the pinned read_ts; concurrently-created scopes are not
surfaced.
- Add hll/ to the Redis db_0 example tree (top-level layout already
had it; the per-adapter example lagged).
- Add --stream-merge-strategy / --preserve-ttl / --preserve-visibility
to the elastickv-restore apply CLI block.
New nits from the Gemini changes:
- Pick one form for DynamoDB bundle-mode flags. Two-flag form
(--dynamodb-bundle-mode jsonl + --dynamodb-bundle-size 64MiB)
throughout; drop the inline jsonl:size=64MiB form.
- RenewBackupRequest.ttl_ms documents the same 60s-24h range
constraint as BeginBackupRequest, bounded above by
backup_max_ttl_ms; out-of-range returns InvalidArgument.
Tests added: TestRenewBackupTTLRangeValidation,
TestListAdaptersAndScopesAtPinTS.
repeated string dynamodb_tables = 1; // from !ddb|meta|table| scan
671
-
repeated string s3_buckets = 2; // from !s3|bucket|meta| scan
709
+
repeated string dynamodb_tables = 1; // from !ddb|meta|table| scan at read_ts
710
+
repeated string s3_buckets = 2; // from !s3|bucket|meta| scan at read_ts
672
711
repeated uint32 redis_databases = 3; // {0} until multi-db lands
673
-
repeated string sqs_queues = 4; // from !sqs|queue|meta| scan
712
+
repeated string sqs_queues = 4; // from !sqs|queue|meta| scan at read_ts
674
713
}
675
714
```
676
715
@@ -833,7 +872,10 @@ elastickv-restore apply \
833
872
[--adapter dynamodb,s3,redis,sqs] \
834
873
[--scope dynamodb=orders] \
835
874
[--mode replace|merge|skip-existing] \
836
-
[--rate-limit 5000ops/s]
875
+
[--rate-limit 5000ops/s] \
876
+
[--preserve-ttl] \
877
+
[--preserve-visibility] \
878
+
[--stream-merge-strategy reject|auto-id]
837
879
```
838
880
839
881
`replace` deletes the target scope before re-importing; `merge`
@@ -1031,6 +1073,8 @@ Scope: out of this proposal; mentioned only to draw the boundary.
1031
1073
| `TestS3PathFileVsDirectoryCollision` | Bucket holds both `path/to` (object) and `path/to/obj`; producer renames the shorter key to `path/to.elastickv-leaf-data` and records it in `KEYMAP.jsonl`; restore tool reverses it via `MANIFEST.s3_collision_strategy` |
1032
1074
| `TestBeginBackupTooManyActiveBackups` | Reaching `max_active_backup_pins` returns `ResourceExhausted`; releasing one pin frees a slot for the next request |
1033
1075
| `TestRenewBackupExtendsDeadline` | `RenewBackup` shifts the deadline; producer's failed-renewal path aborts the dump with a critical log line rather than continuing past the TTL |
1076
+
| `TestRenewBackupTTLRangeValidation` | `RenewBackup` with `ttl_ms < 60s` or `ttl_ms > backup_max_ttl_ms` returns `InvalidArgument`; in-range values succeed |
1077
+
| `TestListAdaptersAndScopesAtPinTS` | A scope created (e.g. CreateTable) after `BeginBackup` is not surfaced by `ListAdaptersAndScopes(pin_token)`; pre-existing scopes are |
0 commit comments