Как решить mysql warning: "InnoDB: page_cleaner: запрограммированный цикл 1000ms занял XXX мс. Настройки могут быть не оптимальными"?

Я запустил mysql import mysql dummyctrad <dumpfile.sql на сервере, и его выполнение заняло слишком много времени. Файл дампа около 5G. Сервер является процессором Centos 6, память = 16G и 8-ядерная, mysql v 5.7 x64-

Являются ли эти обычные сообщения/статус "ожиданием InnoDB: page_cleaner: 1000ms intended loop took 4013ms. The settings might not be optimal таблицы" и сообщение InnoDB: page_cleaner: 1000ms intended loop took 4013ms. The settings might not be optimal InnoDB: page_cleaner: 1000ms intended loop took 4013ms. The settings might not be optimal

содержимое журнала mysql

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)

Update-1

mysqlforum, innodb_lru_scan_depth

изменение значения innodb_lru_scan_depth на 256 улучшило время выполнения запросов на вставку + отсутствие предупреждающего сообщения в журнале, по умолчанию было задано innodb_lru_scan_depth = 1024;

SET GLOBAL innodb_lru_scan_depth=256;

Ответ 1

InnoDB: page_cleaner: цикл, рассчитанный на 1000 мс, занял 4013 мс. Настройки могут быть неоптимальными. (сбрасывается = 1438 и выселяется = 0 в течение времени.)

Проблема типична для экземпляра MySQL, где у вас высокий уровень изменений в базе данных. Запустив импорт 5 ГБ, вы быстро создаете грязные страницы. Когда создаются грязные страницы, поток очистки страниц отвечает за копирование грязных страниц из памяти на диск.

В вашем случае, я предполагаю, что вы не делаете импорт 5 ГБ все время. Так что это исключительно высокая скорость загрузки данных, и она временная. Вы, вероятно, можете игнорировать предупреждения, потому что InnoDB будет постепенно догонять.


Вот подробное объяснение внутренних органов, приводящих к этому предупреждению.

Один раз в секунду программа очистки страниц сканирует пул буферов на наличие грязных страниц, чтобы сбросить их из пула буферов на диск. Предупреждение, которое вы увидели, показывает, что на нем много грязных страниц, которые нужно очистить, и для их загрузки требуется более 4 секунд, когда эта операция завершится менее чем за 1 секунду. Другими словами, он откусывает больше, чем может жевать.

Вы innodb_lru_scan_depth это, уменьшив innodb_lru_scan_depth с 1024 до 256. Это уменьшит, насколько далеко в пул буферов поток чистильщиков страниц ищет грязные страницы во время своего цикла раз в секунду. Вы просите это, чтобы взять меньшие укусы.

Обратите внимание, что если у вас много экземпляров буферного пула, сброс приведет к дополнительной работе. Он откусывает объем работы innodb_lru_scan_depth для каждого экземпляра пула буферов. Таким образом, вы могли непреднамеренно вызвать это узкое место, увеличив число пулов буферов без уменьшения глубины сканирования.

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

Вы можете установить ограничение на количество операций ввода-вывода в innodb_io_capacity используемое для фоновой innodb_io_capacity, с помощью параметров innodb_io_capacity и innodb_io_capacity_max. Первый вариант - это мягкое ограничение пропускной способности ввода-вывода, которое будет запрашивать InnoDB. Но этот предел является гибким; если сбрасывание отстает от скорости создания новой грязной страницы, InnoDB будет динамически увеличивать скорость сброса сверх этого предела. Второй вариант определяет более строгий предел того, насколько далеко InnoDB может увеличить скорость очистки.

Если скорость сброса может соответствовать средней скорости создания новых грязных страниц, то все будет в порядке. Но если вы последовательно создаете грязные страницы быстрее, чем их можно очистить, в конечном итоге ваш буферный пул будет заполняться грязными страницами, пока грязные страницы не innodb_max_dirty_page_pct буферного пула. В этот момент скорость очистки автоматически увеличивается и может снова заставить page_cleaner отправлять предупреждения.

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

Если вы видите это предупреждение все время под средним трафиком, возможно, вы пытаетесь выполнить слишком много запросов записи на этом сервере MySQL. Возможно, пришло время масштабировать и разделять записи по нескольким экземплярам MySQL, каждый из которых имеет свою собственную дисковую систему.

Подробнее об очистителе страниц:

Ответ 2

Узким местом является сохранение данных на жесткий диск. Какой бы жесткий диск у вас не был: 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: 1 + 0 SSD-накопители База данных: таблицы InnoDB innodb_buffer_pool_size = 120G innodb_buffer_pool_instances = 8 innodb_read_io_threads = 64 innodb_write_io_threads = 64

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

Если вы делаете это, используя my.cnf, конечно, не забудьте перезапустить сервер MySQL.

5-е: дополнение

Будучи заинтригованным, я выполнил эту причуду с SET GLOBAL innodb_lru_scan_depth=256; упомянутое выше.

Работая с большими таблицами, я не видел никаких изменений в производительности.

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