Что делать, если MySQL занимает всю оперативную память

14 Oct 2026, 10:26:29
Если MySQL или MariaDB использует почти всю доступную оперативную память (RAM), сервер может начать работать медленно, сайт — периодически переставать отвечать, а процессы базы данных — завершаться из-за нехватки памяти.
Причиной могут быть слишком большие значения параметров MySQL, большое количество одновременных подключений, тяжёлые SQL-запросы, особенности конфигурации СУБД или недостаточный объём оперативной памяти.
В этой статье рассмотрим, как определить причину высокого потребления RAM, проверить системные журналы и оптимизировать настройки MySQL/MariaDB.

1. Проверка использования оперативной памяти

Сначала проверьте общий объём оперативной памяти и её текущее использование:
free -hПример вывода:


Обратите внимание на столбец available. Он показывает, сколько памяти приблизительно доступно приложениям с учётом возможности освободить часть кэша.
Если доступной памяти почти нет, а система активно использует swap, сервер может испытывать нехватку RAM. При этом само по себе высокое потребление памяти не обязательно означает проблему: MySQL может использовать RAM для кэширования данных и индексов.
Посмотрите процессы, потребляющие больше всего памяти:
ps aux --sort=-%mem | head -15


Для просмотра процессов в реальном времени используйте:
top
В top нажмите M, чтобы отсортировать процессы по потреблению памяти.



Если установлен htop, можно использовать его:
htop
Найдите процессы mysqld или mariadbd. Если они находятся в верхней части списка, проверьте настройки СУБД и текущую нагрузку.
Также учитывайте потребление памяти другими приложениями, например PHP-FPM, Nginx, Redis и контейнерами.

2. Проверка журналов на ошибки нехватки памяти

Linux может принудительно завершить процесс MySQL, если системе не хватает оперативной памяти. Этот механизм называется OOM Killer.
Проверьте сообщения ядра:
dmesg -T | grep -iE 'out of memory|oom|killed process'
Также проверьте журнал systemd:
journalctl -k --since "24 hours ago" | grep -iE 'out of memory|oom|killed process'
Если в выводе присутствуют сообщения наподобие:
Out of memory: Killed process 1234 (mysqld)

это означает, что ядро завершило процесс из-за нехватки памяти. Однако для определения причины следует изучить соседние сообщения в журнале: они могут содержать информацию о доступной памяти и других процессах.
Проверьте состояние службы:
systemctl status mysql
В системах с MariaDB имя службы может быть другим:
systemctl status mariadb
Важно: отсутствие сообщений OOM не означает, что с памятью всё в порядке. Журналы могут быть неполными, старые записи могут отсутствовать, а ограничения памяти контейнера или cgroup могут приводить к завершению процессов без очевидной нехватки RAM на всём сервере.
Если MySQL потребляет почти всю память, но не завершается, проблема может проявляться только в замедлении работы сервера.

3. Проверка конфигурации MySQL/MariaDB

Основные параметры сервера базы данных обычно находятся в следующих файлах:
  • /etc/mysql/my.cnf
  • /etc/mysql/mysql.conf.d/mysqld.cnf
  • /etc/my.cnf
  • /etc/my.cnf.d/
Фактическое расположение зависит от дистрибутива, версии СУБД и способа установки. Не все перечисленные файлы обязательно существуют или используются.
Чтобы посмотреть стандартные пути поиска конфигурации, выполните:
mysql --help 2>/dev/null | grep -A 1 "Default options"


Для проверки параметров работающего сервера подключитесь к MySQL/MariaDB:
mysql -u root -p
После ввода пароля выполните SQL-запрос:
SHOW VARIABLES
WHERE Variable_name IN (
    'innodb_buffer_pool_size',
    'max_connections',
    'sort_buffer_size',
    'join_buffer_size',
    'read_buffer_size',
    'read_rnd_buffer_size',
    'tmp_table_size',
    'max_heap_table_size'
);

Какие параметры влияют на потребление памяти
Параметр

Назначение

