PostgreSQLのデプロイメントに少し注意を払い、手入れをすることで、パフォーマンスを保証し、不快な発見を回避し、自信を持って予測可能性を確立することができます。ここにあなたが注意しなければならない7つの事柄があります。
PostgreSQLは、MVCCと呼ばれる手法を使用してトランザクションを実装します。MVCCは長すぎて、詳細に説明するにはトピックが含まれていますが、3つあります。 しなければならない それについて知っている:
- 行を削除すると、その行は将来のトランザクションから「見えない」ものとしてのみマークされます。
- 行を更新すると、新しいバージョンの行が作成されます。古いバージョンは将来のトランザクションに対して非表示としてマークされ、新しいバージョンは表示可能としてマークされます。
- 定期的に、誰かが現在実行中のすべてのトランザクションを調べて、次のように言う必要があります。OK、ここで最も古いトランザクションは#42なので、#42に表示されないすべての行バージョンは、データの一貫性を損なうことなく物理的に削除できます。
これがMVCCの動作方法であり(基本的に)、更新が行われることを意味します。 物理データベースのストレージフットプリントを増やし、削除しない 削減します。 MVCCは物事を行うのに怠惰な方法のように聞こえますが、一貫性とパフォーマンスの両方を提供するため、人気があります。
テーブル内の不要な廃止された行バージョンは、膨張と呼ばれます。 (またはデッドロー )。膨張を解消できるプロセスは、バキュームと呼ばれます。 。 PostgreSQLには、autovacuumと呼ばれる調整可能なしきい値、そしてもちろんVACUUMコマンドを使用して自動的にトリガーされるバキュームプロセスがあります。
一般に、不正確な可視性マップと無駄なディスクI / Oのために、肥大化によってクエリの速度が低下する可能性もあります。
このため、定期的に次のことを行う必要があります。
- データベースの膨張量を監視する
- 定期的にバキュームを実行する
- すべてのテーブルでバキュームが定期的に実行されているかどうかを監視します
テーブルごとの膨張推定値を提供するSQLクエリがいくつかあります。オープンソースのtoolpgmetricsは、手動および自動掃除機の膨張推定値と最終実行時間を提供します。
インデックスも肥大化する可能性があります。インデックスの内部構造はSQLユーザーには不透明であり、インデックスの種類(BTree、ハッシュ、GIN、GISTなど)によって異なりますが、インデックスによって参照される行が削除されると、関連情報が占めるスペースは一般的な考え方のままです。インデックス内は論理的に削除されるだけで、ファイルシステムに戻されません。論理的に削除されたスペースは、後でインデックスで再利用できます。
Postgresにインデックスの物理サイズを縮小させるには2つの方法があります:
- フルバージョンのVACUUMコマンド
- REINDEX
インデックスの肥大化を監視して、少なくとも未使用のスペースの量を認識できるようにする必要があります。行チャーンが高いテーブルでは、通常のインデックス再構築ジョブを設定することは珍しくありません。
インデックスの肥大化は、以前と同じクエリで取得することも、pgmetricsを介して取得することもできます。
特にMVCCシステムでは、トランザクションをできるだけ短くする必要があります。
昨日トランザクションが開始され、その直後にバキュームが実行されたと想像してください。定義上、トランザクションが昨日開始されたときと同じようにすべてのテーブルのすべての行を表示する必要があるため、このトランザクションが開いている限り、それ以上のバキュームは役に立ちません。トランザクションが読み取り専用であっても、これは当てはまります。
その結果、長時間実行されるトランザクションは肥大化を引き起こします。また、システムリソースに依存し、放棄されていないロックを保持し、デッドロックの可能性を高めます。
長時間実行されているトランザクションを監視する最善の方法は、特定の期間を超えて実行されているトランザクションの数についてアラートを設定することです。これは、統計ビューpg_stat_activity
から取得できます。 、そのように:
-- number of transactions that have been open for
-- more than 1 hour
SELECT count(*) FROM pg_stat_activity WHERE xact_start < now()-'1 hour'::interval;
ストリーミングレプリケーションを使用してプライマリPostgreSQLサーバーからホットスタンバイ(別名リードレプリカ)にすべての変更をレプリケートする場合、通常、プライマリで行の更新が発生してから、スタンバイに接続されているアプリケーションに変更が表示されるまでの遅延はわずかです。 。
ただし、このラグが大きくなる場合があります。
- スタンバイシステムは、通常、高負荷またはプロビジョニング不足のために、プライマリからの変更を受信して適用することができず、それに追いつくことができません。
- 劣化したネットワークまたはディスク
- クエリの競合
レプリケーションラグが大きくなるか、さらに悪化するスタンバイでは、古いデータを返すスタンバイと、フェイルオーバーに適さないスタンバイに問い合わせが発生する可能性があります。
ストリーミングレプリケーションを設定している場合は、プライマリとスタンバイの各ペア間のレプリケーションラグを監視することが非常に重要です。アラートを設定して、レプリケーションラグが1分を超えているかどうか、またはセットアップに適したしきい値を確認する必要があります。
この投稿では、プライマリエンドとスタンバイエンドの両方からのレプリケーションラグを測定および監視する方法について詳しく説明しています。
PostgreSQL 9.4で導入されたレプリケーションスロットの使用により、ストリーミングレプリケーションがより堅牢で効率的になります。基本的に、スタンバイはレプリケーションの進行状況をプライマリに報告し、プライマリはこの情報を「レプリケーションスロット」に保存します。
このため、プライマリはスタンバイがどれだけ遅れているかを常に認識しています。これにより、スタンバイがオフラインになったときに、プライマリがWALファイル(レプリケーションを再開するために必要)の十分なバックログを保持できます。したがって、スタンバイが戻ったとき、長い時間が経過した後でも、プライマリはレプリケーションを再開できることを保証できます。
レプリケーションスロットの前に、プライマリは古いWALファイルをクリーンアップする場合があります。これは、スタンバイがそれらを必要としているかどうかを知る方法がなかったためです。スタンバイに必要なWALファイルが削除された場合、レプリケーションを再開する方法はありません。もう一度最初からセットアップする必要があります。
ただし、WALファイルを無期限に保持するというプライマリの動作は、別の問題を引き起こします。スタンバイが廃止され、関連するレプリケーションスロットが削除されなかった場合、WALファイルは永久に保持されます。この理由で保持されるWALファイルは、max_wal_size
によって設定された制限の対象ではありません。 およびその他の構成オプション。
この状況は、WALファイルがディスクスペース全体を使い果たすまで続き、PostgreSQLログファイルに警告も表示されません。
言うまでもなく、非アクティブなレプリケーションスロットは、検出されたときに処理する必要があります。次を使用して、非アクティブなレプリケーションスロットを見つけます:
SELECT slot_name FROM pg_replication_slots WHERE NOT active;
ANALYZEはテーブルに対して実行され、テーブルの内容に関する統計情報を収集および更新します。この情報は、クエリプランナーがすべてのSQLクエリの実行プランを準備するために使用されます。テーブルの内容に関する最新の統計により、実行プランが改善され、クエリが高速化されます。
autovacuumデーモンは通常、VACUUMの後にANALYZEを実行します。ただし、これはANALYZEでは十分な頻度ではない可能性があります。 配布の場合 頻繁に変更される可能性のあるデータのうち、ANALYZEをより頻繁に実行する必要があります。
通常、ANALYZEは非常に適切に動作します。読み取りロックのみが必要であり、リソースを使いすぎず、妥当な時間で完了します。頻繁に実行する側では安全です。
しばらく分析されていないテーブルに注意することは良い考えです。クエリを使用してテーブルが最後に(自動)分析された時刻を確認します:
SELECT schemaname || '.' || relname, last_analyze, last_autoanalyze
FROM pg_stat_user_tables;
CPU負荷、メモリ、ディスク使用量を監視することは、データベースを使用するアプリケーションの増大するニーズを満たすのに十分な容量を手元に確保するのに大いに役立ちます。
PostgreSQLは、1つの接続を処理するために1つのプロセスを生成します。これは現在最もスケーラブルなアーキテクチャではないかもしれませんが、安定性の面で大きく貢献しています。また、OSの平均負荷をより意味のあるものにします。通常、PostgreSQLボックスはPostgreSQLのみを実行するため、平均負荷が3であるということは、通常、CPUコアが使用可能になり、スケジュールできるようになるのを待機している接続が3つあることを意味します。通常の1日または1週間の最大負荷平均を監視することで、CPUフロントでボックスがどの程度オーバープロビジョニングまたはアンダープロビジョニングされているかを見積もることができます。
もちろん、メモリと空きディスク容量は標準的な監視対象です。より多くの接続とより長く実行されるトランザクションは、メモリに対してより高い要求を課します。また、ディスクの空き領域を監視するときは、表領域ごとに追跡することを忘れないでください。