LGTM-стек #2: postgres_exporter — метрики PostgreSQL для Prometheus

postgres_exporter — отдельный процесс рядом с node_exporter: тот снимает метрики хоста, этот подключается к PostgreSQL как обычный клиент и превращает системные представления (pg_stat_*) в формат Prometheus. ...

September 27, 2026 · llexa

DBA #10: transaction ID wraparound — почему PostgreSQL сам себя вакуумит

32-битный счётчик транзакций (XID) циклический: оборот — раз в 4 млрд, а 2 млрд — граница, после которой без vacuum’а старые строки рискуют оказаться “из будущего”. Отсюда суета вокруг wraparound. autovacuum_freeze_max_age (по умолчанию 200 млн) форсирует anti-wraparound autovacuum на старых таблицах, даже при выключенном autovacuum в конфиге — единственное исключение из настройки. Кто горит — видно запросом: SELECT c.oid::regclass AS table_name, greatest(age(c.relfrozenxid), age(t.relfrozenxid)) AS age FROM pg_class c LEFT JOIN pg_class t ON c.reltoastrelid = t.oid WHERE c.relkind IN ('r', 'm'); Warning в логах (“must be vacuumed within N transactions”) — за 40 млн до порога, запас ещё есть. Проигнорировать — база уходит в read-only при <3 млн до wraparound, выход один - вакуум от суперпользователя. ...

September 23, 2026 · llexa

DBA на минималках #9: WAL и archive_command для PITR

Point-in-time recovery в PostgreSQL строится на непрерывном архиве WAL-сегментов — без него pg_basebackup даёт снимок на момент бэкапа, и всё, что случилось после, потеряно безвозвратно. Минимум в postgresql.conf: wal_level = replica archive_mode = on archive_command = 'test ! -f /archive/%f && cp %p /archive/%f' %p — путь к сегменту, %f — имя файла. test ! -f не даёт молча перезаписать уже сохранённый сегмент. С PostgreSQL 12 recovery_target_time и restore_command идут прямо в postgresql.conf, режим восстановления включает файл recovery.signal в PGDATA — отдельного recovery.conf больше нет. restore_command — обратный путь: читает сегменты из архива в pg_wal. ...

September 16, 2026 · llexa

pgAudit: детальный аудит-лог для PostgreSQL

Штатный log_statement = all пишет все запросы плоским текстом без структуры — для аудита по требованиям безопасности (кто читал таблицу с ПДн, кто менял схему) этого недостаточно. pgAudit добавляет классифицированный лог, который проще парсить и фильтровать. Подключение: shared_preload_libraries = 'pgaudit' (требует перезапуска инстанса, не reload). Дальше в postgresql.conf или на уровне роли: ALTER SYSTEM SET pgaudit.log = 'read, write, ddl'; SELECT pg_reload_conf(); Классы read/write логируют SELECT и модифицирующие запросы отдельно от ddl (CREATE/ALTER/DROP) — можно включить только то, что реально нужно для аудита, не заливая лог избыточным SELECT-шумом на нагруженной базе. ...

September 16, 2026 · llexa

Patroni: switchover vs failover — в чём разница

Patroni управляет ролью лидера кластера через DCS (etcd/consul). Разница между switchover и failover — не терминология, а кто принимает решение. Switchover — плановая смена лидера: patronictl switchover --leader node1 --candidate node2 Старый лидер останавливается, реплика догоняет WAL, простой минимален. Failover — реакция на исчезновение лидера. Patroni сам выбирает нового из реплик по отставанию WAL и приоритету, без гарантии нулевого лага. patronictl failover — та же логика вручную, без ожидания реального отказа. ...

September 15, 2026 · llexa

DBA на минималках #8: VACUUM FULL и pg_repack

