Skip to content

Commit

Permalink
backupccl: dont validate introduced tenant spans
Browse files Browse the repository at this point in the history
In restore, we run a validation step in checkMissingIntroducedSpans() in which
we decode each introduced span in the backup manifests. This decoding step
naively assumed each introduced span was a table span. Incremental backups of
tenants, however, contain introduced tenant key spans, causing the validation
step to inadvertently fail during a restore of a tenant.

This patch skips this validation step for introduced tenant spans as it
does not apply to introduced tenant spans.

Epic: None

Release note: none
  • Loading branch information
msbutler authored and darinpp committed Aug 22, 2023
1 parent 4c802f9 commit c2fa404
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
62 changes: 62 additions & 0 deletions pkg/ccl/backupccl/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6898,6 +6898,68 @@ func TestBackupRestoreInsideMultiPodTenant(t *testing.T) {
})
}

// TestBackupRestoreCreatedAndDroppedTenant ensures that a restore of a tenant works if a
// incremental backups captured the creation or deletion of a tenant.
func TestBackupRestoreCreatedAndDroppedTenant(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)

params := base.TestClusterArgs{ServerArgs: base.TestServerArgs{
Knobs: base.TestingKnobs{
JobsTestingKnobs: jobs.NewTestingKnobsWithShortIntervals(),
TenantTestingKnobs: &sql.TenantTestingKnobs{
// The tests expect specific tenant IDs to show up.
EnableTenantIDReuse: true,
},
},

DisableDefaultTestTenant: true},
}

const numAccounts = 1
tc, systemDB, _, cleanupFn := backupRestoreTestSetupWithParams(
t, singleNode, numAccounts, InitManualReplication, params,
)
_, _ = tc, systemDB
defer cleanupFn()

// NB: tenant certs for 10, 11, 20 are embedded. See:
_ = security.EmbeddedTenantIDs()

systemDB.Exec(t, "CREATE TENANT foo")

systemDB.Exec(t, "SET sql_safe_updates =off;")

getAOST := func() string {
var ts string
systemDB.QueryRow(t, `SELECT cluster_logical_timestamp()`).Scan(&ts)
return ts
}
t1 := getAOST()

systemDB.Exec(t, fmt.Sprintf("BACKUP INTO 'nodelocal://1/clusterwide' AS OF SYSTEM TIME '%s' with include_all_secondary_tenants;", t1))

systemDB.Exec(t, "CREATE TENANT baz")

t2 := getAOST()
systemDB.Exec(t, fmt.Sprintf("BACKUP INTO LATEST IN 'nodelocal://1/clusterwide' AS OF SYSTEM TIME %s with include_all_secondary_tenants;", t2))

systemDB.Exec(t, "DROP TENANT baz")

t3 := getAOST()
systemDB.Exec(t, fmt.Sprintf("BACKUP INTO LATEST IN 'nodelocal://1/clusterwide' AS OF SYSTEM TIME %s with include_all_secondary_tenants;", t3))

restoreCmd := func(aost string, name string) string {
return fmt.Sprintf("RESTORE TENANT 2 FROM LATEST IN 'nodelocal://1/clusterwide' AS OF SYSTEM TIME %s with tenant_name = '%s'", aost, name)
}

systemDB.Exec(t, restoreCmd(t1, "full"))

systemDB.Exec(t, restoreCmd(t2, "after-create"))

systemDB.Exec(t, restoreCmd(t3, "after-drop"))
}

// Ensure that backing up and restoring tenants succeeds.
func TestBackupRestoreTenant(t *testing.T) {
defer leaktest.AfterTest(t)()
Expand Down
7 changes: 7 additions & 0 deletions pkg/ccl/backupccl/targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,13 @@ func checkMissingIntroducedSpans(
// backed up from ts=0).
tablesIntroduced := make(map[descpb.ID]struct{})
for _, span := range mainBackupManifests[i].IntroducedSpans {
if rest, _, err := keys.DecodeTenantPrefix(span.Key); err != nil {
return err
} else if len(rest) == 0 {
// The key span represents a whole tenant's key space. Checking for
// introduced tables does not apply.
continue
}
_, tableID, err := codec.DecodeTablePrefix(span.Key)
if err != nil {
return err
Expand Down

0 comments on commit c2fa404

Please sign in to comment.