Administrando replicación en PostgreSQL con REPMGR

Como sabemos en PostgreSQL podemos tener una configuracion de replicación maestro-esclavo (hot-standby) de forma facil, pero esta configuración no nos provee un failover o recuperación del maestro. Tenemos varias alternativas que junto con PostgreSQL nos pueden proveer estas características.

Sin embargo aquí hablaremos de REPMGR que es una herramienta para poder administrar la replicación hot-standby de PostgreSQL, nos ofrece características como poder cambiar de modo esclavo a maestro de forma manual ó automática, capacidad de que los esclavos del cluster sigan al nuevo maestro y poder recuperar al maestro.

En esta publicación realizaremos los siguientes ejercicios:

Instalación

En esta publicación manejaremos PostgreSQL 9.2 y ** CentOS 6.x**

En todos nuestros nodos debemos instalar los siguientes paquetes:

Estos paquetes se encuentra dentro del repositorio oficial de postgresql (ha excepción de rsync) que debes instalar antes para poder encontrar los paquetes que se listan arriba.

# yum install postgresql92-server postgresql92-contrib repmgr92 rsync -y
# chkconfig postgresql-9.2 on
# service postgresql-9.2 initdb

Antes de empezar, tenga encuentra la siguiente estructura de configuración de red de los nodos.

Nombre IP Hostname
nodo1 192.168.1.1 nodo1.example.com
nodo2 192.168.1.2 nodo2.example.com
nodo3 192.168.1.3 nodo3.example.com

El nodo maestro sera el nodo1 y los demás los esclavos (standby). [[more]]

Configuraciones

Configuraciones del nodo maestro

Iniciamos el servicio en el nodo1

# service postgresql-9.2 start

Creamos un usuario y la base de datos que usara REPMGR

CREATE ROLE repmgr_usr LOGIN SUPERUSER;
CREATE DATABASE repmgr_db OWNER repmgr_usr;

Instalamos las funciones necesarias para la base de datos de REPMGR

$ su - postgres
$ psql -f /usr/pgsql-9.2/share/contrib/repmgr_funcs.sql repmgr_db

Configuración de accesos al servicio postgresql

$ vim /var/lib/pgsql/9.2/data/pg_hba.conf
# Acceso nodo1
host    repmgr_db       repmgr_usr  192.168.1.1/32         trust
host    replication     repmgr_usr  192.168.1.1/32         trust
# Acceso nodo2
host    repmgr_db       repmgr_usr  192.168.1.2/32         trust
host    replication     repmgr_usr  192.168.1.2/32         trust
# Acceso nodo3
host    repmgr_db       repmgr_usr  192.168.1.3/32         trust
host    replication     repmgr_usr  192.168.1.3/32         trust

En la publicación estaremos usando VIM para editar los archivos de configuración desde terminal. Siéntase en libertad de usar la que mas le acomode (gedit, emacs, nano, etc).

Configuraciones generales del servicio.

$ vim /var/lib/pgsql/9.2/data/postgresql.conf
listen_addresses='*'
wal_level = 'hot_standby'
archive_mode = on
archive_command = 'cd .'
max_wal_senders = 10
wal_keep_segments = 5000
hot_standby = on
shared_preload_libraries = 'repmgr_funcs'

Reiniciar el servicio para cargas las nuevas configuraciones

# service postgresql-9.2 restart

Configuraciones adicionales

Estas configuraciones nos aseguran la conectividad entre los nodos y es importante realizar para el correcto funcionamiento del cluster.

Configuración de hostnames (opcional)

Si no contamos con un servicio de dominio (DNS) para poder asignarle a los servidores un dominio valido podemos usar la resolución por medio del archivo /etc/hosts.

# vim /etc/hosts
192.168.1.1 nodo1.example.com
192.168.1.2 nodo2.example.com
192.168.1.3 nodo3.example.com

Asegure de hacer la misma configuración para todos los nodos del cluster.

Inicio de sesión SSH private-key

Esta configuración es indispensable, ya que los archivos base de postgresql se van ha sincronizar con la herramienta rsync y este utilizara este tipo de acceso con los nodos.

Siguiendo en el nodo1 configuramos de las siguiente forma, iniciamos una sesión del usuario postgres y generamos sus llaves de acceso y lo agregamos entre las llaves autorizadas.

$ su - postgres
$ ssh-keygen
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
$ exit

Cuando genere la llave no le asigne frase de acceso (passphrase).

Ahora vamos a enviarle las llaves (publica y privada) y la lista de llaves autorizadas a todos los nodos que estarán en el cluster.

