Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: severe regression in ORM query performance {django} #96218

Closed
dikshant opened this issue Jan 30, 2023 · 12 comments · Fixed by #96397
Closed

sql: severe regression in ORM query performance {django} #96218

dikshant opened this issue Jan 30, 2023 · 12 comments · Fixed by #96397
Assignees
Labels
branch-release-23.1 Used to mark GA and release blockers, technical advisories, and bugs for 23.1 C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. C-investigation Further steps needed to qualify. C-label will change. GA-blocker T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions)

Comments

@dikshant
Copy link

dikshant commented Jan 30, 2023

I was investigating ORM query performance in CRDB 22.2.2 as well as latest (g69dd453d0e) and noticed some major regressions for Django's table introspection query when testing on Roachprod.

Steps to repro:

  1. Create two separate 9 node multi region roachprod cluster using 22.2.2 and latest
roachprod create rp-test -n 9 --gce-zones 'us-east4-a','us-east4-a','us-east4-a','us-west2-a','us-west2-a','us-west2-a','us-central1-a','us-central1-a','us-central1-a' && roachprod stage rp-test release v22.2.2 && roachprod start rp-test:1-9
  1. Create lots of tables. (15k)
for i in $(seq 1 15000); do echo "CREATE TABLE t_$i (i INT PRIMARY KEY, j INT);" >> out.sql;
cat out.sql | roachprod sql rp-test
  1. Run the following query in both clusters:
              SELECT
                c.relname,
                CASE
                    WHEN c.relispartition THEN 'p'
                    WHEN c.relkind IN ('m', 'v') THEN 'v'
                    ELSE 't'
                END,
                obj_description(c.oid, 'pg_class')
            FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
            WHERE c.relkind IN ('f', 'm', 'p', 'r', 'v')
                AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                AND pg_catalog.pg_table_is_visible(c.oid);
  1. Observe that latest (g69dd453d0e) takes a lot longer than 22.2.2 and the query plans are different.

Jira issue: CRDB-24010

@dikshant dikshant added C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. C-investigation Further steps needed to qualify. C-label will change. T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions) labels Jan 30, 2023
@ZhouXing19
Copy link
Collaborator

ZhouXing19 commented Jan 30, 2023

Adding more info -- I tried on my single-region gceworker with the latest commit on master (10ef5d9d7a) and it took shorter time for the same number of table and query, and gave different plan:

root@localhost:26257/defaultdb> SELECT VERSION();                                                        
                                                       version
---------------------------------------------------------------------------------------------------------------------
  CockroachDB CCL v23.1.0-alpha.1-1423-g10ef5d9d7a-dirty (x86_64-pc-linux-gnu, built 2023/01/30 22:19:41, go1.19.4)
(1 row)

Time: 9ms total (execution 8ms / network 0ms)

root@localhost:26257/defaultdb> EXPLAIN ANALYZE SELECT t.typname,t.oid FROM pg_catalog.pg_type t         
                             ->    JOIN pg_catalog.pg_namespace n ON (t.typnamespace = n.oid)            
                             ->      WHERE n.nspname  != 'pg_toast'                                      
                             ->           AND                                                            
                             ->        (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM                   
                             -> pg_catalog.pg_class c WHERE c.oid = t.typrelid));                        
                          info
