Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
93644: sql: better `SHOW RANGES` and changes to `crdb_internal.ranges{,_no_leases}` r=ecwall a=knz

Fixes #93617.
Fixes #80906.
Fixes #93198.
Epic: CRDB-22701

The output of `crdb_internal.ranges{,_no_leases}` and `SHOW
RANGES` was irreparably broken by the introduction of range coalescing
(ranges spanning multiple tables/databases).

Moreover, the start/end keys of SHOW RANGES were often empty or
NULL due to incorrect/excessive truncation.

This commit fixes this by introducing a new design for SHOW RANGES
and tweaking the definition of `crdb_internal.ranges{,_no_leases}`.

Note: THIS IS A BREAKING CHANGE. See the "backward-incompatible
change" release notes below for suggestions on updating client code.

----

**Short documentation.**

<details>

The revised syntax is now:
```
  SHOW CLUSTER RANGES [WITH <options>]
  SHOW RANGES [FROM DATABASE <dbname> | FROM CURRENT_CATALOG] [ WITH <options> ]
  SHOW RANGES FROM TABLE <tablename> [ WITH <options> ]
  SHOW RANGES FROM INDEX <idxname> [ WITH <options> ]

  <options> is a combination of TABLES, INDEXES, KEYS, DETAILS and EXPLAIN.
```

New syntax: `SHOW CLUSTER RANGES`, `SHOW RANGES` with no `FROM`, `FROM
CURRENT_CATALOG`, `WITH` clause.

In summary, we have:
- `SHOW CLUSTER RANGES` which includes all ranges, including those not
  belonging to any table.
- `SHOW RANGES [FROM DATABASE | FROM CURRENT_CATALOG]` which includes
  only ranges overlapping with any table in the target db.
  Note: `SHOW RANGES` without target (NEW!) is an alias for `SHOW RANGES FROM
  CURRENT_CATALOG`.
- `SHOW RANGES FROM TABLE` selects only ranges that overlap with the
  given table.
- `SHOW RANGES FROM INDEX` selects only ranges that overlap with the
  given index.

Then:

- if `WITH TABLES` is specified, the rows are duplicated to detail
  each table included in each range (1 row per range-table
  intersection).
- if `WITH INDEXES` is specified, the rows are duplicated to detail each
  index included in each range (1 row per range-index intersection).
- otherwise, there is just 1 row per range.

In summary:

| Statement                                          | Row identity                     | Before                     | After                            |
|----------------------------------------------------|----------------------------------|----------------------------|----------------------------------|
| `SHOW RANGES FROM DATABASE`                        | rangeID                          | Includes schema/table name | (CHANGE) No schema/table name    |
| `SHOW RANGES FROM TABLE`                           | rangeID                          | Includes index name        | (CHANGE) No index name           |
| `SHOW RANGES FROM INDEX`                           | rangeID                          | Includes index name        | Unchanged                        |
| `SHOW RANGES FROM DATABASE ... WITH TABLES` (NEW)  | rangeID, schema/table name       | N/A                        | Includes schema/table name       |
| `SHOW RANGES FROM DATABASE ... WITH INDEXES` (NEW) | rangeID, schema/table/index name | N/A                        | Includes schema/table/index name |
| `SHOW RANGES FROM TABLE ... WITH INDEXES` (NEW)    | rangeID, index name              | N/A                        | Includes index name              |
| `SHOW CLUSTER RANGES` (NEW)                        | rangeID                          | N/A                        |                                  |
| `SHOW CLUSTER RANGES WITH TABLES` (NEW)            | rangeID, schema/table name       | N/A                        | Includes db/schema/table name    |
| `SHOW CLUSTER RANGES WITH INDEXES` (NEW)           | rangeID, schema/table/index name | N/A                        | Includes db/sch/table/index name |

| Statement                                          | Start/end key column, before | Start/end key column, after           |
|----------------------------------------------------|------------------------------|---------------------------------------|
| `SHOW RANGES FROM DATABASE`                        | Truncates table/index IDs    | (CHANGE) Includes table/index ID      |
| `SHOW RANGES FROM TABLE`                           | Truncates table/index IDs    | (CHANGE) Includes table/index ID      |
| `SHOW RANGES FROM INDEX`                           | Truncates table/index IDs    | Unchanged                             |
| `SHOW RANGES FROM DATABASE ... WITH TABLES` (NEW)  | N/A                          | Includes table/index ID               |
| `SHOW RANGES FROM DATABASE ... WITH INDEXES` (NEW) | N/A                          | Includes table/index ID               |
| `SHOW RANGES FROM TABLE ... WITH INDEXES` (NEW)    | N/A                          | Truncates table ID, includes index ID |
| `SHOW CLUSTER RANGES` (NEW)                        | N/A                          | Includes table/index ID               |
| `SHOW CLUSTER RANGES WITH TABLES` (NEW)            | N/A                          | Includes table/index ID               |
| `SHOW CLUSTER RANGES WITH INDEXES` (NEW)           | N/A                          | Includes table/index ID               |

In any case, all the columns from `crdb_internal.ranges_no_leases` are
included. By default, the start/end key boundaries are pretty-printed
as in previous versions.

