Skip to content

Commit a8567ec

Browse files
committed
sql: introduce sql_stats_canary_window storage parameter
This commit introduces a new table-level storage parameter `sql_stats_canary_window` that can be specified in CREATE TABLE or ALTER TABLE statements. The canary window specifies how long newly collected statistics will remain in "canary" state before being promoted to stable, enabling gradual rollout of new statistics to mitigate performance regressions. When set to a positive duration, this parameter enables canary statistics rollout for the table. During the canary window, the cluster setting sql.stats.canary_fraction (introduced in the next commit) determines what percentage of queries use the new canary statistics versus the previous stable statistics, providing a buffer period for observation and intervention. Note that this commit adds only syntax support and storage for the parameter. The actual canary statistics selection logic will be implemented in subsequent commits. Release note (sql change): A new table storage parameter `sql_stats_canary_window` has been introduced to enable gradual rollout of newly collected table statistics. It takes a duration string as the value. When set with a positive duration, the new statistics remain in a "canary" state for the specified duration before being promoted to stable. This allows for controlled exposure and intervention opportunities before statistics are fully deployed across all queries.
1 parent 3b2811c commit a8567ec

File tree

23 files changed

+315
-153
lines changed

23 files changed

+315
-153
lines changed

pkg/ccl/logictestccl/tests/3node-tenant/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/ccl/logictestccl/tests/local-read-committed/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/ccl/logictestccl/tests/local-repeatable-read/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/cli/testdata/doctor/test_recreate_zipdir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ SELECT crdb_internal.unsafe_upsert_namespace_entry(100, 0, 'public', 101, true);
1414
SELECT crdb_internal.unsafe_upsert_descriptor(102, decode('125a0a08706f73746772657310661a300a0b0a0561646d696e100218020a0d0a067075626c696310801018000a0a0a04726f6f74100218021204726f6f741803220028013a0c0a067075626c69631202086740004a005a0210007000', 'hex'), true);
1515
SELECT crdb_internal.unsafe_upsert_namespace_entry(0, 0, 'postgres', 102, true);
1616
SELECT crdb_internal.unsafe_upsert_descriptor(103, decode('2249086612067075626c6963186722310a0b0a0561646d696e100218020a0d0a067075626c696310840418000a0a0a04726f6f7410021802120561646d696e18032a00300140004a007000', 'hex'), true);
17-
SELECT crdb_internal.unsafe_upsert_descriptor(104, decode('0a8d030a01741868206428013a0042280a016910011a0e0801104018002a0030005014600020013000680070007800800100880100980100423c0a05726f77696410021a0e0801104018002a0030005014600020002a0e756e697175655f726f77696428293001680070007800800100880100980100480352780a06745f706b6579100118012205726f7769642a0169300240004a10080010001a00200028003000380040005a0070017a0408002000800100880100900104980101a20106080012001800a80100b20100ba0100c00100c801d88aed86ddb7c5e517d00101e00100e9010000000000000000f20100f8010060026a210a0b0a0561646d696e100218020a0a0a04726f6f74100218021204726f6f741803800101880103980100b2011b0a077072696d61727910001a01691a05726f776964200120022801b80101c20100e80100f2010408001200f801008002009202009a0200b20200b80200c00265c80200e00200800300880302a80300b00300d00300d80300e00300f80300880400980400a00400a80400b00400', 'hex'), true);
17+
SELECT crdb_internal.unsafe_upsert_descriptor(104, decode('0a90030a01741868206428013a0042280a016910011a0e0801104018002a0030005014600020013000680070007800800100880100980100423c0a05726f77696410021a0e0801104018002a0030005014600020002a0e756e697175655f726f77696428293001680070007800800100880100980100480352780a06745f706b6579100118012205726f7769642a0169300240004a10080010001a00200028003000380040005a0070017a0408002000800100880100900104980101a20106080012001800a80100b20100ba0100c00100c801d88aed86ddb7c5e517d00101e00100e9010000000000000000f20100f8010060026a210a0b0a0561646d696e100218020a0a0a04726f6f74100218021204726f6f741803800101880103980100b2011b0a077072696d61727910001a01691a05726f776964200120022801b80101c20100e80100f2010408001200f801008002009202009a0200b20200b80200c00265c80200e00200800300880302a80300b00300d00300d80300e00300f80300880400980400a00400a80400b00400b80400', 'hex'), true);
1818
COMMIT;

