PostgreSQLチェックポイントで何が起こりますか?


22

チェックポイントログの一部を次に示します。

2014-03-26 11:51:29.341 CDT,,,18682,,532854fc.48fa,4985,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 15047 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 30 recycled; write=68.980 s, sync=1.542 s, total=70.548 s; sync files=925, longest=0.216 s, average=0.001 s",,,,,,,,,""
2014-03-26 11:56:05.430 CDT,,,18682,,532854fc.48fa,4987,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 16774 buffers (1.6%); 0 transaction log file(s) added, 0 removed, 31 recycled; write=72.542 s, sync=17.164 s, total=89.733 s; sync files=885, longest=3.812 s, average=0.019 s",,,,,,,,,""
2014-03-26 12:01:21.650 CDT,,,18682,,532854fc.48fa,4989,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 14436 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 33 recycled; write=122.350 s, sync=5.212 s, total=127.676 s; sync files=924, longest=3.740 s, average=0.005 s",,,,,,,,,""
2014-03-26 12:06:25.028 CDT,,,18682,,532854fc.48fa,4991,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 13277 buffers (1.3%); 0 transaction log file(s) added, 0 removed, 29 recycled; write=126.217 s, sync=5.733 s, total=131.991 s; sync files=894, longest=1.859 s, average=0.006 s",,,,,,,,,""
2014-03-26 12:10:41.958 CDT,,,18682,,532854fc.48fa,4993,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 20765 buffers (2.0%); 0 transaction log file(s) added, 0 removed, 28 recycled; write=88.015 s, sync=10.818 s, total=98.872 s; sync files=881, longest=2.690 s, average=0.012 s",,,,,,,,,""

データベースが非常に遅い場合があることに気付きました-通常より短い非常に多くのクエリが現在よりずっと長くスタックしているのを見ることができます。それは明確な犯人なしで定期的に起こります。

質問:チェックポイントがこれを引き起こす可能性はありますか?チェックポイントの「同期」フェーズではどうなりますか?

回答:


32

PostgreSQLは、操作中に変更をトランザクションログファイルに記録しますが、実際のデータベーステーブルにすぐにはフラッシュしません。通常は、変更をメモリに保持し、要求があったときにメモリから変更を返します。ただし、RAMがいっぱいになり始め、それらを書き出す必要がある場合を除きます。

これは、クラッシュした場合、ディスク上のテーブルが最新のものにならないことを意味します。バックアップを開始する前に、トランザクションログを再生して、ディスク上のテーブルに変更を適用する必要があります。大きな、ビジーなデータベースの場合は、時間がかかる場合があります。

そのため、トランザクションログが永久に増大し続けることがないように、PostgreSQLは定期的にチェックポイントを実行し、DBがクリーンな状態であることを確認します。保留中のすべての変更をディスクにフラッシュし、変更のクラッシュリカバリレコードを保持するために使用されていたトランザクションログをリサイクルします。

このフラッシュは2つのフェーズで発生します。

  • テーブルwrite()のダーティのバッファリングshared_buffers; そして
  • fsync() 変更が実際にディスクにヒットすることを確認するために影響を受けるファイルの

どちらもディスクI / Oの負荷を増加させる可能性があります。これらの書き込みによって引き起こされる競合により、読み取りが遅くなり、トランザクションをコミットするために必要なWALセグメントのフラッシュも遅くなります。

これは長年の課題でしたが、RAMが増え、より多くのデータをバッファリングして書き出すのに時間がかかるシステムが増えているため、状況は悪化しています。このLWN.netの記事で説明されているように、現時点でこれに対処する方法について、LinuxコミュニティとPostgreSQLコミュニティの間で議論があります。(LWN.netは、人々が購読しなければ、この種の素晴らしい作品を書き続けることができません。私は購読者であり、このリンクは有用で有益であるため、このリンクを共有しています。ある種の。)

