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