Как решить предупреждение mysql: "InnoDB: page_cleaner: цикл 1000 мс потребовал XXX мс. Настройки могут быть не оптимальными"?
Я запустил mysql import mysql dummyctrad Являются ли эти нормальные сообщения / статус "ожидание сброса таблицы" и сообщение содержимое журнала mysql Список процессов: Update-1 mysqlforum, innodb_lru_scan_depth изменение значения innodb_lru_scan_depth на 256 улучшило время выполнения запросов на вставку + отсутствие предупреждающего сообщения в журнале, по умолчанию было задано innodb_lru_scan_depth=1024;InnoDB: page_cleaner: 1000ms intended loop took 4013ms. The settings might not be optimal
2016-12-13T10:51:39.909382Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 4013ms. The settings might not be optimal. (flushed=1438 and evicted=0, during the time.)
2016-12-13T10:53:01.170388Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 4055ms. The settings might not be optimal. (flushed=1412 and evicted=0, during the time.)
2016-12-13T11:07:11.728812Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 4008ms. The settings might not be optimal. (flushed=1414 and evicted=0, during the time.)
2016-12-13T11:39:54.257618Z 3274915 [Note] Aborted connection 3274915 to db: 'dummyctrad' user: 'root' host: 'localhost' (Got an error writing communication packets)
mysql> show processlist \G;
*************************** 1. row ***************************
Id: 3273081
User: root
Host: localhost
db: dummyctrad
Command: Field List
Time: 7580
State: Waiting for table flush
Info:
*************************** 2. row ***************************
Id: 3274915
User: root
Host: localhost
db: dummyctrad
Command: Query
Time: 2
State: update
Info: INSERT INTO `radacct` VALUES (351318325,'kxid ge:7186','abcxyz5976c','user100
*************************** 3. row ***************************
Id: 3291591
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: starting
Info: show processlist
*************************** 4. row ***************************
Id: 3291657
User: remoteuser
Host: portal.example.com:32800
db: ctradius
Command: Sleep
Time: 2
State:
Info: NULL
4 rows in set (0.00 sec)
SET GLOBAL innodb_lru_scan_depth=256;
2 ответа
InnoDB: page_cleaner: цикл, рассчитанный на 1000 мс, занял 4013 мс. Настройки могут быть неоптимальными. (сбрасывается =1438 и выселяется =0 в течение времени.)
Проблема типична для экземпляра MySQL, где у вас высокий уровень изменений в базе данных. Запустив импорт 5 ГБ, вы быстро создаете грязные страницы. Когда создаются грязные страницы, поток очистки страниц отвечает за копирование грязных страниц из памяти на диск.
В вашем случае, я предполагаю, что вы не делаете импорт 5 ГБ все время. Так что это исключительно высокая скорость загрузки данных, и она временная. Вы, вероятно, можете игнорировать предупреждения, потому что InnoDB будет постепенно догонять.
Вот подробное объяснение внутренних органов, приводящих к этому предупреждению.
Один раз в секунду программа очистки страниц сканирует пул буферов на наличие грязных страниц, чтобы сбросить их из пула буферов на диск. Предупреждение, которое вы увидели, показывает, что на нем много грязных страниц, которые нужно очистить, и для их загрузки требуется более 4 секунд, когда эта операция завершится менее чем за 1 секунду. Другими словами, он откусывает больше, чем может жевать.
Вы скорректировали это, уменьшив innodb_lru_scan_depth
с 1024 до 256. Это уменьшает, насколько далеко в пул буферов поток чистильщика страниц ищет грязные страницы во время своего цикла раз в секунду. Вы просите это, чтобы взять меньшие укусы.
Обратите внимание, что если у вас много экземпляров буферного пула, сброс приведет к дополнительной работе. Откусывает innodb_lru_scan_depth
объем работы для каждого экземпляра буферного пула. Таким образом, вы могли непреднамеренно вызвать это узкое место, увеличив число пулов буферов без уменьшения глубины сканирования.
Документация для innodb_lru_scan_depth
говорит: "Параметр меньше значения по умолчанию, как правило, подходит для большинства рабочих нагрузок". Похоже, они дали этой опции значение, которое слишком высоко по умолчанию.
Вы можете установить ограничение на IOPS, используемое для фоновой очистки, с помощью innodb_io_capacity
а также innodb_io_capacity_max
опции. Первый вариант - это мягкое ограничение пропускной способности ввода-вывода, которое будет запрашивать InnoDB. Но этот предел является гибким; если сбрасывание отстает от скорости создания новой грязной страницы, InnoDB будет динамически увеличивать скорость сброса сверх этого предела. Второй вариант определяет более строгий предел того, насколько далеко InnoDB может увеличить скорость очистки.
Если скорость сброса может идти в ногу со средней скоростью создания новых грязных страниц, то все будет в порядке. Но если вы последовательно создаете грязные страницы быстрее, чем их можно очистить, в конечном итоге ваш буферный пул будет заполняться грязными страницами, пока грязные страницы не превысят innodb_max_dirty_page_pct
буферного пула. В этот момент скорость очистки автоматически увеличивается и может снова заставить page_cleaner отправлять предупреждения.
Другим решением было бы разместить MySQL на сервере с более быстрыми дисками. Вам нужна система ввода / вывода, которая может обрабатывать пропускную способность, требуемую при очистке страницы.
Если вы видите это предупреждение все время под средним трафиком, возможно, вы пытаетесь выполнить слишком много запросов записи на этом сервере MySQL. Возможно, пришло время масштабировать и разделять записи по нескольким экземплярам MySQL, каждый из которых имеет свою собственную дисковую систему.
Узнайте больше об очистителе страницы: https://blogs.oracle.com/mysqlinnodb/entry/introducing_page_cleaner_thread_in
Узким местом является сохранение данных на жесткий диск. Какой бы жесткий диск у вас не был: SSD, обычный, NVMe и т. Д.
Обратите внимание, что это решение относится в основном к InnoDB
У меня была такая же проблема, я применил несколько решений.
1-й: проверка, что не так
atop -d
покажет вам использование диска. Если диск "занят", попробуйте остановить все запросы к базе данных (но не останавливайте службу сервера MySQL!)
Чтобы отслеживать, сколько запросов у вас есть, используйте mytop, innotop или эквивалентный.
Если у вас 0 запросов, но использование диска ЕЩЕ ОДНО 100% от нескольких секунд / нескольких минут, то это означает, что сервер mysql пытается очистить грязные страницы / выполнить некоторую очистку, как упоминалось ранее (отличный пост Билла Карвина),
ТОГДА можно попробовать применить такие решения:
2-й: оптимизация аппаратного обеспечения
Если ваш массив не поддерживает RAID 1+0, удвойте скорость сохранения данных с помощью такого решения. Попробуйте расширить возможности вашего жесткого диска с записью данных. Попробуйте использовать SSD или более быстрый HDD. Применение этого решения зависит от ваших аппаратных и бюджетных возможностей и может варьироваться.
3-й: настройка программного обеспечения
Если harware cotroller работает нормально, но вы хотите увеличить скорость сохранения данных, вы можете настроить их в конфигурационном файле mysql:
3.1.
innodb_flush_log_at_trx_commit = 2
-> если вы используете таблицы innodb, то лучше всего работает с одной таблицей на файл:innodb_file_per_table = 1
3.2.
продолжаем с InnoDB:innodb_flush_method = O_DIRECT
innodb_doublewrite = 0
innodb_support_xa = 0
innodb_checksums = 0
Приведенные выше строки в целом сокращают объем данных, которые необходимо сохранить на жестком диске, поэтому производительность выше.
3,3
general_log = 0
slow_query_log = 0
Вышеуказанные строки отключают сохранение журналов, конечно, это еще один объем данных, который будет сохранен на жестком диске
3.4 еще раз проверьте, что происходит, например, tail -f /var/log/mysql/error.log
4-е: общие примечания
Общие примечания: это было протестировано в MySQL 5.6 и 5.7.22 ОС: Debian 9
RAID: диски SSD 1 + 0 База данных: таблицы InnoDBinnodb_buffer_pool_size = 120G
innodb_buffer_pool_instances = 8
innodb_read_io_threads = 64
innodb_write_io_threads = 64
Общий объем оперативной памяти на сервере: 200 ГБ
После этого вы можете наблюдать более высокую загрузку процессора; это нормально, потому что запись данных происходит быстрее, поэтому процессор будет работать сильнее.
Если вы делаете это, используя my.cnf, конечно, не забудьте перезапустить сервер MySQL.
5-е: дополнение
Будучи заинтригованным, я сделал эту причуду сSET GLOBAL innodb_lru_scan_depth=256;
упомянутое выше.
Работая с большими таблицами, я не видел никаких изменений в производительности.
После исправлений выше я не избавился от предупреждений, однако вся система работает значительно быстрее. Все вышеперечисленное - всего лишь эксперимент, но я измерил результаты, они мне немного помогли, так что, надеюсь, это может быть полезно для других.
Это может просто указывать на плохую производительность файловой системы в целом - симптом не связанной проблемы. В моем случае я потратил час на изучение этого, анализ моих системных журналов и почти дошел до точки настройки конфигурации MySQL, когда решил проверить свой облачный хостинг. Оказалось, что от соседа произошли "оскорбительные всплески ввода-вывода". что мой хозяин быстро решил после того, как я обратил на это их внимание.
Я рекомендую узнать вашу базовую / ожидаемую производительность файловой системы, остановить MySQL и измерить производительность файловой системы, чтобы определить, есть ли более фундаментальные проблемы, не связанные с MySQL.