Risolvere i problemi relativi all'operatore AlloyDB Omni Kubernetes

Seleziona una versione della documentazione:

Questa pagina mostra come risolvere i problemi relativi all'operatore AlloyDB Omni Kubernetes.

Raccogliere informazioni di debug

Queste sezioni descrivono come raccogliere log e configurazioni per il debug.

Recupera i log dai pod dell'operatore

Per recuperare i log dai pod dell'operatore, esegui i seguenti comandi:

kubectl logs deployments/fleet-controller-manager -c manager -n alloydb-omni-system
kubectl logs deployments/local-controller-manager -c manager -n alloydb-omni-system

Recuperare i log dei pod del database

Per recuperare i log del pod del database, esegui questi comandi:

kubectl logs al-<id-instance-name>-0 -n db
kubectl logs -l alloydbomni.internal.dbadmin.goog/dbcluster=dbcluster-name -c database -n db

I seguenti log sono esempi di controlli di integrità del database riusciti:

I1106 16:17:28.826188      30 gateway.go:166] "DatabaseHealthCheck: handling request" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-sample"
I1106 16:17:28.826295      30 gateway.go:184] "DatabaseHealthCheck: request handled successfully" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-s
ample"
I1106 16:17:34.810447      30 gateway.go:166] "DatabaseHealthCheck: handling request" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-sample"
I1106 16:17:34.834844      30 gateway.go:184] "DatabaseHealthCheck: request handled successfully" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-s
ample"
I1106 16:17:38.825843      30 gateway.go:166] "DatabaseHealthCheck: handling request" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-sample"
I1106 16:17:38.825959      30 gateway.go:184] "DatabaseHealthCheck: request handled successfully" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-s
ample"

Recupera il file postgresql.log

Per recuperare postgresql.log, esegui questo comando:

kubectl exec -it al-id-instance-name-0 -n db -c database -- cat /obs/diagnostic/postgresql.log

Recupera il file YAML DBInstance

Per recuperare il file YAML DBInstance, esegui questo comando:

kubectl get dbclusters.a <dbcluster-name> -n db -o yaml

Recuperare configurazioni e log per scenari di alta disponibilità

Per recuperare configurazioni e log specifici per scenari di alta disponibilità (HA), esegui i seguenti comandi:

kubectl get replicationconfig -n <namespace>
kubectl get deletestandbyjobs.alloydbomni.internal -n <namespace> -o yaml
kubectl get createstandbyjobs.alloydbomni.internal -n <namespace> -o yaml
kubectl get failovers.alloydbomni.dbadmin.goog -n <namespace> -o yaml

Recuperare gli stati di pod e STS

Per recuperare gli stati di pod e StatefulSet (STS), esegui i seguenti comandi:

kubectl describe pod -n <namespace> <pod-name>
kubectl describe statefulset -n <namespace> al-<id-instance-name>

Identificare gli errori

Queste sezioni descrivono come identificare gli errori.

Cerca lo stato di errore e i codici di errore

Per identificare il codice di errore, controlla il file YAML DBCluster in stato. Per ulteriori informazioni, consulta la documentazione sui codici di errore.

Per recuperare il file YAML DBCluster, esegui questo comando:

kubectl get dbclusters.a <dbcluster-name> -n <dbcluster-namespace> -o yaml

Cerca criticalIncidents. Questa sezione contiene il codice di errore e una traccia dello stack.

Di seguito sono riportati esempi di criticalIncidents:

status:
    certificateReference:
      certificateKey: ca.crt
      secretRef:
        name: dbs-al-cert-dr-mce
        namespace: dr
    conditions:
    -   lastTransitionTime: "2024-10-07T22:46:03Z"
    ...
    criticalIncidents:
    -   code: DBSE0304
      createTime: "2024-10-03T11:50:54Z"
      message: 'Healthcheck: Health check invalid result.'
      resource:
        component: healthcheck
        location:
          group: alloydbomni.internal.dbadmin.goog
          kind: Instance
          name: bc0f-dr-mce
          namespace: dr
          version: v1
      stackTrace:
      -   component: healthcheck
        message: 'DBSE0304: Healthcheck: Health check invalid result. rpc error: code
          = Code(10304) desc = DBSE0304: Healthcheck: Health check invalid result.
          dbdaemon/healthCheck: invalid timestamp read back from the healthcheck table.
          Lag is 384837.296269 seconds, wanted 35 seconds'

Puoi anche recuperare lo stato estraendo campi specifici in formato JSON:

