Когда приходишь на аудит СУБД к разным компаниям, картина удивительно похожа: одни и те же проблемы, одни и те же причины. Меня зовут Андрей, я DBA в группе поддержки системного ПО Центра экспертизы по комплексному сервису К2Тех, сертифицированный эксперт Postgres Pro. В этой статье представлен ТОП-10 ошибок, с которыми мы встречаемся чаще всего. Я разберу, чем они опасны, почему возникают, и как их можно решить. Скорее всего, многие пункты покажутся вам до боли знакомыми:
1. Отсутствующие или битые резервные копии PostgreSQL
Проблема
Резервное копирование PostgreSQL — это первое, на что обращаем внимание при работе с базой данных, даже если решаем смежную задачу. Здесь два типа проблем: бэкапов нет совсем или восстановиться из них не получится. Второй случай не менее опасен самой уверенностью, что копии делаются — а при восстановлении СУБД выясняется, что последний рабочий бэкап повреждён или выполнялся месяц назад.
Риски
Классика «мёртвых» бэкапов: задачи в cron работали, но стоит кому‑то поправить пути или параметры — копирование тихо останавливается. Никаких алертов. Через месяц выясняется, что бэкапов нет. И даже при использовании систем резервного копирования бывает схожая история, например, со слотами репликации: некоторые инструменты создают их для получения WAL и при сбоях могут оставлять зависшими:
postgres=# SELECT slot_name, slot_type, active, pg_size_pretty( pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) ) AS retained_wal FROM pg_replication_slots WHERE active = false; slot_name | slot_type | active | retained_wal -----------+-----------+--------+-------------- backup | physical | f | 99 MB (1 строка)
Если не настроен мониторинг PostgreSQL, раздел на диске незаметно переполняется и база встаёт.
Причины
Причины этого банальны. В больших компаниях систему иногда выводят в прод раньше, чем успевают согласовать место хранения, настроить агент, закрепить регламент, выполнить тестовые восстановления резервных копий и настроить мониторинг бэкапов. В меньших командах это чаще вопрос дисциплины: пока всё работает, сделаем потом.
Примеры
Пример 1: недавно при аудите СУБД в крупной организации обнаружили резервные копии, которые получали обычным копированием файлов PostgreSQL. Снаружи всё выглядело нормально: копии создавались, файлы лежали на месте. Но когда попробовали восстановиться из такого бэкапа, база начала сыпать ошибками. Дальше раскопали повреждённые системные индексы, некорректную цепочку WAL и неконсистентные данные. То есть резервная копия PostgreSQL была, а вот восстановиться из неё было невозможно.
Пример 2: во время миграции 1С‑системы крупного ритейлера всплыла другая проблема. Используемый инструмент резервного копирования втихую создавал «битые» инкрементальные бэкапы. Хорошо, что это выяснилось во время проверки, а не после сбоя, когда резервная копия внезапно понадобилась бы по‑настоящему.
Пример 3: резервное копирование важной банковской БД в несколько терабайт осуществляется посредством бэкапов ВМ, восстанавливаться из которых никто не пробовал. В дашборде системы резервного копирования отображалось, будто бэкап sql занимал всего пять минут, на деле же он прерывался ядром ОС из‑за нехватки памяти.
Решение
Разговор про бэкапы в конечном счёте всегда сводится к одному вопросу: пробовали ли вы из них восстанавливаться. Инструмент резервного копирования должен корректно работать с PostgreSQL, уметь снять консистентный снимок работающей базы и корректно обработать WAL. Проверка средствами самого инструмента полезна, но не заменяет полноценное восстановление.
Тот же pg_probackup умеет проверять резервную копию на целостность и находить повреждённые файлы — это помогает отловить часть проблем заранее: как выявить само повреждение, так и не перезаписать валидный бэкап битыми данными при ротации, чтобы иметь возможность их восстановления. Данный инструмент проверяет контрольные суммы по умолчанию при попытке сделать бэкап, и выводит ошибку, если с ними что‑то не так. Подобную проверку можно вызвать и вручную для существующих бэкапов:
pg_probackup-15 validate --instance=main -B /var/lib/postgresql/backups INFO: Validate backups of the instance 'main' INFO: Validating backup TIFWKT INFO: Backup TIFWKT data files are valid INFO: Backup TIFWKT WAL segments are valid INFO: Validating backup TIFWJK INFO: Backup TIFWJK data files are valid INFO: Backup TIFWJK WAL segments are valid INFO: All backups are valid
Но ответ на главный вопрос — поднимется база или нет — появляется только после реального тестового восстановления PostgreSQL.
2. Избыточные привилегии пользователей
Аудит информационной безопасности СУБД — это отдельная важная задача, которую выполняют специалисты ИБ до выхода системы в промышленную эксплуатацию. Она затрагивает такие темы, как, например, ротация паролей, сканеры и патчи уязвимостей, RLS, маскирование и шифрование данных. В этом и следующем пункте мы рассмотрим две базовые вещи, которые тем не менее часто замечаем на практике со стороны DBA.
Проблема
Приложение под суперпользователем — одна из частых вещей, которые мы видим на аудите PostgreSQL. Пока всё штатно, проблем с суперпользователем не видно. Они начинаются, когда обнаруживаются уязвимости, а потом оказывается, что в одном инстансе живут сразу несколько систем.
Риски
Если одно приложение взломали или оно само работает с багами, права суперпользователя автоматически открывают доступ к другим базам, ролям, служебным объектам. По сути, компрометация одной системы становится проблемой всего инстанса.
Причины
Иногда никто уже не помнит, почему именно выдали такие права. Система работает, жалоб нет — трогать страшно. А иногда, что удивительно, так рекомендует вендор.
Примеры
Несколько раз встречали ситуацию, когда приложение годами работало под суперпользователем просто потому, что так было настроено ещё на этапе внедрения. Никто не проверял, какие привилегии ему реально нужны сейчас. Когда начинали разбираться, выяснялось, что большая часть прав давно не используется.
Решение
Нужно посмотреть, какие операции приложение выполняет на самом деле, собрать минимальный набор привилегий и постепенно убрать лишнее (здесь и далее — подобные значимые изменения необходимо предварительно тестировать вне продуктивной среды). Отдельно стоит проверить роли для установки и обновления.
SELECT rolname, rolsuper, rolcreaterole, rolcreatedb
FROM pg_roles
WHERE rolsuper = true;
Во многих системах их потом используют для повседневной работы, хотя изначально они для этого не предназначались.
3. Сетевой доступ: широкий по умолчанию
Проблема
В pg_hba.conf регулярно встречаются правила, разрешающие подключения практически с любого IP, а в работе СУБД, особенно с кластерной обвязкой, нередко не используется SSL/TLS.
Риски
Такая конфигурация резко увеличивает поверхность атаки: база оказывается доступна из любой точки сети, а иногда и из интернета. Широкие правила усложняют обнаружение аномальной активности и разграничение легитимных подключений, потому что в логах теряется ценная информация о том, откуда реально приходят запросы. Если при этом компрометированы учётные данные или само приложение, злоумышленник получает доступ к базе с любого хоста, а отсутствие TLS дополнительно повышает риск перехвата данных и проблем с выполнением требований ИБ.
Причины
Обычно это тянется ещё с внедрения: систему нужно поднять быстро, поэтому доступ открывают максимально широко, а шифрование и более точные ограничения откладывают на потом. До этого «потом» дело доходит не всегда, тем более что сертификаты нужно выпускать, продлевать и ставить на мониторинг, а старые драйверы или приложения не всегда корректно работают с новыми SSL‑настройками.
Решение
На практике это лечится довольно легко: сначала смотрят, кто реально подключается к базе, затем закрывают всё лишнее, ограничивают доступ по адресам и ролям:
# что часто находим в pg_hba.conf - доступ для любых пользователей и IP # и устаревший и небезопасный вариант хэша паролей host all all 0.0.0.0/0 md5 # что должно быть: конкретный пользователь и IP, или хотя бы подсеть # scram-sha-256 - более секьюрный режим, вероятно потребуется пересоздать пароли пользователей host all app_user 10.10.1.0/24 scram-sha-256
а для крупных контуров по возможности выносят аутентификацию в LDAP или Active Directory, чтобы не поддерживать такие правила вручную.
4. Логирование PostgreSQL
Проблема
С логированием PostgreSQL ситуация похожая. Кажется, что оно есть почти у всех, но на аудитах регулярно выясняется, что нужные данные просто не сохранились. Например, логи уходят в syslog и хранятся сутки. Потом происходит инцидент, а через пару дней разбираться уже не с чем.
Риски
В такой ситуации даже понятный сбой расследуется дольше просто потому, что у команды не остаётся фактуры для разбора.
Причина
Обычно это тянется ещё с этапа быстрого старта: логи включают по минимальному шаблону, чтобы «хоть что‑то было», параметры ротации и retention выставляются на глаз, а детальная настройка уровней логирования откладывается до первых серьёзных проблем. В результате в критический момент в журнале оказывается или слишком мало информации (только общие подключения без контекста запроса), или настолько много шума, что нужные события теряются.
Решение
На практике это лечится довольно просто: сначала определяют, какие события действительно важны для разбора инцидентов. Например, подключения, DDL, ошибки и контрольные точки, блокировки, временные файлы, долгая работа автовакуум:
log_connections = on log_disconnections = on log_statement = 'ddl' log_error_verbosity = verbose log_min_messages = WARNING log_min_error_statement = error log_checkpoints = on log_lock_waits = on log_temp_files = 524288 log_autovacuum_min_duration = 5000
Затем настраивают корректную ротацию и централизованный сбор с разумным сроком хранения. Полный список настроек СУБД можно уточнить в документации. Здесь нужно учитывать и интенсивность нагрузки, включение некоторых метрик может повлиять на производительность. Однако наличие базовых вещей значительно упрощает анализ инцидентов в дальнейшем.
Если требования по безопасности выше, подключают аудит действий пользователей. Кто менял объекты, кто выдавал права, кто менял настройки. Для этого можно использовать расширения вроде pgaudit, аудит на уровне файлов ОС, а сами события потом отправляют в SIEM вместе с остальными журналами.
5. Целостность данных PostgreSQL, о которой никто не думает
Проблема
Контрольные суммы в PostgreSQL включаются при создании нового инстанса по умолчанию только в актуальной 18 версии, поэтому в рабочих системах их до сих пор регулярно встречаем отключенными.
Риски
Проблема в том, что без контрольных сумм повреждение данных может долго оставаться незамеченным. База PostgreSQL работает, запросы выполняются, никаких ошибок нет. Всё выглядит нормально до тех пор, пока приложение или пользователь не обратятся к конкретному повреждённому блоку.
Причина
Обычно причина таких повреждений находится вне самой СУБД: это аппаратные сбои, проблемы подсистемы хранения, файловой системы, виртуализации или некорректное завершение работы сервера. Без checksums такие повреждения могут долго не проявляться.
Пример
Один из таких случаев был в банковской системе мониторинга. Ошибка всплыла только после обращения к определённым данным. Пока разбирались с причиной, объём повреждений увеличился, а часть сервисов перестала работать. После этого разговор быстро перешёл к резервным копиям и возможности восстановления бэкапа postgresql.
Решение
Проверить, включены ли контрольные суммы, можно в psql:
postgres=# SHOW data_checksums; data_checksums ---------------- on (1 строка)
Если контрольные суммы включены, PostgreSQL обнаруживает проблему при чтении повреждённого блока и пишет об этом в журнал. Например, такое предупреждение вывелось в логи при попытке обработки битых страниц автовакуумом (там же рядом обычно доступен и контекст для дальнейшего анализа — при обработке каких объектов и какой операцией произошёл сбой):
2026-07-19 20:31:00.141 MSK [3199783] @ WARNING: page verification failed, calculated checksum 48850 but expected 56000
Часть информации о битых страницах можно найти и в стандартных вью СУБД:
postgres=# SELECT datname, checksum_failures, checksum_last_failure FROM pg_stat_database WHERE checksum_failures > 0;
Если за логами следит мониторинг PostgreSQL, о проблеме обычно узнают ещё до того, как начинают жаловаться пользователи.
Лучше включать контрольные суммы сразу при развёртывании, а не вспоминать о них во время аудита PostgreSQL или после инцидента.
Для их включения потребуется остановка СУБД (на момент написания статьи, в будущей 19 версии планируется добавление возможности сделать это «онлайн»). В современных версиях можно воспользоваться утилитой pg_checksums:
pg_checksums --pgdata /var/lib/postgresql/data --enable
С её помощью можно проверить валидность уже существующих контрольных сумм:
6. Мониторинг
Проблема
Деградацию производительности часто обнаруживают только после жалоб пользователей, срабатывания инфраструктурных алертов или уже заметного ухудшения работы системы. И тут всё упирается в данные.
Риски
Если мониторинг не был настроен, разбираться приходится практически вслепую. DBA видит только текущее состояние системы, а не ту картину, которая привела к проблеме. Причина может остаться неустановленной и потом повториться.
Причина
Обычно это происходит не из‑за сложных ограничений, а потому, что мониторинг производительности не внедряют на старте: пока система работает приемлемо, его откладывают на потом.
Решение
Решение здесь стандартное: внедрить инструменты, которые сохраняют историю производительности и позволяют анализировать запросы, ожидания и деградации ретроспективно. Это может быть как набор отдельных расширений — pg_stat_statements, pg_wait_sampling, pgpro_pwr, pg_profile, — так и готовые платформы вроде Tantor Platform, PoWA или Postgres Pro Manager. Главное, чтобы система не просто собирала метрики, а позволяла быстро восстановить картину инцидента.
Минимальный набор мониторинга
Обычно начинают с базовых вещей инфраструктурного мониторинга: CPU, память, диски и свободное место на разделах. Для Prometheus/Grafana или Zabbix есть готовые шаблоны мониторинга Linux, PostgreSQL и Patroni, и во многих случаях этого уже достаточно, чтобы быстро получить нормальную картину происходящего.
Дальше смотрят на саму базу: например, статистику запросов через pg_stat_statements, ожидания через pg_wait_sampling, долгие транзакции, ошибки в логах и медленные запросы.
Но со временем почти в каждой крупной системе появляется свой набор метрик и алертов. То, что критично для одной базы, может вообще не иметь значения для другой. Поэтому готовые шаблоны обычно берут за основу, а дальше дорабатывают под конкретную систему.
7. Долгие транзакции
Проблема
Долгие транзакции встречаются регулярно.
Риски
Очень часто именно они оказываются причиной деградации производительности, хотя на первый взгляд с базой всё в порядке.
Причина
Даже без генерации временных файлов долгая транзакция отключает автоматическую очистку всех новых мёртвых версий строк, ухудшает статистику планировщика, занимает слот подключения и ресурсы системы, удерживает длительные блокировки PostgreSQL.
На высоконагруженных системах, где не используются коммерческие форки СУБД с 64-битным счётчиком транзакций долгое удержание горизонта транзакций и блокирование заморозки строк может привести к проблеме, известной как xid wraparound, и положить базу в read‑only.
Пример
В одной банковской системе из смежной интеграции пришли некорректные данные. Запрос ушёл в бесконечную рекурсию и начал генерировать временные файлы. Мониторинг это заметил, сессию остановили. Если бы нет — довольно быстро закончилось бы место на диске.
Долгие транзакции в рабочей СУБД можно найти через вью pg_stat_activity:
SELECT pid, NOW() - xact_start AS transaction_duration, state, wait_event_type AS waiting, age(backend_xmin) AS xmin_age, usename, COALESCE(SUBSTR(query, 1, 40), '') AS query_snippet FROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY transaction_duration DESC LIMIT 10;
pid | transaction_duration | state | waiting | xmin_age | usename | query_snippet --------+----------------------+---------------------+---------+----------+-----------+------------------------------- 2389092 | 00:47:38.702829 | idle in transaction | Client | | postgres | delete from pgbench_accounts; 2389243 | 00:46:26.550487 | active | Lock | 8 | postgres | UPDATE pgbench_accounts SET abalance = a
Если какая‑то сессия висит часами или даже сутками, это зачастую приводит к деградации производительности базы данных.
Решение
Обычно такие ситуации связаны с логикой приложения, интеграций или пакетных процессов. Поэтому помимо мониторинга длительности транзакций и сессий в состоянии idle in transaction здесь почти всегда приходится разбирать источник проблемы на стороне приложения и при необходимости ограничивать такие сессии таймаутами. Для idle сессий на стороне СУБД это можно сделать через параметр idle_in_transaction_session_timeout.
8. Фрагментированность таблиц и автовакуум
Проблема
Автовакуум работает, но таблицы всё равно растут — с таким вопросом приходят регулярно. Обычно проблема не в самом автовакууме, а в том, что он возвращает системе не всё освободившееся дисковое пространство, а только часть на концах страниц.
Риски
Таблица может продолжать занимать много места даже при формально корректной работе обслуживания, а рост bloat со временем начинает замедлять чтение, ухудшать работу кэша и увеличивать нагрузку на диск.
Причина
Обычно к этому приводят частые UPDATE и DELETE, неоптимальный fillfactor, долгие транзакции и отсутствие регулярного контроля состояния самых тяжёлых объектов.
Пример и решение
Посмотреть таблицы с большим числом мёртвых строк и приблизительно оценить эффективность работы автовакуума можно при помощи встроенных вью:
SELECT schemaname, relname, n_live_tup, n_dead_tup, ROUND((n_dead_tup::DECIMAL / GREATEST(n_live_tup + n_dead_tup, 1)) * 100, 2) AS dead_pct, pg_size_pretty(pg_table_size(relid)) AS t_size, last_autovacuum, autovacuum_count FROM pg_stat_user_tables WHERE n_dead_tup > 0 ORDER BY n_dead_tup DESC LIMIT 20;
schemaname | relname | n_live_tup | n_dead_tup | dead_pct | t_size | last_autovacuum | autovacuum_count ------------+--------------------+------------+------------+----------+--------+--------------------------------+----------------- public | pgbench_accounts | 100000 | 1871 | 1.84 | 14 MB | | 0 public | pgbench_branches | 1 | 10 | 90.91 | 40 kB | 2026-07-20 00:15:03.596424+03 | 11 public | pgbench_tellers | 10 | 3 | 23.08 | 40 kB | 2026-07-20 00:15:04.197462+03 | 9 (3 строки)
Для понимания физической фрагментированности полезно использовать расширение pgstattuple, которое позволяет относительно быстро получить приблизительную оценку через функцию pgstattuple_approx (работает с погрешностью). На больших базах запрос всё равно может быть ресурсоёмким, но полезен в качестве примера:
WITH top_tables AS ( SELECT c.oid AS table_oid, c.relname AS table_name, pg_total_relation_size(c.oid) AS total_size FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind = 'r' AND n.nspname NOT LIKE 'pg_%' AND n.nspname != 'information_schema' ORDER BY total_size DESC LIMIT 30 ) SELECT 'Table' AS object_type, tt.table_name, pg_size_pretty(tt.total_size) AS object_size, ROUND(st.approx_free_percent::numeric, 2) AS approx_fragmentation_percent FROM top_tables tt CROSS JOIN LATERAL pgstattuple_approx(tt.table_oid) st ORDER BY tt.total_size DESC;
object_type | table_name | object_size | approx_fragmentation_percent -------------+---------------------+-------------+------------------------------ Table | pgbench_accounts | 17 MB | 1.32 Table | pgbench_history | 7568 kB | 0.05 Table | pgbench_branches | 56 kB | 86.08 Table | pgbench_tellers | 56 kB | 84.67 (4 строки)
Таблицы в примерах выше маленькие, и для них данная статистика не совсем актуальна, но картина меняется, когда речь идёт о больших объектах СУБД, которые длительное время обновляются и не подвергаются регулярному обслуживанию.
В одной банковской системе мы нашли около 500 ГБ фрагментации в единственной таблице. Причиной подобного обычно являются частые изменения данных в таблице, неоптимальная настройка fillfactor и отсутствие регулярного обслуживания СУБД. Посмотрели через pgstattuple, перестроили через pg_repack и получили почти двукратное сокращение размера:
pg_repack -j 8 -d mydb -t mytable --no-kill-backend
Заодно ускорились запросы. Так как pg_repack умеет перестраивать объекты без длительной эксклюзивной блокировки, обычно в продуктивных системах используют именно его, а не VACUUM FULL. Оба способа имеют свои нюансы и ограничения, и требуют дополнительного места на диске. Даже для pg_repack требуется кратковременная блокировка и таблица, создаваемая через триггеры. Лучше проводить тестирование в тестовой среде, подобрать оптимальное число потоков, чтобы не перегрузить систему.
Поэтому на практике приходится не только настраивать автовакуум, но и отдельно контролировать bloat по таблицам и индексам, мониторить долгие транзакции и точечно перестраивать самые проблемные объекты.
9. Несоответствие настроек СУБД серверным характеристикам и нагрузке
Проблема
Часто в ходе аудита выявляется, что настройки СУБД неэффективно утилизируют ресурсы сервера и не соответствуют текущему профилю нагрузки. Оказывается, что при увеличении ресурсов сервера, например, ядер или RAM, проблемы с производительностью уходят лишь на короткое время, а потом возвращаются снова.
Риски
Проблема здесь не только в неэффективном использовании ресурсов: со временем система начинает работать медленнее возможного и хуже переносит рост нагрузки, хотя формально железа стало больше.
В enterprise среде PostgreSQL на дефолтных настройках встречается редко — обычно используются стандартные best practices или конфиги, полученные с сайтов‑калькуляторов или средствами вроде pg_tune.
Причина
Такие настройки часто подбирают один раз и потом долго не пересматривают под изменившуюся инфраструктуру и реальный профиль нагрузки.
Прежде чем смотреть подробные отчёты о производительности часто бывает полезно оценить базовые настройки:
SELECT name, setting, unit, source FROM pg_settings WHERE name IN ( 'shared_buffers', 'effective_cache_size', 'work_mem', 'maintenance_work_mem', 'max_connections', 'checkpoint_completion_target', 'checkpoint_timeout', ‘max_wal_size’, 'huge_pages', 'max_worker_processes' );
Решение
Аудит производительности является обширной темой, потому что на работу СУБД оказывает влияние много внешних факторов, таких как, например, антивирусы, работоспособность и настройки сети, дисковой подсистемы и виртуализации. Однако часто быстродействие системы удаётся улучшить путём более точной подстройки под текущую нагрузку, а не просто «по шаблону». Если используется автоматически сгенерированный конфиг — лучше проверять его актуальность после значимых инфраструктурных изменений.
Если система активно развивается, и, например, интенсивно возрастает количество подключений, одних настроек СУБД может быть недостаточно. Необходимо оценивать масштабируемость системы, и, например, рассмотреть использование балансировщиков вроде pgbouncer, партиционирования, перехода на энтерпрайз форки.
10. Архитектура и бизнес‑риски: RTO/RPO, о которых никто не спрашивал
Проблема
Для важных продуктивных систем часто предъявляются требования к целевому времени возврата системы в работу и объёму данных, который возможно потерять (RTO, RPO).
Риски
Проблема здесь не в самих требованиях, а в том, что их давно никто не сверял с реальной системой. База растёт, меняется инфраструктура, появляются новые сервисы, а резервное копирование и сценарии возврата в работу остаются прежними. В какой‑то момент оказывается, что система поднимается уже совсем не за то время, на которое рассчитывал бизнес.
Причина
Отказоустойчивые кластерные конфигурации PostgreSQL имеют множество архитектурных нюансов, которые выявляются при аудите и которым можно посвятить отдельную статью. Распределение узлов между ЦОДами, настройки DCS и Patroni PostgreSQL, использование синхронной репликации, прокси и балансировщиков — всё это может напрямую повлиять на доступность системы и нарушить требования бизнеса. Обычно причина таких расхождений в том, что архитектуру проектируют под формальный признак отказоустойчивости, а не под реальные бизнес‑сценарии отказа. Установить кластер по шаблонам и плейбукам из интернета не сложно, но корректная эксплуатация требует внимания.
Примеры
Пример 1: на одном из аудитов крупного банка исследовали отказоустойчивый кластер Patroni PostgreSQL. С самим кластером на первый взгляд всё было в порядке, но обнаружилось другое ограничение — балансировщики, через которые приложение подключалось к СУБД. При отказе основного балансировщика система останавливалась. Соответственно, бизнес‑требование к доступности системы вообще не соблюдалось при отказе узла. Нашли это ещё на этапе опытной эксплуатации, до выхода в прод.
Пример 2: Patroni‑кластер крупной транспортной компании спустя пару лет после начала эксплуатации вышел из строя из‑за превышения стандартного лимита хранения данных в etcd. PostgreSQL ушёл в read‑only. Чтобы избежать такой ситуации, нужно мониторить ошибки кластерного ПО, актуализировать его лимиты и не забывать про регулярное обслуживание DCS. Как правило, при подобных проблемах есть какая‑то сопутствующая причина — например, периодическая сетевая недоступность.
Пример 3: из запомнившегося: у одного банковского заказчика тестовые контуры разворачивались из продакшн‑бэкапа. Система постепенно росла, а процесс оставался прежним. В какой‑то момент развёртывание стало занимать почти двое суток и заметно нагружать продакшн. После пересмотра схемы тот же процесс удалось уложить примерно в час.
Решение
Проверка соответствия архитектуры реальным требованиям обычно начинается с простой вещи: подъёма базы из резервной копии и замера времени. Иногда уже на этом этапе находятся неприятные сюрпризы. Для критичных систем этого мало. Здесь уже приходится проводить DRP‑тестирование и проверять аварийные сценарии: отказ узла, потерю сети, переключение между площадками, ошибки при возврате сервиса в работу. Причём проблемы чаще всплывают не в штатном переключении, а в комбинациях событий, которые редко проверяют заранее.
Отчасти подобные ошибки возникают из‑за отсутствия единого стандарта. Чем сложнее архитектура, и чем больше баз данных устанавливается и обслуживается, тем важнее использовать средства автоматизации. Это сокращает индивидуальные ошибки и позволяет в будущем предсказуемым образом обслуживать систему и вносить в неё изменения.
Что отличает команды, к которым мы возвращаемся реже
Зрелые команды отличаются тем, что у них в порядке базовые вещи. Работают резервные копии, настроен мониторинг СУБД, документация не заканчивается схемой из двухлетней презентации. Если нужно понять, какая версия PostgreSQL стоит на сервере или как устроено резервирование, ответ находится за несколько минут, а не через цепочку звонков и переписок.
И ещё одна общая черта — большинство проблем они находят сами. Переполненный диск, зависшая транзакция или переставший работать бэкап редко становятся для них сюрпризом, потому что такие вещи обычно ловятся мониторингом задолго до инцидента.
Но даже эти команды возвращаются к нам снова — не потому, что у них что‑то сломалось, а потому что идеально выстроенная система медленно, но верно стареет. Нагрузка меняется, данных становится больше, появляются новые сервисы и интеграции. То, что было нормой два года назад, со временем может тихо перестать соответствовать реальности — просто потому, что никто не пересматривал архитектуру под новые условия. Регулярный аудит в таком случае — это не признак недоверия к команде, а единственный способ вовремя заметить, как привычные решения перестают работать в изменившемся контексте.
И приходят к нам такие команды, как правило, уже с вопросами, требующими более глубокой экспертизы — и это лучший сценарий: когда аудит нужен не для тушения пожара, а чтобы убедиться, что система готова к будущим вызовам.
Когда и зачем проводить аудит
Универсальной периодичности для аудита нет. Но есть ситуации, когда без него лучше не обходиться: миграция, смена оборудования, обновление операционной системы, передача системы на поддержку. Ещё один повод — когда база годами работает без серьёзных изменений и никто толком не проверяет, что с ней происходит.
Если система уже настроена и работает стабильно, обычно хватает регулярного анализа производительности. Нагрузка меняется, данных становится больше, появляются новые запросы. То, что работало нормально пару лет назад, со временем может стать проблемой.
Если выбирать только одну вещь для проверки, я бы начал с резервных копий. Не с просмотра логов заданий в cron и не с отчёта о том, что бэкапы создаются, а с реального восстановления. Большинство проблем с PostgreSQL можно исправить. Потерянные данные — далеко не всегда.