Then:
- if `WITH KEYS` is specified, the raw key bytes are exposed alongside
  the pretty-printed key boundaries.
- if `WITH DETAILS` is specified, extra _expensive_ information is
  included in the result, as of `crdb_internal.ranges`.
  (requires more roundtrips; makes the operation slower overall)

Then:
- if `WITH EXPLAIN` is specified, the statement simply returns the
  text of the SQL query it would use if `WITH EXPLAIN` was not
  specified. This can be used for learning or troubleshooting.

</details>

See text of release notes below for more details; also the explanatory
comment at the top of `pkg/sql/delegate/show_ranges.go`.

----

**Example use.**

<details>

To test this, use for example the following setup:

```
> -- Enable merge of adjacent ranges with same zone config.
> set cluster setting spanconfig.host_coalesce_adjacent.enabled = true;
> -- Table t has two indexes with some split points.
> create table t(x int primary key, y int);
> create index sec_idx on t(y);
> alter index t@primary split at values(3);
> alter index t@sec_idx split at values(3);
> -- Tables u and v share a range with t@sec_idx.
> create table u(x int);
> create table v(x int);
> -- Make some other tables with forced split points due to different
> -- zone configs.
> create schema otherschema;
> create table otherschema.w(x int);
> create table otherschema.z(x int);
> alter table otherschema.w configure zone using num_replicas = 5;
> alter table otherschema.z configure zone using num_replicas = 7;
```

Example output for `SHOW RANGES FROM DATABASE`:

```
> show ranges from database defaultdb; -- 1 row per range
> show ranges from current_catalog; -- implicit db from session

    start_key    |    end_key     | range_id | ...
-----------------+----------------+----------+----
  /Table/104     | /Table/104/1/3 |       56 | ...
  /Table/104/1/3 | /Table/104/2   |       57 | ...
  /Table/104/2   | /Table/104/2/3 |       55 | ...
  /Table/104/2/3 | /Table/108     |       58 | ...
  /Table/108     | /Table/109     |       59 | ...
  /Table/109     | /Max           |       60 | ...
```

New syntax: `WITH TABLES` / `WITH INDEXES`:

```
> show ranges from database defaultdb with tables; -- 1 row per range/table intersection

    start_key    |    end_key     | range_id | schema_name | table_name | table_start_key |    table_end_key     | ...
-----------------+----------------+----------+-------------+------------+-----------------+----------------------+----
  /Table/104     | /Table/104/1/3 |       56 | public      | t          | /Table/104      | /Table/105           | ...
  /Table/104/1/3 | /Table/104/2   |       57 | public      | t          | /Table/104      | /Table/105           | ...
  /Table/104/2   | /Table/104/2/3 |       55 | public      | t          | /Table/104      | /Table/105           | ...
  /Table/104/2/3 | /Table/108     |       58 | public      | t          | /Table/104      | /Table/105           | ...
  /Table/104/2/3 | /Table/108     |       58 | public      | u          | /Table/105      | /Table/106           | ...
  /Table/104/2/3 | /Table/108     |       58 | public      | v          | /Table/106      | /Table/107           | ...
  /Table/108     | /Table/109     |       59 | otherschema | w          | /Table/108      | /Table/109           | ...
  /Table/109     | /Max           |       60 | otherschema | z          | /Table/109      | /Table/109/PrefixEnd | ...
```

```
> show ranges from database defaultdb with indexes; -- 1 row per range/index intersection

    start_key    |    end_key     | range_id | schema_name | table_name | index_name | index_start_key | index_end_key | ...
-----------------+----------------+----------+-------------+------------+------------+-----------------+---------------+----
  /Table/104     | /Table/104/1/3 |       56 | public      | t          | t_pkey     | /Table/104/1    | /Table/104/2  | ...
  /Table/104/1/3 | /Table/104/2   |       57 | public      | t          | t_pkey     | /Table/104/1    | /Table/104/2  | ...
  /Table/104/2   | /Table/104/2/3 |       55 | public      | t          | sec_idx    | /Table/104/2    | /Table/104/3  | ...
  /Table/104/2/3 | /Table/108     |       58 | public      | t          | sec_idx    | /Table/104/2    | /Table/104/3  | ...
  /Table/104/2/3 | /Table/108     |       58 | public      | u          | u_pkey     | /Table/105/1    | /Table/105/2  | ...
  /Table/104/2/3 | /Table/108     |       58 | public      | v          | v_pkey     | /Table/106/1    | /Table/106/2  | ...
  /Table/108     | /Table/109     |       59 | otherschema | w          | w_pkey     | /Table/108/1    | /Table/108/2  | ...
  /Table/109     | /Max           |       60 | otherschema | z          | z_pkey     | /Table/109/1    | /Table/109/2  | ...
```

Example output for `SHOW RANGES FROM TABLE`:

```
> show ranges from table t;

   start_key   |      end_key       | range_id | ...
---------------+--------------------+----------+----
  …/<TableMin> | …/1/3              |       56 | ...
  …/1/3        | …/2                |       57 | ...
  …/2          | …/2/3              |       55 | ...
  …/2/3        | <after:/Table/108> |       58 | ...
```