kubectl get dbcluster.${DBTYPE:?} -n "${PROJECT:?}" "${DBCLUSTER:?}" -o json -o jsonpath='{.status.criticalIncidents}' | jq

L'output è simile al seguente:

[
  {
    "code": "DBSE0085",
    "createTime": "2024-03-14T05:41:37Z",
    "message": "Platform: Pod is unschedulable.",
    "resource": {
      "component": "provisioning",
      "location": {
        "group": "alloydb.internal.dbadmin.goog",
        "kind": "Instance",
        "name": "b55f-testdbcluster",
        "namespace": "dbs-system",
        "version": "v1"
      }
    },
    "stackTrace": [
      {
        "component": "provisioning",
        "message": "DBSE0085: Platform: Pod is unschedulable. 0/16 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/16 nodes are available: 16 No preemption victims found for incoming pod..: Pod is unschedulable"
      }
    ]
  }
]

Se il messaggio di errore si riferisce al pod del database, controlla le istanze e le risorse del pod nello stesso spazio dei nomi:

kubectl get instances.a dbcluster_name -n dbcluster_namespace -o yaml
kubectl get pods -l alloydbomni.internal.dbadmin.goog/dbcluster=dbcluster_name -l alloydbomni.internal.dbadmin.goog/task-type=database -n dbcluster_namespace

Eseguire il debug dei problemi di memoria

Queste sezioni descrivono come eseguire il debug dei problemi di memoria.

Esegui e acquisisci un dump dell'heap

Attiva questa funzionalità solo per la risoluzione dei problemi. Ricordati di disattivarlo dopo.

Per eseguire un dump dell'heap, completa i seguenti passaggi:

  1. Modifica il deployment dell'operatore nello spazio dei nomi alloydb-omni-system con nome fleet-controller-manager e local-controller-manager.
  2. Aggiungi il seguente argomento al pod --pprof-address=:8642 o a qualsiasi altro porta disponibile.
  3. Attendi il riavvio del pod del controller.
  4. Inoltra la porta precedente. Ad esempio:

    kubectl port-forward -n alloydb-omni-system fleet-controller-manager-pod-name 8642:8642
    
  5. In un altro terminale, esegui go tool pprof http://localhost:8642/debug/pprof/heap. Modifica la porta in modo che corrisponda a quella precedente se non utilizzi 8642.

  6. Connettiti all'indirizzo ed esegui i comandi per la risoluzione dei problemi. Ad esempio: top.

  7. Al termine della risoluzione dei problemi, annulla il passaggio 1 rimuovendo l'argomento e attendendo il riavvio del pod.

Determina il numero di risorse monitorate dall'operatore

Per comprendere le risorse in uso, esegui i seguenti comandi:

kubectl get backuprepositories -A  | wc -l
kubectl get failovers -A  | wc -l
kubectl get instancebackupplans -A  | wc -l
kubectl get instancebackups -A  | wc -l
kubectl get instancerestores -A  | wc -l
kubectl get instances -A  | wc -l
kubectl get instanceswitchovers -A  | wc -l
kubectl get lrojobs -A  | wc -l
kubectl get replicationconfigs -A  | wc -l
kubectl get sidecars -A  | wc -l
kubectl get deployments -A  | wc -l
kubectl get statefulsets -A  | wc -l
kubectl get certificates.cert-manager.io -A  | wc -l
kubectl get issuers.cert-manager.io -A  | wc -l
kubectl get configmaps -A  | wc -l
kubectl get persistentvolumeclaims -A  | wc -l
kubectl get persistentvolumes -A  | wc -l
kubectl get pods -A  | wc -l
kubectl get secrets -A  | wc -l
kubectl get services -A  | wc -l
kubectl get storageclasses.storage.k8s.io -A  | wc -l

Ad esempio, se il numero di secret è elevato, può verificarsi un errore Out Of Memory (OOM).

kubectl get secrets -A | wc -l

Debug avanzato della disponibilità elevata

Questa sezione fa riferimento a risorse che sono implementazioni interne. Questi sono soggetti a modifiche in qualsiasi momento e non hanno impegni di compatibilità retroattiva. Applica le correzioni manuali solo ai problemi relativi ai database non di produzione. Questi passaggi potrebbero rendere il database irrecuperabile.

La configurazione HA di AlloyDB Omni prevede tre fasi:

  1. Configura il server primario per ricevere una connessione dal server di standby.
  2. Inizializza lo standby e connettilo al primario.
  3. Imposta le impostazioni principali per rendere sincrona la connessione.

