Skip to content

Commit c7ac78c

Browse files
craig[bot]annrpommsbutler
committed
141745: pkg/cli: allow system.zones in debug zip r=annrpom a=annrpom This patch adds `system.zones` into debug zip collection. Epic: none Release note: None 143709: backup: fix up encryption handling in compacted backups r=kev-cao a=msbutler Fixes #143725 Release note: none Co-authored-by: Annie Pompa <[email protected]> Co-authored-by: Michael Butler <[email protected]>
3 parents de064de + 57396bd + e985888 commit c7ac78c

File tree

10 files changed

+93
-47
lines changed

10 files changed

+93
-47
lines changed

pkg/backup/backup_job.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,8 +1663,11 @@ func updateBackupDetails(
16631663
startTime = prevBackups[len(prevBackups)-1].EndTime
16641664
}
16651665

1666-
// If we didn't load any prior backups from which get encryption info, we
1667-
// need to generate encryption specific data.
1666+
// If we didn't load any prior backups with EncryptionInfo, we need to
1667+
// generate encryption specific data.
1668+
//
1669+
// TODO(msbutler): consider using prev backups instead of nil encryptiuon
1670+
// info, if possible.
16681671
var encryptionInfo *jobspb.EncryptionInfo
16691672
if encryptionOptions == nil {
16701673
encryptionOptions, encryptionInfo, err = backupencryption.MakeNewEncryptionOptions(ctx, details.EncryptionOptions, kmsEnv)

pkg/backup/backupdest/backup_destination.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,17 @@ type ResolvedDestination struct {
109109
// In addition, in this case that this backup is an incremental backup (either
110110
// explicitly, or due to the auto-append feature), it will resolve the
111111
// encryption options based on the base backup, as well as find all previous
112-
// backup manifests in the backup chain. Additionally, if a startTime is provided,
113-
// it will be used to determine its destination. If one is not provided, we assume
114-
// that the incremental is chained off of the most recent backup in the chain
115-
// and that backup's manifest will be fetched to determine the start time.
112+
// backup manifests in the backup chain. Additionally, if a startTime is
113+
// provided, it will be used to determine its destination. If one is not
114+
// provided, we assume that the incremental is chained off of the most recent
115+
// backup in the chain and that backup's manifest will be fetched to determine
116+
// the start time.
116117
//
117118
// The encryptions passed to the encryption options should include the raw
118-
// encryption options. TODO (kev-cao): Once we have completed the backup
119-
// directory index work, we can remove the need for encryption and KMS.
119+
// encryption options, not the resolved key.
120+
//
121+
// TODO (kev-cao): Once we have completed the backup directory index work, we
122+
// can remove the need for encryption and KMS.
120123
func ResolveDest(
121124
ctx context.Context,
122125
user username.SQLUsername,

pkg/backup/backupencryption/encryption.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func ValidateKMSURIsAgainstFullBackup(
204204
func MakeNewEncryptionOptions(
205205
ctx context.Context, encryptionParams *jobspb.BackupEncryptionOptions, kmsEnv cloud.KMSEnv,
206206
) (*jobspb.BackupEncryptionOptions, *jobspb.EncryptionInfo, error) {
207-
if encryptionParams == nil || encryptionParams.Mode == jobspb.EncryptionMode_None {
207+
if !encryptionParams.IsEncrypted() {
208208
return nil, nil, nil
209209
}
210210
var encryptionOptions *jobspb.BackupEncryptionOptions
@@ -332,7 +332,9 @@ func WriteNewEncryptionInfoToBackup(
332332

333333
// GetEncryptionFromBase retrieves the encryption options of the base backup. It
334334
// is expected that incremental backups use the same encryption options as the
335-
// base backups.
335+
// base backups. The encryptionParams input is expected not to have a key set
336+
// and to simply have the user supplied fields. The output will only have the
337+
// key set.
336338
func GetEncryptionFromBase(
337339
ctx context.Context,
338340
user username.SQLUsername,
@@ -341,7 +343,7 @@ func GetEncryptionFromBase(
341343
encryptionParams *jobspb.BackupEncryptionOptions,
342344
kmsEnv cloud.KMSEnv,
343345
) (*jobspb.BackupEncryptionOptions, error) {
344-
if encryptionParams == nil || encryptionParams.Mode == jobspb.EncryptionMode_None {
346+
if !encryptionParams.IsEncrypted() {
345347
return nil, nil
346348
}
347349
exportStore, err := makeCloudStorage(ctx, baseBackupURI, user)
@@ -359,9 +361,14 @@ func GetEncryptionFromBaseStore(
359361
encryptionParams *jobspb.BackupEncryptionOptions,
360362
kmsEnv cloud.KMSEnv,
361363
) (*jobspb.BackupEncryptionOptions, error) {
362-
if encryptionParams == nil || encryptionParams.Mode == jobspb.EncryptionMode_None {
364+
if !encryptionParams.IsEncrypted() {
363365
return nil, nil
364366
}
367+
368+
if encryptionParams.HasKey() {
369+
return nil, errors.New("encryption options already have a key")
370+
}
371+
365372
opts, err := ReadEncryptionOptions(ctx, baseStore)
366373
if err != nil {
367374
return nil, err

pkg/backup/compaction_job.go

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ func (b *backupResumer) ResumeCompaction(
211211
// We interleave the computation of the compaction chain between the destination
212212
// resolution and writing of backup lock due to the need to verify that the
213213
// compaction chain is a valid chain.
214-
prevManifests, localityInfo, encryption, allIters, err := getBackupChain(
214+
prevManifests, localityInfo, baseEncryptionOpts, allIters, err := getBackupChain(
215215
ctx, execCtx.ExecCfg(), execCtx.User(), initialDetails.Destination,
216216
initialDetails.EncryptionOptions, initialDetails.EndTime, kmsEnv,
217217
)
@@ -253,7 +253,7 @@ func (b *backupResumer) ResumeCompaction(
253253
return err
254254
}
255255
updatedDetails, err = updateCompactionBackupDetails(
256-
ctx, compactChain, initialDetails, backupDest, encryption, kmsEnv,
256+
ctx, compactChain, initialDetails, backupDest, baseEncryptionOpts, kmsEnv,
257257
)
258258
if err != nil {
259259
return err
@@ -492,22 +492,12 @@ func updateCompactionBackupDetails(
492492
compactionChain compactionChain,
493493
initialDetails jobspb.BackupDetails,
494494
resolvedDest backupdest.ResolvedDestination,
495-
encryption *jobspb.BackupEncryptionOptions,
495+
baseEncryptOpts *jobspb.BackupEncryptionOptions,
496496
kmsEnv cloud.KMSEnv,
497497
) (jobspb.BackupDetails, error) {
498498
if len(compactionChain.chainToCompact) == 0 {
499499
return jobspb.BackupDetails{}, errors.New("no backup manifests to compact")
500500
}
501-
var encryptionInfo *jobspb.EncryptionInfo
502-
if encryption != nil {
503-
var err error
504-
_, encryptionInfo, err = backupencryption.MakeNewEncryptionOptions(
505-
ctx, encryption, kmsEnv,
506-
)
507-
if err != nil {
508-
return jobspb.BackupDetails{}, err
509-
}
510-
}
511501
lastBackup := compactionChain.lastBackup()
512502
allDescs, _, err := backupinfo.LoadSQLDescsFromBackupsAtTime(
513503
ctx,
@@ -524,13 +514,16 @@ func updateCompactionBackupDetails(
524514
destination := initialDetails.Destination
525515
destination.Subdir = resolvedDest.ChosenSubdir
526516
compactedDetails := jobspb.BackupDetails{
527-
Destination: destination,
528-
StartTime: compactionChain.start,
529-
EndTime: compactionChain.end,
530-
URI: resolvedDest.DefaultURI,
531-
URIsByLocalityKV: resolvedDest.URIsByLocalityKV,
532-
EncryptionOptions: encryption,
533-
EncryptionInfo: encryptionInfo,
517+
Destination: destination,
518+
StartTime: compactionChain.start,
519+
EndTime: compactionChain.end,
520+
URI: resolvedDest.DefaultURI,
521+
URIsByLocalityKV: resolvedDest.URIsByLocalityKV,
522+
// Because we cannot have nice things, we persist a semi hydrated version of
523+
// EncryptionOptions at planning, and then add the key at the beginning of
524+
// resume using the same data structure in details. NB: EncryptionInfo is
525+
// left blank and only added on the full backup (i think).
526+
EncryptionOptions: baseEncryptOpts,
534527
CollectionURI: resolvedDest.CollectionURI,
535528
ResolvedTargets: allDescsPb,
536529
ResolvedCompleteDbs: lastBackup.CompleteDbs,
@@ -692,28 +685,22 @@ func getBackupChain(
692685
log.Warningf(ctx, "failed to cleanup incremental backup stores: %+v", err)
693686
}
694687
}()
695-
// If encryption keys have not already been computed, then we will compute
696-
// it using the base store.
697-
// TODO (kev-cao): Once we resolve #143725, we can remove this check and
698-
// expect `GetEncryptionFromBaseStore` to be idempotent.
699-
var encryption *jobspb.BackupEncryptionOptions
700-
if encryptionOpts != nil && encryptionOpts.Mode != jobspb.EncryptionMode_None &&
701-
(encryptionOpts.Key != nil || encryptionOpts.KMSInfo != nil) {
702-
encryption = encryptionOpts
703-
} else {
704-
encryption, err = backupencryption.GetEncryptionFromBaseStore(
688+
baseEncryptionInfo := encryptionOpts
689+
if encryptionOpts != nil && !encryptionOpts.HasKey() {
690+
baseEncryptionInfo, err = backupencryption.GetEncryptionFromBaseStore(
705691
ctx, baseStores[0], encryptionOpts, kmsEnv,
706692
)
707693
if err != nil {
708694
return nil, nil, nil, nil, err
709695
}
710696
}
697+
711698
mem := execCfg.RootMemoryMonitor.MakeBoundAccount()
712699
defer mem.Close(ctx)
713700

714701
_, manifests, localityInfo, memReserved, err := backupdest.ResolveBackupManifests(
715702
ctx, &mem, baseStores, incStores, mkStore, resolvedBaseDirs,
716-
resolvedIncDirs, endTime, encryption, kmsEnv,
703+
resolvedIncDirs, endTime, baseEncryptionInfo, kmsEnv,
717704
user, false,
718705
)
719706
if err != nil {
@@ -723,12 +710,12 @@ func getBackupChain(
723710
mem.Shrink(ctx, memReserved)
724711
}()
725712
allIters, err := backupinfo.GetBackupManifestIterFactories(
726-
ctx, execCfg.DistSQLSrv.ExternalStorage, manifests, encryption, kmsEnv,
713+
ctx, execCfg.DistSQLSrv.ExternalStorage, manifests, baseEncryptionInfo, kmsEnv,
727714
)
728715
if err != nil {
729716
return nil, nil, nil, nil, err
730717
}
731-
return manifests, localityInfo, encryption, allIters, nil
718+
return manifests, localityInfo, baseEncryptionInfo, allIters, nil
732719
}
733720

734721
// concludeBackupCompaction completes the backup compaction process after the backup has been

pkg/backup/compaction_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ ARRAY['nodelocal://1/backup/%d'], '%s', ''::BYTES, %d::DECIMAL, %d::DECIMAL
256256
db.Exec(t, "CREATE TABLE foo (a INT, b INT)")
257257
defer func() {
258258
db.Exec(t, "DROP TABLE foo")
259+
db.Exec(t, "SET CLUSTER SETTING jobs.debug.pausepoints = ''")
259260
}()
260261
db.Exec(t, "INSERT INTO foo VALUES (1, 1)")
261262
opts := "encryption_passphrase = 'correct-horse-battery-staple'"
@@ -277,6 +278,10 @@ ARRAY['nodelocal://1/backup/%d'], '%s', ''::BYTES, %d::DECIMAL, %d::DECIMAL
277278
var backupPath string
278279
db.QueryRow(t, "SHOW BACKUPS IN 'nodelocal://1/backup/6'").Scan(&backupPath)
279280
var jobID jobspb.JobID
281+
pause := rand.Intn(2) == 0
282+
if pause {
283+
db.Exec(t, "SET CLUSTER SETTING jobs.debug.pausepoints = 'backup.after.details_has_checkpoint'")
284+
}
280285
db.QueryRow(
281286
t,
282287
fmt.Sprintf(
@@ -290,6 +295,10 @@ crdb_internal.json_to_pb(
290295
backupPath, start, end,
291296
),
292297
).Scan(&jobID)
298+
if pause {
299+
jobutils.WaitForJobToPause(t, db, jobID)
300+
db.Exec(t, "RESUME JOB $1", jobID)
301+
}
293302
waitForSuccessfulJob(t, tc, jobID)
294303
validateCompactedBackupForTablesWithOpts(
295304
t, db, []string{"foo"}, "'nodelocal://1/backup/6'", start, end, opts,

pkg/cli/testdata/zip/file-filters/testzip_file_filters

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ debug/system.tenant_settings.txt
117117
debug/system.tenant_tasks.txt
118118
debug/system.tenant_usage.txt
119119
debug/system.tenants.txt
120+
debug/system.zones.txt
120121
debug/tenant_ranges.err.txt
121122

122123

@@ -246,6 +247,7 @@ debug/system.tenant_settings.txt
246247
debug/system.tenant_tasks.txt
247248
debug/system.tenant_usage.txt
248249
debug/system.tenants.txt
250+
debug/system.zones.txt
249251
debug/tenant_ranges.err.txt
250252

251253

@@ -406,6 +408,7 @@ debug/system.tenant_settings.txt
406408
debug/system.tenant_tasks.txt
407409
debug/system.tenant_usage.txt
408410
debug/system.tenants.txt
411+
debug/system.zones.txt
409412
debug/tenant_ranges.err.txt
410413

411414

@@ -541,6 +544,7 @@ debug/system.tenant_settings.txt
541544
debug/system.tenant_tasks.txt
542545
debug/system.tenant_usage.txt
543546
debug/system.tenants.txt
547+
debug/system.zones.txt
544548
debug/tenant_ranges.err.txt
545549

546550
#include only txt files with system table file exclustion

pkg/cli/zip_table_registry.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,6 @@ var zipInternalTablesPerNode = DebugZipTableRegistry{
11251125
// - system.join_tokens: avoid downloading secret join keys.
11261126
// - system.comments: avoid downloading noise from SQL schema.
11271127
// - system.ui: avoid downloading noise from UI customizations.
1128-
// - system.zones: the contents of crdb_internal.zones is easier to use.
11291128
// - system.statement_bundle_chunks: avoid downloading a large table that's
11301129
// hard to interpret currently.
11311130
// - system.statement_statistics: historical data, usually too much to
@@ -1604,4 +1603,11 @@ limit 5000;`,
16041603
"info",
16051604
},
16061605
},
1606+
"system.zones": {
1607+
customQueryRedacted: `SELECT "id" FROM system.zones;`,
1608+
customQueryUnredacted: `SELECT
1609+
"id",
1610+
crdb_internal.pb_to_json('cockroach.config.zonepb.ZoneConfig', config)
1611+
FROM system.zones;`,
1612+
},
16071613
}

pkg/cli/zip_table_registry_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ func TestNoForbiddenSystemTablesInDebugZip(t *testing.T) {
128128
"system.join_tokens",
129129
"system.comments",
130130
"system.ui",
131-
"system.zones",
132131
"system.statement_bundle_chunks",
133132
"system.statement_statistics",
134133
"system.transaction_statistics",

pkg/jobs/jobspb/jobs.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,17 @@ func (m *ChangefeedProgress_Checkpoint) IsEmpty() bool {
138138
func (r RestoreDetails) OnlineImpl() bool {
139139
return r.ExperimentalCopy || r.ExperimentalOnline
140140
}
141+
142+
func (b *BackupEncryptionOptions) HasKey() bool {
143+
144+
if b.KMSInfo != nil {
145+
return len(b.KMSInfo.EncryptedDataKey) > 0
146+
}
147+
// Used for encryption passphrases.
148+
return len(b.Key) > 0
149+
}
150+
151+
func (b *BackupEncryptionOptions) IsEncrypted() bool {
152+
// For dumb reasons, there are two ways to represent no encryption.
153+
return !(b == nil || b.Mode == EncryptionMode_None)
154+
}

pkg/jobs/jobspb/jobs.proto

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,21 @@ message BackupDetails {
396396
// partitioned backups. The map does not include the default locality.
397397
map<string, string> uris_by_locality_kv = 5 [(gogoproto.customname) = "URIsByLocalityKV"];
398398
bytes deprecated_backup_manifest = 4;
399+
400+
// EncryptionOptions contains user inputed data initially, but once
401+
// ResolveDest is called at the beginning of resumption, this field will
402+
// contain the encryption key.
403+
//
404+
// TODO(msbutler): use seperate job info key to persist hydrated encryption
405+
// keys so encrypted backup logic becomes easier to reason about. This
406+
// shouldn't be as complicated as rocket science.
399407
BackupEncryptionOptions encryption_options = 6;
408+
409+
// EncryptionInfo should only ever get set on the first encrypted backup in
410+
// the chain because it persists the salt that each key in the chain must
411+
// have.
412+
//
413+
// TODO(msbutler): understand if only the full ever sets EncryptionInfo.
400414
EncryptionInfo encryption_info = 9;
401415

402416
// ProtectedTimestampRecord is the ID of the protected timestamp record

0 commit comments

Comments
 (0)