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, но если есть другие процессы, использующие память, вы можете убить процессы, если считаете, что они являются излишним более высоким приоритетом для завершения.

Я не уверен, как вы пишете свои дампы. Я думаю, что это может помочь разбить ваши дампы на более мелкие группы пакетов (наборы таблиц / базы данных), чтобы поддерживать объем памяти на высоком уровне. Просто некоторые мысли по этому поводу.

Другие вопросы по тегам