Вы настроили Nginx, оптимизировали PHP-FPM и подключили Redis Object Cache. Сайт летает, но при пиковой нагрузке база данных всё равно начинает «захлёбываться», а время отклика (TTFB) растёт. Проблема в том, что MySQL и MariaDB по умолчанию устанавливаются с настройками, рассчитанными на крошечные VPS с 512 МБ RAM.
В этом руководстве мы превратим стандартную базу данных в мощный движок, способный обрабатывать тысячи сложных запросов в секунду. Мы разберём ключевые параметры InnoDB, настроим лог медленных запросов и научимся использовать MySQLTuner.
Шаг 1: Анализ текущей конфигурации
Прежде чем менять настройки, нужно понять, как база работает сейчас. Лучший инструмент для этого — MySQLTuner.
# Скачиваем скрипт
wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
chmod +x mysqltuner.pl
# Запускаем (потребуется ввести root-пароль от MySQL)
./mysqltuner.plСкрипт проанализирует работу сервера за последние 24+ часа и выдаст рекомендации. Обратите внимание на разделы [!!] (критические проблемы) и [OK]. Не применяйте рекомендации слепо — мы разберём их ниже с учётом специфики WordPress.
Шаг 2: Ключевые параметры InnoDB
WordPress использует движок InnoDB (или XtraDB в MariaDB). Именно его параметры влияют на производительность на 90%.
Откройте конфигурационный файл:
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
# или для MySQL:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnfНайдите или добавьте секцию [mysqld] и настройте следующие параметры:
1. Размер буфера пула (Самое важное!)
; InnoDB хранит данные и индексы в оперативной памяти.
; Формула: 60-70% от общей RAM сервера (если на сервере только БД).
; Если на сервере также работают Nginx и PHP-FPM, ставьте 40-50%.
innodb_buffer_pool_size = 2G
; Разбиваем пул на несколько экземпляров для снижения конкуренции блокировок
innodb_buffer_pool_instances = 22. Размер лог-файлов
; Увеличиваем размер redo-логов. Это ускоряет запись и снижает I/O.
; Стандартное значение (48M) слишком мало для продакшна.
innodb_log_file_size = 256M
innodb_log_buffer_size = 32M3. Стратегия сброса на диск (Flush)
; 1 = максимальная безопасность (данные не теряются при сбое питания, но медленнее)
; 2 = быстрая запись, риск потери 1 секунды данных при полном отказе сервера
; 0 = максимальная скорость, но высокий риск потери данных
; Для WordPress с регулярными бэкапами (см. нашу статью про бэкапы) можно ставить 2
innodb_flush_log_at_trx_commit = 1Шаг 3: Настройка соединений и таймаутов
Частая ошибка — «Too many connections». Это происходит, когда PHP-FPM открывает больше соединений, чем MySQL может обработать.
; Максимальное количество одновременных подключений.
; Формула: pm.max_children (из PHP-FPM) + 10 (запас для админки и cron)
; Если у вас 30 процессов PHP-FPM, ставьте 40-50. Не ставьте 500 "на всякий случай"!
max_connections = 50
; Таймаут неактивных соединений (закрывать через 60 секунд)
wait_timeout = 60
interactive_timeout = 60
; Максимальный размер пакета (важно для импорта больших дампов)
max_allowed_packet = 64MШаг 4: Включение лога медленных запросов
Чтобы найти плагины или темы, которые генерируют тяжёлые SQL-запросы, включите Slow Query Log.
; Включаем лог медленных запросов
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
; Записывать запросы, выполняющиеся дольше 1 секунды
long_query_time = 1
; Записывать запросы, не использующие индексы
log_queries_not_using_indexes = 1Создайте файл лога и дайте права:
sudo touch /var/log/mysql/mysql-slow.log
sudo chown mysql:mysql /var/log/mysql/mysql-slow.log
sudo chmod 640 /var/log/mysql/mysql-slow.logПерезагрузите MySQL/MariaDB:
sudo systemctl restart mariadb
# или
sudo systemctl restart mysqlШаг 5: Анализ медленных запросов
Через пару дней посмотрите, какие запросы тормозят сайт:
# Топ-10 самых медленных запросов
sudo mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
# Топ-10 запросов, возвращающих больше всего строк
sudo mysqldumpslow -s r -t 10 /var/log/mysql/mysql-slow.logЕсли вы видите запросы от конкретных плагинов (например, wp_postmeta с сложными JOIN), используйте плагин Query Monitor для их анализа в админке или оптимизируйте через индексы.
Шаг 6: Обслуживание таблиц через WP-CLI
Со временем таблицы фрагментируются. Раз в месяц полезно проводить их оптимизацию. Мы уже упоминали WP-CLI — используем его для безопасного обслуживания:
# Переходим в корень сайта
cd /var/www/wordpress
# Оптимизация всех таблиц (аналог OPTIMIZE TABLE)
wp db optimize
# Восстановление поврежденных таблиц
wp db repair
# Проверка целостности
wp db checkЧек-лист оптимизации MySQL/MariaDB
- ✅
innodb_buffer_pool_sizeустановлен в 40-70% от RAM - ✅
innodb_log_file_sizeувеличен до 128-256M - ✅
max_connectionsнастроен под размер пула PHP-FPM - ✅
wait_timeoutснижен до 60 секунд для закрытия зависших соединений - ✅ Включён
slow_query_logдля поиска тяжёлых запросов - ✅ Настроено регулярное обслуживание через WP-CLI
Что делать, если проблемы не решаются?
Ошибка «Too many connections»
Это значит, что PHP-FPM пытается открыть больше соединений, чем разрешено в max_connections. Проверьте настройки пула PHP-FPM (pm.max_children) и увеличьте max_connections в MySQL. Также проверьте, не оставляют ли плагины «висячие» соединения (проблема часто бывает у плагинов кэширования и бэкапов).
База данных ест всю оперативную память
Скорее всего, innodb_buffer_pool_size установлен слишком агрессивно. Помните, что MySQL также потребляет память на каждое соединение (sort_buffer_size, read_buffer_size). Уменьшите buffer_pool на 20% или снизьте max_connections.
Запросы выполняются по 10-20 секунд
Если в логе медленных запросов вы видите конкретные SQL-команды, скопируйте их и выполните в консоли MySQL с командой EXPLAIN перед запросом. Это покажет, какие таблицы сканируются полностью (type: ALL) и где не хватает индексов. Часто проблема решается добавлением индекса в wp_postmeta или wp_options.
Высокая нагрузка на диск (I/O Wait)
Если диск постоянно занят записью, измените innodb_flush_method на O_DIRECT (это отключает двойное буферирование в ОС) и убедитесь, что вы используете NVMe или SSD. На HDD современные версии WordPress работают крайне плохо.
Итог
Оптимизация MySQL — это не разовая акция, а баланс между потреблением RAM, скоростью записи и надёжностью. Настройки, приведённые в этой статье, являются «золотым стандартом» для WordPress на VPS с 4 ГБ RAM. Комбинируя их с Redis Object Cache, вы снизите нагрузку на базу данных на 80-90%, оставив MySQL только для записи новых данных и сложных выборок.