web-dev-qa-db-ja.com

mysqlの警告を解決する方法:「InnoDB:page_cleaner:意図した1000msのループにはXXXmsかかりました。設定は最適ではないかもしれません」

サーバー上でmysql import mysql dummyctrad <dumpfile.sqlを実行しましたが、完了に時間がかかりすぎました。ダンプファイルは約5Gです。サーバーはCentos 6、memory = 16Gおよび8coreプロセッサー、mysql v 5.7 x64-

これらの通常のメッセージ/ステータスは「テーブルフラッシュを待機しています」とメッセージ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

mysqlforuminnodb_lru_scan_depth

innodb_lru_scan_depthの値を256に変更すると、挿入クエリの実行時間が改善され、ログに警告メッセージが表示されなくなりました。デフォルトはinnodb_lru_scan_depth = 1024です。

SET GLOBAL innodb_lru_scan_depth=256;

39
satch_boogie

InnoDB:page_cleaner:意図した1000msのループには4013msかかりました。設定が最適でない場合があります。 (その間、flushed = 1438およびevicted = 0。)

この問題は、データベースの変更率が高いMySQLインスタンスの典型的なものです。 5GBのインポートを実行すると、ダーティページが迅速に作成されます。ダーティページが作成されると、ページクリーナスレッドがダーティページをメモリからディスクにコピーします。

あなたの場合、私はあなたがいつも5GBのインポートをしないと仮定しています。したがって、これは非常に高いデータ負荷率であり、一時的なものです。 InnoDBは徐々に追いつくため、おそらく警告を無視できます。


この警告につながる内部構造の詳細な説明を次に示します。

1秒に1回、ページクリーナーはバッファプールをスキャンしてダーティページを探し、バッファプールからディスクにフラッシュします。あなたが見た警告は、それがフラッシュするダーティページがたくさんあり、それらのバッチをディスクにフラッシュするのに4秒以上かかり、その作業を1秒未満で完了する必要があることを示しています。言い換えれば、噛むことができる以上に噛み付いています。

innodb_lru_scan_depthを1024から256に減らすことでこれを調整しました。これにより、ページクリーナースレッドが1秒に1回のサイクルでダーティページを検索するバッファープールまでの距離が減ります。あなたはそれを小さく噛むように頼んでいます。

バッファプールインスタンスが多数ある場合、フラッシュにより多くの作業が行われることに注意してください。各バッファプールインスタンスのinnodb_lru_scan_depth作業量を食い止めます。そのため、スキャンの深さを減らすことなくバッファプールの数を増やすことで、このボトルネックを誤って引き起こした可能性があります。

innodb_lru_scan_depthのドキュメントには、「デフォルトよりも小さい設定が一般にほとんどのワークロードに適しています」と書かれています。彼らはこのオプションにデフォルトでは高すぎる値を与えたようです。

innodb_io_capacityおよびinnodb_io_capacity_maxオプションを使用して、バックグラウンドフラッシュで使用されるIOPSに制限を設定できます。最初のオプションは、InnoDBが要求するI/Oスループットのソフト制限です。しかし、この制限は柔軟です。フラッシュが新しいダーティページの作成速度に遅れている場合、InnoDBはこの制限を超えてフラッシュ速度を動的に増加させます。 2番目のオプションは、InnoDBがフラッシュレートをどれだけ増加させるかについて、より厳しい制限を定義します。

フラッシュの速度が、新しいダーティページを作成する平均速度に追いつくことができれば、大丈夫です。ただし、ダーティページをフラッシュよりも高速で一貫して作成すると、最終的にバッファプールは、ダーティページがバッファプールのinnodb_max_dirty_page_pctを超えるまでダーティページでいっぱいになります。この時点で、フラッシュ速度は自動的に増加し、再びpage_cleanerが警告を送信する可能性があります。

別の解決策は、より高速なディスクを備えたサーバーにMySQLを配置することです。ページのフラッシュで要求されるスループットを処理できるI/Oシステムが必要です。

平均的なトラフィックで常にこの警告が表示される場合、このMySQLサーバーで書き込みクエリを実行しすぎている可能性があります。スケールアウトし、それぞれが独自のディスクシステムを持つ複数のMySQLインスタンスに書き込みを分割する時が来たかもしれません。

ページクリーナーの詳細をご覧ください。

61
Bill Karwin

ボトルネックはHDDにデータを保存することです。使用しているHDDに関係なく:SSD、通常のHDD、NVMeなど。

このソリューションは主にInnoDBに適用されることに注意してください

私は同じ問題を抱えていて、いくつかの解決策を適用しました。

1番目:何が間違っているのかを確認する

atop -dはディスク使用量を表示します。ディスクが「ビジー」の場合、データベースへのすべてのクエリを停止しようとします(ただし、mysqlサーバーサービスは停止しないでください!)

クエリの数を監視するには、mytop、innotop、または同等のものを使用します。

クエリが0であるが、ディスク使用量が数秒/数分で100%に近い場合、mysqlサーバーはダーティページをフラッシュしようとしている/前述のように何らかのクリーニングを実行している(Bill Karwinの素晴らしい投稿) 。

次に、そのようなソリューションを適用しようとすることができます:

2番目:ハーウェア最適化

アレイがRAID 1 + 0でない場合、この種のソリューションを使用してデータを保存する速度を2倍にすることを検討してください。データを書き込むことで、HDDコントローラーの可能性を広げてみてください。 SSDまたは高速のHDDを使用してみてください。この魂動の適用は、あなたのハーウェアと予算の可能性に依存し、異なる場合があります。

3番目:ソフトウェアの調整

Harware cotrollerは正常に機能しているが、データの保存速度を拡張したい場合は、mysql構成ファイルで設定できます。

3.1。

innodb_flush_log_at_trx_commit = 2-> innodbテーブルを使用している場合/ファイルごとに1つのテーブルを使用して、私の経験から最高の状態で動作します: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何が起こっているかをもう一度確認してくださいtail -f /var/log/mysql/error.log

4番目:一般的な注意事項

一般的な注意事項:これはMySQL 5.6および5.7.22でテストされましたOS: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サーバー内のRAMの総量:200GB

それを実行すると、CPU使用率が高くなることがあります。これは正常なことです。データの書き込みがより高速になり、CPUがより激しく動作するからです。

もちろん、my.cnfを使用してそれを行う場合は、MySQLサーバーを再起動することを忘れないでください。

5日:補足

興味をそそられて、上記のSET GLOBAL innodb_lru_scan_depth=256;でこの癖をしました。

大きなテーブルで作業しても、パフォーマンスに変化はありません。

上記の修正後、警告を取り除くことはできませんでしたが、システム全体が大幅に高速に動作しています。上記はすべて実験にすぎませんが、私は結果を測定しましたが、少し助けになりました。

11
Vilq