Где находится файл 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_size | 60–75% RAM | Главный параметр — буфер данных и индексов InnoDB |
innodb_log_file_size | 256M–1G | Размер лога транзакций (больше = быстрее запись) |
innodb_flush_log_at_trx_commit | 1 (safe) / 2 (fast) | 1 = полная надёжность, 2 = быстрее но риск потери 1 сек |
innodb_flush_method | O_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 и старше)
Применение настроек
sudo systemctl restart mysql
# или
sudo systemctl restart mariadb
# Проверка
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"wget http://mysqltuner.pl/ -O mysqltuner.pl && perl mysqltuner.plОшибки после изменения my.cnf
| Ошибка | Причина | Решение |
|---|---|---|
| [ERROR] InnoDB: Cannot allocate memory for the buffer pool | innodb_buffer_pool_size выставлен больше, чем реально доступно RAM (без учёта других процессов) | Снизить значение до 60–75% от общей RAM с запасом на ОС и другие сервисы |
| [ERROR] Too many connections | max_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.