Сервер для PostgreSQL: CPU, RAM, NVMe и восстановление 列印

  • 0

Для нового небольшого проекта с PostgreSQL можно взять за отправную точку для теста 4 vCPU, 16 ГБ RAM и NVMe. Это пример начальной конфигурации, а не обещание производительности: база на 20 ГБ с тяжёлыми отчётами может требовать больше ресурсов, чем база на 200 ГБ с редкими короткими запросами.

Сервер нужно выбирать по двум результатам: он выдерживает рабочую нагрузку и позволяет восстановить проект за приемлемое время. Количество ядер, объём памяти и надпись NVMe ещё не подтверждают ни первого, ни второго.

Ниже рассматривается PostgreSQL на Linux для сайтов, CRM и других прикладных систем. SQL-примеры рассчитаны на PostgreSQL 16–18. Для специализированных сборок, например под 1С, дополнительно проверяйте совместимость платформы, расширений и версии СУБД.

Какие данные собрать перед выбором сервера

Если база уже работает, измеряйте её во время обычной нагрузки и замедления. Нужны размер данных вместе с индексами, рост за месяц, количество одновременно выполняемых запросов, доля записи и время важных операций. Число зарегистрированных пользователей не заменяет эти показатели.

Подключитесь к нужной базе через psql. Для просмотра чужих сеансов потребуется роль с правами мониторинга, например pg_monitor, или администратор. Следующие запросы читают статистику:

SELECT pg_size_pretty(pg_database_size(current_database())) AS database_size;

SELECT state, wait_event_type, count(*) AS sessions
FROM pg_stat_activity
WHERE datname = current_database()
  AND backend_type = 'client backend'
GROUP BY state, wait_event_type
ORDER BY sessions DESC;

SELECT temp_files,
       pg_size_pretty(temp_bytes) AS temp_written,
       stats_reset
FROM pg_stat_database
WHERE datname = current_database();

Первый результат показывает объём выбранной базы. Он не включает другие базы, весь каталог WAL и место для будущих операций. Второй помогает отличить активную работу от ожидания: например, Lock означает ожидание блокировки. Значение NULL само по себе не доказывает нехватку CPU.

temp_bytes — накопленный объём записи во временные файлы. Сравните два замера за известный интервал с неизменным stats_reset. Быстрый рост во время отчёта — повод проверить его план и настройки памяти. Это ещё не основание увеличивать RAM или work_mem для всех запросов.

Для нового проекта вместо статистики потребуется тестовая база с реалистичным объёмом и сценарии приложения: поиск, создание записи, отчёт, пакетная загрузка. Проверка на нескольких сотнях строк плохо предсказывает работу с миллионами.

CPU: когда нужны быстрые ядра, а когда их количество

Производительность одного ядра важна для операций, которые выполняются последовательно. Дополнительные ядра помогают обслуживать несколько запросов одновременно и выполнять подходящие параллельные планы. Но PostgreSQL не распределяет любой запрос по всем доступным ядрам.

Поэтому сравнивайте модель и поколение CPU, условия предоставления vCPU и результаты своего теста. Одинаковое число виртуальных ядер у разных тарифов не гарантирует одинаковую производительность. Для VPS уточните, разделяется ли процессорное время с соседями и есть ли ограничения длительной нагрузки.

На Linux загрузку по ядрам можно посмотреть командой из пакета sysstat:

mpstat -P ALL 1 10

Если занято одно ядро, а остальные свободны, проверьте конкретный запрос. Если во время нужной нагрузки заняты почти все ядра и запросы не ждут диска или блокировок, тест конфигурации с большим числом ядер оправдан. Устойчивая высокая доля %steal в виртуальной машине требует отдельной проверки у провайдера: гостевая ОС ждёт процессорное время.

Если pg_stat_statements уже подключён, найдите запросы с наибольшим суммарным временем выполнения:

SELECT queryid, calls,
       round(total_exec_time::numeric, 1) AS total_ms,
       round(mean_exec_time::numeric, 1) AS mean_ms,
       left(query, 120) AS query
FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database
              WHERE datname = current_database())
ORDER BY total_exec_time DESC
LIMIT 10;

