Skip to content

Commit

Permalink
sql: add ALTER RANGE RELOCATE
Browse files Browse the repository at this point in the history
Fixes #54971

This commit introduces a new ALTER RANGE RELOCATE
command, which will allow an admin to move a lease
or replica for a specific range. Unlike ALTER TABLE RELOCATE
this command works on a range_id, which makes it a lot easier
to use since the user does not have to worry about range keys, which
are difficult to deal with in an emergncy situation.

Release note (sql change): Introduce new SQL syntax ALTER RANGE RELOCATE
to move a lease or replica between stores. This is helpful in an emergency
situation to relocate data in the cluster.
  • Loading branch information
lunevalex committed Jun 14, 2022
1 parent 5b56709 commit f28110c
Show file tree
Hide file tree
Showing 38 changed files with 1,454 additions and 244 deletions.
482 changes: 252 additions & 230 deletions docs/generated/sql/bnf/BUILD.bazel

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions docs/generated/sql/bnf/alter_range_relocate_lease_stmt.bnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
alter_range_relocate_lease_stmt ::=
'ALTER' 'RANGE' relocate_kw 'LEASE' 'TO' iconst64 'FOR' select_stmt
| 'ALTER' 'RANGE' iconst64 relocate_kw 'LEASE' 'TO' iconst64
5 changes: 5 additions & 0 deletions docs/generated/sql/bnf/alter_range_relocate_stmt.bnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
alter_range_relocate_stmt ::=
'ALTER' 'RANGE' relocate_kw voters_kw 'FROM' iconst64 'TO' iconst64 'FOR' select_stmt
| 'ALTER' 'RANGE' iconst64 relocate_kw voters_kw 'FROM' iconst64 'TO' iconst64
| 'ALTER' 'RANGE' relocate_kw 'NON_VOTERS' 'FROM' iconst64 'TO' iconst64 'FOR' select_stmt
| 'ALTER' 'RANGE' iconst64 relocate_kw 'NON_VOTERS' 'FROM' iconst64 'TO' iconst64
2 changes: 2 additions & 0 deletions docs/generated/sql/bnf/alter_range_stmt.bnf
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
alter_range_stmt ::=
alter_zone_range_stmt
| alter_range_relocate_lease_stmt
| alter_range_relocate_stmt
22 changes: 22 additions & 0 deletions docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,7 @@ unreserved_keyword ::=
| 'REGIONS'
| 'REINDEX'
| 'RELEASE'
| 'RELOCATE'
| 'RENAME'
| 'REPEATABLE'
| 'REPLACE'
Expand Down Expand Up @@ -1330,6 +1331,8 @@ alter_database_stmt ::=

alter_range_stmt ::=
alter_zone_range_stmt
| alter_range_relocate_lease_stmt
| alter_range_relocate_stmt

alter_partition_stmt ::=
alter_zone_partition_stmt
Expand Down Expand Up @@ -1832,6 +1835,16 @@ alter_database_primary_region_stmt ::=
alter_zone_range_stmt ::=
'ALTER' 'RANGE' zone_name set_zone_config

alter_range_relocate_lease_stmt ::=
'ALTER' 'RANGE' relocate_kw 'LEASE' 'TO' iconst64 'FOR' select_stmt
| 'ALTER' 'RANGE' iconst64 relocate_kw 'LEASE' 'TO' iconst64

alter_range_relocate_stmt ::=
'ALTER' 'RANGE' relocate_kw voters_kw 'FROM' iconst64 'TO' iconst64 'FOR' select_stmt
| 'ALTER' 'RANGE' iconst64 relocate_kw voters_kw 'FROM' iconst64 'TO' iconst64
| 'ALTER' 'RANGE' relocate_kw 'NON_VOTERS' 'FROM' iconst64 'TO' iconst64 'FOR' select_stmt
| 'ALTER' 'RANGE' iconst64 relocate_kw 'NON_VOTERS' 'FROM' iconst64 'TO' iconst64

