Postgres instance manager
=========================

KubernetesのEDB
Postgresは、フェールオーバー管理のための外部ツールに依存しません。これは、Kubernetes
APIサーバーと、 **Postgresインスタンスマネージャー**
と呼ばれるネイティブキーコンポーネントに依存するだけです。

インスタンスマネージャーは、PostgreSQLサーバープロセス\ ``postmaster``
としても知られるライフサイクル全体を処理します。

新しいクラスターを作成すると、オペレーターはインスタンスごとにポッドを作成します。フィールド\ ``.spec.instances``
は、作成するインスタンスの数を指定します。

各ポッドは、メインコンテナの親プロセスPID
1としてインスタンスマネージャーを起動し、PostgreSQLインスタンスを実行します。ポッドのライフタイム中、インスタンスマネージャーはバックエンドとして機能して
`startup, liveness and readiness probes <https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes>`_  を処理します。

スタートアップ、ライブネス、および準備状況プローブ
--------------------------------------------------

KubernetesのEDB Postgresは `PostgreSQL's `pg_isready` <https://www.postgresql.org/docs/current/app-pg-isready.html>`_ を活用

Kubernetesのスタートアップ、ライブネス、および準備状況プローブを実装します。

スタートアッププローブ
^^^^^^^^^^^^^^^^^^^^^^

startupプローブは、
PostgreSQLインスタンスがプライマリかスタンバイかにかかわらず、\ ``pg_isready``
に従って完全に起動していることを確認します。
startupプローブの実行中、livenessプローブとreadnessプローブは無効のままです。
Kubernetes標準に従って、startupプローブが失敗すると、kubeletはコンテナを終了し、再起動します。

EDB
Postgresが提供する起動プローブは、起動プローブが成功するまでに許可される最大時間を秒単位で指定するパラメーター\ ``.spec.startDelay``
を介して構成できます。少なくとも、プローブは\ ``pg_isready`` が\ ``0``
または\ ``1`` を返す必要があります。

デフォルトでは、\ ``startDelay`` は\ ``3600``
秒に設定されます。特定の環境でPostgreSQLが完全に初期化する必要がある時間に基づいて、この設定を調整することをお勧めします。

..  Warning::
   `.spec.startDelay` の設定が低すぎると、livenessプローブが途中でアクティブ化される可能性があり、PostgreSQLが完全に初期化されていない場合は不必要なPodが再起動する可能性があります。

KubernetesのEDB
Postgresは、次のデフォルトパラメーターを使用して起動プローブを構成します。

.. code:: yaml

   failureThreshold: FAILURE_THRESHOLD
   periodSeconds: 10
   successThreshold: 1
   timeoutSeconds: 5

``failureThreshold`` 値は、 ``startDelay`` を\ ``periodSeconds``
で除算することにより自動的に計算されます。

構成の\ ``.spec.probes.startup``
セクションでプローブ設定をカスタマイズできます。

..  Warning::
   カスタムプローブ設定がクラスターの操作要件に合わせて調整されていることを確認して、意図しない中断を回避します。

..  Note::
   プローブ構成の詳細については、 :ref:`probe API documentation <API Reference - v1.25.1>` を参照してください。

``.spec.probes.startup.failureThreshold``
を手動で指定すると、デフォルトの動作がオーバーライドされ、\ ``startDelay``
の自動使用が無効になります。

たとえば、次の構成は、 ``startDelay``
をバイパスして、カスタムプローブパラメーターを明示的に設定します。

.. code:: yaml


   #  ... snip

   spec:
     probes:
       startup:
         periodSeconds: 3
         timeoutSeconds: 3
         failureThreshold: 10

Liveness Probe
^^^^^^^^^^^^^^

livenessプローブは、startupプローブが正常に完了した後に開始されます。その主な役割は、PostgreSQLインスタンスプライマリまたはスタンバイが正常に動作していることを確認することです。これは、
``pg_isready`` ユーティリティを使用して実現します。終了コード ``0``
サーバーが接続を受け入れていることを示します と\ ``1``
起動時やスマートシャットダウン中など、サーバーが接続を拒否していることを示します
は、有効な結果として扱われます。
Kubernetes標準に従って、livenessプローブが失敗すると、kubeletはコンテナを終了し、再起動します。

