PostgreSQL cluster replicas get out of sync
The replicas for Cloud Native PostgreSQL and EDB Postgres clusters occasionally get out of sync with the primary node.
If you use IBM Cloud PakĀ® foundational services version 4.18.0 or earlier with EDB Postgres, see IBM Software Hub.
For foundational services versions 4.19.x with IBM Postgres, see the following sections.
Symptoms
This issue can manifest in several ways:
- You see a mismatch in the data between the replicas.
- The database cluster is stuck in the
Waiting for the instances to become activestate.To check the status of the database cluster, run the following command. Replace<instance-namespace>with the namespace where thecommon-service-dbcluster instance is installed.oc get cluster.pg.ibm.com \ -n <instance-namespace> - One or more of the database pods are in the
CrashLoopBackOffstate or are stuck in theRunningstate.To check the status of the database pods, run the following command:oc get pods \ -n <instance-namespace> \ -l pg.ibm.com/podRole=instanceNote: If the command returnscommon-service-dbpods in theCrashLoopBackOffstate, complete step 1b in Diagnosing the problem to determine whether you need to contact IBM Support for help with resolving the issue. - A backup checkpoint job, such as
zen-checkpoint-backup-job-*, fails.
Diagnosing the problem
Confirm that the replicas are out of sync:
- Check the logs for errors:
- Search the PostgreSQL operator logs for the phrase,
WAL. In the following command, replace the<operator-namespace>value with the namespace where IBM Cloud PakĀ® foundational services, also called the IBM Common Service Operator, is installed.oc logs -n <operator-namespace> \ -l app.kubernetes.io/name=cloud-native-postgresql \ | grep "WAL"Look for messages with the following phrases:missing WAL filestried restoring WALs
- Search the PostgreSQL pod logs for the phrase,
Failed to execute pg_rewind:oc logs -n <instance-namespace> \ -l pg.ibm.com/podRole=instance \ | grep '"level":"error"' \ | grep 'Failed to execute pg_rewind'Note: If thecommon-service-dbpods are in theCrashLoopBackOffstate, and you see the preceding phrases in thecommon-service-dbpod logs, contact IBM Support for assistance for resolving the following issue:common-service-db pod in CrashLoopBackOff state due to EDB WAL storage full.
For other pods, if you see either of the preceding phrases in the log files, proceed to the next step.
- Search the PostgreSQL operator logs for the phrase,
- Set the
POSTGRES_CLUSTERenvironment variable to the name of the PostgreSQL cluster where you want to check the replica status:export POSTGRES_CLUSTER=<cluster-name>Note: If you don't know the name of the PostgreSQL cluster, run the following command to see a list of any PostgreSQL clusters in the project:oc get cluster.pg.ibm.com \ -n <instance-namespace> - If you have the Cloud Native PostgreSQL (CNP) plug-in for
kubectl, you can use it to check the status of the PostgreSQL cluster:
- Run the following command to check the status of the cluster:
kubectl cnp status ${POSTGRES_CLUSTER} - Compare the
Current LSNof the primary node with theReceived LSNandReplay LSNfor the replicas.- If the log sequence number (LSN) is the same, the replicas are in sync.
- If the LSN is different, proceed to Resolving the problem.
- Run the following command to check the status of the cluster:
- If you do not have the CNP plug-in, run the following commands to compare the log sequence number on the primary node and on the replicas:
- Set the
PRIMARY_POD,PRIMARY_POD_LSN,REPLICA_POD, andREPLICA_POD_LSNenvironment variables:- For environments with one replica pod, set the
PRIMARY_PODandREPLICA_PODenvironment variables:export PRIMARY_POD=$(oc get pod -n <instance-namespace> -l pg.ibm.com/cluster=${POSTGRES_CLUSTER},role=primary -o jsonpath="{.items[0].metadata.name}") export REPLICA_POD=$(oc get pod -n <instance-namespace> -l pg.ibm.com/cluster=${POSTGRES_CLUSTER},role=replica -o name)Set thePRIMARY_POD_LSNandREPLICA_POD_LSNenvironment variables:export PRIMARY_POD_LSN=$(oc exec ${PRIMARY_POD} -n <instance-namespace> -c postgres -- psql -U postgres -c "SELECT pg_current_wal_lsn();" | sed -n '3p' | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//') export REPLICA_POD_LSN=$(oc -n <instance-namespace> exec -t ${REPLICA_POD} $ -c postgres -- psql -U postgres -c "SELECT pg_last_wal_replay_lsn();" | sed -n '3p' | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//') - For environments with multiple replica pods, set the
PRIMARY_PODenvironment variable:export PRIMARY_POD=$(oc get pod -n <instance-namespace> -l pg.ibm.com/cluster=${POSTGRES_CLUSTER},role=primary -o jsonpath="{.items[0].metadata.name}")- Get the name of the replica pods. The command returns the list of pods that are associated with the specified PostgreSQL cluster,
(${POSTGRES_CLUSTER}).oc get pod -n <instance-namespace> -l pg.ibm.com/cluster=${POSTGRES_CLUSTER},role=replica -o name - Set the
REPLICA_PODenvironment variable to one of the replica pods:export REPLICA_POD=<pod-name> - Set the
PRIMARY_POD_LSNandREPLICA_POD_LSNenvironment variables:export PRIMARY_POD_LSN=$(oc exec ${PRIMARY_POD} -n <instance-namespace> -c postgres -- psql -U postgres -c "SELECT pg_current_wal_lsn();" | sed -n '3p' | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//') export REPLICA_POD_LSN=$(oc -n <instance-namespace> exec -t ${REPLICA_POD} $ -c postgres -- psql -U postgres -c "SELECT pg_last_wal_replay_lsn();" | sed -n '3p' | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//')
- Get the name of the replica pods. The command returns the list of pods that are associated with the specified PostgreSQL cluster,
- For environments with one replica pod, set the
- For each replica, compare the LSN for the primary node and the replica pod:
The LSN of the primary node and the replica pod should be the same. If the LSN of any of the replica pods is different than the LSN of the primary pod, the PostgreSQL cluster is in an out-of-sync state and you must complete Resolving the problem.echo $PRIMARY_POD_LSN, $REPLICA_POD_LSN
- Set the
Resolving the problem
If the LSN of the primary pod and the replica pod are different, complete the following steps:
- Check whether the EDB Postgres cluster is fenced:
oc get cluster.pg.ibm.com ${POSTGRES_CLUSTER} -o yaml | grep fencedInstances - If the EDB Postgres cluster is fenced, lift the fencing:
oc annotate cluster.pg.ibm.com ${POSTGRES_CLUSTER} pg.ibm.com/fencedInstances- - Wait several minutes. Then, check the status of the EDB Postgres cluster:
oc get cluster.pg.ibm.com ${POSTGRES_CLUSTER} \ -n <instance-namespace>- If the status is
Cluster in healthy state, no additional resolution is required. - If the status is not
Cluster in healthy state, continue to the next step.
- If the status is
- Get the name of the persistent volume claim associated with the replica pod:
In theoc describe pod ${REPLICA_POD} -n <instance-namespace>Volumessection, get theClaimNamevalue. The name of the persistent volume claim is usually the same as the name of the replica pod. - Delete the persistent volume claim:
- If the claim name is the same as the replica pod name, use the following command:
oc delete pvc ${REPLICA_POD} -n <instance-namespace> - If the claim name is different from the replica pod name, use the following command:
oc delete pvc <pvc-name> -n <instance-namespace>
- If the claim name is the same as the replica pod name, use the following command:
- Delete the replica pod:
oc delete pod ${REPLICA_POD} -n <instance-namespace>