pkg/cli/testdata/doctor/test_recreate_zipdir-json

Lines changed: 6 additions & 6 deletions
Large diffs are not rendered by default.

pkg/sql/catalog/bootstrap/testdata/testdata

Lines changed: 134 additions & 134 deletions
Large diffs are not rendered by default.

pkg/sql/catalog/catpb/catalog.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ const (
104104
// RBRUsingConstraintTableSettingName is the name of the REGIONAL BY ROW region
105105
// column inference setting.
106106
RBRUsingConstraintTableSettingName = "infer_rbr_region_col_using_constraint"
107+
108+
// CanaryStatsWindowSettingName is the name of the stats canary window table setting.
109+
CanaryStatsWindowSettingName = "sql_stats_canary_window"
107110
)
108111

109112
// AutoStatsCollectionEnabled indicates if automatic statistics collection is

pkg/sql/catalog/descpb/structured.proto

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,15 @@ message TableDescriptor {
13781378
optional uint32 rbr_using_constraint = 70 [(gogoproto.nullable) = false,
13791379
(gogoproto.customname) = "RBRUsingConstraint", (gogoproto.casttype) = "ConstraintID"];
13801380

1381-
// Next ID: 71
1381+
// StatsCanaryWindow specifies the duration for which newly collected statistics
1382+
// remain in "canary" state before being promoted to stable. During this
1383+
// window, the cluster setting sql.stats.canary_fraction determines what
1384+
// percentage of queries use the new canary statistics vs. the previous stable
1385+
// statistics. This provides a buffer period for observation and intervention
1386+
// before new statistics are fully deployed to all queries throughout the
1387+
// cluster.
1388+
optional int64 stats_canary_window = 71 [(gogoproto.nullable) = false, (gogoproto.casttype)="time.Duration"];
1389+
// Next ID: 72
13821390
}
13831391

13841392
// ExternalRowData indicates that the row data for this object is stored outside

pkg/sql/catalog/tabledesc/structured.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2604,6 +2604,9 @@ func (desc *wrapper) GetStorageParams(spaceBetweenEqual bool) ([]string, error)
26042604
if desc.IsSchemaLocked() {
26052605
appendStorageParam(`schema_locked`, `true`)
26062606
}
2607+
if desc.StatsCanaryWindow != 0 {
2608+
appendStorageParam(`sql_stats_canary_window`, fmt.Sprintf(`'%s'`, desc.StatsCanaryWindow.String()))
2609+
}
26072610
if usingFK := desc.GetRegionalByRowUsingConstraint(); usingFK != descpb.ConstraintID(0) {
26082611
// NOTE: when validating the descriptor, we check that the referenced
26092612
// constraint exists, so this should never fail.

pkg/sql/catalog/tabledesc/ttl.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func ValidateRowLevelTTL(ttl *catpb.RowLevelTTL) error {
5555
}
5656
}
5757
if ttl.RowStatsPollInterval != 0 {
58-
if err := ValidateTTLRowStatsPollInterval("ttl_row_stats_poll_interval", ttl.RowStatsPollInterval); err != nil {
58+
if err := ValidateNotNegativeInterval("ttl_row_stats_poll_interval", ttl.RowStatsPollInterval); err != nil {
5959
return err
6060
}
6161
}
@@ -154,9 +154,8 @@ func ValidateTTLCronExpr(key string, str string) error {
154154
return nil
155155
}
156156

157-
// ValidateTTLRowStatsPollInterval validates the automatic statistics field
158-
// of TTL.
159-
func ValidateTTLRowStatsPollInterval(key string, val time.Duration) error {
157+
// ValidateNotNegativeInterval validates the provided interval is not negative.
158+
func ValidateNotNegativeInterval(key string, val time.Duration) error {
160159
if val < 0 {
161160
return pgerror.Newf(
162161
pgcode.InvalidParameterValue,

0 commit comments

Comments
 (0)