ポッドが生きていないとして分類されるまでの時間は、
``.spec.livenessProbeTimeout`` パラメーターを介して構成できます。

KubernetesのEDB
Postgresは、次のデフォルトパラメーターを使用してlivenessプローブを構成します。

.. code:: yaml

   failureThreshold: FAILURE_THRESHOLD
   periodSeconds: 10
   successThreshold: 1
   timeoutSeconds: 5

``failureThreshold`` 値は、 ``livenessProbeTimeout``
を\ ``periodSeconds`` で除算することにより自動的に計算されます。

デフォルトでは、\ ``.spec.livenessProbeTimeout`` は\ ``30``
秒に設定されます。これは、livenessプローブが、各チェックの間に10秒の間隔で、3回連続したプローブ障害を検出した場合に障害を報告することを意味します。

構成の\ ``.spec.probes.liveness``
セクションでプローブ設定をカスタマイズできます。

..  Warning::
   カスタムプローブ設定がクラスターの操作要件に合わせて調整されていることを確認して、意図しない中断を回避します。

..  Note::
   プローブ構成の詳細については、 :ref:`probe API documentation <API Reference - v1.25.1>` を参照してください。

``.spec.probes.liveness.failureThreshold``
を手動で指定すると、デフォルトの動作がオーバーライドされ、\ ``livenessProbeTimeout``
の自動使用が無効になります。

たとえば、次の構成は、 ``livenessProbeTimeout``
をバイパスして、カスタムプローブパラメーターを明示的に設定します。

.. code:: yaml


   #  ... snip

   spec:
     probes:
       liveness:
         periodSeconds: 3
         timeoutSeconds: 3
         failureThreshold: 10

Readiness Probe
^^^^^^^^^^^^^^^

スタートアッププローブが正常に完了すると、準備状況プローブが開始されます。その目的は、PostgreSQLインスタンスがトラフィックを受け入れ、要求を処理する準備ができているかどうかを確認することです。ストリーミングレプリカの場合、レプリカが少なくとも1回ソースに接続していることも必要です。
Kubernetes標準に従って、準備状況プローブが失敗した場合、ポッドは未準備としてマークされ、どのサービスからトラフィックを受信しません。

EDB Postgres for
Kubernetesは、準備状況プローブの次のデフォルト構成を使用します。

.. code:: yaml

   failureThreshold: 3
   periodSeconds: 10
   successThreshold: 1
   timeoutSeconds: 5

デフォルト設定が要件に合わない場合は、 ``.spec.probes.readiness``
スタンザでパラメーターを指定して、readnessプローブを完全にカスタマイズできます。例

.. code:: yaml


   #  ... snip

   spec:
     probes:
       readiness:
         periodSeconds: 3
         timeoutSeconds: 3
         failureThreshold: 10

..  Warning::
   カスタムプローブ設定がクラスターの操作要件と一致していることを確認して、意図しない中断を防ぎます。

..  Note::
   プローブの構成の詳細については、 :ref:`probe API <API Reference - v1.25.1>` を参照してください。

シャットダウン制御
------------------

Postgresを実行しているポッドが手動で、またはノードドレイン操作に続いてKubernetesによって削除されると、kubeletはインスタンスマネージャーに終了信号を送信し、インスタンスマネージャーは適切な方法でPostgreSQLのシャットダウンを担当します。
``.spec.smartShutdownTimeout`` および\ ``.spec.stopDelay``
オプションは秒単位であり、PostgreSQLがシャットダウンするまでの時間を制御します。値はデフォルトでそれぞれ180および1800秒です。

シャットダウン手順は2つの手順で構成されます。

1. インスタンスマネージャーは **スマート**
   シャットダウンを要求し、PostgreSQLへの新しい接続を禁止します。このステップは最大\ ``.spec.smartShutdownTimeout``
   秒間続きます。