alter_zone_partition_stmt ::=
'ALTER' 'PARTITION' partition_name 'OF' 'TABLE' table_name set_zone_config
| 'ALTER' 'PARTITION' partition_name 'OF' 'INDEX' table_index_name set_zone_config
Expand Down Expand Up @@ -2323,6 +2336,15 @@ survival_goal_clause ::=
primary_region_clause ::=
'PRIMARY' 'REGION' opt_equal region_name

relocate_kw ::=
'TESTING_RELOCATE'
| 'EXPERIMENTAL_RELOCATE'
| 'RELOCATE'

voters_kw ::=
'VOTERS'
|

alter_default_privileges_target_object ::=
'TABLES'
| 'SEQUENCES'
Expand Down
17 changes: 17 additions & 0 deletions pkg/ccl/logictestccl/testdata/logic_test/tenant_unsupported
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,20 @@ ALTER TABLE kv EXPERIMENTAL_RELOCATE LEASE VALUES (1, 'k')

statement error operation is unsupported in multi-tenancy mode
SELECT crdb_internal.check_consistency(true, '', '')

statement error operation is unsupported in multi-tenancy mode
ALTER RANGE 1 RELOCATE LEASE TO 2

statement error operation is unsupported in multi-tenancy mode
ALTER RANGE RELOCATE LEASE TO 2 FOR SELECT range_id from crdb_internal.ranges where table_name = 'kv'

statement error operation is unsupported in multi-tenancy mode
ALTER RANGE 1 RELOCATE FROM 1 TO 2

statement error operation is unsupported in multi-tenancy mode
ALTER RANGE RELOCATE FROM 1 TO 2 FOR SELECT range_id from crdb_internal.ranges where table_name = 'kv'

# Can not query inflight traces on sql pods

statement error table crdb_internal.cluster_inflight_traces is not implemented on tenants
SELECT * from crdb_internal.cluster_inflight_traces WHERE trace_id = 42
44 changes: 44 additions & 0 deletions pkg/kv/kvserver/client_lease_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -952,3 +952,47 @@ func TestLeasesDontThrashWhenNodeBecomesSuspect(t *testing.T) {
return errors.Errorf("Expected server 1 to have at lease 1 lease.")
})
}

// TestAlterRangeRelocate verifies that the ALTER_RANGE commands work as expected.
func TestAlterRangeRelocate(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)

ctx := context.Background()
const numStores = 6
tc := testcluster.StartTestCluster(t, numStores,
base.TestClusterArgs{
ReplicationMode: base.ReplicationManual,
},
)
defer tc.Stopper().Stop(ctx)

_, rhsDesc := tc.SplitRangeOrFatal(t, keys.UserTableDataMin)
tc.AddVotersOrFatal(t, rhsDesc.StartKey.AsRawKey(), tc.Targets(1, 2)...)

// We start with having the range under test on (1,2,3).
db := tc.ServerConn(0)
// Move 2 -> 4.
_, err := db.Exec("ALTER RANGE " + rhsDesc.RangeID.String() + " RELOCATE FROM 2 TO 4")
require.NoError(t, err)
require.NoError(t, tc.WaitForVoters(rhsDesc.StartKey.AsRawKey(), tc.Targets(0, 2, 3)...))
// Move lease 1 -> 4.
_, err = db.Exec("ALTER RANGE " + rhsDesc.RangeID.String() + " RELOCATE LEASE TO 4")
require.NoError(t, err)
testutils.SucceedsSoon(t, func() error {
repl := tc.GetFirstStoreFromServer(t, 3).LookupReplica(rhsDesc.StartKey)
if !repl.OwnsValidLease(ctx, tc.Servers[0].Clock().NowAsClockTimestamp()) {
return errors.Errorf("Expected lease to transfer to node 4")
}
// Do this to avoid snapshot problems below when we do another replica move.
if repl != tc.GetRaftLeader(t, rhsDesc.StartKey) {
return errors.Errorf("Expected node 4 to be the raft leader")
}
return nil
})