innodb_buffer_pool_sizeРазмер буферного пула InnoDB для кэширования данных и индексов
max_connectionsМаксимальное количество одновременных подключений
sort_buffer_sizeБуфер для операций сортировки
join_buffer_sizeБуфер для некоторых операций JOIN
read_buffer_sizeБуфер последовательного чтения
read_rnd_buffer_sizeБуфер чтения строк в определённом порядке
tmp_table_sizeОграничение размера внутренних временных таблиц в памяти в пределах применимых механизмов
max_heap_table_sizeМаксимальный размер таблиц типа MEMORY
Не все буферы выделяются сразу при запуске MySQL. Многие из них могут выделяться отдельно для каждого подключения или конкретной операции. Поэтому сочетание больших буферов и большого числа активных подключений способно привести к значительному потреблению RAM.
При этом нельзя просто сложить все значения параметров и считать результат точным объёмом требуемой памяти. Фактическое потребление зависит от версии СУБД, количества активных операций, конфигурации и особенностей запросов.

4. Оптимизация InnoDB Buffer Pool

Параметр innodb_buffer_pool_size определяет объём памяти, используемой InnoDB для хранения кэшированных данных и индексов.
Посмотрите его текущее значение:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';


Если сервер выделен преимущественно под MySQL, буферный пул может занимать значительную часть оперативной памяти. Однако на сервере с веб-сайтом, PHP-FPM, Nginx и другими приложениями необходимо оставить достаточно RAM для остальных процессов.
Например, на сервере с 8 ГБ RAM и несколькими дополнительными сервисами можно рассмотреть начальное значение 2–3 ГБ, если текущая настройка слишком велика и это подтверждается диагностикой. Это только пример, а не универсальная рекомендация.
Откройте файл конфигурации MySQL и добавьте параметр в секцию [mysqld] либо измените существующее значение:
[mysqld]
innodb_buffer_pool_size = 2G

Перед изменением проверьте текущую конфигурацию и сохраните резервную копию файла.
После изменения конфигурации может потребоваться перезапуск службы.
Для MySQL:
systemctl restart mysql
Для MariaDB:
systemctl restart mariadb
Перезапуск прервёт текущие подключения к базе данных, поэтому выполняйте его с учётом нагрузки на сайт и наличия окна обслуживания.
В некоторых версиях MySQL размер буферного пула можно изменить динамически. Возможность изменения и допустимые значения зависят от версии и конфигурации.
Например, в поддерживающих эту операцию версиях можно выполнить:
SET GLOBAL innodb_buffer_pool_size = 2147483648;
Значение указано в байтах и соответствует 2 ГиБ.
Изменение через SET GLOBAL обычно не сохраняется после перезапуска. Для постоянного применения настройку следует внести в конфигурационный файл. В поддерживаемых версиях MySQL можно также использовать SET PERSIST, предварительно проверив его доступность и особенности работы в конкретной версии.

5. Ограничение количества подключений

Большое количество одновременных подключений может увеличивать потребление памяти, особенно при выполнении тяжёлых запросов.
Проверьте максимальное количество подключений:
SHOW VARIABLES LIKE 'max_connections';

Посмотрите текущее число подключений:
SHOW STATUS LIKE 'Threads_connected';


Узнайте максимальное количество одновременно использовавшихся подключений:
SHOW STATUS LIKE 'Max_used_connections';


Max_used_connections показывает исторический максимум с момента запуска сервера или сброса соответствующей статистики. Этот показатель помогает оценить пиковую нагрузку, но не гарантирует, что будущие пики будут такими же.
Например, если max_connections установлен в 500, а исторический максимум составляет 40, можно рассмотреть уменьшение лимита. Однако сначала следует проверить период наблюдения, пики нагрузки и потребности приложений.
Для изменения настройки в конфигурационном файле:
[mysqld]
max_connections = 150