```
> show ranges from table u;

         start_key        |      end_key       | range_id | ...
--------------------------+--------------------+----------+----
  <before:/Table/104/2/3> | <after:/Table/108> |       58 | ...
```

```
> show ranges from table otherschema.w;

  start_key    |  end_key     | range_id | ...
---------------+--------------+----------+----
  …/<TableMin> | …/<TableMax> |       59 | ...
```

New syntax: `SHOW RANGES FROM TABLE ... WITH INDEXES`:

```
> show ranges from table t with indexes;

  start_key    |      end_key       | range_id | index_name | index_start_key | index_end_key | ...
---------------+--------------------+----------+------------+-----------------+---------------+----
  …/<TableMin> | …/1/3              |       56 | t_pkey     | …/1             | …/2           | ...
  …/1/3        | …/<IndexMax>       |       57 | t_pkey     | …/1             | …/2           | ...
  …/<IndexMin> | …/2/3              |       55 | sec_idx    | …/2             | …/3           | ...
  …/2/3        | <after:/Table/108> |       58 | sec_idx    | …/2             | …/3           | ...
```

```
> show ranges from table u with indexes;

         start_key        |      end_key       | range_id | index_name | index_start_key | index_end_key | ...
--------------------------+--------------------+----------+------------+-----------------+---------------+----
  <before:/Table/104/2/3> | <after:/Table/108> |       58 | u_pkey     | …/1             | …/2           | ...
```

```
> show ranges from table otherschema.w with indexes;

  start_key    |  end_key     | range_id | index_name | index_start_key | index_end_key | ...
---------------+--------------+----------+------------+-----------------+---------------+----
  …/<TableMin> | …/<TableMax> |       59 | w_pkey     | …/1             | …/2           | ...
```

Example output for `SHOW RANGES FROM INDEX`:

```
> show ranges from index t@t_pkey;

  start_key    |  end_key     | range_id | ...
---------------+--------------+----------+----
  …/<TableMin> | …/3          |       56 | ...
  …/3          | …/<IndexMax> |       57 | ...
```

```
> show ranges from index t@sec_idx;

  start_key    |      end_key       | range_id | ...
---------------+--------------------+----------+----
  …/<IndexMin> | …/3                |       55 | ...
  …/3          | <after:/Table/108> |       58 | ...
```

```
> show ranges from index u@u_pkey;

         start_key        |      end_key       | range_id | ...
--------------------------+--------------------+----------+----
  <before:/Table/104/2/3> | <after:/Table/108> |       58 | ...
```

```
> show ranges from index otherschema.w@w_pkey;

  start_key    |  end_key     | range_id | ...
---------------+--------------+----------+----
  …/<TableMin> | …/<TableMax> |       59 | ...
```

See release notes below for details.

</details>

----