Смотрите одновременно число вызовов и среднее время: частый короткий запрос тоже может создавать основную нагрузку. Если расширение не настроено, для его подключения обычно требуется изменение конфигурации и перезапуск; запланируйте это отдельно.

Медленный запрос сначала изучите через EXPLAIN. Вариант EXPLAIN (ANALYZE, BUFFERS) действительно выполняет запрос, поэтому тяжёлые операции и запросы, изменяющие данные, разбирайте на тестовой копии. Новый процессор не устранит ненужный полный просмотр таблицы или ожидание длинной транзакции.

RAM: вся база не обязана помещаться в память

Для часто повторяющихся чтений полезно держать в памяти активно используемые страницы таблиц и индексов. Старые записи, к которым почти не обращаются, не обязательно постоянно хранить в кеше. Поэтому правило «RAM должна равняться размеру базы» не подходит для всех систем.

Память расходуют общий кеш PostgreSQL, кеш файловой системы, запросы, служебные процессы и соседние приложения. В контейнере ориентируйтесь также на лимит памяти контейнера: свободная RAM физического сервера не отменяет этот лимит.

Посмотрите действующие параметры:

SHOW shared_buffers;
SHOW work_mem;
SHOW hash_mem_multiplier;
SHOW effective_cache_size;
SHOW max_connections;

Для сервера, выделенного под PostgreSQL, документация предлагает начинать с shared_buffers около 25% RAM. Например, для 32 ГБ это 8 ГБ. Это старт для проверки, а не общий лимит памяти PostgreSQL. Если рядом работают приложение и другие службы, бюджет нужно уменьшить с учётом их потребления.

work_mem применяется к отдельным операциям сортировки и хеширования. У запроса таких операций может быть несколько; одновременно работают разные сеансы и параллельные процессы. Условные 100 запросов, каждый с двумя одновременными сортировками по 64 МиБ, дают до 12,5 ГиБ только на эти сортировки, ещё без дополнительных параллельных процессов. Хеширование учитывает также hash_mem_multiplier.

Поэтому увеличение work_mem проверяйте на конкретных запросах и при реальной конкуренции. effective_cache_size вообще не выделяет память: это оценка доступного кеша для планировщика.

Проверьте free -h и vmstat 1 10. В vmstat оценивайте строки после первой, которая показывает средние значения с момента загрузки. Важны доступная память и продолжающийся обмен со swap в столбцах si/so, особенно одновременно с ростом задержек. Сам факт занятого swap не доказывает текущую нехватку RAM.

При большом числе соединений оцените пул подключений, например PgBouncer, и лимиты приложения. Пул позволяет управлять числом серверных соединений; режим его работы должен быть совместим с приложением. Простое увеличение max_connections не создаёт дополнительной вычислительной мощности.

NVMe: смотрите на задержки записи и доступную ёмкость

Для PostgreSQL важна не только скорость последовательного чтения больших файлов. Запросы обращаются к страницам таблиц и индексов, а фиксация транзакций зависит от надёжной записи журнала WAL — журнала предзаписи, по которому PostgreSQL восстанавливает изменения.

При умеренной нагрузке может хватить SATA SSD. NVMe стоит выбирать, когда требуется больше операций ввода-вывода и низкие задержки. Но быстрый интерфейс не гарантирует стабильную скорость под длительной записью. У выделенного сервера уточните модель накопителей, ресурс записи и наличие защиты от потери питания — PLP. У VPS дополнительно проверьте ограничения операций ввода-вывода и пропускной способности хранилища.

Во время нагрузки посмотрите:

iostat -y -xz 1 10

Утилита входит в sysstat. Сравнивайте задержки чтения и записи, очередь запросов и показатели PostgreSQL с нормальным состоянием того же сервера. Один показатель %util не даёт надёжного ответа о насыщении NVMe или виртуального хранилища.

Не отключайте fsync и full_page_writes ради красивого теста. Это может привести к повреждению базы после сбоя. Такой результат нельзя переносить на рабочую систему с требованиями к сохранности данных. Отключение synchronous_commit — отдельный компромисс: при сбое можно потерять уже подтверждённые клиенту последние транзакции.

