forked from cockroachdb/cockroach
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ccl: add an option to perform a regionless RESTORE
This patch adds the ability to restore a multi-region database onto a single region cluster by adding a new option for the RESTORE syntax, `strip_localities`. This option will strip RegionConfigs from databases and LocalityConfigs from tables. Epic: none Fixes: cockroachdb#105623 Release note (sql change): A new option for the RESTORE syntax, `strip_localities`, has been added. This can be used to strip the locality information from a backup when there are mismatched cluster regions between the backup's cluster and the target cluster. The following are behaviors that will most likely not be encountered with the specific use case that this patch provides, but are documented nonetheless: Note: Adding a primary region to a regionless restore (with or without regional by row table(s)) will not work out-of-the-box, but does produce an accurate message detailing a user to essentially `DROP TYPE [database].public.crdb_internal_region;` (and for cluster restores, `ALTER DATABASE [database] CONFIGURE ZONE DISCARD;`). Note: Restoring a cluster/database/table with a regional by row table will not work out-of-the box. In particular, if we are performing writes, the `crdb_region` column needs to specify the region of the new row(s) being written to the table. The user will need to alter said column and set a default that makes sense, along with discarding the zone config (this latter is due to the fact that the zone config holds all outdated info related to the partitions, constraints, etc.). These are due to a conflict with the `crdb_region` column already being present in the regionless restore. This column specifies each row's home region and is a prefix to the table's primary key. Stripping localities does not touch this column as it would be an expensive operation that includes rewriting the entire table ([internal discussion here](https://cockroachlabs.slack.com/archives/C04N0AS14CT/p1694618761011619)).
- Loading branch information
Showing
13 changed files
with
944 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright 2023 The Cockroach Authors. | ||
// | ||
// Licensed as a CockroachDB Enterprise file under the Cockroach Community | ||
// License (the "License"); you may not use this file except in compliance with | ||
// the License. You may obtain a copy of the License at | ||
// | ||
// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt | ||
|
||
package backupccl | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/cockroachdb/cockroach/pkg/base" | ||
"github.com/cockroachdb/cockroach/pkg/ccl/backupccl/backuptestutils" | ||
"github.com/cockroachdb/cockroach/pkg/ccl/multiregionccl/multiregionccltestutils" | ||
"github.com/cockroachdb/cockroach/pkg/ccl/utilccl" | ||
"github.com/cockroachdb/cockroach/pkg/jobs" | ||
"github.com/cockroachdb/cockroach/pkg/sql" | ||
"github.com/cockroachdb/cockroach/pkg/testutils" | ||
"github.com/cockroachdb/cockroach/pkg/testutils/skip" | ||
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" | ||
"github.com/cockroachdb/cockroach/pkg/testutils/testcluster" | ||
"github.com/cockroachdb/cockroach/pkg/util/leaktest" | ||
"github.com/cockroachdb/cockroach/pkg/util/log" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// The goal of this test is to ensure that if a user ever performed a | ||
// regionless restore where the backed-up target has a regional by row table, | ||
// they would be able to get themselves out of a stuck state without needing | ||
// an enterprise license (in addition to testing the ability to use strip_localities | ||
// without said license). | ||
func TestMultiRegionRegionlessRestoreNoLicense(t *testing.T) { | ||
defer leaktest.AfterTest(t)() | ||
defer log.Scope(t).Close(t) | ||
|
||
skip.UnderStressRace(t, "test is too heavy to run under stress") | ||
|
||
ctx := context.Background() | ||
|
||
dir, dirCleanupfn := testutils.TempDir(t) | ||
defer dirCleanupfn() | ||
|
||
_, mrSqlDB, cleanup := multiregionccltestutils.TestingCreateMultiRegionCluster( | ||
t, 3 /* numServers */, base.TestingKnobs{}, multiregionccltestutils.WithBaseDirectory(dir), | ||
) | ||
defer cleanup() | ||
mrSql := sqlutils.MakeSQLRunner(mrSqlDB) | ||
|
||
// Create the database & table, insert some values. | ||
mrSql.Exec(t, | ||
`CREATE DATABASE d PRIMARY REGION "us-east1" REGIONS "us-east2"; | ||
CREATE TABLE d.t (x INT); | ||
INSERT INTO d.t VALUES (1), (2), (3);`, | ||
) | ||
|
||
// Make table regional by row. | ||
mrSql.Exec(t, `ALTER TABLE d.t SET LOCALITY REGIONAL BY ROW;`) | ||
|
||
if err := backuptestutils.VerifyBackupRestoreStatementResult(t, mrSql, `BACKUP DATABASE d INTO $1`, localFoo); err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
defer utilccl.TestingDisableEnterprise()() | ||
|
||
sqlTC := testcluster.StartTestCluster( | ||
t, singleNode, base.TestClusterArgs{ServerArgs: base.TestServerArgs{ | ||
ExternalIODir: dir, | ||
DefaultTestTenant: base.TestControlsTenantsExplicitly, | ||
Knobs: base.TestingKnobs{ | ||
JobsTestingKnobs: jobs.NewTestingKnobsWithShortIntervals(), | ||
TenantTestingKnobs: &sql.TenantTestingKnobs{ | ||
// This test expects a specific tenant ID to be selected after DROP TENANT. | ||
EnableTenantIDReuse: true, | ||
}, | ||
}, | ||
}}, | ||
) | ||
defer sqlTC.Stopper().Stop(ctx) | ||
sqlDB := sqlutils.MakeSQLRunner(sqlTC.Conns[0]) | ||
|
||
if err := backuptestutils.VerifyBackupRestoreStatementResult(t, sqlDB, `RESTORE DATABASE d FROM LATEST IN $1 WITH strip_localities`, localFoo); err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
// Get us in the state that allows us to perform writes. | ||
// This is the main purpose of this test - we want to ensure that this process is available | ||
// to those without enterprise licenses. | ||
sqlDB.Exec(t, `ALTER TABLE d.t ALTER COLUMN crdb_region SET DEFAULT 'us-east1'; | ||
ALTER TABLE d.t CONFIGURE ZONE DISCARD;`) | ||
|
||
// Perform some writes to d's table. | ||
sqlDB.Exec(t, `INSERT INTO d.t VALUES (4), (5), (6)`) | ||
|
||
var rowCount int | ||
sqlDB.QueryRow(t, `SELECT count(x) FROM d.t`).Scan(&rowCount) | ||
require.Equal(t, 6, rowCount) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.