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

Я побежал в MySQL импорт dummyctrad в MySQL

являются ли эти обычные сообщения / статус "ожидание таблицы флеш" и сообщение 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)

Processlist:

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)

обновление-1

mysqlforum ,innodb_lru_scan_depth

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

SET GLOBAL innodb_lru_scan_depth=256;

2 ответов


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

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

в вашем случае, я предположим, вы не делаете импорт 5GB все время. Таким образом, это исключительно высокая скорость загрузки данных, и это временно. Вероятно, вы можете игнорировать предупреждения, потому что 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


узким местом является сохранение данных на HDD. Любой HDD у вас есть: SSD, обычный, NVMe и т. д.

обратите внимание, что это решение применяется в основном к InnoDB

у меня была такая же проблема, я применил несколько решений.

1-й: проверка, что случилось

atop -d покажет вам использование дискового пространства. Если диск "занят", попробуйте остановить все запросы к базе данных (но не останавливайте службу mysql server!)

чтобы проверить, сколько запросов вы имейте, используйте mytop, innotop или эквивалент.

если у вас есть 0 запросов, но использование диска все еще рядом со 100% от нескольких секунд / нескольких минут, то это означает, что сервер mysql пытается очистить грязные страницы / сделать некоторую очистку, как упоминалось ранее (отличный пост Билла Карвина).

тогда вы можете попробовать применить такие решения:

2nd: оптимизация harware

если Ваш массив не находится в RAID 1+0, подумайте о двойной скорости сохранения данных, используя такой вид решение. Попробуйте расширить возможности HDD cotroller с помощью записи данных. Попробуйте использовать SSD или более быстрый HDD. Применение этого soultion зависит от ваших harware и бюджетных возможностей и может варьироваться.

3nd: настройка программного обеспечения

если harware cotroller работает нормально, но вы хотите расширить скорость сохранения данных, которые вы можете настроить в файле конфигурации mysql:

3.1.

innodb_flush_log_at_trx_commit = 2 -> Если вы используете InnoDB таблицы Он работает от моего experisnce лучше всего с одним таблица на файл: innodb_file_per_table = 1

3.2.

продолжение с InnoDB: innodb_flush_method = O_DIRECT innodb_doublewrite = 0 innodb_support_xa = 0 innodb_checksums = 0

строки выше в целом уменьшают объем данных, необходимых для сохранения на HDD, поэтому производительность больше.

3.3

general_log = 0 slow_query_log = 0

строки выше отключить сохранение журналов, конечно, это еще один объем данных, которые будут сохранены на HDD

3.4 проверьте еще раз, что происходит usit например tail-f/var/log/mysql / ошибка.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 Общий объем оперативной памяти на сервере: 200GB

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

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

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

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

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

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