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 , и контейнер просто аварийно завершает работу.

Обычно использование памяти контейнером увеличивается до 21 ГБ примерно за неделю использования, и я думаю, что может остаться там, если мы это сделаем не запускать "большие" операции, но если запускается команда mysqldump , в какой-то момент во время дампа, который просто превысит выделенный предел, и произойдет сбой (это не произойдет, когда мы не достигли ~ 95% использования памяти ранее на этой неделе).

Я не понимаю, почему MySQL не управляет своей памятью лучше и освобождает ее часть для запуска новых команд, которые ему необходимо выполнить?

Мы попытались поставить mysqldump команды в другом контейнере, чтобы попытаться «изолировать» эту большую операцию n, но это, похоже, ничего не меняет, основная часть работы по-прежнему выполняется контейнером Mysql, который в конечном итоге аварийно завершает работу, когда другой контейнер выполняет дамп.

На что мы должны обратить внимание? Наши настройки просто не в порядке? Мы настраиваем их после запуска mysqltuner.pl, и я могу выполнить новый запуск, если вы считаете, что проблема заключается в этом.

У нас около 700 баз данных с ~ 40 таблицами в каждой и, возможно, около 10 одновременных подключений mysql в в среднем с некоторыми всплесками на 30 или 50. БД имеют размер от 10 до 200 МБ.

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

2
задан 29 April 2019 в 14:31
3 ответа

Запустите mysqldump с параметром - quick .

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

Нет, я не знаю, почему они назвали эту опцию - быстро .

1
ответ дан 3 December 2019 в 12:29

Есть статья из Percona, которая может быть полезна:

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

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

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

24 апреля 02:43:18 ядро ​​db01: Недостаточно памяти: завершить процесс 22211 (mysqld) score 986 или жертвовать потомком

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

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

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

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

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

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

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

0
ответ дан 3 December 2019 в 12:29

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

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

0
ответ дан 3 December 2019 в 12:29

Теги

Похожие вопросы