---------------------------------------------------------
  planning time: 557µs
  execution time: 4.2s
  distribution: local
  vectorized: true
  maximum memory usage: 3.6 MiB
  network usage: 0 B (0 messages)
  sql cpu time: 168ms

  • hash join
  │ nodes: n1
  │ actual row count: 82
  │ estimated max memory allocated: 100 KiB
  │ estimated max sql temp disk usage: 0 B
  │ sql cpu time: 247µs
  │ equality: (oid) = (typnamespace)
  │
  ├── • filter
  │   │ nodes: n1
  │   │ actual row count: 5
  │   │ sql cpu time: 8µs
  │   │ filter: nspname != 'pg_toast'
  │   │
  │   └── • virtual table
  │         nodes: n1
  │         actual row count: 5
  │         sql cpu time: 158µs
  │         table: pg_namespace@primary
  │
  └── • filter
      │ nodes: n1
      │ actual row count: 82
      │ sql cpu time: 2ms
      │ filter: (typrelid = 0) OR "?column?"
      │
      └── • distinct
          │ nodes: n1
          │ actual row count: 15,380
          │ estimated max memory allocated: 370 KiB
          │ estimated max sql temp disk usage: 0 B
          │ sql cpu time: 3ms
          │ distinct on: rownum
          │ error on duplicate
          │
          └── • hash join (left outer)
              │ nodes: n1
              │ actual row count: 15,380
              │ estimated max memory allocated: 2.6 MiB
              │ estimated max sql temp disk usage: 0 B
              │ sql cpu time: 24ms
              │ equality: (typrelid) = (oid)
              │
              ├── • ordinality
              │   │ nodes: n1
              │   │ actual row count: 15,380
              │   │ sql cpu time: 187µs
              │   │
              │   └── • virtual table
              │         nodes: n1
              │         actual row count: 15,380
              │         sql cpu time: 30ms
              │         table: pg_type@primary
              │
              └── • render
                  │
                  └── • virtual table
                        nodes: n1
                        actual row count: 30,322
                        sql cpu time: 108ms
                        table: pg_class@primary
(69 rows)

Time: 4.245s total (execution 4.237s / network 0.008s)

and with 22.2.2:

root@localhost:26257/defaultdb> SELECT VERSION();
                                       version
--------------------------------------------------------------------------------------
  CockroachDB CCL v22.2.2 (x86_64-pc-linux-gnu, built 2023/01/30 22:32:32, go1.19.1)
(1 row)


Time: 3ms total (execution 3ms / network 0ms)

root@localhost:26257/defaultdb> EXPLAIN ANALYZE SELECT t.typname,t.oid FROM pg_catalog.pg_type t
   JOIN pg_catalog.pg_namespace n ON (t.typnamespace = n.oid)
     WHERE n.nspname  != 'pg_toast'
          AND
       (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid));
                          info
---------------------------------------------------------
  planning time: 300µs
  execution time: 2.7s
  distribution: local
  vectorized: true
  maximum memory usage: 3.6 MiB
  network usage: 0 B (0 messages)

  • hash join
  │ nodes: n1
  │ actual row count: 78
  │ estimated max memory allocated: 100 KiB
  │ estimated max sql temp disk usage: 0 B
  │ equality: (oid) = (typnamespace)
  │
  ├── • filter
  │   │ nodes: n1
  │   │ actual row count: 5
  │   │ filter: nspname != 'pg_toast'
  │   │
  │   └── • virtual table
  │         nodes: n1
  │         actual row count: 5
  │         table: pg_namespace@primary
  │
  └── • filter
      │ nodes: n1
      │ actual row count: 78
      │ filter: (typrelid = 0) OR "?column?"
      │
      └── • distinct
          │ nodes: n1
          │ actual row count: 15,368
          │ estimated max memory allocated: 370 KiB
          │ estimated max sql temp disk usage: 0 B
          │ distinct on: rownum
          │ error on duplicate
          │
          └── • hash join (left outer)
              │ nodes: n1
              │ actual row count: 15,368
              │ estimated max memory allocated: 2.6 MiB
              │ estimated max sql temp disk usage: 0 B
              │ equality: (typrelid) = (oid)
              │
              ├── • ordinality
              │   │ nodes: n1
              │   │ actual row count: 15,368
              │   │
              │   └── • virtual table
              │         nodes: n1
              │         actual row count: 15,368
              │         table: pg_type@primary
              │
              └── • render
                  │
                  └── • virtual table
                        nodes: n1
                        actual row count: 30,306
                        table: pg_class@primary
(59 rows)


Time: 2.662s total (execution 2.656s / network 0.006s)

@rafiss rafiss self-assigned this Jan 31, 2023
@rafiss
Copy link
Collaborator

rafiss commented Feb 1, 2023

