Skip to content

PostgreSQL — алерт когда таблица bloat-ится

Таблица занимает 200 ГБ из них 150 ГБ — bloat (dead tuples). VACUUM FULL требует exclusive lock, autovacuum не справляется. Заметишь когда index-scan станет seq-scan.

Рецепт

bash
#!/usr/bin/env bash
# /etc/cron.d/pg-bloat
# 0 3 * * * postgres /opt/pg-bloat.sh

DB=${PGDATABASE:-postgres}
THRESH_PCT=${THRESH_PCT:-30}          # alert above 30 % bloat

BLOATED=$(psql -At -d "$DB" -c "
  SELECT relname || ':' || ROUND(100.0 * n_dead_tup / GREATEST(n_live_tup, 1)) AS bloat_pct
  FROM pg_stat_user_tables
  WHERE n_live_tup > 100000
    AND 100.0 * n_dead_tup / GREATEST(n_live_tup, 1) > $THRESH_PCT
  ORDER BY n_dead_tup DESC
  LIMIT 5;
")

if [ -n "$BLOATED" ]; then
  COUNT=$(echo "$BLOATED" | wc -l)
  EXAMPLES=$(echo "$BLOATED" | tr '\n' ',')
  curl -fsS "$HEARTBEAT_URL" --data-urlencode "tables_bloated=$COUNT,examples=$EXAMPLES"
  exit 2
fi
echo "OK (no tables > ${THRESH_PCT}% bloat)"

То же самое в Enterno.io

Заверните в Enterno heartbeat — увидите тренд «bloat растёт на 1 % в день» и сможете spланировать pg_repack за неделю до OOM.

Настроить HTTP monitor → ← Все рецепты

Похожие рецепты

Нужно ловить момент, когда реплика начала отставать от мастера больше чем на 10 секунд.