Comment attendre que PostgreSQL soit démarrable / restaurable?


8

Je teste une mise à niveau de PostgreSQL 8.2.1 à 9.2 sur une machine virtuelle exécutant une distribution Linux personnalisée. La procédure de mise à niveau est la suivante:

  1. Démarrez le pgservice
  2. Passez l'aspirateur sur toutes les bases de données (vous ne savez pas si cela est nécessaire)
  3. Sauvegarde avec pg_dumpall
  4. Arrêtez le pgservice
  5. Éloignez le répertoire où les données sont stockées ( /var/pg; c'est une configuration simple à serveur unique)
  6. Installez PostgreSQL 9.2
  7. initdb
  8. Démarrez le serveur
  9. Restaurer les données sauvegardées
  10. reindexdb toutes les bases de données
  11. Recréez la referential_constraintsvue
  12. Videz toutes les bases de données (AFAIK requis après cette mise à niveau)

Cette procédure fonctionne très bien sur un hôte, sauvegarde et restauration sans accroc. Sur une autre machine avec une base de données différente, les points 1 à 7 fonctionnent correctement, mais le serveur ne démarre pas à moins que j'ajoute un sleep 1après initdb, et même alors, les données sauvegardées ne peuvent pas être restaurées car "le système de base de données démarre". Quelles sont les façons standard de gérer cela, à l'exception de ces terribles hacks:

  1. sleeppendant un certain temps généreusement avant chaque opération,
  2. en boucle jusqu'à ce qu'il fonctionne ou jusqu'à ce qu'un délai d'attente généreux soit atteint, ou
  3. en boucle jusqu'à ce qu'il accepte une requête triviale ou qu'un délai soit atteint.

Edit: La " solution " n'a pas fonctionné après tout. Que faut-il pour s'assurer que la base de données est prête à exécuter une restauration?


Juste une idée: pouvez-vous tester le initdbstatut de sortie? Je suppose que lorsque le travail est terminé, c'est terminé.
dezso

@dezso Nope, initdbest exécuté de manière synchrone, donc lorsque le serveur est démarré, il initdbest déjà terminé avec succès.
l0b0

Ensuite, je n'ai pas de meilleure idée que de boucler un test simple qui vérifie que les choses sont prêtes.
dezso

2) n'est pas nécessaire. 10) n'est également pas nécessaire car la restauration du vidage recréera tous les index.
a_horse_with_no_name

Réponses:


5

initdb ne revient pas tant qu'il n'est pas terminé, il ne devrait donc pas y avoir de pause nécessaire entre lui et le démarrage du serveur. Il y a eu des bugs dans PostgreSQL où il s'est terminé sans tout vider d'abord sur le disque. Je n'en connais aucune en ce moment, mais la nature des bugs est que vous ne les connaissez pas toujours.

Si vous utilisez la commande pg_ctl pour démarrer la base de données, utilisez les paramètres "-w" pour cela afin d'attendre la fin du démarrage avant de revenir. Il ne fait rien d'extraordinaire - il fait juste le "est-il encore prêt?" boucle pour vous.

Notez que si vous obtenez un crash du serveur avec beaucoup de données qui doivent être relues avant que le serveur puisse démarrer, le délai d'attente défini par "-t" sur l'attente pg_ctl peut être trop faible.

Il n'y a aucune raison de VACUUMER les bases de données sources avant d'en faire un pg_dump. Bien que cela puisse accélérer un peu le vidage, le vide lui-même prendra plus de temps que cette amélioration.


Est-ce que l'étape 12. est requise? Je m'attendrais à ce que les tables soient contiguës (ou presque contiguës après un pg_restore -j{morethan1}).
dezso

Nous courons postmasterpour démarrer le démon, et il ne semble pas avoir une telle option.
l0b0

2

le travailla solution cassée était de modifier le script init pour vérifier à plusieurs reprises si le port approprié est utilisé. S'il n'apparaît pas après une minute, le démarrage est considéré comme ayant échoué. Pseudo-code:

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

Edit: Il s'avère que ce n'est pas suffisant. L'étape de restauration:

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"

Message d'erreur:

psql: FATAL:  the database system is starting up
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.