Обычный autovacuum помечает мёртвые строки как свободное место, но не возвращает его файловой системе — таблица физически не уменьшается. VACUUM FULL пересобирает таблицу с нуля и реально сжимает файл на диске, но берёт ACCESS EXCLUSIVE lock на всё время работы — для большой таблицы это часы простоя. pg_repack (расширение + CLI) делает то же без долгой блокировки: создаёт копию таблицы, применяет накопленные за время копирования изменения через триггер, и подменяет таблицу коротким ACCESS EXCLUSIVE только на финальный swap — секунды, а не часы. ...

September 9, 2026 · llexa

dasha: дашборд здоровья кластера PostgreSQL

Обычно здоровье кластера PostgreSQL собирают вручную из pg_stat_statements, pg_stat_activity и логов VACUUM. dasha (github.com/dbulashev/dasha) сводит это в один веб-дашборд: медленные запросы, неэффективные индексы, блокировки, размер таблиц и прогресс VACUUM — с итоговым Health Score по формуле с весами. cd deploy/compose docker compose up -d # веб-интерфейс: http://localhost:3000 Бэкенд на Go 1.26, фронт на Vue 3.5, поддерживает PostgreSQL 14-18, аутентификацию через OIDC и RBAC, снимки состояния кластера для истории. Есть MCP-коннектор — можно подключить ИИ-ассистента прямо к метрикам кластера, и интеграция с Yandex Cloud для поиска по логам. ...

September 5, 2026 · llexa

pgbouncer: пул соединений перед PostgreSQL

PostgreSQL на каждое соединение форкает отдельный backend-процесс — при сотнях коротких подключений (веб-запросы, serverless-функции) это съедает память и CPU на сам факт подключения, ещё до первого запроса. pgbouncer держит пул готовых соединений к базе и раздаёт их клиентам. [databases] mydb = host=127.0.0.1 port=5432 dbname=mydb [pgbouncer] listen_port = 6432 pool_mode = transaction max_client_conn = 1000 default_pool_size = 20 Режимы pool_mode: session — за клиентом до disconnect, совместимо со всем (advisory locks, prepared statements) transaction — на время транзакции, самый экономный, но ломает session-level фичи statement — на один запрос, только для read-only трафика psql -h 127.0.0.1 -p 6432 -U app mydb # подключение через pgbouncer, не напрямую в базу #postgresql #dba ...

September 2, 2026 · llexa

pgbouncer: пул соединений перед PostgreSQL

PostgreSQL на каждое соединение форкает отдельный backend-процесс — при сотнях коротких подключений (веб-запросы, serverless-функции) это съедает память и CPU на сам факт подключения, ещё до первого запроса. pgbouncer держит пул готовых соединений к базе и раздаёт их клиентам. [databases] mydb = host=127.0.0.1 port=5432 dbname=mydb [pgbouncer] listen_port = 6432 pool_mode = transaction max_client_conn = 1000 default_pool_size = 20 Режимы pool_mode: session — за клиентом до disconnect, совместимо со всем (advisory locks, prepared statements) transaction — на время транзакции, самый экономный, но ломает session-level фичи statement — на один запрос, только для read-only трафика psql -h 127.0.0.1 -p 6432 -U app mydb # подключение через pgbouncer, не напрямую в базу #postgresql #dba ...

August 4, 2026 · llexa

pg_dump, pg_restore, pg_basebackup: три инструмента, а не один

Три утилиты, три разных уровня бэкапа — путаница возникает, когда пытаются взаимозаменить логический и физический бэкап там, где это не работает. pg_dump -Fc mydb > mydb.dump # логический дамп одной БД pg_restore -d mydb_new --clean --if-exists mydb.dump pg_basebackup -D /backup/base -Ft -z -P -U replicator # физическая копия кластера pg_dump — логический: SQL-представление данных, можно восстановить одну таблицу из дампа целой БД, версии источника и назначения могут отличаться. pg_basebackup — физический: побайтовая копия PGDATA, восстанавливается только целиком, зато на её основе строится репликация и point-in-time recovery через WAL. Для одной таблицы — pg_dump -t, для кластера с минимальным RPO — pg_basebackup плюс архив WAL. ...

July 29, 2026 · llexa