sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQL 13:スロットにプライマリを殺させないでください

    バージョン9.4以降のPostgreSQLの興味深い機能の1つは、レプリケーションスロットを使用してWALファイルの削除を制御する機能です。欠点は、レプリケーションスロットにより、ディスクが古いWALでいっぱいになり、メインの本番サーバーが停止する可能性があることです。この記事では、PostgreSQLレプリケーションスロットと、PostgreSQL13の新機能がこの問題の防止にどのように役立つかについて説明します。

    WALプロダクション

    ご存知のように、WALは、プライマリサーバーでのデータベースの変更(挿入、更新、など)のために作成されます。 。よりアクティブなデータベースはより多くのWALを生成します—非常にアクティブなサーバーでは、毎分何ギガバイトのWALが生成される可能性があります。 WALは、名前が昇順でファイルに書き込まれ、ファイルは常に同じサイズです(16 MBがデフォルトで一般的です)。ファイル内のデータが不要になったら、そのファイルをリサイクルできます。 、これは、後で新しいデータを入力できるように、シーケンス内のより高い番号の位置に名前を変更することを意味します。

    (追加のファイルの作成につながるアクティビティの急増などの特別な状況があります。後で急増がなくなると、それらの余分なファイルはリサイクルされずに削除されます。)

    すべてのデータベース書き込みアクティビティはWALを生成するため、ディスクスペースが使用可能であることが重要です。 WALを格納しているディスクがいっぱいになると、サーバーは新しいトランザクションを処理できなくなり、スタックする可能性があります。さらに悪いことに、サーバーが完全に倒れる可能性があります。したがって、これは絶対に避けなければならない状況です。

    レプリケーションスロット

    PostgreSQLでのレプリケーションは、WALファイルを処理することで機能します。これが機能するためには、すべてのWALファイルが処理されるまで一時的に利用可能である必要があります。したがって、メインのWAL管理者にファイルをリサイクルまたは削除しないように指示するメカニズムが必要です。

    レプリケーションスロットを入力します。スロットは、これを示すメカニズムです。 私たちが取っているバックアップにはそれが必要です WALファイルです。まだ削除しないでください。またはこれ レプリカはまだ処理されていません WALファイルですので、しばらくそのままにしておいてください。

    それ自体では、レプリケーションスロットはほとんどディスクスペースを占有しません。 WAL内の位置へのポインタを含む、ほんの少しのメタデータを格納するだけです。ただし、保護するWALデータは別の問題です。非常にアクティブなサーバーでは、ギガバイト以下で測定できます。

    WAL消費

    物理レプリカへのデータのフィードとは、プライマリサーバーからWALデータをコピーすることを意味します。同様に、論理レプリカはWALデータを読み取る(そして解釈されたバージョンをレプリカに送信する)必要があります。読み取られるWAL位置は、スロットが追跡するものです。レプリカが何らかの方法でWALデータを保護したら、スロットを進めることができます。これにより、プライマリのWAL管理者に、WALファイルを削除できるようになったことを通知します。これは、レプリカがアクティブなときに継続的に発生するため、プライマリサーバーのWALは同じ量のディスクスペースを使用するか、それより少し多く使用します。条件によっては、2倍または10倍でも許容できる場合があります。

    問題は、レプリカが完全に停止し、長期間回復しない場合です。または、レプリカが破棄され、DBAがレプリケーションスロットの削除を忘れた場合。または、スロットがいくつかの実験の忘れられた残り物です。または、レプリカが低速のネットワークリンクを介して供給されている場合でも、予約済みのWALは無制限に大きくなります。そして、それはカチカチと音を立てる爆弾になります。

    スロットサイズの制限

    この問題に対処するために、堀口恭太郎は2017年2月からPostgreSQLパッチを使用して、スロットによって予約されるWALのサイズを制限していました。非常に長いレビューと手直しのプロセスを経て、PostgreSQL 13に統合し、高可用性PostgreSQLファームの管理を改善しました。

    主な原則は、レプリカをフィードしてすべての本番環境を停止するプライマリサーバーを強制終了するよりも、レプリカを強制終了する方がよいということです(スロットを無効にすることで、以下で詳しく説明します)。

    それが機能する方法は非常に簡単です:max_slot_wal_keep_sizeを設定します (ドキュメント)postgresql.confで、レプリケーションスロットが予約できるWALのディスクスペースの最大量。スロットがそのポイントに到達してチェックポイントが発生した場合、そのスロットは無効とマークされ、一部のWALファイルが削除される可能性があります。スロットがwalsenderによってアクティブに使用されていた場合 プロセス、そのプロセスは終了するように通知されます。ウォルマートが再び起動すると、必要なWALファイルがもう存在しないことがわかります。そのスロットを使用しているレプリカは再クローン化する必要があります。

    max_slot_wal_keep_sizeの場合 がデフォルト値であるゼロの場合、制限はありません。スロットがディスクをいっぱいにすると障害が発生するため、これはお勧めしません。

    スロットヘルスの監視

    いくつかの監視機能も含まれています。 pg_replication_slotsの2つの列が関連しています。最も重要なのはwal_statusです 。その列がreservedの場合 、次にスロットはmax_wal_size内のデータを指しています; extendedの場合 その後、max_wal_sizeを超えました 、ただし、wal_keep_sizeのいずれかによって引き続き保護されます またはmax_slot_wal_keep_sizemax_slot_wal_keep_sizeの場合を含む ゼロです)。どちらの状態も良好で正常です。ただし、スロットが制限を超えると、最初にunreservedになります。 、つまり、差し迫った危険にさらされていますが、十分に迅速であれば回復できます。最後に、ステータスはlostになります WALファイルが削除され、リカバリが不可能な場合。

    もう1つの列はsafe_wal_sizeです :このスロットがWALファイルを削除する危険にさらされる前に書き込むことができるWALのバイト数を示します。監視システムでこの列を注意深く監視し、列が少なくなるとアラートを発することをお勧めします。ゼロまたは負の値は、チェックポイントが発生するとすぐにレプリカが停止することを意味します:

    SELECT slot_name, active, wal_status, safe_wal_size
      FROM pg_catalog.pg_replication_slots;

    この新機能により、レプリカの保守がより簡単かつ堅牢になると確信しています。これらの問題が原因で生産が停止しても、これ以上災害が発生しないことを願っています。

    (注:safe_wal_size 13beta3で導入されたため、必ず最新のドキュメントを参照してください。そうしないと、min_safe_lsnが表示されます。 代わりは。無視してください。)

    ありがとう

    この問題の解決に取り組んでくれた堀口恭太郎に特に感謝します。何人かのレビュアーがこれについて深く理解しました。特に澤田正彦、藤井正夫、ジェハン・ギヨーム・デ・ロルテ、アミット・カピラ(順不同)に感謝します。


    1. MariaDBでのLOG()のしくみ

    2. PostgreSQLの時間値から分を引く

    3. MySQLで次に利用可能なIDを見つける

    4. 移行のためのPostgreSQL外部キーチェックを無効にする