Il passaggio 2 è in genere il più lento. A seconda delle dimensioni del database, l'operazione potrebbe richiedere diverse ore.

A ogni istanza di replica deve essere collegato un replicationconfig. Ad esempio: bash ❯ k get replicationconfigs.alloydbomni.internal.dbadmin.goog NAME PARENT TYPE ROLE READY HEALTHY 9f47-dbcluster-sample--7576-dbcluster-sample 9f47-dbcluster-sample Physical Upstream True True ds-7576-dbcluster-sample 7576-dbcluster-sample Physical Downstream True True

In questo esempio:

  • L'istanza 9f47-dbcluster-sample è configurata come upstream fisico.
  • L'istanza 7576-dbcluster-sample è configurata come downstream fisico.

La specifica della configurazione di replica indica le impostazioni previste, mentre lo stato riflette lo stato effettivo letto dal database. Se lo stato e la specifica non corrispondono, il controller sta ancora tentando di applicare la modifica o si è verificato un errore che impedisce l'applicazione della modifica. Ciò si rifletterà nei campi di stato.

Job in standby

Devono essere presenti due set di job interni che monitorano il flusso di lavoro di uno standby:

  • createstandbyjobs.alloydbomni.internal.dbadmin.goog
  • deletestandbyjobs.alloydbomni.internal.dbadmin.goog

Se la configurazione sembra bloccata, visualizza i job relativi al cluster di database (DBC). Il job potrebbe contenere messaggi di errore che spiegano lo stato della configurazione. I job vengono puliti automaticamente dopo un po' di tempo dal loro completamento, quindi potresti non visualizzarne nessuno se non ce ne sono in corso.

k get createstandbyjob

L'output è simile al seguente:

apiVersion: alloydbomni.dbadmin.gdc.goog/v1
  kind: CreateStandbyJob
  metadata:
    creationTimestamp: "2024-11-05T03:34:26Z"
    finalizers:
    -   createstandbyjob.dbadmin.goog/finalizer
    generation: 1804
    labels:
      dbs.internal.dbadmin.goog/dbc: foo-ha-alloydb1-clone1
    name: foo-ha-alloydb1-clone1--ac00-foo-ha-alloydb1-clone1--6036-foo-ha-alloydb1-clone1-1730777666
    namespace: db
    resourceVersion: "11819071"
    uid: 1f24cedf-b326-422f-9405-c96c8720cd90
  spec:
    attempt: 3
    cleanup: false
    currentStep: SetupSynchronous
    currentStepTime: "2024-11-05T03:45:31Z"
    metadata:
      dbc: foo-ha-alloydb1-clone1
      primaryInstance: ac00-foo-ha-alloydb1-clone1
      retryError: 'etcdserver: leader changed'
      standbyInstance: 6036-foo-ha-alloydb1-clone1
    requeueTime: "2024-11-05T18:33:03Z"
    startTime: "2024-11-05T03:36:56Z"

Verifica principale

La prima cosa da verificare è che il primario sia configurato correttamente. Deve essere presente un profilo di replica per ogni standby. Se isSynchronous è true nella specifica e nello stato, la configurazione dovrebbe essere completata. Se isSynchronous è false nella specifica e nello stato, significa che non è ancora stato raggiunto il passaggio 3. Visualizza i job di standby per verificare se sono presenti job in esecuzione e se sono presenti messaggi di errore.

  replication:
    profiles:
    -   isActive: true
      isSynchronous: true
      name: ha:4c82-dbcluster-sample::d85d-dbcluster-sample
      password:
        name: ha-rep-pw-dbcluster-sample
        namespace: default
      passwordResourceVersion: "896080"
      role: Upstream
      type: Physical
      username: alloydbreplica

Verifica che l'annotazione disableHealthcheck sia falsa. È progettato per essere disattivato solo durante un failover o uno switchover.

apiVersion: alloydbomni.internal.dbadmin.goog/v1
kind: Instance
metadata:
  annotations:
    dbs.internal.dbadmin.goog/consecutiveHealthcheckFailures: "0"
    dbs.internal.dbadmin.goog/disableHealthcheck: "false"
    dr-secondary: "false"
    forceReconcile: "1730414498"

Query

Per verificare che le risorse sul pod DB siano configurate correttamente, accedi al database come utente amministratore alloydbadmin. Poi esegui le seguenti query:

Slot di replica

