jeudi 20 septembre 2012

Backup d'une DB PostGreSql Windows avec PgAgent

Cet article présente toutes les étapes de mon périple pour exécuter un backup pg_dump avec pgAgent... y compris celles permettant la résolution des différents problèmes.

Je précise quand même que le backup pg_dump + pgAgent sur Windows Serveur 2008 est fonctionnel ;-)

Ce billet est rédigé en étapes... toutes les étapes par lesquelles je suis passé (dans l'ordre de lecture).
Qui sait, il sera peut être source d'inspiration si un jour vous en avez besoin.

Installation
J'utilise PostgreSQL 9.1, par conséquent, l'installation est des plus simple.
Il suffit d'utiliser l'utilitaire "StackBuilder" de PostgreSql et de selectionner l'utilitaire pgAgent

Commande pg_dump
Commencer par faire fonctionner une tâche de backup en utilisant l'instruction pg_dump
Ensuite, faite le nécessaire pour l'appeler depuis une ligne de commande sur le serveur.
Dans mon cas, j'obtiens la commande batch suivante:

"c:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" --no-password --host localhost --port 5432 --username "postgres" --role "postgres"  --format tar --blobs --encoding UTF8 --oids --verbose --file "d:\GGBackup\Serveur\StockProd.backup" "stockprod"

La commande pg_dump peut être obtenu à l'aide de l'utilitaire backup de pgAdmin III (qui indique la commande pg_dump à utiliser).
Voir l'article " PostgreSql - Backup et restaure d'une base de donnée" pour plus d'information.

Configuration d'un Job
La fin de l'article "Setting up pgAgent and schedule backup job" de PostGresOnline.com.
Il faut bien entendu stipuler une tâche de type BATCH pour pouvoir exécuter une commande DOS.

Service pgAgent
J'ai quand même eu quelques problèmes pour faire fonctionner mon Job de backup.
Le pire, c'est quand il reste dans l'état "running" alors que le job ne fonctionne visiblement pas.
Savoir qu'il y a un service Windows et pouvoir le démarrer et l'arrêter est une information utile pour gérer l'inattendu.

net stop pgAgent
net start pgAgent

Information utile trouvé sur cet article de Vibhor Kumar

Malheureusement, ma première tâche de backup ne cesse m'indiquer le message "failed" à chaque fois que j'essaye de l'exécuter.

J'ai donc créé une simple tâche qui fait une requête SQL dans une table.
Cette requête est "select * from FILE0050 LIMIT 12".
Malheureusement, cette tâche aussi ne retourne que des erreurs. Le problème est probablement la configuration du service!

pgAgent en mode DEBUG
En cas de problèmes, l'un des options est de démarrer le service en mode DEBUG.


net stop pgAgent


Localiser l'exécutable (qui se trouve en C:\Program Files (x86)\pgAgent\bin sur un système 64 bits).
Exécuter ensuite:


pgAgent.exe DEBUG hostaddr=127.0.0.1 dbname=postgres user=postgres password=xxx


Où xxx est le mot de passe que vous utilisez pour vous connecter sur la DB avec pgAdmin III.
User contient l'identification de l'utilisateur PostgreSql. Attention, il est sensible à la case. Dans mon premier essais j'ai utilisé user=Postgres alors que ma connexion avec pgAdmin III utilise postgres.

Si le nom d'utilisateur (ou mot de passe) est incorrect, vous obtenez un message du genre...
WARNING: Couldn't create the primary connection (attempt 1): FATAL:  authentification par mot de passe ÚchouÚe pour l'utilisateur  ½ Postgres ╗

pgAgent avec log DEBUG

Pour obtenir plus de message de log, il faut ajouter l'option -l 2 .
Cela donne la commande suivante:

pgAgent.exe DEBUG hostaddr=127.0.0.1 dbname=postgres user=postgres password=xxx -l 2

L'exécution en Mode Debug m'apprend que mon Job sql est exécuté mais n'indique pas pourquoi il continue à échouer!

Source de l'information:
  • L'article pgAgent sur Let's Prosgres
Le "Host Agent" du Job
Il semblerait que le paramètre "Host Agent" du job soit vraiment important.
Toujours en suivant les recommandation de l'article pgAgent, j'ai éxécuté la requête suivante sur le serveur.
Une info en provenance de PostgreSql.fr laisse à penser que cela n'est pas forcement utile (voir ce lien).

SELECT jagstation FROM pgagent.pga_jobagent;


pour apprendre que Host Agent devrait valoir exactement:
SERVEUR.home


Une fois le Job modifié et relancé, ma petite tâche SQL continue à échouer... sans plus d'information Arrghhh!?!?


Obtenir les messages d'outputs
Lorsqu'un JOB est exécuté, il est possible de retrouver le message d'output  d'un Step d'exéction du JOB.
En cas d'erreur, cet output peut devenir vraiment très utile.
Pour l'obtenir:
  1. Sélectionner le Step dans le Job
  2. Sélectionner le volet Statistique
  3. Chercher la colonne Output.
Il est également possible d'obtenir la liste des messages d'output exécutés par le l'Agent

SELECT jslid, jsloutput from pgagent.pga_jobsteplog WHERE jslstatus != 's' AND jsloutput != '' ORDER BY jslstart DESC; 

Attention: il faut copier coller le résultat dans notepad pour vraiment voir le message (la cellule est quelques-fois vide dans pgAdmin... pourtant elle contient quelque-chose :-) ).

