Come aspettare che PostgreSQL sia avviabile / ripristinabile?


8

Sto testando un aggiornamento PostgreSQL da 8.2.1 a 9.2 su una macchina virtuale che esegue una distribuzione Linux personalizzata. La procedura di aggiornamento è la seguente:

  1. Avvia il pgservizio
  2. Vuoto tutti i DB (non sono sicuro che sia necessario)
  3. Backup con pg_dumpall
  4. Interrompere il pgservizio
  5. Allontana la directory in cui sono archiviati i dati ( /var/pg; è una semplice configurazione a server singolo)
  6. Installa PostgreSQL 9.2
  7. initdb
  8. Avvia il server
  9. Ripristina i dati scaricati
  10. reindexdb tutti i DB
  11. Ricrea la referential_constraintsvista
  12. Vuoto tutti i DB (AFAIK richiesto dopo questo aggiornamento)

Questa procedura funziona bene su un host, eseguendo il backup e il ripristino senza intoppi. Su un altro computer con un database diverso, i punti da 1 a 7 funzionano correttamente, ma il server non si avvia a meno che non aggiunga un sleep 1dopo initdb, e anche in questo caso i dati scaricati non possono essere ripristinati perché "il sistema del database si sta avviando". Quali sono i modi standard per gestirlo, ad eccezione di questi terribili hack:

  1. sleeping per un periodo di tempo generoso prima di entrambe le operazioni,
  2. loop fino a quando non funziona o fino a quando non viene raggiunto un timeout generoso, o
  3. loop fino a quando non accetta una query banale o viene raggiunto un timeout.

Modifica: la " soluzione " non ha funzionato dopo tutto. Cosa serve per assicurarsi che il database sia pronto per eseguire un ripristino?


Solo un'idea: puoi verificare lo initdbstato di uscita? Suppongo che quando è pronto il lavoro è fatto.
dezso,

@dezso No, initdbviene eseguito in modo sincrono, quindi quando il server viene avviato initdbè già terminato correttamente.
l0b0,

Quindi non ho idea migliore di eseguire un semplice test che verifica che le cose siano pronte.
dezso,

2) non è necessario. 10) inoltre non è necessario in quanto il ripristino del dump ricrea tutti gli indici.
a_horse_with_no_name,

Risposte:


5

initdb non ritorna fino al termine, quindi non dovrebbe esserci alcuna pausa tra esso e l'avvio del server. Ci sono stati dei bug in PostgreSQL in cui è stato completato senza scaricare tutto prima sul disco. Non conosco nessuna sinistra in questo momento, ma la natura dei bug è che non sempre li conosci.

Se si utilizza il comando pg_ctl per avviare il database, utilizzare i parametri "-w" per attendere fino al termine dell'avvio prima di tornare. Non fa nulla di speciale - fa solo "è pronto ancora?" loop per te.

Si noti che se si verifica un arresto anomalo del server con molti dati che devono essere riprodotti prima che il server possa essere avviato, il timeout impostato da "-t" nell'attesa di pg_ctl potrebbe essere troppo basso.

Non c'è motivo di VACUUM i database di origine prima di eseguirne uno pg_dump. Mentre potrebbe accelerare un po 'la discarica, il vuoto stesso richiederà più tempo di quel miglioramento.


È richiesto il 12. passaggio? Mi aspetto che le tabelle siano contigue (o quasi contigue dopo un pg_restore -j{morethan1}).
dezso,

Stiamo correndo postmasterper avviare il demone e non sembra avere tale opzione.
l0b0

2

Il Lavorandosoluzione rotta era modificare lo script di init per verificare ripetutamente se la porta pertinente è in uso. Se non viene visualizzato dopo un minuto, l'avvio viene considerato non riuscito. Pseudo-codice:

start() {
    pg start
    checks=0
    while checks < 30:
        return true if the port is in use
        sleep 2
        checks++
    return false
}

Modifica: risulta che questo non è sufficiente. Il passaggio di ripristino:

PGOPTIONS='--client-min-messages=warning' psql \
    --no-psqlrc \
    --variable=ON_ERROR_STOP=1 \
    --quiet \
    --log-file="$restore_log" \
    --single-transaction \
    --username postgres \
    --file="$sql_backup"

Messaggio di errore:

psql: FATAL:  the database system is starting up
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.