Дисковый бюджет считайте так: данные и индексы + ожидаемый рост + локальный WAL + временные файлы и обслуживание + ОС и журналы + свободный запас. Перестроение большого индекса или таблицы тоже может требовать дополнительного места.

Например, если расчётный максимум всех этих данных и операций составляет 300 ГБ, диск с 300 ГБ доступного места не подходит. При выбранном для проекта запасе 25% потребуется не менее 400 ГБ полезной ёмкости. Это пример планирования, а не обязательный процент PostgreSQL.

Считайте ёмкость после RAID: зеркало из двух дисков по 1 ТБ даёт примерно 1 ТБ до форматирования. RAID уменьшает последствия некоторых отказов диска, но не защищает от ошибочного удаления таблицы.

Контролируйте размер pg_wal. Сломанная архивация или отставший потребитель репликационного слота — механизма удержания журнала для репликации — могут удерживать WAL и заполнить диск. max_wal_size не является жёстким пределом этого каталога. Удалять файлы WAL вручную нельзя: сначала выясните причину удержания.

Если используются архивация или репликационные слоты, на основном сервере проверьте:

SELECT archived_count, last_archived_time,
       failed_count, last_failed_time
FROM pg_stat_archiver;

SELECT slot_name, active, restart_lsn
FROM pg_replication_slots;

Рост failed_count между замерами означает новые ошибки архивации: найдите причину в журнале PostgreSQL и восстановите доставку в архив. Старое время последней архивации на простаивающей базе само по себе не доказывает сбой. Если потребитель слота отключён, а restart_lsn не меняется при продолжающейся записи, проверьте его работоспособность и удержание WAL. Не удаляйте слот без понимания, как затем восстановится его потребитель.

Как понять, какой ресурс ограничивает PostgreSQL

Что наблюдаете Что проверить Следующий шаг
Один запрос медленный, остальные работают нормально План, индексы, объём обрабатываемых строк, ожидание блокировок Исправить запрос или схему доступа; затем повторить тест CPU
При росте нагрузки заняты все ядра, растёт время ответа Нет ли ожидания I/O, не выполняется ли лишняя работа Сравнить более быстрый CPU или больше ядер на том же сценарии
Растут swap и временные файлы, возникают ошибки нехватки памяти Конкурентные запросы, лимиты памяти, параметры PostgreSQL и соседние процессы Ограничить одновременную работу, исправить чрезмерные настройки; при необходимости добавить RAM
Запросы ждут I/O, задержки диска растут Объём чтения, запись WAL, фоновые операции и лимиты хранилища Уменьшить ненужный ввод-вывод или выбрать более производительное хранилище
Диск заполняется быстрее роста полезных данных WAL, временные файлы, журналы, работу autovacuum — фонового обслуживания таблиц — и длинные транзакции Найти источник роста; расширение диска использовать как запас времени, а не замену исправлению
CPU и диск свободны, приложение отвечает медленно Блокировки, очередь подключений и задержку между приложением и БД Разобрать ожидание; покупка дополнительных ресурсов может ничего не изменить

Показатели нужно сопоставлять по времени. Снимок загрузки через полчаса после жалобы не объясняет, что происходило во время проблемы.

VPS или выделенный сервер: как проверить выбор до переноса

VPS удобен, когда его ресурсов и условий изоляции достаточно для проекта. Выделенный сервер имеет смысл при длительной высокой нагрузке, большом объёме RAM или требованиях к конкретным дискам и их схеме. Физическая машина сама по себе не создаёт резервный узел и не гарантирует автоматическое восстановление.

Приложение и PostgreSQL могут работать на одном VPS, если не мешают друг другу. Разделение полезно при конкуренции за ресурсы или разных требованиях к обслуживанию, но добавляет сетевую задержку. Проверяйте время операций со стороны приложения. При сетевом подключении проверьте firewall и pg_hba.conf: доступ к PostgreSQL должен быть разрешён только нужным узлам приложения и администрирования.

