HowTo/MigratePostgres
Migration vers PostgreSQL 9.2
Installation de PostgreSQL 9.2
L'installation d'une nouvelle version de postgres peut entraîner le redémarrage de toutes les autres instances installées. Pour éviter cela, il faut éditer le fichier /etc/postgresql/X.Y/cluster/start.conf et modifier le type de démarrage à manual le temps de l'installation. Il faut bien évidemment le remettre à auto une fois l'installation finie si les anciennes versions doivent rester démarrées ultérieurement.
Utilisation du dépôt apt communautaire.
En tant que root, à faire sur les deux serveurs (maître et esclave): Positionner l'instance 8.4 en gestion manuelle dans le fichier /etc/postgresql/X.Y/cluster/start.conf
Déclaration du dépôt dans le fichier /etc/apt/sources.list.d/pgdg.list :
deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main
Ajout de la clé du dépôt :
wget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | sudo apt-key add -
Mise à jour de la liste des paquets :
apt-get update
Installation des paquets de PostgreSQL 9.2 :
apt-get install postgresql-9.2 postgresql-client-9.2 postgresql-contrib-9.2 postgresql-server-dev-9.2 postgresql-plperl-9.2
Sur l'esclave, en tant qu'utilisateur postgres:
Création du répertoire d'archivage :
mkdir ~/wal92
Si la modification du fichier start.conf a été effectuée correctement, cette étape n'a aucune influence sur les instances postgres existantes.
Paramétrage de PostgreSQL 9.2
Comme il s'agit d'un serveur sous-dimensionné par rapport aux serveurs de productions, les valeurs renseignées ici ne sont pas représentatives de la configuration qu'il faudra appliquer en production. De plus, sans informations sur le système disque sous-jacent, il est impossible de configurer efficacement les paramètres liés aux disques.
En tant qu'utilisateur root :
Mise en place de cette configuration dans le fichier /etc/postgresql/9.2/main/postgresql.conf :
listen_addresses = '*' port = 5433 max_connections = 100 shared_buffers = 1GB -> 10GB maintenance_work_mem = 800MB -> 1GB wal_level = hot_standby wal_buffers = 32MB checkpoint_segments = 70 checkpoint_completion_target = 0.9 archive_mode = on archive_command = 'rsync %p postgres@<ip>:/var/lib/postgresql/wal92/%f' max_wal_senders = 3 autovacuum = on hot_standby = on
Bien vérifier que l'adresse IP correspond à celle de l'esclave !
Selon la quantité de mémoire allouée à PostgreSQL, il pourra être nécessaire de modifier le paramètre shmmax. Par exemple :
echo "kernel.shmmax=10737418240" >> /etc/sysctl.conf sysctl -p kernel.shmmax=68719476736 kernel.shmall=4294967296
Redémarrage de la nouvelle instance PostgreSQL : pg_ctlcluster 9.2 main restart Récupération de la configuration du fichier pg_hba.conf de la 8.4 pour la 9.2. Le fichier est présent dans le répertoire /etc/postgresql/8.4/main et son contenu doit être copié dans le répertoire /etc/postgresql/9.2/main.
Streaming replication
Création d'un utilisateur pour la réplication :
psql -p 5433 -c "CREATE ROLE replicateur LOGIN REPLICATION PASSWORD 'un mot de passe compliqué'" postgres
Ajout d'une ligne dans le fichier /etc/postgresql/9.2/main/pg_hba.conf pour autoriser l'utilisateur postgres à se connecter en streaming replication :
host replication replicateur <ip host>/32 md5
Rechargement de la configuration de PostgreSQL :
pg_ctlcluster 9.2 main reload
Mise en place de l'esclave
En tant qu'utilisateur postgres, sur l'esclave : Éteindre postgres sur l'esclave : pg_ctlcluster 9.2 main stop
Création du fichier ~postgres/.pgpass:
192.168.96.201:5433:*:replicateur:un mot de passe compliqué. _EOF chmod 600 ~postgres/.pgpass Penser à récupérer le mot de passe généré plus haut ! Initialisation du répertoire $PGDATA : rm -rf /var/lib/postgresql/9.2/main/ mkdir /var/lib/postgresql/9.2/main/ chmod 700 /var/lib/postgresql/9.2/main/ /usr/lib/postgresql/9.2/bin/pg_basebackup -U postgres -h 192.168.96.201 -p 5433 -U replicateur -P -c fast -D /var/lib/postgresql/9.2/main/ echo > /var/lib/postgresql/9.2/main/recovery.conf <<EOF restore_command = 'cp /var/lib/postgresql/wal92/%f %p' standby_mode = on primary_conninfo = 'host=192.168.96.201 port=5433 user=replicateur application_name=slave' archive_cleanup_command = '/usr/lib/postgresql/9.2/bin/pg_archivecleanup /var/lib/postgresql/wal92/ %r' EOF
Bien vérifier que l'adresse IP correspond à celle du maître ! (attention, elle est présente deux fois)
Recopier les fichiers /etc/postgresql/9.2/main/pg_hba.conf et /etc/postgresql/9.2/main/postgresql.conf du maître dans le même répertoire sur l'esclave à savoir /etc/postgresql/9.2/main/.
Démarrage de postgres :
pg_ctlcluster 9.2 main start
Vérifier que la connexion en streaming replication est bien visible depuis le maître, grâce à la vue pg_stat_replication.
Sauvegarde de l'instance 8.4
Couper les accès au serveur dans le pg_hba.conf
Dans le cadre d'un changement de version majeure, la sauvegarde doit toujours se faire à l'aide des binaires de la version la plus récente.
La sauvegarde est réalisée à l'aide d'un petit script que voici :
#!/bin/bash PGBIN=/usr/lib/postgresql/9.2/bin DST=/var/lib/postgresql/dump export PGPORT=5432 echo "sauvegarde des bases..." for i in $($PGBIN/psql -At -c "select datname from pg_database where datname != 'postgres' and not datistemplate"); do echo "Sauvegarde de la base $i..." time $PGBIN/pg_dump -Fc $i > $DST/$i.dump done echo "Sauvegardes des objets globaux..." time $PGBIN/pg_dumpall -g > $DST/globals.sql echo "Fin."
Et est lancée ainsi :
./sauvegarde92.sh 2>&1 | tee sauvegarde92.log
Sur le serveur de test (srvtest01), la sauvegarde a pris environ 30 minutes. Sur le deuxième serveur (rds01), plus proche de la prod, la dernière sauvegarde a duré 18 minutes 35 secondes.
Restauration sur l'instance 9.2
Sur les serveur de productions, il sera certainement plus efficace d'utiliser un plus grand nombre de job, en modifiant le paramètre -j.
La restauration se fait à l'aide de ce script :
#!/bin/bash PGBIN=/usr/lib/postgresql/9.2/bin DST=/var/lib/postgresql/dump export PGPORT=5433 echo "restauration des globaux..." $PGBIN/psql -f $DST/globals.sql for i in $(ls $DST/*.dump); do echo "Restauration de la sauvegarde $i..." time $PGBIN/pg_restore -U postgres -C -d postgres -j2 $i done
Et est lancée ainsi :
./restauration92.sh 2>&1 | tee restauration.log
Sur le serveur de test (srvtest01), la restauration a pris environ 4 heures. Sur le deuxième serveur (rds01), plus proche de la prod, la restauration a duré 38 minutes et 45 secondes.
Mise à jour des statistiques sur l'instance 9.2
Cette mise à jour se fait à l'aide de ce script :
#!/bin/bash PGBIN=/usr/lib/postgresql/9.2/bin export PGPORT=5433 for i in $($PGBIN/psql -At -c "select datname from pg_database where datname != 'postgres' and not datistemplate"); do echo "Analyze de la base $i..." time $PGBIN/psql -c "VACUUM ANALYZE;" $i done
Et est lancée ainsi :
./vacuumanalyze92.sh 2>&1 | tee vacuumanalyze.log
Sur le serveur rds01, plus proche de la prod, la restauration a duré 5 minutes et 5 secondes.
Changement de port de l'instance 9.2
Avant sa mise à disposition de la production, l'instance 9.2 doit être placée sur le port 5432 :
Arrêt des instances en 8.4 sur les 2 serveurs :
/etc/init.d/postgresql stop 8.4
Modification sur les deux serveurs du port de l'instance 9.2 à 5432 dans le fichier de configuration
/etc/postgresql/9.2/main/postgresql.conf
Modification du port à 5432 dans le fichier PGPASS /var/lib/postgresql/.pgpass
Redémarrage des instances sur les deux serveurs :
/etc/init.d/postgresql restart 9.2