HowTo/MigratePostgres

From LunaSys
Jump to navigation Jump to search

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