До переноса подготовьте тестовую копию и проведите проверку:

  1. Восстановите реалистичный объём данных с нужными индексами и расширениями. Сохраните версию PostgreSQL и настройки, чтобы сравнение серверов было корректным.
  2. Воспроизведите обычную и пиковую нагрузку приложения. Укажите заранее допустимое время ключевых операций и число одновременно выполняемых запросов.
  3. Измеряйте не только среднюю задержку, но и p95/p99 — время, быстрее которого завершаются 95% и 99% операций. Проверяйте ошибки и тайм-ауты.
  4. Повторите тест при резервном копировании и обычных фоновых работах. Несколько секунд тестирования не показывают устойчивую производительность.
  5. Изменяйте один существенный фактор за раз и сравнивайте результат. Зафиксируйте запас на ожидаемый рост.

pgbench подходит для воспроизводимого теста, особенно с собственными SQL-сценариями. Его стандартный результат нельзя напрямую переводить в число пользователей вашего приложения. Маленький набор данных, полностью попавший в кеш, также не проверяет поведение большой базы на диске.

Для сравнения конфигураций посмотрите VPS/VDS HSTQ и выделенные серверы HSTQ. Перед заказом укажите профиль нагрузки, объём данных, рост и требования к восстановлению. Модель CPU, параметры хранилища, резервные копии и объём администрирования согласуйте для выбранной услуги: базовая поддержка инфраструктуры не заменяет сопровождение PostgreSQL.

Как выбрать резервное копирование под допустимую потерю данных

Сначала определите два показателя. RPO — какой период последних изменений допустимо потерять. RTO — за какое время нужно вернуть приложение в работу. Например, «не больше пяти минут данных и не больше часа простоя» — уже требования, по которым можно проверить схему.

Способ Когда подходит Ограничение
Логический дамп через pg_dump Небольшая база, перенос отдельных объектов, допустимо вернуться к моменту копии Восстановление данных и индексов может быть долгим; обычный дамп не даёт произвольного отката по времени
Физическая базовая копия и непрерывный архив WAL Нужно восстановление к выбранному моменту — PITR Нужны подходящая базовая копия и непрерывная цепочка WAL; физическая копия не служит способом перехода на другую основную версию PostgreSQL
Реплика PostgreSQL Нужно сократить время возвращения сервиса после отказа основного узла Ошибочное изменение тоже реплицируется; нужны отдельные резервные копии и процедура переключения

При ежедневном дампе можно потерять почти сутки изменений, а при пропущенном запуске — больше. Для PITR используют, например, pgBackRest: он управляет базовыми копиями, архивом WAL и восстановлением. Один архив WAL без базовой копии не восстанавливает кластер. Обычный pg_dump не заменяет базовую физическую копию для PITR.

Храните копии и необходимые WAL вне сервера с базой. Не рассчитывайте на обычное копирование каталога работающего PostgreSQL: файловая копия требует согласованной процедуры. Отдельно сохраните конфигурацию, список расширений и доступы к хранилищу. У логических дампов глобальные объекты, включая роли, сохраняются отдельно, например через pg_dumpall --globals-only.

При архивации завершёнными сегментами WAL на малоактивной базе отправка может задерживаться. archive_timeout позволяет принудительно завершать сегменты по времени, но сам по себе не гарантирует RPO: архив ещё должен успешно попасть во внешнее хранилище.

Если pgBackRest уже настроен, проверьте его конфигурацию и доступные копии. Здесь app — пример имени stanza, то есть набора настроек вашего кластера:

sudo -u postgres pgbackrest --stanza=app check
sudo -u postgres pgbackrest --stanza=app info

check должен завершиться успешно; он в том числе проверяет доставку тестового сегмента WAL. В info проверьте дату подходящей копии и доступные диапазоны WAL. Ошибка проверки требует разбора журналов и доступов к репозиторию. Успешный результат этих команд ещё не заменяет восстановление.

Как проверить восстановление до аварии

Проводите проверку на отдельном сервере или изолированном кластере. Исходную базу и единственную резервную копию не изменяйте. Подготовьте совместимую версию PostgreSQL, нужные расширения, кодировку и правила сортировки, достаточно места и доступ к архиву. Для первой репетиции проще использовать ту же основную версию, что у источника.