![attention banner](https://media.tenor.com/-AeK-iJpxuoAAAAM/pay-attention-warning.gif)

**Backward-incompatible changes.**

Release note (backward-incompatible change): CockroachDB now supports
sharing storage ranges across multiple indexes/tables. As a result,
there is no more guarantee that there is at most one SQL object (e.g.
table/index/sequence/materialized view) per storage range.

Therefore, the columns `table_id`, `database_name`, `schema_name`,
`table_name` and `index_name` in `crdb_internal.ranges` and
`.ranges_no_leases` have become nonsensical: a range cannot be
attributed to a single table/index any more.

As a result:

- The aforementioned columns in the `crdb_internal` virtual tables
  have been removed. Existing code can use the SHOW RANGES
  statement instead, optionally using WITH KEYS to expose
  the raw start/end keys.

- `SHOW RANGES FROM DATABASE` continues to report one row per range,
  but stops returning the database / schema / table / index name.

- `SHOW RANGES FROM TABLE` continues to report one row per range,
  but stops returning the index name.

Suggested replacements:

- Instead of `SELECT range_id FROM crdb_internal.ranges WHERE table_name = 'x'`

  Use: `SELECT range_id FROM [SHOW RANGES FROM TABLE x]`

- Instead of `SELECT range_id FROM crdb_internal.ranges WHERE table_name = $1 OR table_id = $2`
  (variable / unpredictable table name or ID)

  Use: `SELECT range_id FROM [SHOW RANGES FROM CURRENT_CATALOG WITH TABLES] WHERE table_name = $1 OR table_id = $2`

- Instead of `SELECT start_key FROM crdb_internal.ranges WHERE table_name = 'x'`

  Use: `SELECT raw_start_key FROM [SHOW RANGES FROM TABLE x WITH KEYS]`

- Instead of `SELECT start_key FROM crdb_internal.ranges WHERE table_name = $1 OR table_id = $2`
  (unpredictable / variable table name or ID)

  Use: `SELECT raw_start_key FROM [SHOW RANGES FROM CURRENT_CATALOG WITH TABLES, KEYS] WHERE table_name = $1 OR table_id = $2`

Release note (backward-incompatible change): The format of the
columns `start_key` and `end_key` for `SHOW RANGES FROM DATABASE`
and `SHOW RANGES FROM TABLE` have been extended to include which
table/index the key belong to. This is necessary because a range
can now contain data from more than one table/index.

Release note (backward-incompatible change): The format of
the columns `start_key` and `end_key` for `SHOW RANGE ... FOR ROW`
has been changed to stay consistent with the output of `SHOW RANGES
FROM INDEX`.

Release note (backward-incompatible change): The output of `SHOW
RANGES` does not include `range_size`, `range_size_mb`, `lease_holder`
and `lease_holder_localities` any more by default. This ensures that
`SHOW RANGES` remains fast in the common case. Use the (NEW) option
`WITH DETAILS` to include these columns.

----

**Other changes.**

Release note (bug fix): In some cases the start/end key columns of the
output of `SHOW RANGES` was missing. This was corrected.

Release note (sql change): Two new virtual tables
`crdb_internal.index_spans` and `.table_spans` have been introduced,
which list the logical keyspace used by each index/table.

----

**New features.**

Release note (sql change): The following new statements are
introduced:

- `SHOW RANGES FROM CURRENT_CATALOG` and `SHOW RANGES` without
  parameter: alias for `SHOW RANGES FROM DATABASE` on the session's
  current database.

- `SHOW RANGES FROM DATABASE ... WITH TABLES`
  Reports at least one row per table. It's possible for the same
  range ID to be repeated across multiple rows, when a range spans
  multiple tables.

- `SHOW RANGES FROM DATABASE ... WITH INDEXES`
  Reports at least one row per index. It's possible for the same
  range ID to be repeated across multiple rows, when a range spans
  multiple indexes.

- `SHOW RANGES FROM TABLE ... WITH INDEXES`
  Reports at least one row per index. It's possible for the same
  range ID to be repeated across multiple rows, when a range spans
  multiple indexes.

- `SHOW CLUSTER RANGES [ WITH { INDEXES | TABLES } ]` Reports ranges
  across the entire cluster, including ranges that don't contain table
  data. The behavior of `WITH INDEXES` and `WITH TABLES` is the same
  as for `SHOW RANGES FROM DATABASE`.

Additionally, the following new options have been added to the `SHOW
RANGES` statement:

- `WITH KEYS`: produce the raw bytes of the start/end key boundaries.
- `WITH DETAILS`: produce more details, using computations that
  require extra network roundtrips. Makes the operation slower
  overall.
- `WITH EXPLAIN`: produce the text of the SQL query used to
  run the statement.

93657: ui: Populate database filter dropdown in stmts page with `SHOW DATABASES`  sql-over-http call r=gtr a=gtr

Fixes: #70461.

Previously, the databases filter dropdown was populated by the
`StatementsResponse` API call.This would result in some databases for
which we do not receive any stmts to be ignored.According to above
issue, the database filter - drop down should always be populated with
cluster databases even when there are no statements or transactions for
them.This commit populates the database filter dropdown using the
`getDatabasesList()` API call which itself executes the`SHOW DATABASES`
SQL query.

Creating a new empty database from the SQL shell: 
<img width="960" alt="Screen Shot 2022-12-19 at 10 48 04 AM" src="https://user-images.githubusercontent.com/35943354/208500315-dd3de725-cfa2-4303-aeeb-3491a98a89d7.png">

Clicking the "Databases" dropdown: 
<img width="259" alt="Screen Shot 2022-12-19 at 10 54 36 AM" src="https://user-images.githubusercontent.com/35943354/208500338-6021a805-130d-48f7-846c-c7c6d7782773.png">

Release note(ui change): The databases filter dropdown in the stmts
page now uses the `getDatabasesList()` API call, resulting in all
cluster databases showing up.

93937: server: refactor database index recommendations for DatabaseDetails API r=THardy98 a=THardy98

Resolves: #93909

Previously, the DatabaseDetails API would fetch the index recommendations of the database by executing an expensive query for **each table of the database**, then coalesce the results of each table to get the database-level result. This was needlessly expensive and impractical, particularly so for large schemas. This change ensures that only a single query is executed **per database** to fetch its index recommendations.

-----

**SHORT DEMOS**
Short demos of the change in latency before/after running `demo` on db-console. Notably, `movr` is the only database that we check for index recommendations.

**Before**
https://www.loom.com/share/fc7ca49e4f9c46738831c23742112069

**After**
https://www.loom.com/share/be6e4711ca1d43409774995dece0673b

Noted Improvements:
- The latency on fetching stats for `movr` improves from ~250ms to ~60ms
- Not shown in the videos above but the number of query calls improves from 45 to 4.

Release note (performance improvement): Refactored the query logic when fetching database index recommendations for the DatabaseDetails API endpoint, greatly reducing the query time and cost, particularly for large schemas.

94156: roachtest: update version map for 22.2.1 r=absterr08 a=absterr08

links epic https://cockroachlabs.atlassian.net/browse/REL-228

Release note: none

Co-authored-by: Raphael 'kena' Poss <knz@thaumogen.net>
Co-authored-by: gtr <gerardo@cockroachlabs.com>
Co-authored-by: Thomas Hardy <thardy@cockroachlabs.com>
Co-authored-by: Abby Hersh <abby@cockroachlabs.com>
  • Loading branch information
5 people committed Dec 22, 2022
5 parents 02d74e7 + e67d2fd + 5d6236e + 5786a71 + 08829cf commit 6b72f70
Show file tree
Hide file tree
Showing 114 changed files with 3,962 additions and 2,280 deletions.
9 changes: 6 additions & 3 deletions docs/generated/sql/bnf/show_ranges_stmt.bnf
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
show_ranges_stmt ::=
'SHOW' 'RANGES' 'FROM' 'TABLE' table_name
| 'SHOW' 'RANGES' 'FROM' 'INDEX' table_index_name
| 'SHOW' 'RANGES' 'FROM' 'DATABASE' database_name
'SHOW' 'RANGES' 'FROM' 'INDEX' table_index_name opt_show_ranges_options
| 'SHOW' 'RANGES' 'FROM' 'TABLE' table_name opt_show_ranges_options
| 'SHOW' 'RANGES' 'FROM' 'DATABASE' database_name opt_show_ranges_options
| 'SHOW' 'RANGES' 'FROM' 'CURRENT_CATALOG' opt_show_ranges_options
| 'SHOW' 'RANGES' opt_show_ranges_options
| 'SHOW' 'CLUSTER' 'RANGES' opt_show_ranges_options
16 changes: 13 additions & 3 deletions docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -867,9 +867,12 @@ show_statements_stmt ::=
| 'SHOW' 'ALL' opt_cluster statements_or_queries

show_ranges_stmt ::=
'SHOW' 'RANGES' 'FROM' 'TABLE' table_name
| 'SHOW' 'RANGES' 'FROM' 'INDEX' table_index_name
| 'SHOW' 'RANGES' 'FROM' 'DATABASE' database_name
'SHOW' 'RANGES' 'FROM' 'INDEX' table_index_name opt_show_ranges_options
| 'SHOW' 'RANGES' 'FROM' 'TABLE' table_name opt_show_ranges_options
| 'SHOW' 'RANGES' 'FROM' 'DATABASE' database_name opt_show_ranges_options
| 'SHOW' 'RANGES' 'FROM' 'CURRENT_CATALOG' opt_show_ranges_options
| 'SHOW' 'RANGES' opt_show_ranges_options
| 'SHOW' 'CLUSTER' 'RANGES' opt_show_ranges_options

show_range_for_row_stmt ::=
'SHOW' 'RANGE' 'FROM' 'TABLE' table_name 'FOR' 'ROW' '(' expr_list ')'
Expand Down Expand Up @@ -1077,6 +1080,7 @@ unreserved_keyword ::=
| 'DEPENDS'
| 'DESTINATION'
| 'DETACHED'
| 'DETAILS'
| 'DISCARD'
| 'DOMAIN'
| 'DOUBLE'
Expand Down Expand Up @@ -1950,6 +1954,9 @@ statements_or_queries ::=
'STATEMENTS'
| 'QUERIES'

opt_show_ranges_options ::=
'WITH' show_ranges_options

opt_compact ::=
'COMPACT'
|
Expand Down Expand Up @@ -2645,6 +2652,9 @@ targets_roles ::=
| 'TYPE' type_name_list
| grant_targets

show_ranges_options ::=
( 'TABLES' | 'INDEXES' | 'DETAILS' | 'KEYS' | 'EXPLAIN' ) ( ( ',' 'TABLES' | ',' 'INDEXES' | ',' 'DETAILS' | ',' 'EXPLAIN' | ',' 'KEYS' ) )*

partition ::=
'PARTITION' partition_name

Expand Down
2 changes: 1 addition & 1 deletion pkg/ccl/backupccl/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1386,7 +1386,7 @@ WITH
AS prev_lease_holder,
lease_holder
FROM
[SHOW RANGES FROM TABLE data.bank]
[SHOW RANGES FROM TABLE data.bank WITH DETAILS]
)
SELECT
count(*)
Expand Down
8 changes: 6 additions & 2 deletions pkg/ccl/backupccl/testdata/backup-restore/column-families
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ RESTORE cfs FROM LATEST IN 'nodelocal://1/foo' WITH into_db='r1';
----

