Skip to content

Commit 67b1251

Browse files
authored
Merge pull request #160604 from yuzefovich/backport25.3.7-rc-160051
release-25.3.7-rc: sql: add distsql_prevent_partitioning_soft_limited_scans
2 parents 310e203 + 9451ee0 commit 67b1251

File tree

10 files changed

+202
-8
lines changed

10 files changed

+202
-8
lines changed

pkg/sql/distsql_physical_planner.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,14 +2435,11 @@ func (dsp *DistSQLPlanner) planTableReaders(
24352435
ignoreMisplannedRanges bool
24362436
err error
24372437
)
2438+
sd := planCtx.ExtendedEvalCtx.SessionData()
24382439
if planCtx.isLocal {
24392440
spanPartitions, parallelizeLocal = dsp.maybeParallelizeLocalScans(ctx, planCtx, info)
2440-
} else if info.post.Limit == 0 {
2441-
// No hard limit - plan all table readers where their data live. Note
2442-
// that we're ignoring soft limits for now since the TableReader will
2443-
// still read too eagerly in the soft limit case. To prevent this we'll
2444-
// need a new mechanism on the execution side to modulate table reads.
2445-
// TODO(yuzefovich): add that mechanism.
2441+
} else if info.post.Limit == 0 && (info.spec.LimitHint == 0 || !sd.DistSQLPreventPartitioningSoftLimitedScans) {
2442+
// No limits - plan all table readers where their data live.
24462443
bound := PartitionSpansBoundDefault
24472444
if info.desc.NumFamilies() > 1 {
24482445
bound = PartitionSpansBoundCFWithinRow
@@ -2452,7 +2449,7 @@ func (dsp *DistSQLPlanner) planTableReaders(
24522449
return err
24532450
}
24542451
} else {
2455-
// If the scan has a hard limit, use a single TableReader to avoid
2452+
// If the scan has a hard or soft limit, use a single TableReader to avoid
24562453
// reading more rows than necessary.
24572454
sqlInstanceID, err := dsp.getInstanceIDForScan(ctx, planCtx, info.spans, info.reverse)
24582455
if err != nil {

pkg/sql/exec_util.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4309,6 +4309,10 @@ func (m *sessionDataMutator) SetUseImprovedRoutineDepsTriggersAndComputedCols(va
43094309
m.data.UseImprovedRoutineDepsTriggersAndComputedCols = val
43104310
}
43114311

4312+
func (m *sessionDataMutator) SetDistSQLPreventPartitioningSoftLimitedScans(val bool) {
4313+
m.data.DistSQLPreventPartitioningSoftLimitedScans = val
4314+
}
4315+
43124316
// Utility functions related to scrubbing sensitive information on SQL Stats.
43134317

43144318
// quantizeCounts ensures that the Count field in the

pkg/sql/logictest/testdata/logic_test/information_schema

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3982,6 +3982,7 @@ distribute_join_row_count_threshold 1000
39823982
distribute_scan_row_count_threshold 10000
39833983
distribute_sort_row_count_threshold 1000
39843984
distsql_plan_gateway_bias 2
3985+
distsql_prevent_partitioning_soft_limited_scans off
39853986
distsql_use_reduced_leaf_write_sets on
39863987
enable_auto_rehoming off
39873988
enable_create_stats_using_extremes on

pkg/sql/logictest/testdata/logic_test/pg_catalog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,6 +2986,7 @@ distribute_scan_row_count_threshold 10000
29862986
distribute_sort_row_count_threshold 1000 NULL NULL NULL string
29872987
distsql off NULL NULL NULL string
29882988
distsql_plan_gateway_bias 2 NULL NULL NULL string
2989+
distsql_prevent_partitioning_soft_limited_scans off NULL NULL NULL string
29892990
distsql_use_reduced_leaf_write_sets on NULL NULL NULL string
29902991
enable_auto_rehoming off NULL NULL NULL string
29912992
enable_create_stats_using_extremes on NULL NULL NULL string
@@ -3231,6 +3232,7 @@ distribute_scan_row_count_threshold 10000
32313232
distribute_sort_row_count_threshold 1000 NULL user NULL 1000 1000
32323233
distsql off NULL user NULL off off
32333234
distsql_plan_gateway_bias 2 NULL user NULL 2 2
3235+
distsql_prevent_partitioning_soft_limited_scans off NULL user NULL off off
32343236
distsql_use_reduced_leaf_write_sets on NULL user NULL on on
32353237
enable_auto_rehoming off NULL user NULL off off
32363238
enable_create_stats_using_extremes on NULL user NULL on on
@@ -3463,6 +3465,7 @@ distribute_scan_row_count_threshold NULL NULL
34633465
distribute_sort_row_count_threshold NULL NULL NULL NULL NULL
34643466
distsql NULL NULL NULL NULL NULL
34653467
distsql_plan_gateway_bias NULL NULL NULL NULL NULL
3468+
distsql_prevent_partitioning_soft_limited_scans NULL NULL NULL NULL NULL
34663469
distsql_use_reduced_leaf_write_sets NULL NULL NULL NULL NULL
34673470
distsql_workmem NULL NULL NULL NULL NULL
34683471
enable_auto_rehoming NULL NULL NULL NULL NULL

pkg/sql/logictest/testdata/logic_test/show_source

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ distribute_scan_row_count_threshold 10000
9090
distribute_sort_row_count_threshold 1000
9191
distsql off
9292
distsql_plan_gateway_bias 2
93+
distsql_prevent_partitioning_soft_limited_scans off
9394
distsql_use_reduced_leaf_write_sets on
9495
enable_auto_rehoming off
9596
enable_create_stats_using_extremes on
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# LogicTest: 5node
2+
3+
# Regression test for lazy reading of soft-limited scans.
4+
5+
statement ok
6+
CREATE TABLE abc (a INT PRIMARY KEY, b INT, c STRING, FAMILY (a, b, c))
7+
8+
statement ok
9+
INSERT INTO abc SELECT i, i % 10, repeat('c', 16384) FROM generate_series(0, 99) AS s(i)
10+
11+
statement ok
12+
ALTER TABLE abc SPLIT AT SELECT i * 20 FROM generate_series(1, 4) AS s(i)
13+
14+
retry
15+
statement ok
16+
ALTER TABLE abc EXPERIMENTAL_RELOCATE
17+
SELECT ARRAY[i+1], i * 20 FROM generate_series(0, 4) as s(i)
18+
19+
# Verify data placement.
20+
query TTTI colnames,rowsort
21+
SELECT start_key, end_key, replicas, lease_holder from [SHOW RANGES FROM TABLE abc WITH DETAILS]
22+
ORDER BY 1
23+
----
24+
start_key end_key replicas lease_holder
25+
<before:/Table/72> …/1/20 {1} 1
26+
…/1/20 …/1/40 {2} 2
27+
…/1/40 …/1/60 {3} 3
28+
…/1/60 …/1/80 {4} 4
29+
…/1/80 <after:/Max> {5} 5
30+
31+
statement ok
32+
ANALYZE abc
33+
34+
query T
35+
EXPLAIN ANALYZE (DISTSQL) SELECT a FROM abc WHERE a >= 0 AND a < 100 ORDER BY a LIMIT 10
36+
----
37+
planning time: 10µs
38+
execution time: 100µs
39+
distribution: <hidden>
40+
vectorized: <hidden>
41+
plan type: custom
42+
rows decoded from KV: 10 (80 B, 20 KVs, 10 gRPC calls)
43+
maximum memory usage: <hidden>
44+
DistSQL network usage: <hidden>
45+
regions: <hidden>
46+
isolation level: serializable
47+
priority: normal
48+
quality of service: regular
49+
·
50+
• scan
51+
sql nodes: <hidden>
52+
kv nodes: <hidden>
53+
regions: <hidden>
54+
actual row count: 10
55+
KV time: 0µs
56+
KV rows decoded: 10
57+
KV pairs read: 20
58+
KV bytes read: 80 B
59+
KV gRPC calls: 10
60+
estimated max memory allocated: 0 B
61+
estimated row count: 10 (10% of the table; stats collected <hidden> ago)
62+
table: abc@abc_pkey
63+
spans: [/0 - /99]
64+
limit: 10
65+
·
66+
Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJyMktFq20wQhe__pxjmKgEFr_7elIVCG9ulpnYcZJNSWhNGq4mzWNKquyNsY_xYfYE-WVnJTtrSQPdCaM5-e-asRgcM30rUuBhPx8MlELzP5jOg3MCnD-NsDBcEX1ulXvEbUJfw7mb0pBhIlbqEeTYaZ3D9GQimk9lkCanCBGtX8A1VHFB_wRRXCTbeGQ7B-SgdOmBS7FCrBG3dtBLlVYLGeUZ9QLFSMmpcUl5yxlSwH0TjgoVs2dlSbt5Sbu6bDe8xwaEr26oOGggTXDQUXwfqapCqeG5qKyt9to93ELsHDXXal57X1kVeOEgvia1Yg_rxPZwQtw1QsHEFF_rJJ98LB_BMhYbXCq57dZ3dDsFQWYZnsiHrz-T_UZvdDYcQhBswrq0FLngnA1vLpQY1eAaYNy8BFe2g4sr5PVBZOkMSo_UpchLzyAFcK00rGiLfXeEspApXxwT78vTtg9CaUae_DGsyQq2Oyb_PK-PQuDrwb6N6qZP6o9NVelwlyMWa-58kuNYbvvXOdGxfzjujTig4SL-b9sWkPm8F8UxVH3-V4EPptve2QI3qtK7-8jgvjAdoHeLFFo9u29ku902M9UBl4ARntOERC_vK1jaINajFt3w8_vczAAD__xOuBa4=
67+
68+
query T
69+
EXPLAIN ANALYZE (DISTSQL) SELECT a FROM abc WHERE a >= 0 AND a < 100 AND b != 5 ORDER BY a LIMIT 10
70+
----
71+
planning time: 10µs
72+
execution time: 100µs
73+
distribution: <hidden>
74+
vectorized: <hidden>
75+
plan type: custom
76+
rows decoded from KV: 60 (480 B, 120 KVs, 60 gRPC calls)
77+
maximum memory usage: <hidden>
78+
DistSQL network usage: <hidden>
79+
regions: <hidden>
80+
isolation level: serializable
81+
priority: normal
82+
quality of service: regular
83+
·
84+
• limit
85+
│ count: 10
86+
87+
└── • filter
88+
│ sql nodes: <hidden>
89+
│ regions: <hidden>
90+
│ actual row count: 50
91+
│ execution time: 0µs
92+
│ estimated row count: 90
93+
│ filter: b != 5
94+
95+
└── • scan
96+
sql nodes: <hidden>
97+
kv nodes: <hidden>
98+
regions: <hidden>
99+
actual row count: 60
100+
KV time: 0µs
101+
KV rows decoded: 60
102+
KV pairs read: 120
103+
KV bytes read: 480 B
104+
KV gRPC calls: 60
105+
estimated max memory allocated: 0 B
106+
estimated row count: 12 - 100 (100% of the table; stats collected <hidden> ago)
107+
table: abc@abc_pkey
108+
spans: [/0 - /99]
109+
·
110+
Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJzsV9tu4zYQfe9XTOcpQWWIlC-xCSyQruNFjeaycIwtijZY0NKsV4gkqiRdxw38Wf2BflkhKfJa2ti1AhQIsNaDAQ6HwzlnzpD0I5o_IhR4O7ocDacg4d3k5grkzIdffhpNRnByIuH3BWNtegPsFH68voDS4gNn7PTJNoPv30D3FG4mF6MJvP0VJFyOr8ZT4AwdTFRA1zImg-I35Oighw620cEOOtjFOwdTrXwyRunM5TFfMA4eUDAHwyRd2Mx856CvNKF4RBvaiFDgVM4impAMSLvZRgFZGUb5NnLmn8uZ_zG9pxU6OFTRIk6MAOnADB28TWU2clnL9bKVP3-AbFMjIOHFUNM8VJmPJWMLkw1jEsD--ds8uailgYB8FVAggHuFdbayZECTDAQMevC2sM4n74fgyygyXzxTGerS08u4uPowHIKxlIKvFomFE3qwbpjYUwEsB1g4EN3vcojlA8QUK70CGUXKlzZLjeVZzKT1P5MBtbDpwgrI_HMIpYF7eLd2sBg-UW6snBMKvlWj8QUKtnYOL9O7MLKkSbvdao0Ku4BzL5ePEGJ8Pe2jg5dhHNpCO_RA_sKGKqmy_99Y2E4sXg1LdyeWLxCUDkhTUM3_nP-Ad-tnAF-rlkpdXpPkTZbXOf_f8bVr-Hi1WPzwnuIv6imPtdzOsamaNxVvUqdNU_VeZVP1Kli8wzXnvUhzHdZye0fNNdec16ROG82dvUrNnVWwtA_XXPtFmuuxlts_aq655tpN6rTRXP9Vaq5fwdI5XHOdF2muz1ouZ0fRNRddp0mhNqIbvErRDZq8vidkUpUYqiDZtROr7dTi2fuWgjkV72GjFtqn91r5uW8xvMkD5YaAjC1meTEYJ-WUsZpkvPnzsB2J743kVSLx7UjdeiRvf05NkmrvDdXZHYnXI3WawpN5VTAhu1T6HiJpKfFXGymV9qUMbVVkARnSoYzCv-TXCiyX5arT5FP4Z34KsK258igoJ_tFI5bTMRkj5xWP7qHa3qaoV6eou5ei3m6yvXqk3pHsGtlndYrO9lLU3012ux6pfyS7Rna_TtFg_4nEdrPd-eqY3H_ifot0D7Lr6VOklh_DAAWyp6_1zE_5YbZAzk12R95-Vsucr-kqzW64TzIy5OCVvKcLsqTjMAmNDX0UVi9ovf7u3wAAAP__qpTOfA==
111+
112+
statement ok
113+
SET distsql_prevent_partitioning_soft_limited_scans = on
114+
115+
query T
116+
EXPLAIN ANALYZE (DISTSQL) SELECT a FROM abc WHERE a >= 0 AND a < 100 AND b != 5 ORDER BY a LIMIT 10
117+
----
118+
planning time: 10µs
119+
execution time: 100µs
120+
distribution: <hidden>
121+
vectorized: <hidden>
122+
plan type: generic, reused
123+
rows decoded from KV: 12 (96 B, 24 KVs, 12 gRPC calls)
124+
maximum memory usage: <hidden>
125+
DistSQL network usage: <hidden>
126+
regions: <hidden>
127+
isolation level: serializable
128+
priority: normal
129+
quality of service: regular
130+
·
131+
• limit
132+
│ count: 10
133+
134+
└── • filter
135+
│ sql nodes: <hidden>
136+
│ regions: <hidden>
137+
│ actual row count: 10
138+
│ execution time: 0µs
139+
│ estimated row count: 90
140+
│ filter: b != 5
141+
142+
└── • scan
143+
sql nodes: <hidden>
144+
kv nodes: <hidden>
145+
regions: <hidden>
146+
actual row count: 12
147+
KV time: 0µs
148+
KV rows decoded: 12
149+
KV pairs read: 24
150+
KV bytes read: 96 B
151+
KV gRPC calls: 12
152+
estimated max memory allocated: 0 B
153+
estimated row count: 12 - 100 (100% of the table; stats collected <hidden> ago)
154+
table: abc@abc_pkey
155+
spans: [/0 - /99]
156+
·
157+
Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJyUUt1q20wQvf-eYr65imGDV-4P7UIgje1Q0zgOikkprQmr1cRZImnV3RGxCX6svkCfrKxkt0lo0lYXgjl79sycPXOH4WuBCs_HJ-PhHDQcp7Mp6MzAx_fjdAx7exq-NFK-oAOQPXh3OoIdYiCRsrfFMvj_AF71YJaOxikcfQINJ5PpZA6JRIGVy-lUlxRQfcYEFwJr7wyF4HyE7lrCJF-hkgJtVTcc4YVA4zyhukO2XBAqnOusoJR0Tr4fhXNibYtWVmfmUGfmsr6hNQocuqIpq6BAC8hQ4HmtY9WX-_1ExqsfLiB2DQqqpCs9La2LJKbAHcS2JAXy-7ewpbjbADkZl1OuIBl0aLZmCuBJ5wrevoajDl2mZ0MwuijCL2atrd8xBy9R4PRiOITAVINxTcWwRyvu24p7CmTrsCMQ3TxFKPUKSiqdX4MuCmc0x9FkO0Wm2VxTANdw3bCCyG8t7IBkgIuNwK7cvnlgvSRUyb2QJiNUciP-PqdjWzB58v3kYUgdruBw0O6LUmpyOn-DAmdxmsPIPrGl5W5taEWmYeuqhzn82ZV80tXgkavkX1ylFGpXBXrg6alO8lGn_WSzEEj5krqVD67xhs68My23K2etUAvkFLg7TbpiUu2OAnvS5c9Q7islzyoNnlNaCLwq3O2lzVGh3H77v_ntPowX9DLEJzq_dret7HxdR4NXuggkcKpvaERMvrSVDWwNKvYNbTb__QgAAP__DIZi7A==
158+
159+
statement ok
160+
RESET distsql_prevent_partitioning_soft_limited_scans

pkg/sql/opt/exec/execbuilder/tests/5node/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ go_test(
1212
"//build/toolchains:is_heavy": {"test.Pool": "heavy"},
1313
"//conditions:default": {"test.Pool": "large"},
1414
}),
15-
shard_count = 28,
15+
shard_count = 29,
1616
tags = ["cpu:3"],
1717
deps = [
1818
"//pkg/base",

pkg/sql/opt/exec/execbuilder/tests/5node/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/sessiondatapb/local_only_session_data.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,10 @@ message LocalOnlySessionData {
743743
// triggers or computed columns. The fix applies at routine creation time and
744744
// prevents unnecessary column dependencies from being recorded.
745745
bool use_improved_routine_deps_triggers_and_computed_cols = 196;
746+
// DistSQLPreventPartitioningSoftLimitedScans, when true, prevents the distsql
747+
// physical planner from partitioning scans with soft limits into multiple
748+
// TableReaders. When true, this matches the behavior for hard limits.
749+
bool distsql_prevent_partitioning_soft_limited_scans = 197 [(gogoproto.customname) = "DistSQLPreventPartitioningSoftLimitedScans"];
746750

747751
///////////////////////////////////////////////////////////////////////////
748752
// WARNING: consider whether a session parameter you're adding needs to //

pkg/sql/vars.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4389,6 +4389,23 @@ var varGen = map[string]sessionVar{
43894389
},
43904390
GlobalDefault: globalFalse,
43914391
},
4392+
4393+
// CockroachDB extension.
4394+
`distsql_prevent_partitioning_soft_limited_scans`: {
4395+
GetStringVal: makePostgresBoolGetStringValFn(`distsql_prevent_partitioning_soft_limited_scans`),
4396+
Set: func(_ context.Context, m sessionDataMutator, s string) error {
4397+
b, err := paramparse.ParseBoolVar("distsql_prevent_partitioning_soft_limited_scans", s)
4398+
if err != nil {
4399+
return err
4400+
}
4401+
m.SetDistSQLPreventPartitioningSoftLimitedScans(b)
4402+
return nil
4403+
},
4404+
Get: func(evalCtx *extendedEvalContext, _ *kv.Txn) (string, error) {
4405+
return formatBoolAsPostgresSetting(evalCtx.SessionData().DistSQLPreventPartitioningSoftLimitedScans), nil
4406+
},
4407+
GlobalDefault: globalFalse,
4408+
},
43924409
}
43934410

43944411
func ReplicationModeFromString(s string) (sessiondatapb.ReplicationMode, error) {

0 commit comments

Comments
 (0)