alloydbadmin=# select * from pg_replication_slots;
-[ RECORD 1 ]-------+---------------------------------------------
slot_name           | d85d_dbcluster_sample
plugin              |
slot_type           | physical
datoid              |
database            |
temporary           | f
active              | t
active_pid          | 250
xmin                | 16318
catalog_xmin        |
restart_lsn         | 0/CA657F0
confirmed_flush_lsn |
wal_status          | reserved
safe_wal_size       |
two_phase           | f

Uno stato buono è la presenza di uno slot di replica con lo stesso nome dell'istanza di standby. L'assenza di uno slot di replica indica che il primo passaggio della configurazione non è stato completato correttamente.

Se active == t non è vero, significa che lo standby non si connette per qualche motivo (rete, standby non completato, ecc.) e il debug probabilmente dovrà continuare sul lato standby.

Statistiche di replica

alloydbadmin=# select * from pg_stat_replication;
-[ RECORD 1 ]----+----------------------------------------------------------------
pid              | 250
usesysid         | 16385
usename          | alloydbreplica
application_name | d85d_dbcluster_sample
client_addr      | 10.54.79.196
client_hostname  | gke-samwise-default-pool-afaf152d-8197.us-central1-a.c.foo
client_port      | 24914
backend_start    | 2024-10-30 21:44:26.408261+00
backend_xmin     |
state            | streaming
sent_lsn         | 0/CA64DA8
write_lsn        | 0/CA64DA8
flush_lsn        | 0/CA64DA8
replay_lsn       | 0/CA64DA8
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 2
sync_state       | sync
reply_time       | 2024-11-04 22:08:04.370838+00

Se non esiste, significa che non è presente alcuna connessione attiva. Il valore di sync_state deve essere sync. Se non è sync, significa che l'ultimo passaggio della configurazione non è stato completato. L'analisi dei log / job dovrebbe fornire maggiori dettagli.

Verifica in standby

Lo standby deve avere un profilo di replica che corrisponda allo stesso profilo del primario:

  replication:
    profiles:
    -   host: 10.54.79.210
      isActive: true
      isSynchronous: true
      name: ha:4c82-dbcluster-sample::d85d-dbcluster-sample
      passwordResourceVersion: "896080"
      port: 5432
      role: Downstream
      type: Physical
      username: alloydbreplica

Se non è presente una connessione dall'istanza in standby a quella primaria, esistono due possibilità comuni:

  1. La configurazione dello standby è ancora in corso.
  2. Lo standby riceve un errore durante la configurazione o il tentativo di connessione.

Per verificare se si verifica l'opzione 1, recupera i log del pod del database e cerca le istruzioni di log denominate dbdaemon/setupPhysicalReplicationDownstream. Di seguito sono riportati alcuni esempi di log di configurazione riuscita:

I1104 22:42:42.604871     103 replication.go:107] "dbdaemon/setupPhysicalReplicationDownstream: begin setup" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
2024-11-04 22:42:42,605 INFO waiting for postgres to stop
2024-11-04 22:42:43,566 INFO stopped: postgres (exit status 0)
I1104 22:42:43.567590     103 replication.go:131] "dbdaemon/setupPhysicalReplicationDownstream: about to call pg_basebackup" log_name="agent" project_ns="default" dbcluster="dbcluster-sample" cmd=["-h","10.54.79.210","-D","/mnt/disks/pgsql/pg_basebackup_data","-U","alloydbreplica","-v","-P","-p","5432","-w","-c","fast"]
I1104 22:42:44.206403     103 replication.go:139] "dbdaemon/setupPhysicalReplicationDownstream: pg_basebackup finished" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.206440     103 replication.go:141] "dbdaemon/setupPhysicalReplicationDownstream: replacing data directory with pg_basebackup data directory" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.244749     103 replication.go:148] "dbdaemon/setupPhysicalReplicationDownstream: replaced data directory with pg_basebackup data directory" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.244783     103 replication.go:150] "dbdaemon/setupPhysicalReplicationDownstream: Creating config files" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.251565     103 replication.go:155] "dbdaemon/setupPhysicalReplicationDownstream: removing postgresql config file for log archiving" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.251621     103 replication.go:160] "dbdaemon/setupPhysicalReplicationDownstream: removing postgresql auto config file" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.251689     103 replication.go:165] "dbdaemon/setupPhysicalReplicationDownstream: Successfully wrote to config file" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
2024-11-04 22:42:44,256 INFO spawned: 'postgres' with pid 271
2024-11-04 22:42:45,469 INFO success: postgres entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
I1104 22:42:45.469838     103 replication.go:174] "dbdaemon/setupPhysicalReplicationDownstream: backup replication configuration after changing replication config" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:45.476732     103 replication.go:179] "dbdaemon/setupPhysicalReplicationDownstream: finished standby setup" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"