Для логического дампа в формате custom, созданного с pg_dump -Fc, можно сначала проверить восстановление данных. Следующий пример выполняется только на отдельном тестовом сервере с обычной установкой PostgreSQL в Linux. Файл заранее размещён по указанному пути и доступен пользователю postgres; имя restore_check ещё не занято. Выполняйте команды по очереди и останавливайтесь при любой ошибке:

sudo -u postgres pg_restore --list /var/lib/postgresql/restore-check/appdb.dump

sudo -u postgres createdb --template=template0 restore_check

sudo -u postgres pg_restore --exit-on-error \
  --no-owner --no-privileges --no-tablespaces \
  --dbname=restore_check \
  /var/lib/postgresql/restore-check/appdb.dump

sudo -u postgres psql -X -v ON_ERROR_STOP=1 \
  --dbname=restore_check -c 'ANALYZE;'

--list показывает оглавление, но не проверяет восстановимость всех данных. Успех — завершившийся без ошибок импорт и последующая проверка содержимого. Если дамп ссылается на роли, например в политиках доступа, подготовьте их заранее.

Флаги --no-owner, --no-privileges и --no-tablespaces упрощают первую проверку: исходные владельцы и права не воспроизводятся, объекты размещаются в стандартном хранилище тестовой базы. Для полной репетиции воспроизведите нужные роли, владение, разрешения и размещение объектов; проверьте подключение под пользователем приложения.

При ошибке версии используйте совместимые клиентские утилиты и сервер. При отсутствии расширения установите его совместимую версию на тестовый сервер. Ошибки ролей и прав исправляйте по сохранённой схеме доступа. Не объявляйте восстановление успешным, пока ошибки импорта не устранены.

Для физической копии с PITR проведите отдельную репетицию: выберите точку после завершения базовой копии, восстановите кластер из внешнего хранилища и убедитесь, что проигрывание WAL дошло до нужного момента. Если PostgreSQL сообщает о недостающем WAL или недостижимой цели восстановления, проверьте цепочку, диапазон хранения, временную зону цели и выбранную копию. Нельзя обходить эту проблему удалением WAL или применять pg_resetwal как обычный способ восстановления.

После технического запуска подключите тестовую копию приложения, отключив реальные рассылки, платежи и фоновые задания. Проверьте важные записи, число ключевых записей и последнюю известную операцию, чтение и тестовую запись. Для PITR подготовьте две контрольные записи с подтверждёнными транзакциями до и после выбранной точки: первая должна присутствовать, вторая — отсутствовать.

Засекайте весь путь: получение сервера, скачивание копии, распаковку, восстановление, проигрывание WAL и запуск приложения. Условные 500 ГБ архива при эффективной скорости передачи 100 МБ/с потребуют около 83 минут только на передачу. Требование восстановиться за полчаса такая схема уже не выполняет.

Повторяйте репетицию после смены основной версии PostgreSQL, расширений, инструмента резервного копирования или хранилища. В журнале проверки сохраняйте дату копии, достигнутую точку восстановления, ошибки и полное время возврата приложения в работу.


這篇文章有幫助嗎?

相關文章

Какие есть боты/сервисы, которые стоит добавить в исключения? Практический гайд для защиты сайта и бизнеса В современных условиях кибербезопасности настройка блокировок и фильтров — обязательная мера для... Что делать, если сертификаты Let’s Encrypt не обновляются? Простое решение за 5 минут Сертификаты от Let’s Encrypt стали стандартом для бесплатной автоматической защиты сайтов по... Какие сервисы и решения реально помогают? Топ-10 инструментов Почему взламывают сайты и что самое опасное? Современный сайт на WordPress, Битрикс, Joomla,... Лучшие версии PHP и MySQL сейчас для WordPress: что выбрать для максимальной стабильности и скорости? WordPress — самая популярная CMS в мире, и именно поэтому вопрос о правильной версии PHP и... Где сейчас захостить видео, чтобы его просто вставлять на свой сайт без рекламы? Лучшие альтернативы YouTube В 2025 году все чаще сталкиваемся с ситуацией: YouTube работает с перебоями, вставки грузятся...
« 返回

知識庫