query-sql
SELECT max(length(start_key)) FROM [SHOW RANGES FROM TABLE orig.cfs];
SELECT start_key FROM [SHOW RANGES FROM TABLE orig.cfs]
----
2
…/<TableMin>
…/1/0
…/1/1
…/1/2
…/1/3
41 changes: 23 additions & 18 deletions pkg/ccl/backupccl/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/kv/kvserver"
"github.com/cockroachdb/cockroach/pkg/roachpb"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/desctestutils"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/testutils"
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
Expand Down Expand Up @@ -399,11 +400,8 @@ func waitForTableSplit(t *testing.T, conn *gosql.DB, tableName, dbName string) {
testutils.SucceedsSoon(t, func() error {
count := 0
if err := conn.QueryRow(
"SELECT count(*) "+
"FROM crdb_internal.ranges_no_leases "+
"WHERE table_name = $1 "+
"AND database_name = $2",
tableName, dbName).Scan(&count); err != nil {
fmt.Sprintf("SELECT count(*) FROM [SHOW RANGES FROM TABLE %s.%s]",
tree.NameString(dbName), tree.NameString(tableName))).Scan(&count); err != nil {
return err
}
if count == 0 {
Expand All @@ -416,13 +414,8 @@ func waitForTableSplit(t *testing.T, conn *gosql.DB, tableName, dbName string) {
func getTableStartKey(t *testing.T, conn *gosql.DB, tableName, dbName string) roachpb.Key {
t.Helper()
row := conn.QueryRow(
"SELECT start_key "+
"FROM crdb_internal.ranges_no_leases "+
"WHERE table_name = $1 "+
"AND database_name = $2 "+
"ORDER BY start_key ASC "+
"LIMIT 1",
tableName, dbName)
fmt.Sprintf(`SELECT crdb_internal.table_span('%s.%s'::regclass::oid::int)[1]`,
tree.NameString(dbName), tree.NameString(tableName)))
var startKey roachpb.Key
require.NoError(t, row.Scan(&startKey))
return startKey
Expand Down Expand Up @@ -450,10 +443,22 @@ func getStoreAndReplica(
) (*kvserver.Store, *kvserver.Replica) {
t.Helper()
startKey := getTableStartKey(t, conn, tableName, dbName)

// Okay great now we have a key and can go find replicas and stores and what not.
r := tc.LookupRangeOrFatal(t, startKey)
l, _, err := tc.FindRangeLease(r, nil)
require.NoError(t, err)

var l roachpb.Lease
testutils.SucceedsSoon(t, func() error {
var err error
l, _, err = tc.FindRangeLease(r, nil)
if err != nil {
return err
}
if l.Replica.NodeID == 0 {
return errors.New("range does not have a lease yet")
}
return nil
})

lhServer := tc.Server(int(l.Replica.NodeID) - 1)
return getFirstStoreReplica(t, lhServer, startKey)
Expand Down Expand Up @@ -572,10 +577,10 @@ func runGCAndCheckTraceOnCluster(
t.Helper()
var startKey roachpb.Key
testutils.SucceedsSoon(t, func() error {
err := runner.DB.QueryRowContext(ctx, `
SELECT start_key FROM crdb_internal.ranges_no_leases
WHERE table_name = $1 AND database_name = $2
ORDER BY start_key ASC`, tableName, databaseName).Scan(&startKey)
err := runner.DB.QueryRowContext(ctx, fmt.Sprintf(`
SELECT raw_start_key
FROM [SHOW RANGES FROM TABLE %s.%s WITH KEYS]
ORDER BY raw_start_key ASC`, tree.NameString(databaseName), tree.NameString(tableName))).Scan(&startKey)
if err != nil {
return errors.Wrap(err, "failed to query start_key ")
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/ccl/changefeedccl/changefeed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2763,7 +2763,7 @@ func TestChangefeedRestartMultiNode(t *testing.T) {
sqlDB.Exec(t, `CREATE TABLE test_tab (a INT PRIMARY KEY, b INT UNIQUE NOT NULL)`)
sqlDB.Exec(t, `INSERT INTO test_tab VALUES (0, 0)`)

row := sqlDB.QueryRow(t, `SELECT range_id, lease_holder FROM [SHOW RANGES FROM TABLE test_tab] LIMIT 1`)
row := sqlDB.QueryRow(t, `SELECT range_id, lease_holder FROM [SHOW RANGES FROM TABLE test_tab WITH DETAILS] LIMIT 1`)
var rangeID, leaseHolder int
row.Scan(&rangeID, &leaseHolder)

Expand Down Expand Up @@ -2821,7 +2821,7 @@ func TestChangefeedStopPolicyMultiNode(t *testing.T) {
sqlDB.Exec(t, `CREATE TABLE test_tab (a INT PRIMARY KEY)`)
sqlDB.Exec(t, `INSERT INTO test_tab VALUES (0)`)

row := sqlDB.QueryRow(t, `SELECT range_id, lease_holder FROM [SHOW RANGES FROM TABLE test_tab] LIMIT 1`)
row := sqlDB.QueryRow(t, `SELECT range_id, lease_holder FROM [SHOW RANGES FROM TABLE test_tab WITH DETAILS] LIMIT 1`)
var rangeID, leaseHolder int
row.Scan(&rangeID, &leaseHolder)

Expand Down
2 changes: 2 additions & 0 deletions pkg/ccl/logictestccl/testdata/logic_test/crdb_internal_tenant
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ crdb_internal gossip_liveness table admin NULL NULL
crdb_internal gossip_network table admin NULL NULL
crdb_internal gossip_nodes table admin NULL NULL
crdb_internal index_columns table admin NULL NULL
crdb_internal index_spans table admin NULL NULL
crdb_internal index_usage_statistics table admin NULL NULL
crdb_internal invalid_objects table admin NULL NULL
crdb_internal jobs table admin NULL NULL
Expand Down Expand Up @@ -93,6 +94,7 @@ crdb_internal system_jobs table admin NULL NULL
crdb_internal table_columns table admin NULL NULL
crdb_internal table_indexes table admin NULL NULL
crdb_internal table_row_statistics table admin NULL NULL
crdb_internal table_spans table admin NULL NULL
crdb_internal tables table admin NULL NULL
crdb_internal tenant_usage_details view admin NULL NULL
crdb_internal transaction_contention_events table admin NULL NULL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,28 +257,27 @@ CREATE INDEX t_presplit_idx_member_id ON t_presplit (member_id) USING HASH WITH

skipif config 3node-tenant
query TITTT colnames,retry
SELECT t.name, r.table_id, r.index_name, r.start_pretty, r.end_pretty
FROM crdb_internal.tables t
JOIN crdb_internal.ranges r ON t.table_id = r.table_id
WHERE t.name = 't_presplit'
AND t.state = 'PUBLIC'
AND r.split_enforced_until IS NOT NULL;
SELECT table_name, table_id, index_name, start_key, end_key
FROM [SHOW RANGES FROM DATABASE test WITH INDEXES]
WHERE table_name = 't_presplit'
ORDER BY start_key
----
name table_id index_name start_pretty end_pretty
t_presplit 112 t_presplit_idx_member_id /Table/112/2 /Table/112/2/"new york"/0
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/0 /Table/112/2/"new york"/1
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/1 /Table/112/2/"new york"/2
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/2 /Table/112/2/"new york"/3
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/3 /Table/112/2/"new york"/4
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/4 /Table/112/2/"new york"/5
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/5 /Table/112/2/"new york"/6
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/6 /Table/112/2/"new york"/7
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/7 /Table/112/2/"seattle"/0
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/0 /Table/112/2/"seattle"/1
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/1 /Table/112/2/"seattle"/2
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/2 /Table/112/2/"seattle"/3
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/3 /Table/112/2/"seattle"/4
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/4 /Table/112/2/"seattle"/5
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/5 /Table/112/2/"seattle"/6
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/6 /Table/112/2/"seattle"/7
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/7 /Table/112/3/"new york"/0
table_name table_id index_name start_key end_key
t_presplit 112 t_presplit_pkey /Table/109/11/"seattle"/15 /Table/112/2
t_presplit 112 t_presplit_idx_member_id /Table/112/2 /Table/112/2/"new york"/0
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/0 /Table/112/2/"new york"/1
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/1 /Table/112/2/"new york"/2
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/2 /Table/112/2/"new york"/3
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/3 /Table/112/2/"new york"/4
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/4 /Table/112/2/"new york"/5
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/5 /Table/112/2/"new york"/6
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/6 /Table/112/2/"new york"/7
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"new york"/7 /Table/112/2/"seattle"/0
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/0 /Table/112/2/"seattle"/1
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/1 /Table/112/2/"seattle"/2
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/2 /Table/112/2/"seattle"/3
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/3 /Table/112/2/"seattle"/4
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/4 /Table/112/2/"seattle"/5
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/5 /Table/112/2/"seattle"/6
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/6 /Table/112/2/"seattle"/7
t_presplit 112 t_presplit_idx_member_id /Table/112/2/"seattle"/7 /Table/112/3/"new york"/0
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ ap-southeast-2 23
query TT
SELECT start_key, end_key FROM [SHOW RANGE FROM TABLE regional_by_row_table FOR ROW ('ap-southeast-2', 1)]
----
NULL NULL
<before:/Table/53> <after:/Table/110/5>

query TIIII
SELECT crdb_region, pk, pk2, a, b FROM regional_by_row_table
Expand Down Expand Up @@ -392,12 +392,12 @@ ALTER TABLE regional_by_row_table SPLIT AT VALUES ('ca-central-1', 0), ('us-east
ALTER TABLE regional_by_row_table EXPERIMENTAL_RELOCATE VALUES (ARRAY[1], 'ap-southeast-2', 0), (ARRAY[4], 'ca-central-1', 0), (ARRAY[7], 'us-east-1', 0);

query TTTI colnames,rowsort
SELECT start_key, end_key, replicas, lease_holder FROM [SHOW RANGES FROM INDEX regional_by_row_table@primary]
SELECT start_key, end_key, replicas, lease_holder FROM [SHOW RANGES FROM INDEX regional_by_row_table@primary WITH DETAILS]
----
start_key end_key replicas lease_holder
NULL /"\x80"/0 {1} 1
/"\x80"/0 /"\xc0"/0 {4} 4
/"\xc0"/0 NULL {7} 7
start_key end_key replicas lease_holder
<before:/Table/53> …/"\x80"/0 {1} 1
/"\x80"/0 /"\xc0"/0 {4} 4
/"\xc0"/0 <after:/Table/110/5> {7} 7

statement ok
SET locality_optimized_partitioned_index_scan = false
Expand Down Expand Up @@ -640,12 +640,12 @@ ALTER TABLE child SPLIT AT VALUES ('ca-central-1', 0), ('us-east-1', 0);
ALTER TABLE child EXPERIMENTAL_RELOCATE VALUES (ARRAY[1], 'ap-southeast-2', 0), (ARRAY[4], 'ca-central-1', 0), (ARRAY[7], 'us-east-1', 0);

query TTTI colnames,rowsort
SELECT start_key, end_key, replicas, lease_holder FROM [SHOW RANGES FROM INDEX child@primary]
SELECT start_key, end_key, replicas, lease_holder FROM [SHOW RANGES FROM INDEX child@primary WITH DETAILS]
----
start_key end_key replicas lease_holder
NULL /"\x80"/0 {1} 1
/"\x80"/0 /"\xc0"/0 {4} 4
/"\xc0"/0 NULL {7} 7
start_key end_key replicas lease_holder
<before:/Table/110/5> …/"\x80"/0 {1} 1
/"\x80"/0 /"\xc0"/0 {4} 4
/"\xc0"/0 <after:/Max> {7} 7

statement ok
SET locality_optimized_partitioned_index_scan = false
Expand Down
5 changes: 3 additions & 2 deletions pkg/ccl/logictestccl/testdata/logic_test/tenant_unsupported
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ ALTER TABLE kv SPLIT AT VALUES ('foo')
statement error pq: could not UNSPLIT AT \('foo'\): rpc error: code = Unauthenticated desc = request \[1 AdmUnsplit\] not permitted
ALTER TABLE kv UNSPLIT AT VALUES ('foo')

#UNSPLIT ALL succeeds because there is no split point at this time.
statement ok
ALTER TABLE kv UNSPLIT ALL

Expand All @@ -70,10 +71,10 @@ 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'
ALTER RANGE RELOCATE LEASE TO 2 FOR SELECT range_id FROM [SHOW RANGES FROM TABLE 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'
ALTER RANGE RELOCATE FROM 1 TO 2 FOR SELECT range_id FROM [SHOW RANGES FROM TABLE kv]
6 changes: 3 additions & 3 deletions pkg/ccl/multiregionccl/region_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestMultiRegionDatabaseStats(t *testing.T) {

_, err := db.ExecContext(ctx,
`CREATE DATABASE test PRIMARY REGION "us-west";
use test;
USE test;
CREATE TABLE a(id uuid primary key);`)
require.NoError(t, err)

Expand All @@ -66,8 +66,8 @@ func TestMultiRegionDatabaseStats(t *testing.T) {
testutils.SucceedsWithin(t, func() error {
// Get the list of nodes from ranges table
row := db.QueryRowContext(ctx,
`use test;
with x as (show ranges from table a) select replicas from x;`)
`USE test;
WITH x AS (SHOW RANGES FROM TABLE a) SELECT replicas FROM x;`)
var nodesStr string
err = row.Scan(&nodesStr)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/cli/zip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ table_name NOT IN (
'forward_dependencies',
'gossip_network',
'index_columns',
'index_spans',
'kv_catalog_comments',
'kv_catalog_descriptor',
'kv_catalog_namespace',
Expand All @@ -90,6 +91,7 @@ table_name NOT IN (
'predefined_comments',
'session_trace',
'session_variables',
'table_spans',
'tables',
'cluster_statement_statistics',
'cluster_transaction_statistics',
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/roachtest/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ go_library(
"//pkg/sql",
"//pkg/sql/pgwire/pgcode",
"//pkg/sql/pgwire/pgerror",
"//pkg/sql/sem/tree",
"//pkg/storage/enginepb",
"//pkg/testutils",
"//pkg/testutils/skip",
Expand Down
12 changes: 5 additions & 7 deletions pkg/cmd/roachtest/tests/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -1281,10 +1281,9 @@ func runBackupMVCCRangeTombstones(ctx context.Context, t test.Test, c cluster.Cl
// Check that we actually wrote MVCC range tombstones.
var rangeKeys int
require.NoError(t, conn.QueryRowContext(ctx, `
SELECT sum((crdb_internal.range_stats(start_key)->'range_key_count')::INT)
FROM crdb_internal.ranges
WHERE database_name = 'tpch' AND table_name = 'orders'
`).Scan(&rangeKeys))
SELECT sum((crdb_internal.range_stats(raw_start_key)->'range_key_count')::INT)
FROM [SHOW RANGES FROM TABLE tpch.orders WITH KEYS]
`).Scan(&rangeKeys))
require.NotZero(t, rangeKeys, "no MVCC range tombstones found")

// Fingerprint for restore comparison, and assert that it matches the initial
Expand Down Expand Up @@ -1327,9 +1326,8 @@ func runBackupMVCCRangeTombstones(ctx context.Context, t test.Test, c cluster.Cl
err = conn.QueryRowContext(ctx, `
SELECT range_id, stats::STRING
FROM [
SELECT range_id, crdb_internal.range_stats(start_key) AS stats
FROM crdb_internal.ranges
WHERE database_name = 'tpch'
SELECT range_id, crdb_internal.range_stats(raw_start_key) AS stats
FROM [SHOW RANGES FROM DATABASE tpch WITH KEYS]
]
WHERE (stats->'live_count')::INT != 0 OR (
(stats->'key_count')::INT > 0 AND (stats->'range_key_count')::INT = 0
Expand Down
4 changes: 3 additions & 1 deletion pkg/cmd/roachtest/tests/clearrange.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ func runClearRange(

var startHex string
if err := conn.QueryRow(
`SELECT to_hex(start_key) FROM crdb_internal.ranges_no_leases WHERE database_name = 'bigbank' AND table_name = 'bank' ORDER BY start_key ASC LIMIT 1`,
`SELECT to_hex(raw_start_key)
FROM [SHOW RANGES FROM TABLE bigbank.bank WITH KEYS]
ORDER BY raw_start_key ASC LIMIT 1`,
).Scan(&startHex); err != nil {
t.Fatal(err)
}
Expand Down
Loading

0 comments on commit 6b72f70

Please sign in to comment.