Значение 150 приведено в качестве примера, а не универсальной рекомендации.
На поддерживающих это изменение версиях параметр можно изменить без перезапуска:
SET GLOBAL max_connections = 150;
Изменение действует на работающий сервер, но обычно не сохраняется после перезапуска без настройки конфигурационного файла или использования поддерживаемого механизма сохранения параметров.
Уменьшение лимита не устранит причину тяжёлых запросов и может привести к ошибкам подключения, если реальная нагрузка превысит новое значение.
Если подключений много, дополнительно проверьте, использует ли приложение пул соединений и корректно ли оно закрывает неиспользуемые подключения.

6. Проверка активных запросов

Если MariaDB занимает много памяти, посмотрите, какие запросы выполняются прямо сейчас: сортировки, JOIN и большие выборки могут требовать значительного объёма памяти.
SHOW FULL PROCESSLIST;
На что обратить внимание:
  • запросы с большим значением в колонке Time (время выполнения в секундах), то есть выполняющиеся долго;
  • состояния Sorting result, Creating sort index, Copying to tmp table: они говорят о сортировках и временных таблицах, которым нужна дополнительная память;
  • очень большое количество одновременных запросов.
Эти признаки сами по себе не доказывают проблему, но показывают, что именно стоит изучить подробнее. Если явных тяжёлых запросов нет, переходите к проверке настроек памяти.

7. Проверка временных таблиц и буферов запросов

MySQL может использовать память для внутренних временных таблиц и обработки отдельных операций.
Проверьте параметры:
SHOW VARIABLES
WHERE Variable_name IN (
    'tmp_table_size',
    'max_heap_table_size',
    'sort_buffer_size',
    'join_buffer_size',
    'read_buffer_size',
    'read_rnd_buffer_size'
);



Если значения слишком велики для доступного объёма RAM, рассмотрите их уменьшение.
Например, можно проверить работу со следующими значениями:
[mysqld]
sort_buffer_size = 2M
join_buffer_size = 2M
read_buffer_size = 1M
read_rnd_buffer_size = 2M
tmp_table_size = 16M
max_heap_table_size = 16M

Это пример умеренных значений, которые необходимо адаптировать к реальной нагрузке и требованиям приложения. Перед изменением сравните их с текущими настройками и оцените последствия.
Уменьшение tmp_table_size и max_heap_table_size может привести к тому, что некоторые временные таблицы будут использовать диск или другой механизм хранения вместо памяти. Это способно снизить потребление RAM, но иногда увеличивает время выполнения запросов.
При этом поведение внутренних временных таблиц зависит от версии СУБД. Например, в MySQL 8.0 используется механизм TempTable, на работу которого также влияют дополнительные параметры, включая temptable_max_ram. В MariaDB механизмы и ограничения могут отличаться.
Поэтому не следует считать, что двух параметров tmp_table_size и max_heap_table_size достаточно для полного контроля всей памяти, используемой временными таблицами.
Не увеличивайте эти параметры без необходимости в надежде ускорить базу данных: на сервере с большим количеством подключений это может привести к обратному эффекту.

8. Проверка swap

Swap позволяет Linux использовать дисковое пространство как дополнительную виртуальную память. Он не заменяет оперативную память и обычно значительно медленнее RAM.
Проверьте состояние swap:
swapon --show
free -h

Для наблюдения за активностью подкачки используйте:
vmstat 1 10

Обратите внимание на столбцы si и so:
  • si — объём данных, считываемых из swap в память.
  • so — объём данных, записываемых из памяти в swap.
Если они регулярно показывают ненулевые значения при высокой нагрузке, система активно перемещает страницы памяти между RAM и swap.
Наличие занятого swap само по себе не означает проблему: Linux может сохранять там давно неиспользуемые страницы. Важнее текущая доступность RAM, активность подкачки и влияние на производительность приложений.
Не отключайте swap на сервере, испытывающем нехватку памяти, без предварительной оценки: это может повысить риск срабатывания OOM Killer.

9. Проверка потребления памяти процессом MySQL