Ma tâche SQL - toujours en failed mais exécutée!!!
En y regardant de plus près, les statistiques du step (commande SQL) sont à failed mais retourne un "result" de 12.
C'est bien le nombre d'enregistrement retourner par la requête.
La requête est donc bien exécutée... mais est interprétée comme "failed" pour une raison que j'ignore.


En replaçant ma requête sql avec 
   SELECT "HELLO"
le result de la statistique indique "1" (une row).

Le problème est donc ailleurs que dans l'exécution... c'est déjà une bonne nouvelle.

Retour sur ma tâche de backup
La tâche était donc définie comme
"c:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" --no-password --host localhost --port 5432 --username "postgres" --role "postgres"  --format tar --blobs --encoding UTF8 --oids --verbose --file "d:\GGBackup\Serveur\StockProd.backup" "stockprod"

De l'expérience juste acquise, je peux consulter l'output.
Je note le message d'erreur suivant:

"
C:\Program Files (x86)\pgAgent\bin>"c:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" --no-password --host localhost --port 5432 --username "postgres" --role "postgres"  --format tar --blobs --encoding UTF8 --oids --verbose --file "d:\GGBackup\Serveur\StockProd.backup" "stockprod"
pg_dump: [programme d'archivage (db)] la connexion à la base de données « stockprod » a échoué : fe_sendauth: no password supplied
pg_dump: *** interrompu du fait d'erreurs
"


C'est donc un problème de mot de passe... pourtant pg_dump.exe n'accepte pas de mot de passe en ligne de commande. Il faut donc absolument l'option --no-password sinon la tâche restera en cours d'exécution (en demandant un mot de passe qui ne peu pas être encoder puisque la session n'est pas interactive!).

Astuce:
L'erreur est plus facile à repérer en utilisant le SQL


SELECT jslid, jsloutput from pgagent.pga_jobsteplog WHERE jslstatus != 's' AND jsloutput != '' ORDER BY jslstart DESC; 

Et en copiant/collant le résultat des cellule (apparemment vide mais pas tellement que cela) dans notepad ;-)

Un password pour mon pg_dump
En se référant à l'article "The password file" de PostgreSql, j'apprends que le fichier pgpass.conf doit se trouver dans le répertoire %APPDATA%\postgresql\pgpass.conf
En vérifiant sur mon Windows Serveur 2008, je trouve le fichier pgpass.conf de l'administrateur dans le répertoire de Roaming.
c:\Users\Administrateur\AppData\Roaming\postgresql\pgpass.conf

Je vais commencer par modifier ce pgpass.conf car je fais des tests en mode DEBUG... et donc avec l'utilisateur interactif qui n'est autre que Administrateur!

Le fichier pgpass.conf d'Administrateur est modifier pour contenir une ligne pour ma DB stockprod.
Ce fichier devient donc:

localhost:5432:postgres:postgres:SECRET
localhost:5432:stockprod:postgres:SECRET

Ensuite, je fais un essai en ligne de commande avec:
"c:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" --no-password --host localhost --port 5432 --username "postgres" --role "postgres"  --format tar --blobs --encoding UTF8 --oids --verbose --file "d:\GGBackup\Serveur\StockProd.backup" "stockprod"
 
et cette fois, le pg_dump s'exécute immédiatement!

Tester la tâche pg_dump avec pgAgent en DEBUG
Finalement, un dernier essai avec pgAgent en mode DEBUG.
Je démarre le pgAgent en mode DEBUG avec l'instruction:
pgAgent.exe DEBUG hostaddr=127.0.0.1 dbname=postgres user=postgres password=SECRET -l 2

Cette session s'exécute en mode interactif et utilisera donc le pgpass.conf de le l'utilisateur Administrateur.
En utilisant pgAdmin III, on redemande l'exécution de la tâche de Backup.
Cette fois aussi la tâche fonctionne, le backup est créé... même si la tâche est indiquée "failed" (mon pgAgent est certainement en pleine crise d'opposition :-) )

pgpass.conf pour le service pgAgent
Le service pgAgent ne fonctionne pas avec le crédential de l'utilisateur Administrateur mais avec celui de son propre utilisateur Windows. Cet utilisateur qui ne nomme normalement "postgres".
Il faut donc créer le fichier avec un contenu identique (voir ci-dessus).

c:\Users\postgres\AppData\Roaming\postgresql\pgpass.conf 

Un essai avec pgAgent
J'arrête mon pgAgent en mode DEBUG pour ensuite démarrer mon service pgAgent à l'aide de 
NET START pgAgent 
Le service est normalement configuré correctement avec l'utilisateur Windows "postgres", celui utilisé durant l'installation avec StackBuilder.

En utilisant pgAdmin III, on redemande l'exécution de la tâche de Backup.
Cette fois-ci, cette tâche sera exécutée par le service pgAgent.
Maintenant, la tâche de backup fonctionne correctement   YES!!!

Ressources
Proposition d'installation du Service
Au détour de mes lecture, j'ai trouver une instruction d'installation du service pgAgent
“C:\Program Files\PostgreSQL\8.2\bin\pgAgent" INSTALL pgAgent –l 2 -u postgres -p XXXX hostaddr=127.0.0.1 dbname=postgres user=Postgres

Un fichier backup par jour
J'ai aussi trouvé cet autre batch qui crée un fichier de backup différent chaque jour.
Bonne idée que j'exploiterais plus tard.
    @echo off
   for /f "tokens=1-4 delims=/ " %%i in ("%date%") do (
     set dow=%%i
     set month=%%j
     set day=%%k
     set year=%%l
   )
   set datestr=%month%_%day%_%year%
   echo datestr is %datestr%
    
   set BACKUP_FILE=<NameOfTheFile>_%datestr%.backup
   echo backup file name is %BACKUP_FILE%
   SET PGPASSWORD=<PassWord>
   echo on
   bin\pg_dump -i -h <HostName> -p 5432 -U <UserName> -F c -b -v -f %BACKUP_FILE% <DATABASENAME>

Source: Automated Backup on Windows sur le woki de postgresql.org 

Output message d'un JOB
Voici une petite requête SQL permettant d'obtenir les messages d'output d'un Job pgAgent.
Merci à rjuju (sur forums.postgresql.fr).

SELECT jsloutput
FROM pgagent.pga_job j
JOIN pgagent.pga_jobstep js ON jstjobid = jobid
JOIN pgagent.pga_jobsteplog jsl ON jsljstid = jstid
WHERE jobname = 'Test'

Aucun commentaire: