Тюнинг ядра Linux под PostgreSQL: vm.overcommit_memory, swappiness и HugePages
- Внезапные аварийные остановки основного процесса PostgreSQL (PID postmaster) операционной системой.
- Высокая задержка транзакций из-за сброса буферов PostgreSQL в Swap при наличии свободной памяти.
- Деградация производительности и дедлоки на уровне ядра из-за Transparent Huge Pages (THP).
1. Настройка параметров виртуальной памяти (/etc/sysctl.d/99-postgresql.conf)
# Строгий запрет оверкоммита (защита от OOM Killer)
vm.overcommit_memory = 2
vm.overcommit_ratio = 80
# Минимизация агрессивности свопинга (своп только при крайней необходимости)
vm.swappiness = 1
# Оптимизация фонового сброса грязных страниц на диск (исключение I/O заторов)
vm.dirty_background_ratio = 3
vm.dirty_ratio = 10
vm.dirty_expire_centisecs = 1500
vm.dirty_writeback_centisecs = 500
# Настройка очередей соединений и разделяемой памяти
net.core.somaxconn = 4096
kernel.sched_migration_cost_ns = 5000000Примените настройки ядра:
sysctl --system2. Отключение Transparent Huge Pages (THP)
Создайте systemd unit /etc/systemd/system/disable-thp.service:
[Unit]
Description=Disable Transparent Huge Pages (THP) for PostgreSQL
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=mongod.service postgresql.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled && echo never > /sys/kernel/mm/transparent_hugepage/defrag'
[Install]
WantedBy=basic.targetsystemctl daemon-reload
systemctl enable --now disable-thp.service3. Проверка текущего статуса THP
cat /sys/kernel/mm/transparent_hugepage/enabled
# Ожидаемый вывод: always madvise [never] Частые вопросы (FAQ)
Почему для PostgreSQL рекомендуется vm.overcommit_memory = 2?
В режиме 2 ядро Linux запрещает выделять больше виртуальной памяти, чем физический объем RAM * overcommit_ratio + Swap. Это предотвращает внезапный приход OOM Killer и убийство СУБД при исчерпании физических страниц.
Зачем полностью отключать Transparent Huge Pages (THP)?
THP динамически выделяет 2MB страницы, что вызывает задержки компактизации памяти ядра (memory compaction spikes) и деградацию производительности СУБД, использующей гранулярные 8KB блоки.
Почему нельзя полностью отключить Swap (swappiness = 0)?
При полном отключении Swap ядро теряет возможность вытеснять неиспользуемые страницы анонимной памяти демонов ОС, что увеличивает риск мгновенного краха при непредвиденных всплесках нагрузки.
Как рассчитать vm.overcommit_ratio при vm.overcommit_memory = 2?
Формула максимального лимита памяти: CommitLimit = (RAM * overcommit_ratio / 100) + Swap. Убедитесь, что сумма (shared_buffers + max_connections * work_mem) строго укладывается в CommitLimit.