Чтобы наблюдать за использованием памяти в реальном времени, выполните:
watch -n 2 'ps -C mysqld -o pid,%mem,rss,vsz,cmd'
Если используется MariaDB и процесс называется mariadbd, выполните:
watch -n 2 'ps -C mariadbd -o pid,%mem,rss,vsz,cmd'


Если команда не показывает процесс, найдите его через общий список процессов:
ps aux --sort=-%mem | head -15
Поля:
  • %MEM — доля физической памяти, используемая процессом.
  • RSS — объём резидентной памяти процесса в килобайтах.
  • VSZ — объём виртуального адресного пространства; он не равен фактическому потреблению RAM.
RSS включает общие страницы памяти, поэтому его нельзя всегда считать точным объёмом памяти, принадлежащим исключительно MySQL. Кроме того, значение RSS не показывает, на какие именно внутренние структуры СУБД расходуется память.
Для дополнительной диагностики можно использовать smem, если он установлен. В MySQL также можно изучить статистику Performance Schema по памяти, если соответствующая инструментация доступна и включена.
Сравнивайте потребление памяти MySQL с общей памятью сервера, активными запросами и использованием RAM другими приложениями.

10. Перезапуск MySQL при критической нехватке памяти

Если сервер уже испытывает серьёзные проблемы, а MySQL не отвечает, сначала соберите доступные данные: состояние RAM, список процессов и журналы ошибок.
Если перезапуск необходим, используйте соответствующую службу.
Для MySQL:
systemctl restart mysql
Для MariaDB:
systemctl restart mariadb
После перезапуска проверьте состояние службы:
systemctl status mysql --no-pager
Или для MariaDB:
systemctl status mariadb --no-pager
Затем проверьте память и журналы.
Для MySQL:
free -h
journalctl -u mysql --since "15 minutes ago" --no-pager

Для MariaDB:
free -h
journalctl -u mariadb --since "15 minutes ago" --no-pager

Если служба не запускается, изучите журнал ошибок и проверьте конфигурацию. Не повторяйте перезапуск многократно без выяснения причины.
Перезапуск может временно освободить память, но не устраняет первопричину. Если проблема вызвана конфигурацией, тяжёлыми запросами или чрезмерным количеством подключений, она может повториться.
Не завершайте процесс через kill -9 без необходимости: это не является стандартным способом обслуживания MySQL и не позволяет процессу корректно завершить работу.

11. Когда следует увеличить оперативную память

Увеличение объёма RAM стоит рассмотреть, если:
  • Настройки MySQL уже оптимизированы, но доступной памяти регулярно недостаточно.
  • База данных и веб-сервер конкурируют за память.
  • Нагрузка и размер базы данных постоянно растут.
  • Пики одновременных подключений соответствуют реальной потребности приложения.
  • Система регулярно использует swap, наблюдается активная подкачка и фиксируются события OOM.
Перед апгрейдом рекомендуется проверить потребление памяти всеми основными процессами, включая PHP-FPM, Nginx, Redis, контейнеры и другие службы.
Если MySQL размещён на сервере с веб-сайтом, важно учитывать суммарное потребление памяти всеми компонентами, а не только буферный пул базы данных.
Также проверьте, нет ли утечек памяти, неоптимальных запросов или слишком большого количества одновременно выполняющихся задач. Увеличение RAM не всегда устраняет эти проблемы.

Заключение

Если MySQL или MariaDB занимает почти всю оперативную память, действуйте последовательно:
  1. Проверьте free -h, top и список процессов.
  2. Найдите сообщения OOM Killer в системных журналах.
  3. Проверьте размер innodb_buffer_pool_size и значение max_connections.
  4. Изучите активные запросы.
  5. Проверьте размеры буферов и настройки временных таблиц с учётом версии СУБД.
  6. Оцените активность swap и потребление памяти другими приложениями.
  7. Вносите изменения постепенно и наблюдайте за результатами.
Главное: не пытайтесь решить проблему простым уменьшением всех параметров или постоянными перезапусками MySQL. Сначала определите источник потребления памяти, затем корректируйте настройки с учётом объёма RAM, нагрузки, версии СУБД и особенностей приложения.