Skip to content

Commit

Permalink
Merge pull request cockroachdb#49745 from pbardea/backport20.1-49591
Browse files Browse the repository at this point in the history
release-20.1: backupccl: all full cluster restore of backup with no user data
  • Loading branch information
pbardea authored Jun 2, 2020
2 parents 1cd438c + 03f873b commit 88b829d
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 29 deletions.
26 changes: 2 additions & 24 deletions pkg/ccl/backupccl/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,28 +74,6 @@ const (
localFoo = "nodelocal://0/foo"
)

func backupRestoreTestSetupEmptyWithParams(
t testing.TB,
clusterSize int,
dir string,
init func(tc *testcluster.TestCluster),
params base.TestClusterArgs,
) (ctx context.Context, tc *testcluster.TestCluster, sqlDB *sqlutils.SQLRunner, cleanup func()) {
ctx = context.Background()

params.ServerArgs.ExternalIODir = dir
tc = testcluster.StartTestCluster(t, clusterSize, params)
init(tc)

sqlDB = sqlutils.MakeSQLRunner(tc.Conns[0])

cleanupFn := func() {
tc.Stopper().Stop(context.TODO()) // cleans up in memory storage's auxiliary dirs
}

return ctx, tc, sqlDB, cleanupFn
}

func backupRestoreTestSetupWithParams(
t testing.TB,
clusterSize int,
Expand Down Expand Up @@ -136,8 +114,8 @@ func backupRestoreTestSetupWithParams(
}

cleanupFn := func() {
tc.Stopper().Stop(context.TODO()) // cleans up in memory storage's auxiliary dirs
dirCleanupFn() // cleans up dir, which is the nodelocal:// storage
tc.Stopper().Stop(ctx) // cleans up in memory storage's auxiliary dirs
dirCleanupFn() // cleans up dir, which is the nodelocal:// storage
}

return ctx, tc, sqlDB, dir, cleanupFn
Expand Down
66 changes: 66 additions & 0 deletions pkg/ccl/backupccl/full_cluster_backup_restore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,63 @@
package backupccl_test

import (
"context"
"fmt"
"reflect"
"strconv"
"testing"

"github.com/cockroachdb/cockroach/pkg/base"
_ "github.com/cockroachdb/cockroach/pkg/ccl/partitionccl"
"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
"github.com/cockroachdb/cockroach/pkg/testutils"
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
"github.com/cockroachdb/cockroach/pkg/testutils/testcluster"
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
)

func backupRestoreTestSetupEmptyWithParams(
t testing.TB,
clusterSize int,
dir string,
init func(tc *testcluster.TestCluster),
params base.TestClusterArgs,
) (ctx context.Context, tc *testcluster.TestCluster, sqlDB *sqlutils.SQLRunner, cleanup func()) {
ctx = context.Background()

params.ServerArgs.ExternalIODir = dir
tc = testcluster.StartTestCluster(t, clusterSize, params)
init(tc)

sqlDB = sqlutils.MakeSQLRunner(tc.Conns[0])

cleanupFn := func() {
tc.Stopper().Stop(ctx) // cleans up in memory storage's auxiliary dirs
}

return ctx, tc, sqlDB, cleanupFn
}

func createEmptyCluster(
t testing.TB, clusterSize int,
) (sqlDB *sqlutils.SQLRunner, tempDir string, cleanup func()) {
ctx := context.Background()

dir, dirCleanupFn := testutils.TempDir(t)
params := base.TestClusterArgs{}
params.ServerArgs.ExternalIODir = dir
tc := testcluster.StartTestCluster(t, clusterSize, params)

sqlDB = sqlutils.MakeSQLRunner(tc.Conns[0])

cleanupFn := func() {
tc.Stopper().Stop(ctx) // cleans up in memory storage's auxiliary dirs
dirCleanupFn() // cleans up dir, which is the nodelocal:// storage
}

return sqlDB, dir, cleanupFn
}

// Large test to ensure that all of the system table data is being restored in
// the new cluster. Ensures that all the moving pieces are working together.
func TestFullClusterBackup(t *testing.T) {
Expand Down Expand Up @@ -244,6 +291,25 @@ func TestIncrementalFullClusterBackup(t *testing.T) {
sqlDBRestore.CheckQueryResults(t, checkQuery, sqlDB.QueryStr(t, checkQuery))
}

// TestEmptyFullClusterResotre ensures that we can backup and restore a full
// cluster backup with only metadata (no user data). Regression test for #49573.
func TestEmptyFullClusterRestore(t *testing.T) {
defer leaktest.AfterTest(t)()

sqlDB, tempDir, cleanupFn := createEmptyCluster(t, singleNode)
_, _, sqlDBRestore, cleanupEmptyCluster := backupRestoreTestSetupEmpty(t, singleNode, tempDir, initNone)
defer cleanupFn()
defer cleanupEmptyCluster()

sqlDB.Exec(t, `CREATE USER alice`)
sqlDB.Exec(t, `CREATE USER bob`)
sqlDB.Exec(t, `BACKUP TO $1`, localFoo)
sqlDBRestore.Exec(t, `RESTORE FROM $1`, localFoo)

checkQuery := "SELECT * FROM system.users"
sqlDBRestore.CheckQueryResults(t, checkQuery, sqlDB.QueryStr(t, checkQuery))
}

func TestDisallowFullClusterRestoreOnNonFreshCluster(t *testing.T) {
defer leaktest.AfterTest(t)()

Expand Down
8 changes: 4 additions & 4 deletions pkg/ccl/backupccl/restore_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -889,15 +889,15 @@ func createImportingTables(
}
}
}
var tempSystemDBID sqlbase.ID
tempSystemDBID := keys.MinNonPredefinedUserDescID
for id := range details.TableRewrites {
if uint32(id) > uint32(tempSystemDBID) {
tempSystemDBID = id
if int(id) > tempSystemDBID {
tempSystemDBID = int(id)
}
}
if details.DescriptorCoverage == tree.AllDescriptors {
databases = append(databases, &sqlbase.DatabaseDescriptor{
ID: tempSystemDBID,
ID: sqlbase.ID(tempSystemDBID),
Name: restoreTempSystemDB,
Privileges: sqlbase.NewDefaultPrivilegeDescriptor(),
})
Expand Down
2 changes: 1 addition & 1 deletion pkg/ccl/backupccl/restore_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func allocateTableRewrites(

// Fail fast if the tables to restore are incompatible with the specified
// options.
maxDescIDInBackup := int64(0)
maxDescIDInBackup := int64(keys.MinNonPredefinedUserDescID)
for _, table := range tablesByID {
if int64(table.ID) > maxDescIDInBackup {
maxDescIDInBackup = int64(table.ID)
Expand Down

0 comments on commit 88b829d

Please sign in to comment.