goon/alembic/versions/20260921_0045_autovacuum_big_tables.py
goon-foss d3713d64b9 fix: source-stats z probki scen, nizsze progi autovacuum
source-stats liczyl flagi tag/obsada dla 2,5 mln par serwis-scena, czyli ok. 5 mln
losowych odczytow indeksow; trwal 22-32 min i przekroczyl limit (GOON-V). Teraz
flagi z probki 3000 scen na serwis (stala, po md5), liczba scen, swiezosc i
miniatury dalej dokladnie. 1 min 51 s, gwiazdki bez zmian, procenty +-2 pkt.

Autovacuum na domyslnych 20% nie ruszal duzych tabel od tygodni (scene_performers
11% stron widocznych, statystyki scenes z 25.08). Migracja 0045 daje 2% dla
szesciu najwiekszych tabel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 12:00:11 +02:00

52 lines
1.7 KiB
Python

"""Nizsze progi autovacuum i autoanalyze dla duzych tabel.
Domyslne progi (20% zmienionych wierszy do vacuum, 10% do analyze) przy 4-23 mln wierszy
znacza, ze autovacuum prawie nie rusza tych tabel: 2026-09-21 scene_performers mialo
ostatni przebieg 27.07 i 11% stron oznaczonych jako widoczne, playback_sources 24%,
a statystyki scenes byly z 25.08. Skutek: index-only scan i tak czyta sterte (w
source-stats 94% odczytow scene_performers szlo na dysk, job przekroczyl 30 min,
Sentry GOON-V), a planista myli sie przy szukaniu po tytule (GOON-73).
2% daje przebieg co ~100 tys. zmian. Autovacuum jest dlawiony (cost_delay 2 ms), wiec
czesciej znaczy krocej, nie ciezej. SET na parametrach tabeli bierze tylko
SHARE UPDATE EXCLUSIVE, nie blokuje odczytow ani zapisow.
Revision ID: 0045_autovacuum_big_tables
Revises: 0044_playback_eporner_thumb_idx
Create Date: 2026-09-21
"""
from __future__ import annotations
from alembic import op
revision = "0045_autovacuum_big_tables"
down_revision: str | None = "0044_playback_eporner_thumb_idx"
branch_labels = None
depends_on = None
_TABLES = (
"scenes",
"playback_sources",
"scene_performers",
"scene_tags",
"scene_external_refs",
"external_records",
)
_PARAMS = (
"autovacuum_vacuum_scale_factor",
"autovacuum_vacuum_insert_scale_factor",
"autovacuum_analyze_scale_factor",
)
def upgrade() -> None:
op.execute("SET LOCAL lock_timeout = '5s'")
for table in _TABLES:
params = ", ".join(f"{p} = 0.02" for p in _PARAMS)
op.execute(f"ALTER TABLE {table} SET ({params})")
def downgrade() -> None:
op.execute("SET LOCAL lock_timeout = '5s'")
for table in _TABLES:
op.execute(f"ALTER TABLE {table} RESET ({', '.join(_PARAMS)})")