// Move lease 3 -> 5.
_, err = db.Exec("ALTER RANGE RELOCATE FROM 3 TO 5 FOR (SELECT range_id from crdb_internal.ranges where range_id = " + rhsDesc.RangeID.String() + ")")
require.NoError(t, err)
require.NoError(t, tc.WaitForVoters(rhsDesc.StartKey.AsRawKey(), tc.Targets(0, 3, 4)...))
}
1 change: 1 addition & 0 deletions pkg/sql/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ go_library(
"refresh_materialized_view.go",
"region_util.go",
"relocate.go",
"relocate_range.go",
"rename_column.go",
"rename_database.go",
"rename_index.go",
Expand Down
8 changes: 8 additions & 0 deletions pkg/sql/catalog/colinfo/result_columns.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,14 @@ var AlterTableScatterColumns = ResultColumns{
{Name: "pretty", Typ: types.String},
}

// AlterRangeRelocateColumns are the result columns of an
// ALTER RANGE .. RELOCATE statement.
var AlterRangeRelocateColumns = ResultColumns{
{Name: "range_id", Typ: types.Int},
{Name: "pretty", Typ: types.String},
{Name: "result", Typ: types.String},
}

// ScrubColumns are the result columns of a SCRUB statement.
var ScrubColumns = ResultColumns{
{Name: "job_uuid", Typ: types.Uuid},
Expand Down
6 changes: 6 additions & 0 deletions pkg/sql/distsql_spec_exec_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,12 @@ func (e *distSQLSpecExecFactory) ConstructAlterTableRelocate(
return nil, unimplemented.NewWithIssue(47473, "experimental opt-driven distsql planning: alter table relocate")
}

func (e *distSQLSpecExecFactory) ConstructAlterRangeRelocate(
input exec.Node, relocateLease bool, relocateNonVoters bool, toStoreID int64, fromStoreID int64,
) (exec.Node, error) {
return nil, unimplemented.NewWithIssue(47473, "experimental opt-driven distsql planning: alter range relocate")
}

func (e *distSQLSpecExecFactory) ConstructBuffer(input exec.Node, label string) (exec.Node, error) {
return nil, unimplemented.NewWithIssue(47473, "experimental opt-driven distsql planning: buffer")
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/sql/opt/exec/execbuilder/relational.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ func (b *Builder) buildRelational(e memo.RelExpr) (execPlan, error) {
case *memo.AlterTableRelocateExpr:
ep, err = b.buildAlterTableRelocate(t)

case *memo.AlterRangeRelocateExpr:
ep, err = b.buildAlterRangeRelocate(t)

case *memo.ControlJobsExpr:
ep, err = b.buildControlJobs(t)

Expand Down
18 changes: 18 additions & 0 deletions pkg/sql/opt/exec/execbuilder/statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,24 @@ func (b *Builder) buildAlterTableRelocate(relocate *memo.AlterTableRelocateExpr)
return planWithColumns(node, relocate.Columns), nil
}

func (b *Builder) buildAlterRangeRelocate(relocate *memo.AlterRangeRelocateExpr) (execPlan, error) {
input, err := b.buildRelational(relocate.Input)
if err != nil {
return execPlan{}, err
}
node, err := b.factory.ConstructAlterRangeRelocate(
input.root,
relocate.RelocateLease,
relocate.RelocateNonVoters,
relocate.ToStoreID,
relocate.FromStoreID,
)
if err != nil {
return execPlan{}, err
}
return planWithColumns(node, relocate.Columns), nil
}

func (b *Builder) buildControlJobs(ctl *memo.ControlJobsExpr) (execPlan, error) {
input, err := b.buildRelational(ctl.Input)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/sql/opt/exec/explain/emit.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ func (e *emitter) nodeName(n *Node) (string, error) {
}

var nodeNames = [...]string{
alterRangeRelocateOp: "relocate",
alterTableRelocateOp: "relocate",
alterTableSplitOp: "split",
alterTableUnsplitAllOp: "unsplit all",
Expand Down Expand Up @@ -783,6 +784,7 @@ func (e *emitter) emitNodeAttributes(n *Node) error {
alterTableUnsplitAllOp,
alterTableRelocateOp,
recursiveCTEOp,
alterRangeRelocateOp,
controlJobsOp,
controlSchedulesOp,
cancelQueriesOp,
Expand Down
Loading

0 comments on commit f28110c

Please sign in to comment.