# rsync -avz ~postgres/.ssh/authorized_keys nodo2.example.com:~postgres/.ssh/
# rsync -avz ~postgres/.ssh/authorized_keys nodo3.example.com:~postgres/.ssh/

# rsync -avz ~postgres/.ssh/id_rsa* nodo2.example.com:~postgres/.ssh/
# rsync -avz ~postgres/.ssh/id_rsa* nodo3.example.com:~postgres/.ssh/

Note que las llaves enviadas son para el usuario postgres, este usuario es el que se va conectar a otros nodos usando ssh (rsync) sin requerir contraseña.

Registrando el nodo maestro

Antes de registrar al nodo maestro necesitamos configurar la herramienta REPMGR.

# vi /etc/repmgr/9.2/repmgr.conf
cluster=mi_cluster
node=1
node_name=nodo1
conninfo='host=nodo1.example.com dbname=repmgr_db user=repmgr_usr'
logfile='/tmp/repmgr-9.2.log'

Ahora registramos el nodo maestro de la siguiente forma.

$ /usr/pgsql-9.2/bin/repmgr -f /etc/repmgr/9.2/repmgr.conf master register --verbose

Registrando nodos standby (esclavos)

Estas configuraciones se realizan en cada servidor esclavo del cluster.

Estando conectado en el nodo esclavo (nodo2) lo primero es clonar al nodo maestro (nodo1) y luego REPMGR se encargara de configurarlo como esclavo (recovery.conf).

$ /usr/pgsql-9.2/bin/repmgr -d repmgr_db -U repmgr_usr standby clone nodo1.example.com --verbose

Iniciamos el servicio postgresql.

# service postgresql-9.2 start

Editamos la configuración de REPMGR (configuración del nodo2).

# vim /etc/repmgr/9.2/repmgr.conf
cluster=mi_cluster
node=2
node_name=nodo2
conninfo='host=nodo2.example.com dbname=repmgr_db user=repmgr_usr'
logfile='/tmp/repmgr-9.2.log'

Ahora registramos nuestro esclavo.

$ /usr/pgsql-9.2/bin/repmgr -f /etc/repmgr/9.2/repmgr.conf standby register --verbose

Podemos verificamos el registro del nodo de la siguiente manera.

$ /usr/pgsql-9.2/bin/repmgr -f /etc/repmgr/9.2/repmgr.conf cluster show
Role      | Connection String 
* master  | host=nodo1.example.com user=repmgr_usr dbname=repmgr_db
standby   | host=nodo2.example.com user=repmgr_usr dbname=repmgr_db

Failover manual

Ahora realizamos el siguiente ejercicio, haremos que el nodo1 se detenga para promover al nodo2 a maestro y después hacer que los demás nodos sigan al nuevo maestro (nodo 2).

Promover al nodo2 a maestro

Antes de promover este nodo detenemos el nodo maestro para simular la baja del servidor.

# poweroff

Ahora nos conectamos al nodo2 y vamos a promoverlo como nodo maestro.

$ su - postgres
$ /usr/pgsql-9.2/bin/repmgr -f /etc/repmgr/9.2/repmgr.conf --verbose standby promote
$ exit
# service postgresql-9.2 restart

Reconfigurar los nodos para seguir al nuevo maestro

Realizamos lo siguiente en cada nodo esclavo para que puedan seguir al nuevo nodo maestro.

$ su - postgres
$ /usr/pgsql-9.2/bin/repmgr -f /etc/repmgr/9.2/repmgr.conf standby follow 

Volver al nodo1 a esclavo

Detener servicio postgresql, al iniciar el servidor maestro es posible que este inicie automáticamente.

# service postgresql-9.2 stop

Clonar a partir del nuevo maestro.

$ su - postgres
$ /usr/pgsql-9.2/bin/repmgr -d repmgr_db -U repmgr_usr --verbose standby clone node2.example.com --ignore-rsync-warning --force
$ exit

Iniciamos el servicio

# service postgresql-9.2 start

Tips extras

Revisar el estado de replicación en nuestro servidor maestro

$ su - postgres
$ psql -x -c "select * from pg_stat_replication;"

Resolución de problemas

Es posible que sea la primera ves que intentas una conexión ssh con el servidor maestro.

$ su - postgres
$ ssh nodo1.example.com
The authenticity of host 'nodo2.example.com (192.168.1.2)' can't be established.
RSA key fingerprint is xx:8e:2e:e9:d0:xx:5d:7b:48:d3:25:xx:18:50:b7:xx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'nodo1.example.com' (RSA) to the list of known hosts.
Welcome to your server.