-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
35306: opt: Prefer index with zone constraints that most closely match locality r=andy-kimball a=andy-kimball Customers can create multiple indexes that are identical, except that they have different locality constraints. This commit teaches the optimizer to prefer the index that most closely matches the locality of the gateway node that is planning the query. This enables scenarios where reference data like a zip code table can be replicated to different regions, and queries will use the copy in the same region. Co-authored-by: Andrew Kimball <[email protected]>
- Loading branch information
Showing
26 changed files
with
1,039 additions
and
70 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# LogicTest: 5node-dist-opt | ||
|
||
# Ensure that cost-based-optimizer uses an index with zone constraints that most | ||
# closely matches the gateway's locality. | ||
|
||
statement ok | ||
CREATE TABLE t ( | ||
k INT PRIMARY KEY, | ||
v STRING, | ||
INDEX secondary (k) STORING (v) | ||
); | ||
|
||
# ------------------------------------------------------------------------------ | ||
# Put table in dc2 and secondary index in dc1 so that the gateway matches the | ||
# secondary index rather the primary index. | ||
# ------------------------------------------------------------------------------ | ||
|
||
statement ok | ||
ALTER TABLE t CONFIGURE ZONE USING constraints='[+region=test,+dc=dc2]' | ||
|
||
statement ok | ||
ALTER INDEX t@secondary CONFIGURE ZONE USING constraints='[+region=test,+dc=dc1]' | ||
|
||
query TTT | ||
EXPLAIN SELECT * FROM t WHERE k=10 | ||
---- | ||
scan · · | ||
· table t@secondary | ||
· spans /10-/11 | ||
|
||
# ------------------------------------------------------------------------------ | ||
# Swap location of primary and secondary indexes and ensure that primary index | ||
# is used instead. | ||
# ------------------------------------------------------------------------------ | ||
|
||
statement ok | ||
ALTER TABLE t CONFIGURE ZONE USING constraints='[+region=test,+dc=dc1]' | ||
|
||
statement ok | ||
ALTER INDEX t@secondary CONFIGURE ZONE USING constraints='[+region=test,+dc=dc2]' | ||
|
||
query TTT | ||
EXPLAIN SELECT * FROM t WHERE k=10 | ||
---- | ||
scan · · | ||
· table t@primary | ||
· spans /10-/10/# | ||
|
||
# ------------------------------------------------------------------------------ | ||
# Use PREPARE to make sure that the prepared plan is invalidated when the | ||
# secondary index's constraints change. | ||
# ------------------------------------------------------------------------------ | ||
|
||
statement | ||
PREPARE p AS SELECT tree, field, description FROM [EXPLAIN SELECT k, v FROM t WHERE k=10] | ||
|
||
query TTT | ||
EXECUTE p | ||
---- | ||
scan · · | ||
· table t@primary | ||
· spans /10-/10/# | ||
|
||
statement ok | ||
ALTER TABLE t CONFIGURE ZONE USING constraints='[+region=test,+dc=dc2]' | ||
|
||
statement ok | ||
ALTER INDEX t@secondary CONFIGURE ZONE USING constraints='[+region=test,+dc=dc1]' | ||
|
||
query TTT | ||
EXECUTE p | ||
---- | ||
scan · · | ||
· table t@secondary | ||
· spans /10-/11 |
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
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,116 @@ | ||
// Copyright 2018 The Cockroach Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
// implied. See the License for the specific language governing | ||
// permissions and limitations under the License. | ||
|
||
package cat | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
|
||
"github.com/cockroachdb/cockroach/pkg/util/treeprinter" | ||
) | ||
|
||
// Zone is an interface to zone configuration information used by the optimizer. | ||
// The optimizer prefers indexes with constraints that best match the locality | ||
// of the gateway node that plans the query. | ||
type Zone interface { | ||
// ReplicaConstraintsCount returns the number of replica constraint sets that | ||
// are part of this zone. | ||
ReplicaConstraintsCount() int | ||
|
||
// ReplicaConstraints returns the ith set of replica constraints in the zone, | ||
// where i < ReplicaConstraintsCount. | ||
ReplicaConstraints(i int) ReplicaConstraints | ||
} | ||
|
||
// ReplicaConstraints is a set of constraints that apply to one or more replicas | ||
// of a range, restricting which nodes can host that range. For example, if a | ||
// table range has three replicas, then two of the replicas might be pinned to | ||
// nodes in one region, whereas the third might be pinned to another region. | ||
type ReplicaConstraints interface { | ||
// ReplicaCount returns the number of replicas that should abide by this set | ||
// of constraints. If 0, then the constraints apply to all replicas of the | ||
// range (and there can be only one ReplicaConstraints in the Zone). | ||
ReplicaCount() int32 | ||
|
||
// ConstraintCount returns the number of constraints in the set. | ||
ConstraintCount() int | ||
|
||
// Constraint returns the ith constraint in the set, where | ||
// i < ConstraintCount. | ||
Constraint(i int) Constraint | ||
} | ||
|
||
// Constraint governs placement of range replicas on nodes. A constraint can | ||
// either be required or prohibited. A required constraint's key/value pair must | ||
// match one of the tiers of a node's locality for the range to locate there. | ||
// A prohibited constraint's key/value pair must *not* match any of the tiers of | ||
// a node's locality for the range to locate there. For example: | ||
// | ||
// +region=east Range can only be placed on nodes in region=east locality. | ||
// -region=west Range cannot be placed on nodes in region=west locality. | ||
// | ||
type Constraint interface { | ||
// IsRequired is true if this is a required constraint, or false if this is | ||
// a prohibited constraint (signified by initial + or - character). | ||
IsRequired() bool | ||
|
||
// GetKey returns the constraint's string key (to left of =). | ||
GetKey() string | ||
|
||
// GetValue returns the constraint's string value (to right of =). | ||
GetValue() string | ||
} | ||
|
||
// FormatZone nicely formats a catalog zone using a treeprinter for debugging | ||
// and testing. | ||
func FormatZone(zone Zone, tp treeprinter.Node) { | ||
child := tp.Childf("ZONE") | ||
if zone.ReplicaConstraintsCount() > 1 { | ||
child = child.Childf("replica constraints") | ||
} | ||
for i, n := 0, zone.ReplicaConstraintsCount(); i < n; i++ { | ||
replConstraint := zone.ReplicaConstraints(i) | ||
constraintStr := formatReplicaConstraint(replConstraint) | ||
if zone.ReplicaConstraintsCount() > 1 { | ||
numReplicas := replConstraint.ReplicaCount() | ||
child.Childf("%d replicas: %s", numReplicas, constraintStr) | ||
} else { | ||
child.Childf("constraints: %s", constraintStr) | ||
} | ||
} | ||
} | ||
|
||
func formatReplicaConstraint(replConstraint ReplicaConstraints) string { | ||
var buf bytes.Buffer | ||
buf.WriteRune('[') | ||
for i, n := 0, replConstraint.ConstraintCount(); i < n; i++ { | ||
constraint := replConstraint.Constraint(i) | ||
if i != 0 { | ||
buf.WriteRune(',') | ||
} | ||
if constraint.IsRequired() { | ||
buf.WriteRune('+') | ||
} else { | ||
buf.WriteRune('-') | ||
} | ||
if constraint.GetKey() != "" { | ||
fmt.Fprintf(&buf, "%s=%s", constraint.GetKey(), constraint.GetValue()) | ||
} else { | ||
buf.WriteString(constraint.GetValue()) | ||
} | ||
} | ||
buf.WriteRune(']') | ||
return buf.String() | ||
} |
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.