I tried with 6fd5b04 (the commit before #95234 was merged), and observed that the apply join is no longer planned. On a local single node cluster with 0 tables:

root@localhost:26257/defaultdb> explain analyze SELECT
                             ->                 c.relname,
                             ->                 CASE
                             ->                     WHEN c.relispartition THEN 'p'
                             ->                     WHEN c.relkind IN ('m', 'v') THEN 'v'
                             ->                     ELSE 't'
                             ->                 END,
                             ->                 obj_description(c.oid, 'pg_class')
                             ->             FROM pg_catalog.pg_class c
                             ->             JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                             ->             WHERE c.relkind IN ('f', 'm', 'p', 'r', 'v')
                             ->                 AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                             ->                 AND pg_catalog.pg_table_is_visible(c.oid);
                                           info
------------------------------------------------------------------------------------------
  planning time: 5ms
  execution time: 120ms
  distribution: local
  vectorized: true
  maximum memory usage: 1000 KiB
  network usage: 0 B (0 messages)

  • render
  │
  └── • distinct
      │ nodes: n1
      │ actual row count: 3
      │ estimated max memory allocated: 10 KiB
      │ estimated max sql temp disk usage: 0 B
      │ distinct on: rownum
      │
      └── • hash join (right outer)
          │ nodes: n1
          │ actual row count: 3
          │ estimated max memory allocated: 60 KiB
          │ estimated max sql temp disk usage: 0 B
          │ equality: (objoid) = (oid)
          │
          ├── • hash join
          │   │ nodes: n1
          │   │ actual row count: 287
          │   │ estimated max memory allocated: 110 KiB
          │   │ estimated max sql temp disk usage: 0 B
          │   │ equality: (relnamespace) = (oid)
          │   │
          │   ├── • virtual table lookup join
          │   │   │ nodes: n1
          │   │   │ actual row count: 287
          │   │   │ table: pg_class@pg_class_oid_idx
          │   │   │ equality: (classoid) = (oid)
          │   │   │ pred: relname = 'pg_class'
          │   │   │
          │   │   └── • filter
          │   │       │ nodes: n1
          │   │       │ actual row count: 2,191
          │   │       │ filter: objsubid = 0
          │   │       │
          │   │       └── • virtual table
          │   │             nodes: n1
          │   │             actual row count: 2,191
          │   │             table: pg_description@primary
          │   │
          │   └── • filter
          │       │ nodes: n1
          │       │ actual row count: 1
          │       │ filter: nspname = 'pg_catalog'
          │       │
          │       └── • virtual table
          │             nodes: n1
          │             actual row count: 5
          │             table: pg_namespace@primary
          │
          └── • ordinality
              │ nodes: n1
              │ actual row count: 3
              │
              └── • virtual table lookup join
                  │ nodes: n1
                  │ actual row count: 3
                  │ table: pg_namespace@pg_namespace_oid_idx
                  │ equality: (relnamespace) = (oid)
                  │ pred: nspname NOT IN ('pg_catalog', 'pg_toast')
                  │
                  └── • filter
                      │ nodes: n1
                      │ actual row count: 132
                      │ filter: "?column?"
                      │
                      └── • render
                          │
                          └── • distinct
                              │ nodes: n1
                              │ actual row count: 296
                              │ estimated max memory allocated: 60 KiB
                              │ estimated max sql temp disk usage: 0 B
                              │ distinct on: rownum
                              │
                              └── • merge join
                                  │ nodes: n1
                                  │ actual row count: 296
                                  │ estimated max memory allocated: 330 KiB
                                  │ estimated max sql temp disk usage: 0 B
                                  │ equality: (oid) = (oid)
                                  │
                                  ├── • virtual table lookup join
                                  │   │ nodes: n1
                                  │   │ actual row count: 320
                                  │   │ table: pg_namespace@pg_namespace_oid_idx
                                  │   │ equality: (relnamespace) = (oid)
                                  │   │
                                  │   └── • virtual table
                                  │         nodes: n1
                                  │         actual row count: 320
                                  │         estimated max memory allocated: 60 KiB
                                  │         estimated max sql temp disk usage: 0 B
                                  │         table: pg_class@pg_class_oid_idx
                                  │
                                  └── • sort
                                      │ nodes: n1
                                      │ actual row count: 296
                                      │ estimated max memory allocated: 110 KiB
                                      │ estimated max sql temp disk usage: 0 B
                                      │ order: +oid
                                      │
                                      └── • filter
                                          │ nodes: n1
                                          │ actual row count: 296
                                          │ filter: relkind IN ('f', 'm', 'p', 'r', 'v')
                                          │
                                          └── • ordinality
                                              │ nodes: n1
                                              │ actual row count: 320
                                              │
                                              └── • virtual table
                                                    nodes: n1
                                                    actual row count: 320
                                                    table: pg_class@primary
(122 rows)

@rafiss
Copy link
Collaborator

rafiss commented Feb 1, 2023

cc @mgartner if you have any ideas for why #95234 would lead to this regression.

@mgartner
Copy link
Collaborator

mgartner commented Feb 1, 2023

I'll take a look. Nothing immediately stands out to me - that PR should have only affected queries that were erroring with could not decorrelate subquery. It shouldn't have changed query plans for any successful queries. Is it possible that another PR in the same bors batch is the cilrpit? Like #93218?

@rafiss
Copy link
Collaborator

rafiss commented Feb 1, 2023

I tried with commit 2f81142 (from #93218), and that also does not have the apply join.

  planning time: 5ms
  execution time: 117ms
  distribution: local
  vectorized: true
  maximum memory usage: 1000 KiB
  network usage: 0 B (0 messages)

  • render
  │
  └── • distinct
      │ nodes: n1
      │ actual row count: 3
      │ estimated max memory allocated: 10 KiB
      │ estimated max sql temp disk usage: 0 B
      │ distinct on: rownum
      │
      └── • hash join (right outer)
          │ nodes: n1
          │ actual row count: 3
          │ estimated max memory allocated: 60 KiB
          │ estimated max sql temp disk usage: 0 B
          │ equality: (objoid) = (oid)
          │
          ├── • hash join
          │   │ nodes: n1
          │   │ actual row count: 287
          │   │ estimated max memory allocated: 110 KiB
          │   │ estimated max sql temp disk usage: 0 B
          │   │ equality: (relnamespace) = (oid)
          │   │
          │   ├── • virtual table lookup join
          │   │   │ nodes: n1
          │   │   │ actual row count: 287
          │   │   │ table: pg_class@pg_class_oid_idx
          │   │   │ equality: (classoid) = (oid)
          │   │   │ pred: relname = 'pg_class'
          │   │   │
          │   │   └── • filter
          │   │       │ nodes: n1
          │   │       │ actual row count: 2,191
          │   │       │ filter: objsubid = 0
          │   │       │
          │   │       └── • virtual table
          │   │             nodes: n1
          │   │             actual row count: 2,191
          │   │             table: pg_description@primary
          │   │
          │   └── • filter
          │       │ nodes: n1
          │       │ actual row count: 1
          │       │ filter: nspname = 'pg_catalog'
          │       │
          │       └── • virtual table
          │             nodes: n1
          │             actual row count: 5
          │             table: pg_namespace@primary
          │
          └── • ordinality
              │ nodes: n1
              │ actual row count: 3
              │
              └── • virtual table lookup join
                  │ nodes: n1
                  │ actual row count: 3
                  │ table: pg_namespace@pg_namespace_oid_idx
                  │ equality: (relnamespace) = (oid)
                  │ pred: nspname NOT IN ('pg_catalog', 'pg_toast')
                  │
                  └── • filter
                      │ nodes: n1
                      │ actual row count: 132
                      │ filter: "?column?"
                      │
                      └── • render
                          │
                          └── • distinct
                              │ nodes: n1
                              │ actual row count: 296
                              │ estimated max memory allocated: 60 KiB
                              │ estimated max sql temp disk usage: 0 B
                              │ distinct on: rownum
                              │
                              └── • merge join
                                  │ nodes: n1
                                  │ actual row count: 296
                                  │ estimated max memory allocated: 330 KiB
                                  │ estimated max sql temp disk usage: 0 B
                                  │ equality: (oid) = (oid)
                                  │
                                  ├── • virtual table lookup join
                                  │   │ nodes: n1
                                  │   │ actual row count: 320
                                  │   │ table: pg_namespace@pg_namespace_oid_idx
                                  │   │ equality: (relnamespace) = (oid)
                                  │   │
                                  │   └── • virtual table
                                  │         nodes: n1
                                  │         actual row count: 320
                                  │         estimated max memory allocated: 60 KiB
                                  │         estimated max sql temp disk usage: 0 B
                                  │         table: pg_class@pg_class_oid_idx
                                  │
                                  └── • sort
                                      │ nodes: n1
                                      │ actual row count: 296
                                      │ estimated max memory allocated: 110 KiB
                                      │ estimated max sql temp disk usage: 0 B
                                      │ order: +oid
                                      │
                                      └── • filter
                                          │ nodes: n1
                                          │ actual row count: 296
                                          │ filter: relkind IN ('f', 'm', 'p', 'r', 'v')
                                          │
                                          └── • ordinality
                                              │ nodes: n1
                                              │ actual row count: 320
                                              │
                                              └── • virtual table
                                                    nodes: n1
                                                    actual row count: 320
                                                    table: pg_class@primary
(122 rows)

Time: 124ms total (execution 123ms / network 1ms)

@mgartner
Copy link
Collaborator

mgartner commented Feb 1, 2023

On 61233f0, the commit in #95234, there is also no apply-join. I'll bisect to hone in on the commit that introduced the apply-join.

@rafiss
Copy link
Collaborator

rafiss commented Feb 1, 2023

My bad. I thought I had tested 61233f0, which was why I tagged you. Thanks for taking on the bisect!

@mgartner
Copy link
Collaborator

mgartner commented Feb 1, 2023

This is the commit where the apply-join gets added: c2c6239.

The pg_table_is_visible builtin, now defined as an "internal UDF", is strict, meaning that if it's input is NULL then it results directly in NULL without being called. In c2c6239 we switched from some special tree.Routine execution logic for this behavior (which was broken in some cases), to wrapping all strict UDFs in a CASE expression. Unfortunately, this CASE expression prevents decorrelation of the inlined subquery that represents the UDF.

One workaround is to mark the builtin (and the ones similar to it) as NOT strict. I believe the behavior of the pg_table_is_visible builtin will be the same. It's defined as:

SELECT n.nspname = any current_schemas(true)
FROM pg_catalog.pg_class c
INNER LOOKUP JOIN pg_catalog.pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid=$1 LIMIT 1

The WHERE c.oid=$1 clause should never be truthy if $1 is NULL, so this query should always return zero rows when presented with NULL. When the last query in a UDF results in zero rows, NULL is returned. In order words, if we mark it as NOT strict, it should return NULL when presented with a NULL argument, just like it would if it were marked strict. The only different being that the query will actually be executed when presented with NULL, whereas it wouldn't if marked as strict. But calling pg_table_is_visible builtin with NULL arguments is an edge case that we probably shouldn't worry about optimizing for.

I'll go ahead and put up a PR.

@rafiss
Copy link
Collaborator

rafiss commented Feb 1, 2023

Nice find! I suppose we should make the same change for the other pg_*_is_visible builtins, since those are likely to be used in the same way.

we switched from some special tree.Routine execution logic for this behavior (which was broken in some cases), to wrapping all strict UDFs in a CASE expression. Unfortunately, this CASE expression prevents decorrelation of the inlined subquery that represents the UDF.

is there a concern that preventing decorrelation would be bad for other performance of other functions?

@DrewKimball
Copy link
Collaborator

DrewKimball commented Feb 2, 2023

@mgartner do you think it would be possible to have a rule that will remove the CaseExpr in a case like this? I'm going to see if I can hack one together.

DrewKimball added a commit to DrewKimball/cockroach that referenced this issue Feb 4, 2023
This patch adds a normalization rule `SimplifyLeakproofBooleanCase`
that replaces a leak-proof boolean CASE statement with an
equivalent boolean expression built using `AND` and `OR` operators.
This is possible when the following conditions are satisfied:
  1. The CASE statement returns a boolean value.
  2. The CASE statement is leak-proof.
  3. The CASE condition is a *constant* boolean value (True, False, NULL).
  4. Each WHEN branch returns a *constant* boolean value.

Example:
```
CASE WHEN a THEN False WHEN b THEN True ELSE c END
=>
((a IS NOT True) AND (b OR c))
```
See the `ConvertCaseToCondition` comment for details.

This is useful for strict UDFs, which implement the argument NULL
check using a CASE statement.

Informs cockroachdb#96218

Release note: None
@mgartner
Copy link
Collaborator

mgartner commented Feb 7, 2023

@mgartner do you think it would be possible to have a rule that will remove the CaseExpr in a case like this? I'm going to see if I can hack one together.

Yes, that seems valuable, but I don't think it helps in this case because these builtins are stable, non-leakproof functions.

@DrewKimball
Copy link
Collaborator

We can still hoist stable functions a lot of the time, right? After function hoisting, the CASE becomes leakproof (at least in this case)

@rafiss rafiss added GA-blocker branch-release-23.1 Used to mark GA and release blockers, technical advisories, and bugs for 23.1 labels Feb 23, 2023
craig bot pushed a commit that referenced this issue Feb 24, 2023
88061: clisqlshell: new infrastructure for describe commands r=rafiss,ZhouXing19 a=knz

Fixes #95320.
Epic: CRDB-23454

The SQL shell (`cockroach sql`, `demo`) now
supports the client-side commands `\l`, `\dn`, `\d`, `\di`, `\dm`,
`\ds`, `\dt`, `\dv`, `\dC`, `\dT`, `\dd`, `\dg`, `\du`, `\df` and `\dd` in a
way similar to `psql`, including the modifier flags `S` and `+`, for
convenience for users migrating from PostgreSQL.

A notable difference is that when a pattern argument is specified, it
should use the SQL "LIKE" syntax (with `%` representing the wildcard
character) instead of PostgreSQL's glob-like syntax (with `*`
representing wildcards).

Issues discovered:

- [x] join bug:  #88096
- [x] semi-join exec error #91012
- [x] `pg_table_is_visible` should return true when given a valid index OID and the index is valid.  #88097
- [x] missing pkey column in pg_index:  #88106
- [x] missing stored columns in pg_index: #88107 
- [x] pg_statistic_ext has problems #88108
- [x] missing view def on materialized views  #88109
- [x] missing schema comments: #88098
- [x] missing pronamespace for functions #94952
- [x] broken pg_function_is_visible for UDFs #94953
- [x] generated columns #92545
- [x] indnullsnotdistinct #92583
- [x] missing prokind #95288
- [x] missing function comments in obj_description #95292
- [x] planning regression #95633

96397: builtins: mark some pg_.* builtins as strict r=DrewKimball a=mgartner

Builtins defined using the UDF `Body` field will be wrapped in a `CASE`
expression if they are strict, i.e., `CalledOnNullInput=false`. When the
builtin is inlined, the `CASE` expression prevents decorrelation,
leaving a slow apply-join in the query plan. This caused a significant
regression of some ORM introspection queries.

Some of these builtins have filters that cause the SQL body to return no rows
if any of the arguments is NULL. In this case, the builtin will have the same
behavior whether or not it is defined as being strict. We can safely optimize
these builtins by setting `CalledOnNullInput=true`.

The following conditions are sufficient to prove that `CalledOnNullInput` can
be set for a builtin function with a SQL body:

  1. The WHERE clause of the SQL query *null-rejects* every argument of the
     builtin. Operators like `=` and `<` *null-reject* their operands because
     they filter rows for which an operand is NULL.

  2. The arguments are not used elsewhere in the query. This is not strictly
     necessary, but simplifies the proof because it ensures NULL arguments will
     not cause the builtin to error.

Examples of SQL statements that would allow `CalledOnNullInput` to be set:
```
SELECT * FROM tab WHERE $1=1 AND $2='two';

SELECT * FROM tab WHERE $1 > 0;
```

Fixes #96218
Fixes #95569

Epic: None

Release note: None


97585: cli: don't scope TLS client certs to a specific tenant by default r=stevendanna a=knz

Epic: CRDB-23559
Fixes: #97584

This commit changes the default for `--tenant-scope` from "only the system tenant" to "cert valid for all tenants".

Note that the scoping is generally useful for security, and it is used in CockroachCloud. However, CockroachCloud does not use our CLI code to generate certs and sets its cert tenant scopes on its own.

Given that our CLI code is provided for convenience and developer productivity, and we don't expect certs generated here to be used in multi-tenant deployments where tenants are adversarial to each other, defaulting to certs that are valid on every tenant is a good choice.

Release note: None


Co-authored-by: Raphael 'kena' Poss <[email protected]>
Co-authored-by: Marcus Gartner <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
branch-release-23.1 Used to mark GA and release blockers, technical advisories, and bugs for 23.1 C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. C-investigation Further steps needed to qualify. C-label will change. GA-blocker T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants