diff --git a/docs/generated/sql/bnf/show_backup.bnf b/docs/generated/sql/bnf/show_backup.bnf index 446da5e23b4d..8a08abd80324 100644 --- a/docs/generated/sql/bnf/show_backup.bnf +++ b/docs/generated/sql/bnf/show_backup.bnf @@ -18,3 +18,6 @@ show_backup_stmt ::= | 'SHOW' 'BACKUP' 'RANGES' string_or_placeholder 'WITH' kv_option_list | 'SHOW' 'BACKUP' 'RANGES' string_or_placeholder 'WITH' 'OPTIONS' '(' kv_option_list ')' | 'SHOW' 'BACKUP' 'RANGES' string_or_placeholder + | 'SHOW' 'BACKUP' 'VALIDATE' string_or_placeholder 'WITH' kv_option_list + | 'SHOW' 'BACKUP' 'VALIDATE' string_or_placeholder 'WITH' 'OPTIONS' '(' kv_option_list ')' + | 'SHOW' 'BACKUP' 'VALIDATE' string_or_placeholder diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index f041578916ea..e5bac4a7e5c8 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -761,6 +761,7 @@ show_backup_stmt ::= | 'SHOW' 'BACKUP' 'SCHEMAS' string_or_placeholder opt_with_options | 'SHOW' 'BACKUP' 'FILES' string_or_placeholder opt_with_options | 'SHOW' 'BACKUP' 'RANGES' string_or_placeholder opt_with_options + | 'SHOW' 'BACKUP' 'VALIDATE' string_or_placeholder opt_with_options show_columns_stmt ::= 'SHOW' 'COLUMNS' 'FROM' table_name with_comment @@ -1878,6 +1879,7 @@ show_backup_details ::= 'SCHEMAS' | 'FILES' | 'RANGES' + | 'VALIDATE' with_comment ::= 'WITH' 'COMMENT' diff --git a/pkg/ccl/backupccl/BUILD.bazel b/pkg/ccl/backupccl/BUILD.bazel index 6b75f0854128..f95d93e1d89e 100644 --- a/pkg/ccl/backupccl/BUILD.bazel +++ b/pkg/ccl/backupccl/BUILD.bazel @@ -90,6 +90,7 @@ go_library( "//pkg/sql/catalog/systemschema", "//pkg/sql/catalog/tabledesc", "//pkg/sql/catalog/typedesc", + "//pkg/sql/doctor", "//pkg/sql/execinfra", "//pkg/sql/execinfrapb", "//pkg/sql/parser", diff --git a/pkg/ccl/backupccl/datadriven_test.go b/pkg/ccl/backupccl/datadriven_test.go index dff084a9a263..73e06514d5bf 100644 --- a/pkg/ccl/backupccl/datadriven_test.go +++ b/pkg/ccl/backupccl/datadriven_test.go @@ -367,6 +367,11 @@ func (d *datadrivenTestState) getSQLDB(t *testing.T, server string, user string) // // - "corrupt-backup" uri= // Finds the latest backup in the provided collection uri an flips a bit in one SST in the backup +// +// - "link-backup" server= src-path= dest-path= +// Creates a symlink from the testdata path to the file IO path, so that we +// can restore precreated backup. src-path and dest-path are comma seperated +// paths that will be joined. func TestDataDriven(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -865,7 +870,22 @@ func TestDataDriven(t *testing.T) { t.Fatal(err) } return "" - + case "link-backup": + server := lastCreatedServer + sourceRelativePath := "" + destRelativePath := "" + ioDir := ds.getIODir(t, server) + d.ScanArgs(t, "server", &server) + d.ScanArgs(t, "src-path", &sourceRelativePath) + d.ScanArgs(t, "dest-path", &destRelativePath) + splitSrcPath := strings.Split(sourceRelativePath, ",") + sourcePath, err := filepath.Abs(testutils.TestDataPath(t, splitSrcPath...)) + require.NoError(t, err) + splitDestPath := strings.Split(destRelativePath, ",") + destPath := filepath.Join(ioDir, filepath.Join(splitDestPath...)) + require.NoError(t, err) + require.NoError(t, os.Symlink(sourcePath, destPath)) + return "" default: return fmt.Sprintf("unknown command: %s", d.Cmd) } diff --git a/pkg/ccl/backupccl/restore_old_versions_test.go b/pkg/ccl/backupccl/restore_old_versions_test.go index 673a16624552..b0ad5ef14595 100644 --- a/pkg/ccl/backupccl/restore_old_versions_test.go +++ b/pkg/ccl/backupccl/restore_old_versions_test.go @@ -588,10 +588,10 @@ func restoreOldVersionClusterTest(exportDir string) func(t *testing.T) { sqlDB.Exec(t, `RESTORE FROM $1`, localFoo) sqlDB.CheckQueryResults(t, "SHOW DATABASES", [][]string{ - {"data", "root", "NULL", "{}", "NULL"}, - {"defaultdb", "root", "NULL", "{}", "NULL"}, - {"postgres", "root", "NULL", "{}", "NULL"}, - {"system", "node", "NULL", "{}", "NULL"}, + {"data", "root", "NULL", "NULL", "{}", "NULL"}, + {"defaultdb", "root", "NULL", "NULL", "{}", "NULL"}, + {"postgres", "root", "NULL", "NULL", "{}", "NULL"}, + {"system", "node", "NULL", "NULL", "{}", "NULL"}, }) sqlDB.CheckQueryResults(t, "SHOW SCHEMAS", [][]string{ diff --git a/pkg/ccl/backupccl/show.go b/pkg/ccl/backupccl/show.go index 75c4bf14d664..bb90547b4ef5 100644 --- a/pkg/ccl/backupccl/show.go +++ b/pkg/ccl/backupccl/show.go @@ -23,6 +23,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/ccl/backupccl/backuputils" "github.com/cockroachdb/cockroach/pkg/ccl/storageccl" "github.com/cockroachdb/cockroach/pkg/cloud" + "github.com/cockroachdb/cockroach/pkg/clusterversion" "github.com/cockroachdb/cockroach/pkg/jobs/jobspb" "github.com/cockroachdb/cockroach/pkg/keys" "github.com/cockroachdb/cockroach/pkg/roachpb" @@ -34,6 +35,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog/descbuilder" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" + "github.com/cockroachdb/cockroach/pkg/sql/doctor" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgnotice" @@ -46,6 +48,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/json" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/mon" + "github.com/cockroachdb/cockroach/pkg/util/protoutil" "github.com/cockroachdb/cockroach/pkg/util/timeutil" "github.com/cockroachdb/cockroach/pkg/util/tracing" "github.com/cockroachdb/errors" @@ -254,6 +257,9 @@ func showBackupPlanHook( shower = backupShowerFileSetup(backup.InCollection) case tree.BackupSchemaDetails: shower = backupShowerDefault(p, true, opts) + case tree.BackupValidateDetails: + shower = backupShowerDoctor + default: shower = backupShowerDefault(p, false, opts) } @@ -1018,6 +1024,69 @@ var backupShowerRanges = backupShower{ }, } +var backupShowerDoctor = backupShower{ + header: colinfo.ResultColumns{ + {Name: "validation_status", Typ: types.String}, + }, + + fn: func(ctx context.Context, info backupInfo) (rows []tree.Datums, err error) { + var descTable doctor.DescriptorTable + var namespaceTable doctor.NamespaceTable + // Extract all the descriptors from the given manifest and generate the + // namespace and descriptor tables needed by doctor. + descriptors, _ := backupinfo.LoadSQLDescsFromBackupsAtTime(info.manifests, hlc.Timestamp{}) + for _, desc := range descriptors { + builder := desc.NewBuilder() + mutDesc := builder.BuildCreatedMutable() + bytes, err := protoutil.Marshal(mutDesc.DescriptorProto()) + if err != nil { + return nil, err + } + descTable = append(descTable, + doctor.DescriptorTableRow{ + ID: int64(desc.GetID()), + DescBytes: bytes, + ModTime: desc.GetModificationTime(), + }) + namespaceTable = append(namespaceTable, + doctor.NamespaceTableRow{ + ID: int64(desc.GetID()), + NameInfo: descpb.NameInfo{ + Name: desc.GetName(), + ParentID: desc.GetParentID(), + ParentSchemaID: desc.GetParentSchemaID(), + }, + }) + } + validationMessages := strings.Builder{} + // We will intentionally not validate any jobs inside the manifest, since + // these will be synthesized by the restore process. + cv := clusterversion.DoctorBinaryVersion + if len(info.manifests) > 0 { + cv = info.manifests[len(info.manifests)-1].ClusterVersion + } + ok, err := doctor.Examine(ctx, + clusterversion.ClusterVersion{Version: cv}, + descTable, namespaceTable, + nil, + false, /*validateJobs*/ + false, + &validationMessages) + if err != nil { + return nil, err + } + if !ok { + validationMessages.WriteString("ERROR: validation failed\n") + } else { + validationMessages.WriteString("No problems found!\n") + } + rows = append(rows, tree.Datums{ + tree.NewDString(validationMessages.String()), + }) + return rows, nil + }, +} + func backupShowerFileSetup(inCol tree.StringOrPlaceholderOptList) backupShower { return backupShower{header: colinfo.ResultColumns{ {Name: "path", Typ: types.String}, diff --git a/pkg/ccl/backupccl/show_test.go b/pkg/ccl/backupccl/show_test.go index 3fe8d870e7cd..22422b817c7b 100644 --- a/pkg/ccl/backupccl/show_test.go +++ b/pkg/ccl/backupccl/show_test.go @@ -545,8 +545,8 @@ func TestShowNonDefaultBackups(t *testing.T) { sqlDB.Exec(t, `BACKUP DATABASE data INTO $1`, fullNonDefault) // Get base number of files, schemas, and ranges in the backup - var oldCount [3]int - for i, typ := range []string{"FILES", "SCHEMAS", "RANGES"} { + var oldCount [4]int + for i, typ := range []string{"FILES", "SCHEMAS", "RANGES", "VALIDATE"} { query := fmt.Sprintf(`SELECT count(*) FROM [SHOW BACKUP %s FROM LATEST IN '%s']`, typ, fullNonDefault) count, err := strconv.Atoi(sqlDB.QueryStr(t, query)[0][0]) diff --git a/pkg/ccl/backupccl/testdata/backup-restore/multiregion b/pkg/ccl/backupccl/testdata/backup-restore/multiregion index b203bcaa4e0e..d6ebd02c3b36 100644 --- a/pkg/ccl/backupccl/testdata/backup-restore/multiregion +++ b/pkg/ccl/backupccl/testdata/backup-restore/multiregion @@ -41,11 +41,11 @@ RESTORE DATABASE d FROM LATEST IN 'nodelocal://0/database_backup/'; query-sql SHOW DATABASES; ---- -d root us-east-1 {eu-central-1,us-east-1,us-west-1} zone -data root {} -defaultdb root {} -postgres root {} -system node {} +d root us-east-1 {eu-central-1,us-east-1,us-west-1} zone +data root {} +defaultdb root {} +postgres root {} +system node {} # A new cluster with different localities settings. new-server name=s3 share-io-dir=s1 allow-implicit-access localities=eu-central-1,eu-north-1 @@ -117,10 +117,10 @@ HINT: to change the default primary region, use SET CLUSTER SETTING sql.defaults query-sql SHOW DATABASES; ---- -defaultdb root {} -no_region_db root eu-central-1 {eu-central-1} zone -postgres root {} -system node {} +defaultdb root {} +no_region_db root eu-central-1 {eu-central-1} zone +postgres root {} +system node {} query-sql USE no_region_db; @@ -162,11 +162,11 @@ HINT: to change the default primary region, use SET CLUSTER SETTING sql.defaults query-sql SHOW DATABASES; ---- -defaultdb root eu-north-1 {eu-north-1} zone -no_region_db root eu-north-1 {eu-north-1} zone -no_region_db_2 root eu-north-1 {eu-north-1} zone -postgres root eu-north-1 {eu-north-1} zone -system node {} +defaultdb root eu-north-1 {eu-north-1} zone +no_region_db root eu-north-1 {eu-north-1} zone +no_region_db_2 root eu-north-1 {eu-north-1} zone +postgres root eu-north-1 {eu-north-1} zone +system node {} query-sql USE no_region_db; @@ -182,9 +182,9 @@ RESTORE DATABASE eu_central_db FROM LATEST IN 'nodelocal://1/eu_central_database query-sql SHOW DATABASES; ---- -defaultdb root eu-north-1 {eu-north-1} zone -eu_central_db root eu-central-1 {eu-central-1} zone -no_region_db root eu-north-1 {eu-north-1} zone -no_region_db_2 root eu-north-1 {eu-north-1} zone -postgres root eu-north-1 {eu-north-1} zone -system node {} +defaultdb root eu-north-1 {eu-north-1} zone +eu_central_db root eu-central-1 {eu-central-1} zone +no_region_db root eu-north-1 {eu-north-1} zone +no_region_db_2 root eu-north-1 {eu-north-1} zone +postgres root eu-north-1 {eu-north-1} zone +system node {} diff --git a/pkg/ccl/backupccl/testdata/backup-restore/restore-schema-only-multiregion b/pkg/ccl/backupccl/testdata/backup-restore/restore-schema-only-multiregion index a8852688402e..6b1b57594913 100644 --- a/pkg/ccl/backupccl/testdata/backup-restore/restore-schema-only-multiregion +++ b/pkg/ccl/backupccl/testdata/backup-restore/restore-schema-only-multiregion @@ -44,11 +44,11 @@ RESTORE DATABASE d FROM LATEST IN 'nodelocal://0/database_backup/' with schema_o query-sql SHOW DATABASES; ---- -d root us-east-1 {eu-central-1,us-east-1,us-west-1} zone -data root {} -defaultdb root {} -postgres root {} -system node {} +d root us-east-1 {eu-central-1,us-east-1,us-west-1} zone +data root {} +defaultdb root {} +postgres root {} +system node {} # A new cluster with different localities settings. new-server name=s3 share-io-dir=s1 allow-implicit-access localities=eu-central-1,eu-north-1 @@ -120,10 +120,10 @@ HINT: to change the default primary region, use SET CLUSTER SETTING sql.defaults query-sql SHOW DATABASES; ---- -defaultdb root {} -no_region_db root eu-central-1 {eu-central-1} zone -postgres root {} -system node {} +defaultdb root {} +no_region_db root eu-central-1 {eu-central-1} zone +postgres root {} +system node {} query-sql USE no_region_db; @@ -165,11 +165,11 @@ HINT: to change the default primary region, use SET CLUSTER SETTING sql.defaults query-sql SHOW DATABASES; ---- -defaultdb root eu-north-1 {eu-north-1} zone -no_region_db root eu-north-1 {eu-north-1} zone -no_region_db_2 root eu-north-1 {eu-north-1} zone -postgres root eu-north-1 {eu-north-1} zone -system node {} +defaultdb root eu-north-1 {eu-north-1} zone +no_region_db root eu-north-1 {eu-north-1} zone +no_region_db_2 root eu-north-1 {eu-north-1} zone +postgres root eu-north-1 {eu-north-1} zone +system node {} query-sql USE no_region_db; @@ -185,9 +185,9 @@ RESTORE DATABASE eu_central_db FROM LATEST IN 'nodelocal://1/eu_central_database query-sql SHOW DATABASES; ---- -defaultdb root eu-north-1 {eu-north-1} zone -eu_central_db root eu-central-1 {eu-central-1} zone -no_region_db root eu-north-1 {eu-north-1} zone -no_region_db_2 root eu-north-1 {eu-north-1} zone -postgres root eu-north-1 {eu-north-1} zone -system node {} +defaultdb root eu-north-1 {eu-north-1} zone +eu_central_db root eu-central-1 {eu-central-1} zone +no_region_db root eu-north-1 {eu-north-1} zone +no_region_db_2 root eu-north-1 {eu-north-1} zone +postgres root eu-north-1 {eu-north-1} zone +system node {} diff --git a/pkg/ccl/backupccl/testdata/backup-restore/show_backup b/pkg/ccl/backupccl/testdata/backup-restore/show_backup new file mode 100644 index 000000000000..d32c318b7d58 --- /dev/null +++ b/pkg/ccl/backupccl/testdata/backup-restore/show_backup @@ -0,0 +1,39 @@ +# These tests validate the SHOW BACKUP command (old and new stynax) with +# backup images that contain both invalid and valid sets of descriptors. + +new-server name=s1 allow-implicit-access +---- + +link-backup server=s1 src-path=show_backup_validate,invalidDependOnBy_21.1 dest-path=invalidDependOnBy_21.1 +---- + +# This backup intentionally has a dangling invalid depend on by reference. +query-sql regex=invalid\sdepended-on-by +SELECT * FROM [SHOW BACKUP VALIDATE FROM 'invalidDependOnBy_21.1' IN 'nodelocal://0/']; +---- +true + +link-backup server=s1 src-path=show_backup_validate,valid-22.2 dest-path=valid-22.2 +---- + +# This backup is completely valid, but has no jobs. +query-sql regex=No\sproblems\sfound! +SELECT * FROM [SHOW BACKUP VALIDATE FROM 'valid-22.2' IN 'nodelocal://0/']; +---- +true + +link-backup server=s1 src-path=show_backup_validate,valid-22.2-with-job dest-path=valid-22.2-with-job +---- + +# This back up is valid, and taken when a job was actively working on the +# descriptor. +query-sql regex=No\sproblems\sfound! +SELECT * FROM [SHOW BACKUP VALIDATE FROM 'valid-22.2-with-job' IN 'nodelocal://0/']; +---- +true + +# Validates the same backup with the old syntax. +query-sql regex=No\sproblems\sfound! +SELECT * FROM [SHOW BACKUP VALIDATE 'nodelocal://0/valid-22.2-with-job']; +---- +true diff --git a/pkg/ccl/backupccl/testdata/show_backup_validate/invalidDependOnBy_21.1/BACKUP_MANIFEST b/pkg/ccl/backupccl/testdata/show_backup_validate/invalidDependOnBy_21.1/BACKUP_MANIFEST new file mode 100644 index 000000000000..07ed4fc32828 Binary files /dev/null and b/pkg/ccl/backupccl/testdata/show_backup_validate/invalidDependOnBy_21.1/BACKUP_MANIFEST differ diff --git a/pkg/ccl/backupccl/testdata/show_backup_validate/invalidDependOnBy_21.1/BACKUP_MANIFEST-CHECKSUM b/pkg/ccl/backupccl/testdata/show_backup_validate/invalidDependOnBy_21.1/BACKUP_MANIFEST-CHECKSUM new file mode 100644 index 000000000000..70747a396825 --- /dev/null +++ b/pkg/ccl/backupccl/testdata/show_backup_validate/invalidDependOnBy_21.1/BACKUP_MANIFEST-CHECKSUM @@ -0,0 +1 @@ +'Üóÿ \ No newline at end of file diff --git a/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2-with-job/BACKUP_MANIFEST b/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2-with-job/BACKUP_MANIFEST new file mode 100644 index 000000000000..2a206281d378 Binary files /dev/null and b/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2-with-job/BACKUP_MANIFEST differ diff --git a/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2-with-job/BACKUP_MANIFEST-CHECKSUM b/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2-with-job/BACKUP_MANIFEST-CHECKSUM new file mode 100644 index 000000000000..2e002fa572ee --- /dev/null +++ b/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2-with-job/BACKUP_MANIFEST-CHECKSUM @@ -0,0 +1 @@ +ûïþ® \ No newline at end of file diff --git a/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2/BACKUP_MANIFEST b/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2/BACKUP_MANIFEST new file mode 100644 index 000000000000..5b096fe9e396 Binary files /dev/null and b/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2/BACKUP_MANIFEST differ diff --git a/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2/BACKUP_MANIFEST-CHECKSUM b/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2/BACKUP_MANIFEST-CHECKSUM new file mode 100644 index 000000000000..b8fd635b7896 --- /dev/null +++ b/pkg/ccl/backupccl/testdata/show_backup_validate/valid-22.2/BACKUP_MANIFEST-CHECKSUM @@ -0,0 +1 @@ +è@>¿ \ No newline at end of file diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region b/pkg/ccl/logictestccl/testdata/logic_test/multi_region index 2ffe788bd002..e85be073b462 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region @@ -2,13 +2,13 @@ # knob-opt: sync-event-log # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant multiregion-9node-3region-3azs-no-los -query TTTT colnames +query TTTTT colnames SHOW REGIONS ---- -region zones database_names primary_region_of -ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} -ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} -us-east-1 {us-az1,us-az2,us-az3} {} {} +region zones database_names primary_region_of secondary_region_of +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} {} +us-east-1 {us-az1,us-az2,us-az3} {} {} {} query TT colnames SHOW REGIONS FROM CLUSTER @@ -166,61 +166,61 @@ CREATE DATABASE invalid_region_db PRIMARY REGION "region_no_exists" REGION "regi statement ok CREATE DATABASE multi_region_test_survive_zone_failure_db PRIMARY REGION "us-east-1" REGIONS "ap-southeast-2", "ca-central-1", "us-east-1" SURVIVE ZONE FAILURE -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -defaultdb root NULL {} NULL -multi_region_test_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} region -multi_region_test_explicit_primary_region_db root ap-southeast-2 {ap-southeast-2,ca-central-1,us-east-1} region -multi_region_test_survive_zone_failure_db root us-east-1 {ap-southeast-2,ca-central-1,us-east-1} zone -postgres root NULL {} NULL -region_test_db root ap-southeast-2 {ap-southeast-2} zone -system node NULL {} NULL -test root NULL {} NULL - -query TTT colnames +database_name owner primary_region secondary_region regions survival_goal +defaultdb root NULL NULL {} NULL +multi_region_test_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} region +multi_region_test_explicit_primary_region_db root ap-southeast-2 · {ap-southeast-2,ca-central-1,us-east-1} region +multi_region_test_survive_zone_failure_db root us-east-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +postgres root NULL NULL {} NULL +region_test_db root ap-southeast-2 · {ap-southeast-2} zone +system node NULL NULL {} NULL +test root NULL NULL {} NULL + +query TTTT colnames SHOW REGIONS FROM ALL DATABASES ---- -database_name regions primary_region -defaultdb {} NULL -multi_region_test_db {ap-southeast-2,ca-central-1,us-east-1} ca-central-1 -multi_region_test_explicit_primary_region_db {ap-southeast-2,ca-central-1,us-east-1} ap-southeast-2 -multi_region_test_survive_zone_failure_db {ap-southeast-2,ca-central-1,us-east-1} us-east-1 -postgres {} NULL -region_test_db {ap-southeast-2} ap-southeast-2 -system {} NULL -test {} NULL +database_name regions primary_region secondary_region +defaultdb {} NULL NULL +multi_region_test_db {ap-southeast-2,ca-central-1,us-east-1} ca-central-1 · +multi_region_test_explicit_primary_region_db {ap-southeast-2,ca-central-1,us-east-1} ap-southeast-2 · +multi_region_test_survive_zone_failure_db {ap-southeast-2,ca-central-1,us-east-1} us-east-1 · +postgres {} NULL NULL +region_test_db {ap-southeast-2} ap-southeast-2 · +system {} NULL NULL +test {} NULL NULL statement ok USE multi_region_test_db -query TTBT colnames +query TTBBT colnames SHOW REGIONS FROM DATABASE ---- -database region primary zones -multi_region_test_db ca-central-1 true {ca-az1,ca-az2,ca-az3} -multi_region_test_db ap-southeast-2 false {ap-az1,ap-az2,ap-az3} -multi_region_test_db us-east-1 false {us-az1,us-az2,us-az3} +database region primary secondary zones +multi_region_test_db ca-central-1 true false {ca-az1,ca-az2,ca-az3} +multi_region_test_db ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} +multi_region_test_db us-east-1 false false {us-az1,us-az2,us-az3} -query TTTT colnames +query TTTTT colnames SHOW REGIONS ---- -region zones database_names primary_region_of -ap-southeast-2 {ap-az1,ap-az2,ap-az3} {multi_region_test_db,multi_region_test_explicit_primary_region_db,multi_region_test_survive_zone_failure_db,region_test_db} {multi_region_test_explicit_primary_region_db,region_test_db} -ca-central-1 {ca-az1,ca-az2,ca-az3} {multi_region_test_db,multi_region_test_explicit_primary_region_db,multi_region_test_survive_zone_failure_db} {multi_region_test_db} -us-east-1 {us-az1,us-az2,us-az3} {multi_region_test_db,multi_region_test_explicit_primary_region_db,multi_region_test_survive_zone_failure_db} {multi_region_test_survive_zone_failure_db} +region zones database_names primary_region_of secondary_region_of +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {multi_region_test_db,multi_region_test_explicit_primary_region_db,multi_region_test_survive_zone_failure_db,region_test_db} {multi_region_test_explicit_primary_region_db,region_test_db} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {multi_region_test_db,multi_region_test_explicit_primary_region_db,multi_region_test_survive_zone_failure_db} {multi_region_test_db} {} +us-east-1 {us-az1,us-az2,us-az3} {multi_region_test_db,multi_region_test_explicit_primary_region_db,multi_region_test_survive_zone_failure_db} {multi_region_test_survive_zone_failure_db} {} query TT SHOW SURVIVAL GOAL FROM DATABASE ---- multi_region_test_db region -query TTBT colnames +query TTBBT colnames SHOW REGIONS FROM DATABASE region_test_db ---- -database region primary zones -region_test_db ap-southeast-2 true {ap-az1,ap-az2,ap-az3} +database region primary secondary zones +region_test_db ap-southeast-2 true false {ap-az1,ap-az2,ap-az3} query TT SHOW SURVIVAL GOAL FROM DATABASE region_test_db @@ -546,12 +546,12 @@ public crdb_internal_region {ca-central-1} root statement ok ALTER DATABASE alter_test_db ADD REGION "ap-southeast-2" -query TTBT colnames +query TTBBT colnames show regions from database alter_test_db ---- -database region primary zones -alter_test_db ca-central-1 true {ca-az1,ca-az2,ca-az3} -alter_test_db ap-southeast-2 false {ap-az1,ap-az2,ap-az3} +database region primary secondary zones +alter_test_db ca-central-1 true false {ca-az1,ca-az2,ca-az3} +alter_test_db ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} query TTTT colnames SHOW ENUMS FROM alter_test_db.public @@ -577,13 +577,13 @@ query T noticetrace ALTER DATABASE alter_test_db ADD REGION IF NOT EXISTS "us-east-1" ---- -query TTBT colnames +query TTBBT colnames show regions from database alter_test_db ---- -database region primary zones -alter_test_db ca-central-1 true {ca-az1,ca-az2,ca-az3} -alter_test_db ap-southeast-2 false {ap-az1,ap-az2,ap-az3} -alter_test_db us-east-1 false {us-az1,us-az2,us-az3} +database region primary secondary zones +alter_test_db ca-central-1 true false {ca-az1,ca-az2,ca-az3} +alter_test_db ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} +alter_test_db us-east-1 false false {us-az1,us-az2,us-az3} query TTTT colnames SHOW ENUMS FROM alter_test_db.public @@ -622,13 +622,13 @@ ALTER DATABASE new_db ADD REGION "us-west-1" statement error pq: database has no regions to drop ALTER DATABASE new_db DROP REGION "us-west-1" -query TTBT colnames +query TTBBT colnames show regions from database alter_test_db ---- -database region primary zones -alter_test_db ca-central-1 true {ca-az1,ca-az2,ca-az3} -alter_test_db ap-southeast-2 false {ap-az1,ap-az2,ap-az3} -alter_test_db us-east-1 false {us-az1,us-az2,us-az3} +database region primary secondary zones +alter_test_db ca-central-1 true false {ca-az1,ca-az2,ca-az3} +alter_test_db ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} +alter_test_db us-east-1 false false {us-az1,us-az2,us-az3} statement ok CREATE DATABASE alter_primary_region_db @@ -648,10 +648,10 @@ RANGE default ALTER RANGE default CONFIGURE ZONE USING constraints = '[]', lease_preferences = '[]' -query TTBT colnames +query TTBBT colnames show regions from database alter_primary_region_db ---- -database region primary zones +database region primary secondary zones query TTTT colnames SHOW ENUMS FROM alter_primary_region_db.public @@ -690,11 +690,11 @@ DATABASE alter_primary_region_db ALTER DATABASE alter_primary_region_db CONFIGU voter_constraints = '[+region=ca-central-1]', lease_preferences = '[[+region=ca-central-1]]' -query TTBT colnames +query TTBBT colnames show regions from database alter_primary_region_db ---- -database region primary zones -alter_primary_region_db ca-central-1 true {ca-az1,ca-az2,ca-az3} +database region primary secondary zones +alter_primary_region_db ca-central-1 true false {ca-az1,ca-az2,ca-az3} query TTTT colnames SHOW ENUMS FROM alter_primary_region_db.public @@ -727,12 +727,12 @@ SHOW ENUMS FROM alter_primary_region_db.public schema name values owner public crdb_internal_region {ap-southeast-2,ca-central-1} root -query TTBT colnames +query TTBBT colnames show regions from database alter_primary_region_db ---- -database region primary zones -alter_primary_region_db ca-central-1 true {ca-az1,ca-az2,ca-az3} -alter_primary_region_db ap-southeast-2 false {ap-az1,ap-az2,ap-az3} +database region primary secondary zones +alter_primary_region_db ca-central-1 true false {ca-az1,ca-az2,ca-az3} +alter_primary_region_db ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} statement ok ALTER DATABASE alter_primary_region_db PRIMARY REGION "ap-southeast-2" @@ -756,12 +756,12 @@ SHOW ENUMS FROM alter_primary_region_db.public schema name values owner public crdb_internal_region {ap-southeast-2,ca-central-1} root -query TTBT colnames +query TTBBT colnames show regions from database alter_primary_region_db ---- -database region primary zones -alter_primary_region_db ap-southeast-2 true {ap-az1,ap-az2,ap-az3} -alter_primary_region_db ca-central-1 false {ca-az1,ca-az2,ca-az3} +database region primary secondary zones +alter_primary_region_db ap-southeast-2 true false {ap-az1,ap-az2,ap-az3} +alter_primary_region_db ca-central-1 false false {ca-az1,ca-az2,ca-az3} statement ok create database alter_survive_db @@ -831,22 +831,22 @@ TABLE t_global ALTER TABLE t_global CONFIGURE ZONE USING voter_constraints = '[+region=ca-central-1]', lease_preferences = '[[+region=ca-central-1]]' -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -alter_primary_region_db root ap-southeast-2 {ap-southeast-2,ca-central-1} zone -alter_survive_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} zone -alter_test_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} zone -defaultdb root NULL {} NULL -multi_region_test_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} region -multi_region_test_explicit_primary_region_db root ap-southeast-2 {ap-southeast-2,ca-central-1,us-east-1} region -multi_region_test_survive_zone_failure_db root us-east-1 {ap-southeast-2,ca-central-1,us-east-1} zone -new_db root NULL {} NULL -postgres root NULL {} NULL -region_test_db root ap-southeast-2 {ap-southeast-2} zone -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +alter_primary_region_db root ap-southeast-2 · {ap-southeast-2,ca-central-1} zone +alter_survive_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +alter_test_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +defaultdb root NULL NULL {} NULL +multi_region_test_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} region +multi_region_test_explicit_primary_region_db root ap-southeast-2 · {ap-southeast-2,ca-central-1,us-east-1} region +multi_region_test_survive_zone_failure_db root us-east-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +new_db root NULL NULL {} NULL +postgres root NULL NULL {} NULL +region_test_db root ap-southeast-2 · {ap-southeast-2} zone +system node NULL NULL {} NULL +test root NULL NULL {} NULL query TT SHOW ZONE CONFIGURATION FOR DATABASE alter_survive_db @@ -864,22 +864,22 @@ DATABASE alter_survive_db ALTER DATABASE alter_survive_db CONFIGURE ZONE USING statement ok alter database alter_survive_db survive region failure -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -alter_primary_region_db root ap-southeast-2 {ap-southeast-2,ca-central-1} zone -alter_survive_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} region -alter_test_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} zone -defaultdb root NULL {} NULL -multi_region_test_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} region -multi_region_test_explicit_primary_region_db root ap-southeast-2 {ap-southeast-2,ca-central-1,us-east-1} region -multi_region_test_survive_zone_failure_db root us-east-1 {ap-southeast-2,ca-central-1,us-east-1} zone -new_db root NULL {} NULL -postgres root NULL {} NULL -region_test_db root ap-southeast-2 {ap-southeast-2} zone -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +alter_primary_region_db root ap-southeast-2 · {ap-southeast-2,ca-central-1} zone +alter_survive_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} region +alter_test_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +defaultdb root NULL NULL {} NULL +multi_region_test_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} region +multi_region_test_explicit_primary_region_db root ap-southeast-2 · {ap-southeast-2,ca-central-1,us-east-1} region +multi_region_test_survive_zone_failure_db root us-east-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +new_db root NULL NULL {} NULL +postgres root NULL NULL {} NULL +region_test_db root ap-southeast-2 · {ap-southeast-2} zone +system node NULL NULL {} NULL +test root NULL NULL {} NULL query TT SHOW ZONE CONFIGURATION FOR DATABASE alter_survive_db @@ -924,22 +924,22 @@ TABLE t_global ALTER TABLE t_global CONFIGURE ZONE USING statement ok alter database alter_survive_db survive zone failure -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -alter_primary_region_db root ap-southeast-2 {ap-southeast-2,ca-central-1} zone -alter_survive_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} zone -alter_test_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} zone -defaultdb root NULL {} NULL -multi_region_test_db root ca-central-1 {ap-southeast-2,ca-central-1,us-east-1} region -multi_region_test_explicit_primary_region_db root ap-southeast-2 {ap-southeast-2,ca-central-1,us-east-1} region -multi_region_test_survive_zone_failure_db root us-east-1 {ap-southeast-2,ca-central-1,us-east-1} zone -new_db root NULL {} NULL -postgres root NULL {} NULL -region_test_db root ap-southeast-2 {ap-southeast-2} zone -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +alter_primary_region_db root ap-southeast-2 · {ap-southeast-2,ca-central-1} zone +alter_survive_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +alter_test_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +defaultdb root NULL NULL {} NULL +multi_region_test_db root ca-central-1 · {ap-southeast-2,ca-central-1,us-east-1} region +multi_region_test_explicit_primary_region_db root ap-southeast-2 · {ap-southeast-2,ca-central-1,us-east-1} region +multi_region_test_survive_zone_failure_db root us-east-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +new_db root NULL NULL {} NULL +postgres root NULL NULL {} NULL +region_test_db root ap-southeast-2 · {ap-southeast-2} zone +system node NULL NULL {} NULL +test root NULL NULL {} NULL query TT SHOW ZONE CONFIGURATION FOR DATABASE alter_survive_db @@ -1075,12 +1075,12 @@ NOTICE: region "us-east-1" is not defined on the database; skipping statement error pgcode 42704 region "non-existent-region" has not been added to the database ALTER DATABASE drop_region_db DROP REGION "non-existent-region" -query TTBT colnames +query TTBBT colnames SHOW REGIONS FROM DATABASE drop_region_db ---- -database region primary zones -drop_region_db ca-central-1 true {ca-az1,ca-az2,ca-az3} -drop_region_db ap-southeast-2 false {ap-az1,ap-az2,ap-az3} +database region primary secondary zones +drop_region_db ca-central-1 true false {ca-az1,ca-az2,ca-az3} +drop_region_db ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} query TTTT colnames SHOW ENUMS FROM drop_region_db @@ -1159,13 +1159,13 @@ ALTER DATABASE start_off_non_multi_region DROP REGION "ca-central-1" statement ok CREATE DATABASE txn_database_drop_regions PRIMARY REGION "ca-central-1" REGIONS "ap-southeast-2", "us-east-1" -query TTBT colnames +query TTBBT colnames SHOW REGIONS FROM DATABASE txn_database_drop_regions ---- -database region primary zones -txn_database_drop_regions ca-central-1 true {ca-az1,ca-az2,ca-az3} -txn_database_drop_regions ap-southeast-2 false {ap-az1,ap-az2,ap-az3} -txn_database_drop_regions us-east-1 false {us-az1,us-az2,us-az3} +database region primary secondary zones +txn_database_drop_regions ca-central-1 true false {ca-az1,ca-az2,ca-az3} +txn_database_drop_regions ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} +txn_database_drop_regions us-east-1 false false {us-az1,us-az2,us-az3} statement ok BEGIN; @@ -1173,11 +1173,11 @@ ALTER DATABASE txn_database_drop_regions DROP REGION "us-east-1"; ALTER DATABASE txn_database_drop_regions DROP REGION "ap-southeast-2"; COMMIT; -query TTBT colnames +query TTBBT colnames SHOW REGIONS FROM DATABASE txn_database_drop_regions ---- -database region primary zones -txn_database_drop_regions ca-central-1 true {ca-az1,ca-az2,ca-az3} +database region primary secondary zones +txn_database_drop_regions ca-central-1 true false {ca-az1,ca-az2,ca-az3} statement ok CREATE DATABASE drop_regions_alter_patterns PRIMARY REGION "ca-central-1" REGIONS "ap-southeast-2", "us-east-1" diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_backup b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_backup index 2730f9a5b478..576b113db924 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_backup +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_backup @@ -4,12 +4,12 @@ # Tests in this file assume no multi-region tenant setup as tenants have no # access to nodelocal. -query TTTT +query TTTTT SHOW REGIONS ---- -ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} -ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} -us-east-1 {us-az1,us-az2,us-az3} {} {} +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} {} +us-east-1 {us-az1,us-az2,us-az3} {} {} {} statement ok CREATE DATABASE "mr-backup-1" primary region "ca-central-1" regions "ap-southeast-2", "us-east-1" @@ -1394,6 +1394,14 @@ DATABASE "mr-restore-1" ALTER DATABASE "mr-restore-1" CONFIGURE ZONE USING voter_constraints = '[+region=ap-southeast-2]', lease_preferences = '[[+region=ap-southeast-2]]' +query TTTTT colnames +SHOW REGIONS +---- +region zones database_names primary_region_of secondary_region_of +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {mr-backup-1,mr-backup-2,mr-restore-1} {mr-backup-2,mr-restore-1} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {mr-backup-1,mr-backup-2} {mr-backup-1} {} +us-east-1 {us-az1,us-az2,us-az3} {mr-backup-1,mr-backup-2,mr-restore-1} {} {} + statement error "crdb_internal_region" is not compatible with type "crdb_internal_region" existing in cluster: could not find enum value "ca-central-1" in "crdb_internal_region" RESTORE TABLE "mr-backup-2".regional_by_table_in_ap_southeast_2 FROM 'nodelocal://0/mr-backup-2/' WITH into_db='mr-restore-1'; diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_default_primary_region b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_default_primary_region index 8964f03e758d..5909df653ea9 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_default_primary_region +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_default_primary_region @@ -25,21 +25,21 @@ CREATE DATABASE db ---- NOTICE: setting ap-southeast-2 as the PRIMARY REGION as no PRIMARY REGION was specified -query TTBT colnames +query TTBBT colnames SHOW REGIONS FROM DATABASE db ---- -database region primary zones -db ap-southeast-2 true {ap-az1,ap-az2,ap-az3} +database region primary secondary zones +db ap-southeast-2 true false {ap-az1,ap-az2,ap-az3} statement ok CREATE DATABASE db_explicit_primary_region PRIMARY REGION "us-east-1" REGIONS "ap-southeast-2" -query TTBT colnames +query TTBBT colnames SHOW REGIONS FROM DATABASE db_explicit_primary_region ---- -database region primary zones -db_explicit_primary_region us-east-1 true {us-az1,us-az2,us-az3} -db_explicit_primary_region ap-southeast-2 false {ap-az1,ap-az2,ap-az3} +database region primary secondary zones +db_explicit_primary_region us-east-1 true false {us-az1,us-az2,us-az3} +db_explicit_primary_region ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} # Test that we cannot drop the PRIMARY REGION. diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_drop_region b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_drop_region index aa4920f94bc1..d4ff2715951d 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_drop_region +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_drop_region @@ -1,12 +1,12 @@ # tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant multiregion-9node-3region-3azs-no-los -query TTTT +query TTTTT SHOW REGIONS ---- -ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} -ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} -us-east-1 {us-az1,us-az2,us-az3} {} {} +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} {} +us-east-1 {us-az1,us-az2,us-az3} {} {} {} statement ok CREATE DATABASE mr PRIMARY REGION "ca-central-1" REGIONS "ap-southeast-2", "us-east-1"; @@ -39,6 +39,21 @@ DROP TABLE kv statement ok CREATE TABLE kv (k INT PRIMARY KEY, v INT) LOCALITY REGIONAL BY ROW +query TTTTT +SHOW REGIONS +---- +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {mr} {} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {mr} {mr} {} +us-east-1 {us-az1,us-az2,us-az3} {mr} {} {} + +query TTBBT colnames +SHOW REGIONS FROM DATABASE mr +---- +database region primary secondary zones +mr ca-central-1 true false {ca-az1,ca-az2,ca-az3} +mr ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} +mr us-east-1 false false {us-az1,us-az2,us-az3} + statement ok ALTER DATABASE mr DROP REGION "us-east-1" diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_import_export b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_import_export index d62e26573fdc..f5e19d060fef 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_import_export +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_import_export @@ -4,13 +4,13 @@ # Tests in this file assume no multi-region tenant setup as tenants have no # access to nodelocal. -query TTTT colnames +query TTTTT colnames SHOW REGIONS ---- -region zones database_names primary_region_of -ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} -ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} -us-east-1 {us-az1,us-az2,us-az3} {} {} +region zones database_names primary_region_of secondary_region_of +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} {} +us-east-1 {us-az1,us-az2,us-az3} {} {} {} query TT colnames SHOW REGIONS FROM CLUSTER diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_config_extensions b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_config_extensions index b124d0d537e1..aaf174647c51 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_config_extensions +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_config_extensions @@ -1,12 +1,12 @@ # tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant -query TTTT +query TTTTT SHOW REGIONS ---- -ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} -ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} -us-east-1 {us-az1,us-az2,us-az3} {} {} +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} {} +us-east-1 {us-az1,us-az2,us-az3} {} {} {} statement ok SELECT crdb_internal.validate_multi_region_zone_configs() diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs index 2a12b3af698b..d7a2b95b3e46 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs @@ -1,12 +1,12 @@ # tenant-cluster-setting-override-opt: allow-zone-configs-for-secondary-tenants allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant multiregion-9node-3region-3azs-no-los -query TTTT +query TTTTT SHOW REGIONS ---- -ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} -ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} -us-east-1 {us-az1,us-az2,us-az3} {} {} +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} {} +us-east-1 {us-az1,us-az2,us-az3} {} {} {} statement ok SELECT crdb_internal.validate_multi_region_zone_configs() @@ -371,17 +371,17 @@ DATABASE "mr-zone-configs" ALTER DATABASE "mr-zone-configs" CONFIGURE ZONE USIN constraints = '[]', lease_preferences = '[]' -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -defaultdb root NULL {} NULL -drop_region_db root NULL {} NULL -gc_ttl_predefined_db root NULL {} NULL -mr-zone-configs root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +defaultdb root NULL NULL {} NULL +drop_region_db root NULL NULL {} NULL +gc_ttl_predefined_db root NULL NULL {} NULL +mr-zone-configs root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok ALTER DATABASE "mr-zone-configs" SET PRIMARY REGION "us-east-1" @@ -392,17 +392,17 @@ ALTER DATABASE "mr-zone-configs" ADD REGION "ca-central-1" statement ok ALTER DATABASE "mr-zone-configs" ADD REGION "ap-southeast-2" -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -defaultdb root NULL {} NULL -drop_region_db root NULL {} NULL -gc_ttl_predefined_db root NULL {} NULL -mr-zone-configs root us-east-1 {ap-southeast-2,ca-central-1,us-east-1} zone -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +defaultdb root NULL NULL {} NULL +drop_region_db root NULL NULL {} NULL +gc_ttl_predefined_db root NULL NULL {} NULL +mr-zone-configs root us-east-1 · {ap-southeast-2,ca-central-1,us-east-1} zone +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL # Ensure that changes to the table-level zone config also require overriding. statement ok diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs_long_regions b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs_long_regions index 1952561fc9c3..40746e2fccd8 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs_long_regions +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs_long_regions @@ -1,12 +1,12 @@ # tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-3node-3superlongregions -query TTTT +query TTTTT SHOW REGIONS ---- -veryveryveryveryveryveryverylongregion1 {} {} {} -veryveryveryveryveryveryverylongregion2 {} {} {} -veryveryveryveryveryveryverylongregion3 {} {} {} +veryveryveryveryveryveryverylongregion1 {} {} {} {} +veryveryveryveryveryveryverylongregion2 {} {} {} {} +veryveryveryveryveryveryverylongregion3 {} {} {} {} statement ok SELECT crdb_internal.validate_multi_region_zone_configs() diff --git a/pkg/ccl/logictestccl/testdata/logic_test/secondary_region b/pkg/ccl/logictestccl/testdata/logic_test/secondary_region index 46428be44392..dddf9fa0b89a 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/secondary_region +++ b/pkg/ccl/logictestccl/testdata/logic_test/secondary_region @@ -1,15 +1,15 @@ # tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-15node-5region-3azs -query TTTT colnames +query TTTTT colnames SHOW REGIONS ---- -region zones database_names primary_region_of -ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} -ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} -us-central-1 {usc-az1,usc-az2,usc-az3} {} {} -us-east-1 {us-az1,us-az2,us-az3} {} {} -us-west-1 {usw-az1,usw-az2,usw-az3} {} {} +region zones database_names primary_region_of secondary_region_of +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {} {} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {} {} {} +us-central-1 {usc-az1,usc-az2,usc-az3} {} {} {} +us-east-1 {us-az1,us-az2,us-az3} {} {} {} +us-west-1 {usw-az1,usw-az2,usw-az3} {} {} {} statement ok CREATE DATABASE non_mr; @@ -462,3 +462,57 @@ ALTER DATABASE mr3 SET SECONDARY REGION "us-central-1" # Make sure a secondary region can not be removed from a super region statement error pq: the secondary region must be in the same super region as the current primary region ALTER DATABASE mr1 ALTER SUPER REGION "test1" VALUES "us-east-1" + +query TTTTT colnames +SHOW REGIONS +---- +region zones database_names primary_region_of secondary_region_of +ap-southeast-2 {ap-az1,ap-az2,ap-az3} {db,mr1,mr2,mr3} {db,mr2} {} +ca-central-1 {ca-az1,ca-az2,ca-az3} {db,mr1,mr2,mr3} {mr3} {mr2} +us-central-1 {usc-az1,usc-az2,usc-az3} {mr1,mr2,mr3} {} {mr3} +us-east-1 {us-az1,us-az2,us-az3} {db,mr1,mr2,mr3} {mr1} {} +us-west-1 {usw-az1,usw-az2,usw-az3} {mr1,mr2,mr3} {} {mr1} + +query TTBBT colnames +SHOW REGIONS FROM DATABASE mr1 +---- +database region primary secondary zones +mr1 us-east-1 true false {us-az1,us-az2,us-az3} +mr1 us-west-1 false true {usw-az1,usw-az2,usw-az3} +mr1 ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} +mr1 ca-central-1 false false {ca-az1,ca-az2,ca-az3} +mr1 us-central-1 false false {usc-az1,usc-az2,usc-az3} + +query TTBBT colnames +SHOW REGIONS FROM DATABASE mr2 +---- +database region primary secondary zones +mr2 ap-southeast-2 true false {ap-az1,ap-az2,ap-az3} +mr2 ca-central-1 false true {ca-az1,ca-az2,ca-az3} +mr2 us-central-1 false false {usc-az1,usc-az2,usc-az3} +mr2 us-east-1 false false {us-az1,us-az2,us-az3} +mr2 us-west-1 false false {usw-az1,usw-az2,usw-az3} + +query TTBBT colnames +SHOW REGIONS FROM DATABASE mr3 +---- +database region primary secondary zones +mr3 ca-central-1 true false {ca-az1,ca-az2,ca-az3} +mr3 us-central-1 false true {usc-az1,usc-az2,usc-az3} +mr3 ap-southeast-2 false false {ap-az1,ap-az2,ap-az3} +mr3 us-east-1 false false {us-az1,us-az2,us-az3} +mr3 us-west-1 false false {usw-az1,usw-az2,usw-az3} + +query TTTT colnames +SHOW REGIONS FROM ALL DATABASES +---- +database_name regions primary_region secondary_region +db {ap-southeast-2,ca-central-1,us-east-1} ap-southeast-2 · +defaultdb {} NULL NULL +mr1 {ap-southeast-2,ca-central-1,us-central-1,us-east-1,us-west-1} us-east-1 us-west-1 +mr2 {ap-southeast-2,ca-central-1,us-central-1,us-east-1,us-west-1} ap-southeast-2 ca-central-1 +mr3 {ap-southeast-2,ca-central-1,us-central-1,us-east-1,us-west-1} ca-central-1 us-central-1 +non_mr {} NULL NULL +postgres {} NULL NULL +system {} NULL NULL +test {} NULL NULL diff --git a/pkg/cli/clisqlshell/sql_test.go b/pkg/cli/clisqlshell/sql_test.go index df997fbf2e70..6eb8d3c5a9e1 100644 --- a/pkg/cli/clisqlshell/sql_test.go +++ b/pkg/cli/clisqlshell/sql_test.go @@ -90,11 +90,11 @@ func Example_sql() { // system node // t root // sql -e \l -e \echo hello - // database_name owner primary_region regions survival_goal - // defaultdb root NULL {} NULL - // postgres root NULL {} NULL - // system node NULL {} NULL - // t root NULL {} NULL + // database_name owner primary_region secondary_region regions survival_goal + // defaultdb root NULL NULL {} NULL + // postgres root NULL NULL {} NULL + // system node NULL NULL {} NULL + // t root NULL NULL {} NULL // hello // sql -e select 1 as "1"; select 2 as "2" // 1 diff --git a/pkg/cli/doctor.go b/pkg/cli/doctor.go index 5893818b1bd5..f396021a6a60 100644 --- a/pkg/cli/doctor.go +++ b/pkg/cli/doctor.go @@ -176,6 +176,7 @@ func runDoctorExamine( descTable, namespaceTable, jobsTable, + true, /*validateJobs*/ debugCtx.verbose, out) if err != nil { diff --git a/pkg/sql/crdb_internal.go b/pkg/sql/crdb_internal.go index 991618c7d4da..6f0f8eaa7106 100644 --- a/pkg/sql/crdb_internal.go +++ b/pkg/sql/crdb_internal.go @@ -277,6 +277,7 @@ CREATE TABLE crdb_internal.databases ( name STRING NOT NULL, owner NAME NOT NULL, primary_region STRING, + secondary_region STRING, regions STRING[], survival_goal STRING, placement_policy STRING, @@ -287,6 +288,7 @@ CREATE TABLE crdb_internal.databases ( func(db catalog.DatabaseDescriptor) error { var survivalGoal tree.Datum = tree.DNull var primaryRegion tree.Datum = tree.DNull + var secondaryRegion tree.Datum = tree.DNull var placement tree.Datum = tree.DNull regions := tree.NewDArray(types.String) @@ -295,8 +297,9 @@ CREATE TABLE crdb_internal.databases ( createNode.Name = tree.Name(db.GetName()) if db.IsMultiRegion() { primaryRegion = tree.NewDString(string(db.GetRegionConfig().PrimaryRegion)) - createNode.PrimaryRegion = tree.Name(db.GetRegionConfig().PrimaryRegion) + secondaryRegion = tree.NewDString(string(db.GetRegionConfig().SecondaryRegion)) + createNode.SecondaryRegion = tree.Name(db.GetRegionConfig().SecondaryRegion) regionConfig, err := SynthesizeRegionConfig(ctx, p.txn, db.GetID(), p.Descriptors()) if err != nil { @@ -345,6 +348,7 @@ CREATE TABLE crdb_internal.databases ( tree.NewDString(db.GetName()), // name tree.NewDName(owner.Normalized()), // owner primaryRegion, // primary_region + secondaryRegion, // secondary_region regions, // regions survivalGoal, // survival_goal placement, // data_placement diff --git a/pkg/sql/delegate/show_databases.go b/pkg/sql/delegate/show_databases.go index 2c53885e0232..3b29badccd88 100644 --- a/pkg/sql/delegate/show_databases.go +++ b/pkg/sql/delegate/show_databases.go @@ -19,7 +19,7 @@ import ( func (d *delegator) delegateShowDatabases(stmt *tree.ShowDatabases) (tree.Statement, error) { query := `SELECT - name AS database_name, owner, primary_region, regions, survival_goal` + name AS database_name, owner, primary_region, secondary_region, regions, survival_goal` if stmt.WithComment { query += `, comment` diff --git a/pkg/sql/delegate/show_regions.go b/pkg/sql/delegate/show_regions.go index 6c62b0d6db5c..bfa3fbc47130 100644 --- a/pkg/sql/delegate/show_regions.go +++ b/pkg/sql/delegate/show_regions.go @@ -34,7 +34,8 @@ func (d *delegator) delegateShowRegions(n *tree.ShowRegions) (tree.Statement, er SELECT name as database_name, regions, - primary_region + primary_region, + secondary_region FROM crdb_internal.databases ORDER BY database_name `, @@ -56,6 +57,7 @@ SELECT r.name AS "database", r.region as "region", r.region = r.primary_region AS "primary", + r.region = r.secondary_region AS "secondary", COALESCE(zones_table.zones, '{}'::string[]) AS zones @@ -63,12 +65,13 @@ FROM [ SELECT name, unnest(dbs.regions) AS region, - dbs.primary_region AS primary_region + dbs.primary_region AS primary_region, + dbs.secondary_region AS secondary_region FROM crdb_internal.databases dbs WHERE dbs.name = %s ] r LEFT JOIN zones_table ON (r.region = zones_table.region) -ORDER BY "primary" DESC, "region"`, +ORDER BY "primary" DESC, "secondary" DESC, "region"`, zonesClause, lexbase.EscapeSQLString(dbName), ) @@ -115,15 +118,24 @@ databases_by_primary_region(region, database_names) AS ( FROM crdb_internal.databases GROUP BY primary_region ), +databases_by_secondary_region(region, database_names) AS ( + SELECT + secondary_region, + array_agg(name) + FROM crdb_internal.databases + GROUP BY secondary_region +), zones_table(region, zones) AS (%s) SELECT zones_table.region, zones_table.zones, COALESCE(databases_by_region.database_names, '{}'::string[]) AS database_names, - COALESCE(databases_by_primary_region.database_names, '{}'::string[]) AS primary_region_of + COALESCE(databases_by_primary_region.database_names, '{}'::string[]) AS primary_region_of, + COALESCE(databases_by_secondary_region.database_names, '{}'::string[]) AS secondary_region_of FROM zones_table LEFT JOIN databases_by_region ON (zones_table.region = databases_by_region.region) LEFT JOIN databases_by_primary_region ON (zones_table.region = databases_by_primary_region.region) +LEFT JOIN databases_by_secondary_region ON (zones_table.region = databases_by_secondary_region.region) ORDER BY zones_table.region `, zonesClause, diff --git a/pkg/sql/doctor/doctor.go b/pkg/sql/doctor/doctor.go index d6cf60ac7ecb..5f9e4b6c1c81 100644 --- a/pkg/sql/doctor/doctor.go +++ b/pkg/sql/doctor/doctor.go @@ -124,6 +124,7 @@ func Examine( descTable DescriptorTable, namespaceTable NamespaceTable, jobsTable JobsTable, + validiateJobs bool, verbose bool, stdout io.Writer, ) (ok bool, err error) { @@ -133,14 +134,18 @@ func Examine( descTable, namespaceTable, jobsTable, + validiateJobs, verbose, stdout) if err != nil { return false, err } - jobsOk, err := ExamineJobs(ctx, descTable, jobsTable, verbose, stdout) - if err != nil { - return false, err + jobsOk := true + if validiateJobs { + jobsOk, err = ExamineJobs(ctx, descTable, jobsTable, verbose, stdout) + if err != nil { + return false, err + } } return descOk && jobsOk, nil } @@ -152,6 +157,7 @@ func ExamineDescriptors( descTable DescriptorTable, namespaceTable NamespaceTable, jobsTable JobsTable, + validateJobs bool, verbose bool, stdout io.Writer, ) (ok bool, err error) { @@ -190,10 +196,12 @@ func ExamineDescriptors( descReport(stdout, desc, "%s", err) } - jobs.ValidateJobReferencesInDescriptor(desc, jobsTable, func(err error) { - problemsFound = true - descReport(stdout, desc, "%s", err) - }) + if validateJobs { + jobs.ValidateJobReferencesInDescriptor(desc, jobsTable, func(err error) { + problemsFound = true + descReport(stdout, desc, "%s", err) + }) + } if verbose { descReport(stdout, desc, "processed") diff --git a/pkg/sql/doctor/doctor_test.go b/pkg/sql/doctor/doctor_test.go index 2f8201658796..f820098a8e9d 100644 --- a/pkg/sql/doctor/doctor_test.go +++ b/pkg/sql/doctor/doctor_test.go @@ -519,6 +519,7 @@ func TestExamineDescriptors(t *testing.T) { test.descTable, test.namespaceTable, test.jobsTable, + true, false, &buf) msg := fmt.Sprintf("Test %d failed!", i+1) diff --git a/pkg/sql/logictest/testdata/logic_test/create_statements b/pkg/sql/logictest/testdata/logic_test/create_statements index 2bb5809dbd04..00dc7071c0d9 100644 --- a/pkg/sql/logictest/testdata/logic_test/create_statements +++ b/pkg/sql/logictest/testdata/logic_test/create_statements @@ -592,6 +592,7 @@ CREATE TABLE crdb_internal.databases ( name STRING NOT NULL, owner NAME NOT NULL, primary_region STRING NULL, + secondary_region STRING NULL, regions STRING[] NULL, survival_goal STRING NULL, placement_policy STRING NULL, @@ -601,6 +602,7 @@ CREATE TABLE crdb_internal.databases ( name STRING NOT NULL, owner NAME NOT NULL, primary_region STRING NULL, + secondary_region STRING NULL, regions STRING[] NULL, survival_goal STRING NULL, placement_policy STRING NULL, diff --git a/pkg/sql/logictest/testdata/logic_test/database b/pkg/sql/logictest/testdata/logic_test/database index bcff2b3c4711..29e4685b4f7a 100644 --- a/pkg/sql/logictest/testdata/logic_test/database +++ b/pkg/sql/logictest/testdata/logic_test/database @@ -10,15 +10,15 @@ CREATE DATABASE IF NOT EXISTS a statement error pgcode 42601 empty database name CREATE DATABASE "" -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -a root NULL {} NULL -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +a root NULL NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok CREATE ROLE newrole LOGIN @@ -31,15 +31,15 @@ true statement ok COMMENT ON DATABASE a IS 'A' -query TTTTTT colnames +query TTTTTTT colnames SHOW DATABASES WITH COMMENT ---- -database_name owner primary_region regions survival_goal comment -a root NULL {} NULL A -defaultdb root NULL {} NULL NULL -postgres root NULL {} NULL NULL -system node NULL {} NULL NULL -test root NULL {} NULL NULL +database_name owner primary_region secondary_region regions survival_goal comment +a root NULL NULL {} NULL A +defaultdb root NULL NULL {} NULL NULL +postgres root NULL NULL {} NULL NULL +system node NULL NULL {} NULL NULL +test root NULL NULL {} NULL NULL # Verify that SHOW SCHEMAS FROM a includes user-defined schemas. statement ok @@ -107,22 +107,22 @@ CREATE DATABASE b8 WITH CONNECTION LIMIT = 1 statement ok CREATE DATABASE c -query TTTTT +query TTTTTT SHOW DATABASES ---- -a root NULL {} NULL -b root NULL {} NULL -b2 root NULL {} NULL -b3 root NULL {} NULL -b4 root NULL {} NULL -b5 root NULL {} NULL -b6 root NULL {} NULL -b7 root NULL {} NULL -c root NULL {} NULL -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +a root NULL NULL {} NULL +b root NULL NULL {} NULL +b2 root NULL NULL {} NULL +b3 root NULL NULL {} NULL +b4 root NULL NULL {} NULL +b5 root NULL NULL {} NULL +b6 root NULL NULL {} NULL +b7 root NULL NULL {} NULL +c root NULL NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok CREATE TABLE b.a (id INT PRIMARY KEY) @@ -173,16 +173,16 @@ DROP DATABASE b7 CASCADE statement error pgcode 42601 empty database name DROP DATABASE "" -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -a root NULL {} NULL -c root NULL {} NULL -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +a root NULL NULL {} NULL +c root NULL NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok CREATE DATABASE b @@ -303,17 +303,17 @@ CREATE DATABASE aa with owner fake_user statement ok CREATE DATABASE a with owner testuser -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -a testuser NULL {} NULL -b root NULL {} NULL -c root NULL {} NULL -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +a testuser NULL NULL {} NULL +b root NULL NULL {} NULL +c root NULL NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL # Non-superusers also must be a member of the new owning role. statement ok diff --git a/pkg/sql/logictest/testdata/logic_test/drop_database b/pkg/sql/logictest/testdata/logic_test/drop_database index e85d6de2fb30..3a58b51e60fa 100644 --- a/pkg/sql/logictest/testdata/logic_test/drop_database +++ b/pkg/sql/logictest/testdata/logic_test/drop_database @@ -7,14 +7,14 @@ SET CLUSTER SETTING sql.cross_db_sequence_references.enabled = TRUE statement ok CREATE DATABASE "foo-bar" -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -foo-bar root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +foo-bar root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok CREATE TABLE "foo-bar".t(x INT) @@ -30,13 +30,13 @@ SELECT name, database_name, state FROM crdb_internal.tables WHERE name = 't' ---- t [106] DROP -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL skipif config local-legacy-schema-changer query TT @@ -49,25 +49,25 @@ NEW SCHEMA CHANGE succeeded statement ok CREATE DATABASE "foo bar" -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -foo bar root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +foo bar root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok DROP DATABASE "foo bar" CASCADE -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok CREATE DATABASE d1 @@ -145,27 +145,27 @@ SELECT * FROM d2.v4 ---- 0 -query TTTTT +query TTTTTT SHOW DATABASES ---- -d1 root NULL {} NULL -d2 root NULL {} NULL -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +d1 root NULL NULL {} NULL +d2 root NULL NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok DROP DATABASE d1 CASCADE -query TTTTT +query TTTTTT SHOW DATABASES ---- -d2 root NULL {} NULL -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +d2 root NULL NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL query error pgcode 42P01 relation "d1.v2" does not exist SELECT * FROM d1.v2 @@ -186,13 +186,13 @@ SELECT * FROM d2.v1 statement ok DROP DATABASE d2 CASCADE -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL query error pgcode 42P01 relation "d2.v1" does not exist SELECT * FROM d2.v1 @@ -234,13 +234,13 @@ SCHEMA CHANGE updating referenced FK table t1(125) for table t2(126) SCHEMA CHANGE GC GC for DROP DATABASE constraint_db CASCADE running SCHEMA CHANGE GC GC for DROP DATABASE d2 CASCADE running -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL query error pgcode 42P01 relation "constraint_db.t1" does not exist SELECT * FROM constraint_db.t1 diff --git a/pkg/sql/logictest/testdata/logic_test/drop_owned_by b/pkg/sql/logictest/testdata/logic_test/drop_owned_by index fd9f6e1992d9..e8c5d6a4a7fe 100644 --- a/pkg/sql/logictest/testdata/logic_test/drop_owned_by +++ b/pkg/sql/logictest/testdata/logic_test/drop_owned_by @@ -465,17 +465,17 @@ CREATE TABLE d2.t1() user root -query TTTTT +query TTTTTT SHOW DATABASES ---- -d1 root NULL {} NULL -d2 root NULL {} NULL -d3 root NULL {} NULL -d4 root NULL {} NULL -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +d1 root NULL NULL {} NULL +d2 root NULL NULL {} NULL +d3 root NULL NULL {} NULL +d4 root NULL NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL statement ok SET DATABASE = d1 diff --git a/pkg/sql/logictest/testdata/logic_test/information_schema b/pkg/sql/logictest/testdata/logic_test/information_schema index bec30581fc17..1778c89e7f27 100644 --- a/pkg/sql/logictest/testdata/logic_test/information_schema +++ b/pkg/sql/logictest/testdata/logic_test/information_schema @@ -222,13 +222,13 @@ TRUNCATE TABLE information_schema.session_variables # Verify information_schema handles reflection correctly. -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL query TTTTIT SHOW TABLES FROM test.information_schema diff --git a/pkg/sql/logictest/testdata/logic_test/rename_database b/pkg/sql/logictest/testdata/logic_test/rename_database index 314143e99066..8b09cd7d83ac 100644 --- a/pkg/sql/logictest/testdata/logic_test/rename_database +++ b/pkg/sql/logictest/testdata/logic_test/rename_database @@ -4,13 +4,13 @@ SET CLUSTER SETTING sql.cross_db_views.enabled = TRUE statement ok SET CLUSTER SETTING sql.cross_db_sequence_references.enabled = TRUE -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL query TTTB SHOW GRANTS ON DATABASE test @@ -52,13 +52,13 @@ SELECT * FROM kv statement error target database or schema does not exist SHOW GRANTS ON DATABASE test -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -u root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +u root NULL NULL {} NULL # check the name in descriptor is also changed query TTTB @@ -102,13 +102,13 @@ user testuser statement error must be owner of database t ALTER DATABASE t RENAME TO v -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -t root NULL {} NULL -u root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +t root NULL NULL {} NULL +u root NULL NULL {} NULL # Test that owners can rename databases as long as they have the CREATEDB # privilege. @@ -172,14 +172,14 @@ ALTER DATABASE defaultdb RENAME TO w; ALTER DATABASE postgres RENAME TO defaultdb; ALTER DATABASE w RENAME TO postgres -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -t root NULL {} NULL -v root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +t root NULL NULL {} NULL +v root NULL NULL {} NULL statement ok SET vectorize=on @@ -196,15 +196,15 @@ statement ok RESET vectorize # Verify that the EXPLAIN above does not actually rename the database (#30543) -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -t root NULL {} NULL -v root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +t root NULL NULL {} NULL +v root NULL NULL {} NULL # Test dependent sequences on different databases upon renames # are allowed now, as well as testing diff --git a/pkg/sql/logictest/testdata/logic_test/role b/pkg/sql/logictest/testdata/logic_test/role index 635ad545450d..3a318474bad6 100644 --- a/pkg/sql/logictest/testdata/logic_test/role +++ b/pkg/sql/logictest/testdata/logic_test/role @@ -1172,14 +1172,14 @@ GRANT SELECT ON privatedb.publictable TO public user testuser -query TTTTT +query TTTTTT SHOW DATABASES ---- -db2 root NULL {} NULL -defaultdb root NULL {} NULL -postgres root NULL {} NULL -publicdb root NULL {} NULL -test root NULL {} NULL +db2 root NULL NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +publicdb root NULL NULL {} NULL +test root NULL NULL {} NULL query TTTTIT SHOW TABLES FROM publicdb diff --git a/pkg/sql/logictest/testdata/logic_test/show_source b/pkg/sql/logictest/testdata/logic_test/show_source index 9d2c6edf927f..f2f225218ba3 100644 --- a/pkg/sql/logictest/testdata/logic_test/show_source +++ b/pkg/sql/logictest/testdata/logic_test/show_source @@ -192,14 +192,14 @@ SELECT * FROM [SHOW ZONE CONFIGURATION FOR TABLE system.users] LIMIT 0 ---- target raw_config_sql -query TTTTT colnames +query TTTTTT colnames SHOW DATABASES ---- -database_name owner primary_region regions survival_goal -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +database_name owner primary_region secondary_region regions survival_goal +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL query TTTTTB colnames,rowsort SELECT * FROM [SHOW GRANTS ON system.descriptor] diff --git a/pkg/sql/logictest/testdata/logic_test/system b/pkg/sql/logictest/testdata/logic_test/system index 51388eabb48f..f479ac5e6fc1 100644 --- a/pkg/sql/logictest/testdata/logic_test/system +++ b/pkg/sql/logictest/testdata/logic_test/system @@ -1,10 +1,10 @@ -query TTTTT +query TTTTTT SHOW DATABASES ---- -defaultdb root NULL {} NULL -postgres root NULL {} NULL -system node NULL {} NULL -test root NULL {} NULL +defaultdb root NULL NULL {} NULL +postgres root NULL NULL {} NULL +system node NULL NULL {} NULL +test root NULL NULL {} NULL # The test expectations are different on tenants because of # descriptor_id_sq, tenant, tenant_usage, and span_configurations. diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index 9a6eecb7a3e3..e181b62db112 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -6632,6 +6632,14 @@ show_backup_stmt: Options: $5.kvOptions(), } } +| SHOW BACKUP VALIDATE string_or_placeholder opt_with_options + { + $$.val = &tree.ShowBackup{ + Details: tree.BackupValidateDetails, + Path: $4.expr(), + Options: $5.kvOptions(), + } + } | SHOW BACKUP error // SHOW HELP: SHOW BACKUP show_backup_details: @@ -6651,6 +6659,10 @@ show_backup_details: { $$.val = tree.BackupRangeDetails } +| VALIDATE + { + $$.val = tree.BackupValidateDetails + } // %Help: SHOW CLUSTER SETTING - display cluster settings // %Category: Cfg diff --git a/pkg/sql/sem/tree/show.go b/pkg/sql/sem/tree/show.go index 51a63ee303f1..58e0712783ab 100644 --- a/pkg/sql/sem/tree/show.go +++ b/pkg/sql/sem/tree/show.go @@ -85,6 +85,9 @@ const ( BackupFileDetails // BackupSchemaDetails identifies a SHOW BACKUP SCHEMAS statement. BackupSchemaDetails + // BackupValidateDetails identifies a SHOW BACKUP VALIDATION + // statement. + BackupValidateDetails ) // TODO (msbutler): 22.2 after removing old style show backup syntax, rename diff --git a/pkg/sql/sqlstats/persistedsqlstats/BUILD.bazel b/pkg/sql/sqlstats/persistedsqlstats/BUILD.bazel index 8238609271e7..dbffa538f556 100644 --- a/pkg/sql/sqlstats/persistedsqlstats/BUILD.bazel +++ b/pkg/sql/sqlstats/persistedsqlstats/BUILD.bazel @@ -46,6 +46,7 @@ go_library( "//pkg/util/log", "//pkg/util/metric", "//pkg/util/mon", + "//pkg/util/retry", "//pkg/util/stop", "//pkg/util/timeutil", "@com_github_cockroachdb_errors//:errors", diff --git a/pkg/sql/sqlstats/persistedsqlstats/scheduled_job_monitor.go b/pkg/sql/sqlstats/persistedsqlstats/scheduled_job_monitor.go index a38d6228e1d7..d61779d3bff6 100644 --- a/pkg/sql/sqlstats/persistedsqlstats/scheduled_job_monitor.go +++ b/pkg/sql/sqlstats/persistedsqlstats/scheduled_job_monitor.go @@ -23,6 +23,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" "github.com/cockroachdb/cockroach/pkg/sql/sqlutil" "github.com/cockroachdb/cockroach/pkg/util/log" + "github.com/cockroachdb/cockroach/pkg/util/retry" "github.com/cockroachdb/cockroach/pkg/util/stop" "github.com/cockroachdb/cockroach/pkg/util/timeutil" "github.com/cockroachdb/errors" @@ -31,7 +32,7 @@ import ( // We don't need this monitor to run very frequent. Normally, the schedule // should remain in the system table once it is created. However, some operations // such as RESTORE would wipe the system table and populate it with the data -// from BAKCUP. In this case, it would be nice for us to preemptively check +// from BACKUP. In this case, it would be nice for us to preemptively check // for the abnormal state of the schedule and restore it. var defaultScanInterval = time.Hour * 6 @@ -56,7 +57,7 @@ var longIntervalWarningThreshold = time.Hour * 24 // jobMonitor monitors the system.scheduled_jobs table to ensure that we would // always have one sql stats scheduled compaction job running. -// It immediately performs this check upon start() and runs the check +// It performs this check immediately upon start() and runs the check // periodically every scanInterval (subject to jittering). type jobMonitor struct { st *cluster.Settings @@ -67,43 +68,36 @@ type jobMonitor struct { } func (j *jobMonitor) start(ctx context.Context, stopper *stop.Stopper) { - j.ensureSchedule(ctx) - j.registerClusterSettingHook() - _ = stopper.RunAsyncTask(ctx, "sql-stats-scheduled-compaction-job-monitor", func(ctx context.Context) { + nextJobScheduleCheck := timeutil.Now() + currentRecurrence := SQLStatsCleanupRecurrence.Get(&j.st.SV) + + stopCtx, cancel := stopper.WithCancelOnQuiesce(ctx) + defer cancel() + timer := timeutil.NewTimer() + // Ensure schedule at startup. + timer.Reset(0) defer timer.Stop() + + // This loop runs every minute to check if we need to update the job schedule. + // We only hit the jobs table if the schedule needs to be updated due to a + // change in the recurrence cluster setting or as a scheduled check to + // ensure the schedule exists, which defaults to every 6 hours. for { - timer.Reset(j.jitterFn(j.scanInterval)) select { case <-timer.C: timer.Read = true - case <-stopper.ShouldQuiesce(): + case <-stopCtx.Done(): return } - j.ensureSchedule(ctx) - } - }) -} - -func (j *jobMonitor) registerClusterSettingHook() { - SQLStatsCleanupRecurrence.SetOnChange(&j.st.SV, func(ctx context.Context) { - j.ensureSchedule(ctx) - if err := j.db.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error { - sj, err := j.getSchedule(ctx, txn) - if err != nil { - return err + if SQLStatsCleanupRecurrence.Get(&j.st.SV) != currentRecurrence || nextJobScheduleCheck.Before(timeutil.Now()) { + j.updateSchedule(stopCtx, j.ie) + nextJobScheduleCheck = timeutil.Now().Add(j.jitterFn(j.scanInterval)) + currentRecurrence = SQLStatsCleanupRecurrence.Get(&j.st.SV) } - cronExpr := SQLStatsCleanupRecurrence.Get(&j.st.SV) - if err = sj.SetSchedule(cronExpr); err != nil { - return err - } - if err = CheckScheduleAnomaly(sj); err != nil { - log.Warningf(ctx, "schedule anomaly detected, disabled sql stats compaction may cause performance impact: %s", err) - } - return sj.Update(ctx, j.ie, txn) - }); err != nil { - log.Errorf(ctx, "unable to find sqlstats clean up schedule: %s", err) + + timer.Reset(time.Minute) } }) } @@ -139,31 +133,50 @@ func (j *jobMonitor) getSchedule( return sj, nil } -func (j *jobMonitor) ensureSchedule(ctx context.Context) { +func (j *jobMonitor) updateSchedule(ctx context.Context, ie sqlutil.InternalExecutor) { var sj *jobs.ScheduledJob var err error - if err = j.db.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error { - // We check if we can get load the schedule, if the schedule cannot be - // loaded because it's not found, we recreate the schedule. - sj, err = j.getSchedule(ctx, txn) - if err != nil { - if !jobs.HasScheduledJobNotFoundError(err) && !errors.Is(err, errScheduleNotFound) { - return err - } - sj, err = CreateSQLStatsCompactionScheduleIfNotYetExist(ctx, j.ie, txn, j.st) + retryOptions := retry.Options{ + InitialBackoff: time.Second, + MaxBackoff: 10 * time.Minute, + } + for r := retry.StartWithCtx(ctx, retryOptions); r.Next(); { + if err = j.db.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error { + // We check if we can get load the schedule, if the schedule cannot be + // loaded because it's not found, we recreate the schedule. + sj, err = j.getSchedule(ctx, txn) if err != nil { + if !jobs.HasScheduledJobNotFoundError(err) && !errors.Is(err, errScheduleNotFound) { + return err + } + sj, err = CreateSQLStatsCompactionScheduleIfNotYetExist(ctx, j.ie, txn, j.st) + if err != nil { + return err + } + } + // Update schedule with new recurrence, if different. + cronExpr := SQLStatsCleanupRecurrence.Get(&j.st.SV) + if sj.ScheduleExpr() == cronExpr { + return nil + } + if err := sj.SetSchedule(cronExpr); err != nil { return err } + sj.SetScheduleStatus(string(jobs.StatusPending)) + return sj.Update(ctx, ie, txn) + }); err != nil && ctx.Err() == nil { + log.Errorf(ctx, "failed to update stats scheduled compaction job: %s", err) + } else { + break } - return nil - }); err != nil { - log.Errorf(ctx, "fail to ensure sql stats scheduled compaction job is created: %s", err) - return } - if err = CheckScheduleAnomaly(sj); err != nil { - log.Warningf(ctx, "schedule anomaly detected: %s", err) + if ctx.Err() == nil { + if err = CheckScheduleAnomaly(sj); err != nil { + log.Warningf(ctx, "schedule anomaly detected, disabling sql stats compaction may cause performance impact: %s", err) + } } + } // CheckScheduleAnomaly checks a given schedule to see if it is either paused diff --git a/pkg/sql/sqlstats/persistedsqlstats/scheduled_sql_stats_compaction_test.go b/pkg/sql/sqlstats/persistedsqlstats/scheduled_sql_stats_compaction_test.go index 1f1001f960cd..47fdfb692b28 100644 --- a/pkg/sql/sqlstats/persistedsqlstats/scheduled_sql_stats_compaction_test.go +++ b/pkg/sql/sqlstats/persistedsqlstats/scheduled_sql_stats_compaction_test.go @@ -29,6 +29,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/tests" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" + "github.com/cockroachdb/cockroach/pkg/testutils/skip" "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" "github.com/cockroachdb/cockroach/pkg/util/log" @@ -177,9 +178,11 @@ func TestScheduledSQLStatsCompaction(t *testing.T) { func TestSQLStatsScheduleOperations(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) + skip.UnderStressRace(t, "test is too slow to run under race") ctx := context.Background() helper, helperCleanup := newTestHelper(t, nil /* sqlStatsKnobs */) + helper.sqlDB.SucceedsSoonDuration = 2 * time.Minute defer helperCleanup() schedID := getSQLStatsCompactionSchedule(t, helper).ScheduleID() @@ -215,7 +218,7 @@ func TestSQLStatsScheduleOperations(t *testing.T) { helper.sqlDB.Exec(t, "SET CLUSTER SETTING sql.stats.cleanup.recurrence = $1", expr) var err error - testutils.SucceedsSoon(t, func() error { + testutils.SucceedsWithin(t, func() error { // Reload schedule from DB. sj := getSQLStatsCompactionSchedule(t, helper) err = persistedsqlstats.CheckScheduleAnomaly(sj) @@ -224,7 +227,8 @@ func TestSQLStatsScheduleOperations(t *testing.T) { } require.Equal(t, expr, sj.ScheduleExpr()) return nil - }) + }, time.Minute*2) + require.True(t, errors.Is( errors.Unwrap(err), persistedsqlstats.ErrScheduleIntervalTooLong), "expected ErrScheduleIntervalTooLong, but found %+v", err) diff --git a/pkg/ui/workspaces/cluster-ui/src/insights/utils.ts b/pkg/ui/workspaces/cluster-ui/src/insights/utils.ts index 4264fe668d2e..6260f7fc9bde 100644 --- a/pkg/ui/workspaces/cluster-ui/src/insights/utils.ts +++ b/pkg/ui/workspaces/cluster-ui/src/insights/utils.ts @@ -219,7 +219,7 @@ export function insightType(type: InsightType): string { case "ReplaceIndex": return "Replace Index"; case "HighContentionTime": - return "High Wait Time"; + return "High Contention Time"; case "HighRetryCount": return "High Retry Counts"; case "SuboptimalPlan": diff --git a/pkg/upgrade/upgrades/precondition_before_starting_an_upgrade.go b/pkg/upgrade/upgrades/precondition_before_starting_an_upgrade.go index 95f2c4832bc3..65141758bd60 100644 --- a/pkg/upgrade/upgrades/precondition_before_starting_an_upgrade.go +++ b/pkg/upgrade/upgrades/precondition_before_starting_an_upgrade.go @@ -16,9 +16,10 @@ import ( "strings" "github.com/cockroachdb/cockroach/pkg/clusterversion" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/upgrade" - "github.com/cockroachdb/errors" ) func preconditionBeforeStartingAnUpgrade( @@ -61,7 +62,7 @@ func preconditionNoInvalidDescriptorsBeforeUpgrading( tree.Name(tree.MustBeDString(row[2])), tree.Name(tree.MustBeDString(row[3])), ) - errMsg.WriteString(fmt.Sprintf("Invalid descriptor: %v (%v) because %v\n", descName.String(), row[0], row[4])) + errMsg.WriteString(fmt.Sprintf("invalid descriptor: %v (%v) because %v\n", descName.String(), row[0], row[4])) } if err != nil { return err @@ -70,6 +71,7 @@ func preconditionNoInvalidDescriptorsBeforeUpgrading( if errMsg.Len() == 0 { return nil } - return errors.AssertionFailedf("There exists invalid descriptors as listed below. Fix these descriptors "+ - "before attempting to upgrade again.\n%v", errMsg.String()) + return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState, + "there exists invalid descriptors as listed below; fix these descriptors "+ + "before attempting to upgrade again:\n%v", errMsg.String()) } diff --git a/pkg/upgrade/upgrades/precondition_before_starting_an_upgrade_external_test.go b/pkg/upgrade/upgrades/precondition_before_starting_an_upgrade_external_test.go index 413bc086e754..c1629a7adc2e 100644 --- a/pkg/upgrade/upgrades/precondition_before_starting_an_upgrade_external_test.go +++ b/pkg/upgrade/upgrades/precondition_before_starting_an_upgrade_external_test.go @@ -104,10 +104,10 @@ func TestPreconditionBeforeStartingAnUpgrade(t *testing.T) { // Attempt to upgrade the cluster version and expect to see a failure _, err := sqlDB.Exec(`SET CLUSTER SETTING version = $1`, v1.String()) require.Error(t, err, "upgrade should be refused because precondition is violated.") - require.Equal(t, "pq: internal error: verifying precondition for version 22.1-2: "+ - "There exists invalid descriptors as listed below. Fix these descriptors before attempting to upgrade again.\n"+ - "Invalid descriptor: defaultdb.public.t (104) because 'relation \"t\" (104): invalid depended-on-by relation back reference: referenced descriptor ID 53: referenced descriptor not found'\n"+ - "Invalid descriptor: defaultdb.public.temp_tbl (104) because 'no matching name info found in non-dropped relation \"t\"'", + require.Equal(t, "pq: verifying precondition for version 22.1-2: "+ + "there exists invalid descriptors as listed below; fix these descriptors before attempting to upgrade again:\n"+ + "invalid descriptor: defaultdb.public.t (104) because 'relation \"t\" (104): invalid depended-on-by relation back reference: referenced descriptor ID 53: referenced descriptor not found'\n"+ + "invalid descriptor: defaultdb.public.temp_tbl (104) because 'no matching name info found in non-dropped relation \"t\"'", strings.ReplaceAll(err.Error(), "1000022", "22")) // The cluster version should remain at `v0`. tdb.CheckQueryResults(t, "SHOW CLUSTER SETTING version", [][]string{{v0.String()}})