Mysql не хватает памяти во время резервного копирования (контейнер Docker)
У нас есть контейнер, выполняющий MariaDB, и несколько других небольших контейнеров на хосте. Контейнеру Mysql было выделено 21 ГБ памяти (из общего объема 32 ГБ), а также несколько других параметров со следующими командами в docker-compose:
db:
command:
- --innodb_buffer_pool_size=4294967296
- --query_cache_size=268435456
- --tmp_table_size=1073741824
- --max_heap_table_size=1073741824
- --table_open_cache=20000
- --max_connections=1000
- --performance_schema
mem_limit: 21g
Проблема, с которой мы столкнулись, заключается в том, что контейнеру mysql не хватает памяти во время некоторых операций резервного копирования, а именно: mysqldump
команды, и контейнер просто вылетает.
В основном использование памяти контейнером достигает 21G в течение примерно недели использования, и я думаю, что может остаться там, если мы не запустим какую-либо "большую" операцию, но если mysqldump
Команда запускается, в какой-то момент во время дампа, который просто устанавливает его сверх выделенного лимита, и он вылетает (этого не происходит, когда мы не достигли ~95% использования памяти ранее на этой неделе).
Я не понимаю, почему MySQL не управляет своей памятью лучше и освобождает некоторые из них для запуска новых команд, которые ему нужно выполнить?
Мы пытались положить mysqldump
Команды в другом контейнере, чтобы попытаться "изолировать" эту большую операцию, но это, похоже, ничего не меняет, основная часть работы по-прежнему выполняется контейнером Mysql, который в конечном итоге завершается сбоем, когда другой контейнер выполняет дамп.
Что мы должны смотреть в? Наши настройки просто не в порядке? Мы настроили их после запуска mysqltuner.pl, и я могу сделать новый запуск, если вы думаете, что в этом проблема.
У нас около 700 баз данных с ~40 таблицами в каждой и, возможно, в среднем около 10 одновременных соединений mysql с некоторыми всплесками 30 или 50. Размеры баз данных составляют от 10 МБ до 200 МБ.
Любая помощь приветствуется, спасибо!
3 ответа
Бежать mysqldump
с --quick
вариант.
По умолчанию mysqldump пытается выгрузить целые таблицы одновременно, что означает, что он должен загрузить всю таблицу в память, и когда память ограничена mysqldump
может потерпеть неудачу. --quick
опция переключается на дамп по строкам, который немного медленнее и создает файлы дампа немного большего размера, но использует гораздо меньше памяти.
Нет не знаю почему назвали опцию --quick
,
Если вы не хотите выделять больше памяти для mysql, вы можете попробовать настроить сервер репликации и выполнить mysqldump оттуда, проблема в том, что mysqldump опасен, когда ваш сервер загружен. Посмотрите параметры, связанные с производительностью, которые также могут помочь https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html
Надеюсь, это поможет.
Есть статья от Percona, которая может быть полезна:
https://www.percona.com/blog/2016/05/03/best-practices-for-configuring-optimal-mysql-memory-usage/
Этот отрывок кажется частично соответствующим:
Следующая вещь, когда дело доходит до конфигурации ОС, это установка убийцы Out Of Memory. Возможно, вы видели такое сообщение в вашем файле журнала ядра:
24 апреля 02:43:18 ядро db01: Недостаточно памяти: процесс Kill 22211 (mysqld), оценка 986 или жертва ребенка
Когда сам MySQL виноват, это довольно рационально. Однако также возможно, что настоящей проблемой были некоторые выполняемые вами пакетные действия: сценарии, резервное копирование и т. Д. В этом случае вы, вероятно, захотите, чтобы эти процессы были завершены, если в системе недостаточно памяти, а не MySQL.
Чтобы сделать MySQL менее вероятным кандидатом на убийство OOM, вы можете настроить поведение, чтобы сделать MySQL менее предпочтительным, с помощью следующего:
echo '-800'> / proc / $ (pidof mysqld) / oom_score_adj
Это заставит ядро Linux предпочитать сначала убивать других потребителей большой памяти.
================================================== ======================
Очевидно, что вы хотите расставить приоритеты в своей работе mysqldump, но если есть другие процессы, использующие память, вы можете убить процессы, если считаете, что они являются излишним более высоким приоритетом для завершения.
Я не уверен, как вы пишете свои дампы. Я думаю, что это может помочь разбить ваши дампы на более мелкие группы пакетов (наборы таблиц / базы данных), чтобы поддерживать объем памяти на высоком уровне. Просто некоторые мысли по этому поводу.