2016-10-14 3 views
2

Dans un script d'initialisation, je veux initialiser un répertoire PostgreSQL, mais pas besoin (et ne veulent pas) un serveur PostgreSQL en cours d'exécution à ce stade.Comment initialiser une base de données PostgreSQL sans exécuter le serveur PostgreSQL

Ce serait une évidence si je viens de créer le cluster (en tant qu'utilisateur postgres):

initdb -D ... 

Cependant, je dois aussi créer le rôle PostgreSQL, créer la base de données et ajouter quelques extensions (aussi en tant qu'utilisateur postgres):

createuser someuser 
createdb -O someuser somedb 
echo 'CREATE EXTENSION xyz;' | psql somedb 

Ces dernières commandes nécessitent un serveur PostgreSQL en cours d'exécution. Donc, tout cela devient tout à fait désordre:

initdb -D ... 

# Start PostgreSQL server in background 
... & 

# Wait in a loop until PostgreSQL server is up and running 
while ! psql -f /dev/null template1; do 
    sleep 0.5 
done 

createuser someuser 
createdb -O someuser somedb 
echo 'CREATE EXTENSION xyz;' | psql somedb 

# Kill PostgreSQL server 
kill ... 

# Wait until the process is really killed 
sleep 2 

Surtout la partie qui attend le serveur PostgreSQL est jamais fiable à 100%. J'ai essayé beaucoup de variantes et chacune d'entre elles a échoué dans environ 1 des 20 courses. En outre, tuer ce processus peut ne pas être fiable à 100% dans un script shell simple, sans parler de s'assurer qu'il s'est arrêté correctement. Je crois qu'il s'agit d'un problème standard qui se produit dans tous les cas d'utilisation impliquant l'amorçage d'un serveur ou la préparation d'une image de machine virtuelle. On s'attend donc à ce qu'en 2016, il y ait des outils existants et réalistes pour cela. Donc mes questions sont:

  • Existe-t-il un moyen plus simple et plus fiable d'y parvenir?
  • Par exemple, existe-t-il un moyen d'exécuter un serveur PostgreSQL dans un mode spécial, où il suffit de démarrer, d'exécuter certaines commandes SQL et de quitter immédiatement après la fin de la dernière commande SQL?
  • En résumé, est-ce que quelque chose de la suite de tests internes de PostgreSQL peut être réutilisé à cet effet?

Répondre

5

Vous recherchez .

Si vous démarrez PostgreSQL comme ça, vous êtes est une session connectée comme qui attend superuser instructions SQL sur l'entrée standard. Dès que vous vous déconnectez (avec fin de fichier), le processus du serveur est arrêté.

Ainsi, vous pouvez le faire comme ça (avec bash):

postgres --single -D /usr/local/pgsql/data postgres <<-"EOF" 
CREATE USER ...; 
CREATE DATABASE somedb ...; 
EOF 

postgres --single -D /usr/local/pgsql/data somedb <<-"EOF" 
CREATE EXTENSION ...; 
EOF 
+0

Merci! Le mode mono-utilisateur était l'indice manquant. Cependant, votre code d'exemple est un peu erroné. Il essaie d'accéder à la base de données avant sa création. Il semble que 'postgres --single' doit être exécuté deux fois - une fois avec la base de données' postgres', puis avec la base de données créée. – vog

+0

Bien sûr. 'dbname' était juste un exemple. Je vais mettre à jour la réponse pour plus de clarté. –