Назад | Перейти на главную страницу

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 МБ.

Любая помощь приветствуется, спасибо!

Бегать mysqldump с --quick вариант.

По умолчанию mysqldump пытается выгрузить сразу целые таблицы, то есть он должен загрузить всю таблицу в память, а когда память ограничена mysqldump может потерпеть неудачу. В --quick опция переключается на выгрузку по строкам, что немного медленнее и создает файлы дампа немного большего размера, но использует гораздо меньше памяти.

Нет, я не знаю, почему назвали вариант --quick.

Если вы не хотите выделять больше памяти для mysql, вы можете попробовать настроить сервер репликации и выполнить mysqldump оттуда, проблема в том, что mysqldump опасен, когда ваш сервер загружен. Пожалуйста, посмотрите параметры, связанные с производительностью, которые также могут помочь https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html#mysqldump-performance-options

Надеюсь, это поможет.

Может быть полезна статья от Percona:

https://www.percona.com/blog/2016/05/03/best-practices-for-configuring-optimal-mysql-memory-usage/

Этот отрывок кажется частично актуальным:

Следующее, что нужно сделать, чтобы настроить ОС, - это установка убийцы нехватки памяти. Возможно, вы видели подобное сообщение в файле журнала ядра:

24 апреля 02:43:18 db01 kernel: Out of memory: убить процесс 22211 (mysqld) с оценкой 986 или пожертвовать дочерним

Когда виноват сам MySQL, это довольно разумный поступок. Однако также возможно, что реальная проблема заключалась в некоторых выполняемых вами пакетных действиях: сценарии, резервное копирование и т. Д. В этом случае вы, вероятно, захотите, чтобы эти процессы завершались, если в системе недостаточно памяти, а не в MySQL.

Чтобы сделать MySQL менее вероятным кандидатом на убийство OOM-убийцей, вы можете настроить поведение, чтобы сделать MySQL менее предпочтительным, со следующим:

echo '-800'> / proc / $ (pidof mysqld) / oom_score_adj

Это заставит ядро ​​Linux в первую очередь убить других тяжелых потребителей памяти.

================================================== ======================

Очевидно, вы хотите установить приоритет своей операции mysqldump, но если есть другие процессы, использующие память, вы можете убить процессы, которые, по вашему мнению, являются излишними, с более высоким приоритетом для завершения.

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