Оптимизация MySQL: тюнинг my.cnf под ресурсы VPS
MySQL и MariaDB при установке используют скромные лимиты памяти, рассчитанные на любое железо. На VPS с NVMe это означает, что движок InnoDB упирается в диск там, где мог бы работать из RAM. Пройдёмся по ключевым параметрам my.cnf и настроим сервер под реальную конфигурацию.
Содержание
Где искать конфиг и как проверить движок
['MySQL читает несколько файлов конфигурации. Посмотреть порядок и активные пути можно так:', "mysqld --verbose --help | grep -A1 'Default options'\n# частые пути: /etc/mysql/my.cnf, /etc/mysql/mysql.conf.d/, /etc/my.cnf", 'Свои правки кладите в отдельный файл, чтобы обновление пакета не затёрло их:', 'sudo nano /etc/mysql/mysql.conf.d/tuning.cnf', 'Убедитесь, что таблицы используют InnoDB — именно его буферы мы будем настраивать. MyISAM в 2020-х уместен разве что для узких сценариев.', 'SELECT table_name, engine FROM information_schema.tables\nWHERE table_schema = DATABASE();']
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS для MySQLГлавный параметр: innodb_buffer_pool_size
['Buffer pool — это кэш данных и индексов InnoDB в памяти. Он даёт самый заметный прирост: чем больше горячих данных помещается в RAM, тем реже сервер идёт на диск.', '- Для выделенного под БД сервера — 60–70% RAM.
- Если на сервере ещё крутится веб-приложение — оставьте запас, начните с 40–50%.
# /etc/mysql/mysql.conf.d/tuning.cnf\n[mysqld]\ninnodb_buffer_pool_size = 5G\ninnodb_buffer_pool_instances = 4\ninnodb_log_file_size = 1G\ninnodb_log_buffer_size = 32M', 'Разбиение пула на instances уменьшает конкуренцию за блокировки при многопоточной нагрузке, а увеличенный log_file_size снижает частоту сброса журнала.']
Запись, flush и NVMe
['Параметр innodb_flush_log_at_trx_commit управляет компромиссом надёжность/скорость. Значение 1 — максимальная надёжность (fsync на каждый коммит), 2 — заметно быстрее ценой возможной потери последней секунды при отказе ОС.', 'innodb_flush_log_at_trx_commit = 1\ninnodb_flush_method = O_DIRECT\ninnodb_io_capacity = 2000\ninnodb_io_capacity_max = 4000', 'O_DIRECT исключает двойное кэширование через ОС, а высокий io_capacity уместен именно на NVMe: медленному диску такие значения только навредят. На AMD EPYC + NVMe у MAATRIX InnoDB реально выдаёт эти IOPS, поэтому лимит не будет бутылочным горлышком.']
Соединения, кэши и таблицы
['Каждое соединение потребляет память под буферы. Не раздувайте max_connections без нужды — лучше пул на стороне приложения.', 'max_connections = 150\nthread_cache_size = 16\ntable_open_cache = 4000\ntmp_table_size = 64M\nmax_heap_table_size = 64M', 'Важно: query cache в MySQL 8 удалён, а в старых версиях и MariaDB его чаще стоит отключить (query_cache_type = 0) — на нагруженной записи он превращается в узкое место из-за глобальной блокировки.', 'thread_cache_size хранит потоки соединений для повторного использования: при частых коротких подключениях это экономит время на их создании. table_open_cache задаёт, сколько дескрипторов таблиц держится открытыми — на схеме с сотнями таблиц заниженное значение приводит к постоянному переоткрытию файлов и росту нагрузки. tmp_table_size и max_heap_table_size стоит держать равными: если временная таблица в памяти превышает меньший из лимитов, MySQL сбрасывает её на диск, и запросы с GROUP BY и сложными сортировками резко замедляются.']
Применение и диагностика
['После правок перезапустите сервер и проверьте, что значения применились:', 'sudo systemctl restart mysql\nmysql -e "SHOW VARIABLES LIKE \'innodb_buffer_pool_size\';"', 'Включите лог медленных запросов — это главный источник данных для дальнейшей оптимизации схемы и индексов. Всё, что выполняется дольше long_query_time секунд, попадёт в лог, а разобрать его удобно утилитой mysqldumpslow, которая группирует похожие запросы:', 'slow_query_log = 1\nslow_query_log_file = /var/log/mysql/slow.log\nlong_query_time = 1', 'sudo mysqldumpslow -s t /var/log/mysql/slow.log | head -20', 'Помните, что тюнинг конфига даёт эффект лишь до определённого предела: если запрос делает полный скан таблицы без индекса, никакой размер buffer pool это не спасёт. Сначала находите тяжёлые запросы через slow log и команду EXPLAIN, добавляете нужные индексы и только потом крутите параметры памяти под реальный профиль нагрузки.', '- buffer_pool на всю RAM — не остаётся памяти под соединения и ОС, приходит OOM.
- innodb_flush_log_at_trx_commit = 0 на проде — риск потерять до секунды транзакций.
- Высокий io_capacity на медленном диске — лишняя нагрузка без пользы.
Где развернуть MySQL
['MySQL с InnoDB чувствителен к скорости диска и задержке fsync. NVMe у MAATRIX на процессорах AMD EPYC даёт быстрый flush журнала и прогрев buffer pool, а локации UK и США удобны для зарубежных проектов. Оплата картой РФ, СБП, криптой или токеном MAAT решает проблему с иностранными провайдерами, ежедневные бэкапы страхуют базу, а root-доступ даёт полный контроль над my.cnf.']Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS для MySQLЧастые вопросы
Какой размер innodb_buffer_pool_size выбрать?
Для сервера, целиком отданного под БД, — около 60–70% RAM. Если рядом работает веб-приложение, уменьшите долю, чтобы оставить память под него и систему.
Стоит ли включать query cache?
В MySQL 8 его уже нет. В более старых версиях и MariaDB на нагруженной записи он обычно вредит из-за глобальной блокировки — чаще его отключают.
Чем InnoDB лучше MyISAM?
InnoDB даёт транзакции, строковые блокировки и восстановление после сбоя. MyISAM блокирует таблицу целиком и не транзакционен — для большинства задач это неприемлемо.