К основному содержимому

Оптимизация MySQL/MariaDB: настройка my.cnf

MySQL / MariaDB · 19.04.2026 · 4 мин чтения
Иллюстрация к статье «Оптимизация MySQL/MariaDB: настройка my.cnf»

Где находится файл my.cnf

MySQL/MariaDB читает конфигурацию из нескольких мест. Порядок загрузки: /etc/mysql/my.cnf → /etc/mysql/mysql.conf.d/*.cnf → ~/.my.cnf. Для MariaDB основной файл: /etc/mysql/mariadb.conf.d/50-server.cnf.

# Проверить, какие файлы читает MySQL:
mysqld --verbose --help 2>/dev/null | grep "Default options" -A 1

Ключевые параметры InnoDB

ПараметрРекомендацияОписание
innodb_buffer_pool_size60–75% RAMГлавный параметр — буфер данных и индексов InnoDB
innodb_log_file_size256M–1GРазмер лога транзакций (больше = быстрее запись)
innodb_flush_log_at_trx_commit1 (safe) / 2 (fast)1 = полная надёжность, 2 = быстрее но риск потери 1 сек
innodb_flush_methodO_DIRECTИсключает двойное кэширование с OS

Оптимальный my.cnf по объёму RAM

Для 2 ГБ RAM:

[mysqld]
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
max_connections = 100
thread_cache_size = 10
table_open_cache = 2000
tmp_table_size = 64M
max_heap_table_size = 64M
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

Для 8 ГБ RAM:

innodb_buffer_pool_size = 5G
innodb_buffer_pool_instances = 4
innodb_log_file_size = 512M
max_connections = 300
tmp_table_size = 128M

Проверка использования InnoDB buffer pool

mysql -u root -p -e "
SELECT 
  FORMAT(@@innodb_buffer_pool_size/1024/1024/1024, 2) AS 'Buffer Pool (GB)',
  FORMAT(Innodb_buffer_pool_pages_data * @@innodb_page_size/1024/1024/1024, 2) AS 'Used (GB)'
FROM information_schema.GLOBAL_STATUS
WHERE Variable_name = 'Innodb_buffer_pool_pages_data';"

Query Cache (MySQL 5.7 и старше)

В MySQL 8.0 Query Cache удалён. В MySQL 5.7 и MariaDB его использование спорно: при высокой записи он создаёт конкуренцию за блокировки. Для высоконагруженных сайтов рекомендуется Redis/Memcached вместо Query Cache.

Применение настроек

sudo systemctl restart mysql
# или
sudo systemctl restart mariadb

# Проверка
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
Используйте MySQLTuner — скрипт автоматически анализирует ваш сервер и даёт конкретные рекомендации по настройке: wget http://mysqltuner.pl/ -O mysqltuner.pl && perl mysqltuner.pl

Ошибки после изменения my.cnf

ОшибкаПричинаРешение
[ERROR] InnoDB: Cannot allocate memory for the buffer poolinnodb_buffer_pool_size выставлен больше, чем реально доступно RAM (без учёта других процессов)Снизить значение до 60–75% от общей RAM с запасом на ОС и другие сервисы
[ERROR] Too many connectionsmax_connections занижен относительно реальной нагрузки, либо пул соединений приложения не закрывает сессииСверить SHOW STATUS LIKE 'Max_used_connections'; с лимитом и приложением
mysqld: unknown variable 'query_cache_size=...'Параметр Query Cache оставлен в my.cnf после обновления на MySQL 8.0, где Query Cache удалён полностьюУдалить все строки query_cache_* из конфигурации

InnoDB vs MyISAM: почему параметры не универсальны

Все параметры innodb_* в этой статье не действуют на таблицы MyISAM — у него нет буфера пула, нет журнала транзакций и нет поддержки внешних ключей. Если в базе остались таблицы MyISAM (часто это system-таблицы старых версий или специально выбранный движок для полнотекстового поиска), их производительность зависит от параметра key_buffer_size, а не от innodb_buffer_pool_size. Смешанные базы требуют настройки обоих буферов, и лишняя память, выделенная под key_buffer_size при отсутствии MyISAM-таблиц, — это память, отобранная у InnoDB буфера без пользы.

Когда тюнинг my.cnf не даст эффекта

Если узкое место — не память и не диск, а сама схема запросов (отсутствующие индексы, SELECT * на широких таблицах, N+1 запросы из ORM), увеличение innodb_buffer_pool_size или tmp_table_size даст лишь временное облегчение симптома. Разница между хорошим и плохим планом запроса на порядки больше, чем разница между хорошими и посредственными настройками my.cnf. Перед тюнингом конфигурации стоит прогнать медленные запросы через EXPLAIN и убедиться, что оптимизировать нечего на уровне SQL.

Проверка эффекта после изменения параметров

# Сверить, что значение реально применилось (а не осталось старым из-за опечатки в секции)
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"

# Отношение cache hit ratio для buffer pool — должно быть близко к 100%
mysql -u root -p -e "
SHOW STATUS LIKE 'Innodb_buffer_pool_read_requests';
SHOW STATUS LIKE 'Innodb_buffer_pool_reads';"
-- hit ratio = 1 - (reads / read_requests), ближе к 1 — лучше

# Полный отчёт по состоянию InnoDB
SHOW ENGINE INNODB STATUS\G

Если Innodb_buffer_pool_reads (физические чтения с диска) остаётся высоким относительно Innodb_buffer_pool_read_requests после увеличения buffer pool, это значит, что рабочий набор данных всё ещё не помещается в память — параметр стоит увеличивать дальше или пересмотреть, какие данные вообще нужно держать в горячем доступе. Диагностика конкретных медленных запросов разобрана в статье про Slow Query Log, а разница движков — в статье про InnoDB и MyISAM.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке