Skip to content

Commit 04e58b8

Browse files
committed
kvserver: allowlist spanconfig updates to bypass range-size backpressure
This commit modifies `backpressurableSpans` to exclude the `system.span_configurations` table by splitting the original span into two ranges that create a gap around the `system.span_configurations` table. This allows spanconfig updates to bypass backpressure entirely, preventing the catch-22 deadlock. The corresponding test is then modified to assert the new behaviour (i.e., span config updates are not blocked). We only allowlist the \`system.span_configurations\` table because protected timestamp cleanup requires two writes: one to remove the PTS record from \`system.protected_ts_records\` and another to translate that removal into updated span configuration in \`system.span_configurations\`. When backpressure blocks the spanconfig update, the reconciliation process cannot complete, preventing protected timestamp cleanup and creating a deadlock where the system cannot clean up its own protected timestamps. Other system tables lack this circular dependency and are not excluded. Fixes: #146982 Release note: None
1 parent b95d17c commit 04e58b8

File tree

3 files changed

+23
-16
lines changed

3 files changed

+23
-16
lines changed

pkg/keys/constants.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,10 @@ var (
374374
NamespaceTableMin = SystemSQLCodec.TablePrefix(NamespaceTableID)
375375
// NamespaceTableMax is the end key of system.namespace.
376376
NamespaceTableMax = SystemSQLCodec.TablePrefix(NamespaceTableID + 1)
377+
// SpanConfigTableMin is the start key of system.span_configurations.
378+
SpanConfigTableMin = SystemSQLCodec.TablePrefix(SpanConfigurationsTableID)
379+
// SpanConfigTableMax is the end key of system.span_configurations.
380+
SpanConfigTableMax = SystemSQLCodec.TablePrefix(SpanConfigurationsTableID + 1)
377381

378382
// 4. Non-system tenant SQL keys
379383
//

pkg/kv/kvserver/client_replica_backpressure_test.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -342,17 +342,18 @@ func TestBackpressureNotAppliedWhenReducingRangeSize(t *testing.T) {
342342
})
343343
}
344344

345-
// TestSpanConfigUpdatesBlockedByRangeSizeBackpressureOnDefaultRanges
346-
// verifies that spanconfig updates are blocked by backpressure when the
347-
// `system.span_configurations` table range becomes full, recreating the issue.
345+
// TestSpanConfigUpdatesDoNotGetBlockByRangeSizeBackpressureOnDefaultRanges
346+
// verifies that spanconfig updates do not block by backpressure when the
347+
// `system.span_configurations` table range becomes full, showing the allowlist
348+
// is working.
348349
//
349350
// Test strategy:
350351
// 1. Configure `system.span_configurations` table range to be a small size (8 KiB).
351352
// 2. Write many large spanconfig records (2 KiB each) to fill up the range.
352-
// 3. Verify spanconfig updates fail due to backpressure when the range is full,
353-
// 4. This test recreates the scenario where spanconfig updates are blocked by
353+
// 3. Verify spanconfig updates do not fail due to backpressure when the range is full,
354+
// 4. This test recreates the scenario where spanconfig updates do not fail due to
354355
// backpressure.
355-
func TestSpanConfigUpdatesBlockedByRangeSizeBackpressureOnDefaultRanges(t *testing.T) {
356+
func TestSpanConfigUpdatesDoNotGetBlockByRangeSizeBackpressureOnDefaultRanges(t *testing.T) {
356357
defer leaktest.AfterTest(t)()
357358
defer log.Scope(t).Close(t)
358359

@@ -438,8 +439,8 @@ func TestSpanConfigUpdatesBlockedByRangeSizeBackpressureOnDefaultRanges(t *testi
438439
if repl != nil {
439440
conf, err := repl.LoadSpanConfig(ctx)
440441
require.NoError(t, err)
441-
t.Logf("current range config - RangeMaxBytes: %d bytes (%d MiB), "+
442-
"RangeMinBytes: %d bytes (%d MiB)",
442+
t.Logf("current range config - RangeMaxBytes: %d bytes (%s), "+
443+
"RangeMinBytes: %d bytes (%s)",
443444
conf.RangeMaxBytes, humanize.Bytes(uint64(conf.RangeMaxBytes)),
444445
conf.RangeMinBytes, humanize.Bytes(uint64(conf.RangeMinBytes)))
445446

@@ -517,9 +518,9 @@ func TestSpanConfigUpdatesBlockedByRangeSizeBackpressureOnDefaultRanges(t *testi
517518
}
518519
}
519520

520-
// Assert that the operation failed due to backpressure.
521-
require.Error(t, err,
522-
"expected span config writes to fail due to backpressure, but they succeeded")
521+
// Assert that the operation does not fail due to backpressure.
522+
require.NoError(t, err,
523+
"expected span config writes to not fail due to backpressure, but they did")
523524

524525
systemSpanConfigurationsTableSpanMVCCStats := roachpb.Span{
525526
Key: keys.SystemSQLCodec.TablePrefix(keys.SpanConfigurationsTableID),
@@ -566,7 +567,7 @@ func TestSpanConfigUpdatesBlockedByRangeSizeBackpressureOnDefaultRanges(t *testi
566567
[]spanconfig.Target{scratchTarget}, []spanconfig.Record{smallSpanconfigRecord},
567568
hlc.MinTimestamp, hlc.MaxTimestamp)
568569

569-
require.Error(t, smallSpanconfigRecordWriteErr,
570-
"expected smallSpanconfigRecord write to fail due to backpressure")
570+
require.NoError(t, smallSpanconfigRecordWriteErr,
571+
"expected smallSpanconfigRecord write to not fail due to backpressure")
571572

572573
}

pkg/kv/kvserver/replica_backpressure.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,11 @@ var backpressureByteTolerance = settings.RegisterByteSizeSetting(
8888
// to be backpressured.
8989
var backpressurableSpans = []roachpb.Span{
9090
{Key: keys.TimeseriesPrefix, EndKey: keys.TimeseriesKeyMax},
91-
// Backpressure from the end of the system config forward instead of
92-
// over all table data to avoid backpressuring unsplittable ranges.
93-
{Key: keys.SystemConfigTableDataMax, EndKey: keys.TableDataMax},
91+
// Exclude the span_configurations table to avoid
92+
// catch-22 situations where protected timestamp updates or garbage
93+
// collection TTL updates are blocked by backpressure.
94+
{Key: keys.SystemConfigTableDataMax, EndKey: keys.SpanConfigTableMin},
95+
{Key: keys.SpanConfigTableMax, EndKey: keys.TableDataMax},
9496
}
9597

9698
// canBackpressureBatch returns whether the provided BatchRequest is eligible

0 commit comments

Comments
 (0)