Add default analyze_interval for partitioned tables
What & why
Partitioning strategies defaulted analyze_interval to nil, so the post-rotation ANALYZE in PartitionManager#run_analyze_on_partitioned_table never fired for any partitioned table that did not explicitly opt in. Only Ci::Partitionable set it (3.days).
Root-cause class: nil default → newly-rotated partitions never get an ANALYZE on rotation → they run with no/stale planner statistics until autovacuum eventually catches up → stale-stats bad query plans. This was a contributing factor in INC-13566 (the security_findings-specific fix is #624174 / !252297).
Change
Introduces a shared Gitlab::Database::Partitioning::BaseStrategy::DEFAULT_ANALYZE_INTERVAL = 1.week and uses it as the default analyze_interval: on all three strategy families:
SlidingListStrategy(andCiSlidingListStrategy)IntRangeStrategyTime::BaseStrategy(monthly / weekly / daily)
Any partitioned table lacking an explicit value now gets periodic post-rotation stats. Per-model overrides still win — Ci::Partitionable stays 3.days, and Security::Finding will be 1.day via #624174.
Ops kill-switch
Because this flips ~50 previously-never-analyzed partitioned tables to a periodic ANALYZE at once, it ships with an ops feature flag analyze_partitioned_tables_on_rotation (default enabled). If the recurring ANALYZE ever causes unexpected database load, disabling the flag immediately stops all post-rotation ANALYZE (a single global off-switch), reverting to prior behaviour without a revert/deploy. Gated in run_analyze_on_partitioned_table.
Why 1.week (conservative)
The post-rotation ANALYZE is issued against the parent table, and ANALYZE on a partitioned parent recurses through the entire partition hierarchy, not just the newly-created leaf. For very large tables (e.g. security_findings, hundreds of millions of rows across many partitions) a full-hierarchy ANALYZE is non-trivial recurring load. A weekly cadence bounds that cost while still ensuring rotated partitions get stats. It is throttled per-interval by last_analyzed_at_within_interval?, so each table analyzes at most once per week by default.
Feature flag history
The original feature flag database_analyze_on_partitioned_tables (introduced with the feature in !130599 (merged), #423135 (closed)) was removed in !132219 (merged) (16.x). The post-rotation ANALYZE path is therefore always-on / no longer gated, which is precisely why this MR reintroduces a dedicated ops kill-switch for it.
Follow-up
Make the post-rotation ANALYZE target only the newly-created leaf partition rather than the parent. That removes the full-hierarchy cost concern and would allow a tighter default interval. Tracked as a follow-up to this MR.
Tests
DEFAULT_ANALYZE_INTERVALfallback expectations on the sliding-list, ci-sliding-list, int-range, monthly and weekly strategy specs.partition_manager_spec/partitioning_spec"when analyze_interval is not set" cases now assert the default runs a throttledANALYZE, plus a new context asserting the ops flag disabled stops the ANALYZE entirely.- Verified locally:
partition_manager_spec+partitioning_spec→ 65 examples, 0 failures (2 pending are unrelated single-DB skips). Rubocop clean.