12

Postgres 9.1.3を実行していますが、最近、サーバーの1つで大きなパフォーマンスの問題が発生し始めました。

クエリはしばらくの間正常に実行されましたが、8月1日の時点で、劇的に遅くなっています。問題のあるクエリのほとんどはSelectクエリであるように見えますが(count(*)を使用したクエリは特に悪いです)、一般に、データベースの実行速度は非常に遅くなります。

サーバーでこのクエリを実行しました。これらはデフォルトの構成ファイルに加えた変更です(注:サーバーは以前はこれらの変更で正常に実行されていたため、それほど重要ではない可能性があります):

       name            |                                                current_setting
---------------------------+---------------------------------------------------------------------------------------------------------------
version                   | PostgreSQL 9.1.2 on x86_64-unknown-linux-gnu, compiled by  gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51), 64-bit
autovacuum                | off
bgwriter_delay            | 20ms
checkpoint_segments       | 6
checkpoint_warning        | 0
client_encoding           | UTF8
default_statistics_target | 1000
effective_cache_size      | 4778MB
effective_io_concurrency  | 2
fsync                     | off
full_page_writes          | off
lc_collate                | en_US.UTF-8
lc_ctype                  | en_US.UTF-8
listen_addresses          | *
maintenance_work_mem      | 1GB
max_connections           | 100
max_stack_depth           | 2MB
port                      | 5432
random_page_cost          | 2
server_encoding           | UTF8
shared_buffers            | 1792MB
synchronous_commit        | off
temp_buffers              | 16MB
TimeZone                  | US/Eastern
wal_buffers               | 16MB
wal_level                 | minimal
wal_writer_delay          | 10ms
work_mem                  | 16MB
(28 rows)

Time: 210.231 ms

通常、このような問題が発生した場合、人々が最初に推奨するのは掃除機をかけることであり、私たちはそれを試みました。ほとんどのデータベースを真空分析しましたが、役に立ちませんでした。

一部のクエリで使用Explainしたところ、テーブルにインデックスが含まれていても、Postgresがシーケンシャルスキャンに頼っていることに気づきました。

シーケンシャルスキャンをオフにして、クエリプランナーにインデックスの使用を強制しましたが、それも役に立ちませんでした。

次に、このクエリを試して、Postgresが探しているものを見つけるために通過していた未使用のディスクスペースがたくさんあるかどうかを確認しました。残念ながら、一部のテーブルには少しかさばりがありましたが、システム全体のパフォーマンスを低下させるほど重要ではないようでした。

減速はI/Oに関連している可能性があると思いますが、詳細を把握することはできません。Postgresはばかげているだけですか?もしそうなら、それのどの部分ですか?VMに何か問題がありますか、それとも物理ハードウェア自体に問題がありますか?

私たちが試したりチェックしたりできることについて、他に何か提案はありますか?

編集:

これを早く更新しなかったことをお詫びします。私は他のことに巻き込まれました。

この特定のマシンでは、仮想マシンの設定に1つの小さな変更を加えることで、パフォーマンスが大幅に向上しました。

IOキャッシングを扱う設定があります。元々はONに設定されていました。常に物事をキャッシュすることは物事を遅くしていると私たちは考えました、そして私たちは正しかったです。オフにしたところ、大幅に改善しました。

興味深いことに、他のほとんどのサーバーではすでにこの設定がオフになっています。

他にも問題がありますが、たくさんのご提案をお待ちしておりますので、よろしくお願いします。

4

4 に答える 4

15

あなたの最大の問題はこの行です:

自動真空| オフ

オンにしても問題はすぐには解決しませんが、事態がさら​​に悪化するのを防ぐことができます。これをオフにすることをお勧めするケースはほとんどありません。主な例外は、大きなバルク負荷とそれに続く明示的なVACUUM FREEZE ANALYZEです。その後、autovacuumをオンに戻す必要があります。自動真空をオフにすると、パフォーマンスが低下します。データベースがこのような悪い状態になったら、autovacuumが回復するために提供できるよりも積極的なメンテナンスが必要になります。