In caso di errore di connessione, controlla i log del pod db e il file di log sul database all'indirizzo /obs/diagnostic/postgresql.log e verifica qual è l'errore durante il tentativo di connessione. Un errore comune è l'assenza di connettività di rete tra lo standby e il primario.

Correzioni manuali

Il modo più semplice per risolvere i problemi di HA è disattivare e riattivare HA impostando numberOfStandbys su 0 e poi reimpostandolo sul numero che preferisci. Se gli standby non vengono disattivati, segui questi passaggi per reimpostare manualmente la configurazione HA in modo che sia vuota:

  1. Elimina manualmente le istanze di standby.
  2. Connettiti al database principale. Esegui una query sugli slot di replica correnti ed elimina gli slot di replica degli standby che vuoi eliminare:

    select pg_drop_replication_slot('<replication_slot_name_here>');
    
  3. Elimina tutti i profili di replica dall'istanza principale che vuoi eliminare.

Se un'istanza non è stata riconciliata di recente, puoi modificare il valore dell'annotazione forceReconcile. Imposta questo valore su un valore numerico qualsiasi, che corrisponde al timestamp dell'ultimo aggiornamento dell'annotazione. L'unico scopo di questa annotazione è fornire un campo che possiamo aggiornare per forzare una nuova riconciliazione.

apiVersion: alloydbomni.internal.dbadmin.goog/v1
kind: Instance
metadata:
  annotations:
    dbs.internal.dbadmin.goog/consecutiveHealthcheckFailures: "0"
    dbs.internal.dbadmin.goog/disableHealthcheck: "false"
    dr-secondary: "false"
    forceReconcile: "1730414498"

Raccogli i log di controllo e motore del database

I log del motore del database e gli audit log sono disponibili come file all'interno del pod del database (che richiede l'accesso root):

  • obs/diagnostic/postgresql.log
  • obs/diagnostic/postgresql.audit
export NAMESPACE=dbcluster-namespace
export DBCLUSTER=dbcluster-sample

export DBPOD=`kubectl get pod -n ${NAMESPACE} -l alloydbomni.internal.dbadmin.goog/dbcluster=${DBCLUSTER} -l alloydbomni.internal.dbadmin.goog/task-type=database -o jsonpath='{.items[0].metadata.name}'`
kubectl exec -n ${NAMESPACE} ${DBPOD} -it -- /bin/bash

$ ls -la /obs/diagnostic/
-rw------- 1 postgres postgres    98438 Sep 25 20:15 postgresql.audit
-rw------- 1 postgres postgres 21405058 Sep 25 20:24 postgresql.log

Raccogliere le metriche del database e del pod del database

L'operatore AlloyDB Omni fornisce un insieme di metriche di base per il motore AlloyDB Omni e il pod che lo ospita. Le metriche sono disponibili come endpoint Prometheus sulla porta 9187. Per accedere agli endpoint, devi identificare i nomi dei pod per il pod del database e il pod di monitoraggio del database, utilizzando le etichette DBCluster e task-type come segue.

export NAMESPACE=default
export DBCLUSTER=dbcluster-sample

export DBPOD=`kubectl get pod -n ${NAMESPACE} -l alloydbomni.internal.dbadmin.goog/dbcluster=${DBCLUSTER},alloydbomni.internal.dbadmin.gdc.goog/task-type=database -o jsonpath='{.items[0].metadata.name}'`

export MONITORINGPOD=`kubectl get pod -n ${NAMESPACE} -l alloydbomni.internal.dbadmin.goog/dbcluster=${DBCLUSTER},alloydbomni.internal.dbadmin.gdc.goog/task-type=monitoring -o jsonpath='{.items[0].metadata.name}'`

Accedere alle metriche del database AlloyDB Omni

kubectl port-forward -n ${NAMESPACE} ${MONITORINGPOD} 9187:9187
curl http://localhost:9187/metrics | grep HELP

Accedere alle metriche dei pod del database

kubectl port-forward -n ${NAMESPACE} ${DBPOD} 9187:9187
curl http://localhost:9187/metrics | grep HELP

Puoi anche configurare Prometheus per estrarre le metriche nel cluster Kubernetes. Per maggiori dettagli, consulta la configurazione Service Discovery di Prometheus Kubernetes.