2. PostgreSQLがまだアップしている場合、インスタンスマネージャーは
   **高速**
   シャットダウンを要求し、既存の接続を終了してすぐに終了します。インスタンスがWALファイルのアーカイブおよび/またはストリーミングを行っている場合、プロセスは\ ``.spec.stopDelay``
   で設定された残り時間まで待機して操作が完了し、強制的にシャットダウンします。このようなタイムアウトは少なくとも15秒である必要があります。

..  Important::
   データベース :ref:`リリース候補の目的 <リリース候補の目的>`  に影響を与えるPostgresクラスターでのデータの損失を回避するには、プライマリインスタンスが実行されているポッドを削除しないでください。この場合、最初に別のインスタンスへのスイッチオーバーを実行します。

スイッチオーバー中のプライマリのシャットダウン
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

スイッチオーバー中のシャットダウン手順は、一般的な場合と少し異なります。実際、オペレーターは、新しいプライマリですべてのデータが利用できるように保証に、選択した新しいプライマリを昇格させる前に、元のプライマリに
**fast** シャットダウンを発行する必要があります。

このため、秒単位で表される\ ``.spec.switchoverDelay``
は、元のプライマリが正常にシャットダウンし、すべてのWALファイルをアーカイブする時間を制御します。デフォルトでは、\ ``3600``
1時間に設定されています。

..  Warning::
   `.spec.switchoverDelay` オプションは :ref:`リリース候補の目的 <リリース候補の目的>` に影響します

PostgreSQLデータベースの :ref:`RTOとRPOのインパクト <RTOとRPOのインパクト>` 低い値に設定すると、RPOよりもRTOが優先される場合がありますが、クラスターレベルおよび/またはバックアップレベルでデータの損失が発生します。逆に、高い値に設定すると、スイッチオーバー中にアクティブなプライマリのないクラスターを長時間放置する間のデータ損失のリスクを取り除くことができます。

フェイルオーバー
----------------

プライマリポッドに障害が発生した場合、クラスターはフェールオーバーモードになります。詳細は :ref:``pg_failover_slots` の有効化 <`pg_failover_slots` の有効化>` を参照してください。

ディスクフル障害
----------------

ストレージの枯渇は、PostgreSQLクラスターのよく知られた問題です。
`PostgreSQL documentation <https://www.postgresql.org/docs/current/diskusage.html#DISK-FULL>`_ 

では、考えられる障害シナリオと、ディスクの使用状況を監視してディスクがいっぱいになるのを防ぐことの重要性を強調しています。

同じことは、KubernetesのEDB
PostgresとKubernetesにも適用されます。 :ref:`モニタリングとメトリック <モニタリングとメトリック>` 

WALセグメントが使用するディスク領域と、Prometheusにエクスポートされたディスク使用量の標準メトリックの確認に関する詳細を提供します。

..  Important::
   実稼働システムでは、データベースを継続的に監視することが重要です。ディスクストレージが使い果たされると、データベースサーバーがシャットダウンする場合があります。

..  Note::
   使い果たしたストレージの検出は、ディスクのサイズと使用状況を正確に報告するストレージクラスに依存しています。これは、KindのようなシミュレートされたKubernetes環境、または`csi-driver-host-path` などのテストストレージクラス実装には当てはまらない場合があります。

WALが含まれるディスクがいっぱいになり、これ以上WALセグメントを保存できなくなると、PostgreSQLは動作を停止します。
KubernetesのEDB
Postgresは、次のWALセグメントを保存するための十分な領域があることを確認することによりこの問題を正しく検出し、復旧が複雑になる可能性のあるフェイルオーバーのトリガーを回避します。

これにより、人間の管理者は根本的な原因に対処できます。

このような場合、ストレージクラスでサポートされている場合、現在最も早いアクションは次のことです。

1. フルPVCのストレージサイズを拡張する

2. ``Cluster`` リソースのサイズを同じ値に増加します

問題が解決され、WALセグメント用の十分な空き領域が確保されると、ポッドが再起動し、クラスターが正常な状態になります。

ドキュメントの :ref:`ボリュームの拡張 <ボリュームの拡張>` も参照してください。