現時点でチェックポイントの影響を減らすためにできる主なことはcheckpoint_completion_target、最終チェックポイントが到着するまでにより多くのデータが書き出されるようにチェックポイントアクティビティを広げることです。ただし、これにはコストがかかります-ページを(たとえば)10回更新すると、クラッシュの安全性のために厳密に1回だけ書き込む必要がある場合でも、チェックポイントの前に高い完了ターゲットで複数回ディスクに書き込まれる可能性があります。完了ターゲットを高くすると、I / Oパターンがよりスムーズになりますが、全体的なI / Oオーバーヘッドが増えます。

他にできることは、オペレーティングシステムがバッファされた書き込みを取得したらすぐにデータの書き込みを開始するように指示することです。これはカーネル側の設定にcheckpoint_completion_target似ており、同様のトレードオフがあります。参照してくださいLinuxのVMのマニュアルを参照して、特にdirty_background_bytesdirty_background_ratiodirty_expire_centisecs


書き込みは長期間にわたって広まっており、問題を引き起こしているとは思わない。同期についてはどうでしょうか、それは万が一世界を停止するような操作ですか?
コンラッドガルス14年

@KonradGarus同期世界を止めるような種類の操作ではありませんが、とにかく頻繁に行われます。上記にリンクした記事を読んでください。かなり技術的な観点からではありますが、問題のタイムリーで有用な要約です。短いバージョンは「Linux上のfsync()は、fsync()と同時に発生するI / Oのパフォーマンスを完全に損なう傾向があります」です。上記のチューニングオプションを使用してこれを緩和し、fsyncでフラッシュする必要がある量を減らすことができます。
クレイグリンガー14年

1

超過に起因する汚れOSのファイルシステムバッファのフラッシュdirty_bytesdirty_ratio ある操作をブロックフォアグラウンドを!

カーネル調整パラメータはdirty_bytesdirty_background_bytesdirty_ratiodirty_background_ratioおよびdirty_centisecs制御ディスクに汚れたOSのファイルシステムバッファのフラッシュ。 dirty_bytesバイト単位のしきい値でdirty_ratioあり、合計メモリの比率としてのしきい値です。 dirty_background_bytesdirty_background_ratio同様のしきい値ですが、フラッシュはバックグラウンドで発生し、完了するまで他の読み取り/書き込み操作をブロックしません。 dirty_centisecsフラッシュが開始されるまでに経過できるセンチ秒数です。

最近、最近のマシンのメモリサイズが劇的に増加したため、これらの調整パラメータのデフォルトはLinuxで低くなりました。5および10%の均一比dirty_background_ratio及びdirty_ratio256ギガバイトマシン上でI / Oシステムをフラッディングすることができます。

バックグラウンドでダーティバッファのフラッシュを開始dirty_background_bytesまたはチューニングdirty_background_ratioするのは難しいです。幸いなことに、適切なファイルに新しい値をエコーすることで、PostgreSQLまたはホストを停止することなく、これらの設定を調整できます。

$ sudo echo [int value of bytes] > /proc/sys/vm/dirty_background_bytes

たとえば、汚れたバイト数を設定して、バックグラウンドフラッシュをトリガーします。バッテリバックアップ、キャパシタバックアップ、またはフラッシュメモリのRAIDカードを使用している場合(クラッシュした場合にデータを保持たいですか?)dirty_background_bytes、書き込みキャッシュバッファサイズの1/2に調整することから始めます。そしてdirty_bytesそのサイズの3/4まで。I / Oプロファイルをiostatsで監視し、遅延の問題が引き続き発生する場合は、データベースの書き込み負荷がファイルバッファーキャッシュのフラッシュを圧倒していることを意味します。遅延が改善するまで値を下げるか、I / Oサブシステムのアップグレードを検討してください。FusionIOカードとSSDは、極端なI / Oスループットの2つの可能性です。

がんばろう!


「ダーティ」データに関するコメントは、速度低下の関連ポイントです。基本的に、ダーティ比が大きいほど、フラッシュを開始する前にダーティデータに割り当てられるバッファが増えます。したがって、フラッシュ遅延を最小限に抑えることは、ダーティバッファを増やすか、ダーティデータがメモリに残る時間を増やすことを意味します。
ピーターTeoh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.