checkpoint_segments | 6

SELECTこれを増やすとデータの変更に役立ちますが、ステートメントの速度を向上させることはあまりありません。

fsync | オフ
full_page_writes | オフ

これらの設定は、永続性を犠牲にして書き込みを高速化するようにPostgreSQLに指示します。ハードウェアまたはOS(またはVM)がクラッシュしたり、突然停止したりすると、データベースが破損するため、最後の既知の正常なバックアップから復元するのが最善の策です。(もちろん、ハードウェアはいつでも故障する可能性があるため、データの損失を気にする場合は、適切なバックアップ戦略があります。)

Maintenance_work_mem | 1GB

これは、8GBのVMには高すぎます。その接続でいくつかの重いメンテナンスを実行する前に、いつでも単一の接続でそれをブーストすることができます。

wal_writer_delay | 10ms

経験豊富な専門家でさえ、これをデフォルトよりも優れたパフォーマンスが得られるものに調整するのに苦労しています。ほとんどの場合、そのままにしておくのが最善です。

この時点での最善の策は、pg_dumpallを使用してデータベースクラスターを他のメディアにダンプし、新しいinitdbから開始して、復元することです。データベースのスーパーユーザーとして、を実行しVACUUM FREEZE ANALYZE(そのFREEZEような一括読み込みの後を除いて、通常は推奨されません)、autovacuumをオンにして実行します。

GregSmithの「PostgreSQL9.0HighPerformance」の本を入手して、注意深く読むことを強くお勧めします。(完全な開示、私は本の技術レビューアの1人でしたが、販売からお金を得ることはありません。)彼が最初に推奨することの1つは、PostgreSQLをインストールする前に、RAMとディスクの速度に関するベンチマーク数値を取得することです。あなたが何を扱っているかを知る方法。

于 2012-08-15T02:08:12.373 に答える
11

確認するのは難しいですが、I/Oの問題を疑うのは正しいと思います。発生する可能性があるのは、テーブルが大きくなるか、接続が増えると、キャッシュヒットが減少し始めることです。これにより、I / O要求が増加し、すべてが遅くなります。その間、より多くのクエリが到着し、問題が悪化します。仮想ディスクは必ずしも物理ディスクと同じように動作するとは限らないため、状況は複雑です。

まず、VMでの実際のアクティビティを測定する必要があります(おそらくvmstatまたはiostatを使用して)。次に、実際のハードウェアでも同じことを行います。最後に、両方でいくつかの標準ディスク帯域幅ツールを実行します(特にランダムな読み取り/書き込みミックス)。これで、使用可能なI/Oがどれだけ使用されているかを確認できます。

クエリプランに関しては、スキーマの詳細と説明の分析出力がなければ、誰も言うことができません。

postgresql.orgメーリングリストは、アーカイブの場合でも便利です。また、以下にリンクされている本は素晴らしいです。

http://www.packtpub.com/postgresql-90-high-performance/book

于 2012-08-13T21:27:45.533 に答える
2

(count(*)を使用したクエリは特に悪いです)、

ウィンドウ関数を調べる必要があります

それ以外の場合は、関連するスキーマとクエリを確認しないとわかりません。

于 2012-08-13T19:13:01.873 に答える
0

自動バキュームもオンにします。真空が干渉する量を制御するために設定できる変数がいくつかあります。あなたが持っているRAMの量であなたはあなたの共有バッファを2048MB-3276MBの間に設定する必要があります。システムが使用していないように見える余分なRAMがたくさんあり、他の場所では必要ない場合は、おそらくハイエンドに近づける必要があります。また、sysctlを使用して最大セグメントサイズを確認することもできます。あなたのmaintenance_work_memは本当に高いですが、あなたが主にメンテナンスをしているなら、それは私が最初に思ったほど悪くはないと思います。

于 2014-01-18T10:46:18.923 に答える