Оптимизация MySQL/MariaDB для WordPress: Настройка my.cnf и InnoDB

Вы настроили 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 = 2

2. Размер лог-файлов

; Увеличиваем размер redo-логов. Это ускоряет запись и снижает I/O.
; Стандартное значение (48M) слишком мало для продакшна.
innodb_log_file_size = 256M
innodb_log_buffer_size = 32M

3. Стратегия сброса на диск (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 только для записи новых данных и сложных выборок.