Streaming Replication (replicación en flujo)

A partir de la versión 9.0, PostgreSql soporta replicación en flujo, lo que permite a los servidores en espera estar más actualizados que con los métodos anteriores de tranferencia de archivos. Los servidores secundarios se conectan al primario, que envía los registros de WAL cuando son generados, sin esperar a que los archivos de WAL se llenen.

Ver RespaldoContinuo para más información.

Configurar seguridad y acceso

Crear un usuario para replicación:

CREATE USER repuser
SUPERUSER
LOGIN
CONNECTION LIMIT 1
ENCRYPTED PASSWORD 'secreto';

En pg_hba.conf habilitar al usuario:

host replication repuser 127.0.0.1/0 md5

Adicionalmente configurar log_connections = on en postgresql.conf para detectar los intentos de replicación.

Configurar replicación en el primario

Establecer los parámetros necesarios en el servidor primario:

max_wal_senders = 1
archive_mode = on
wal_level = hot_standby
archive_command = 'cd .'
wal_keep_segments = 10000 # por ej. para 160 GB

Para replicación sincrónica, configurar synchronous_standby_names (PostgreSQL 9.1+):

synchronous_standby_names = '*'

Ajustar los parámetros para Hot-Standby vistos en RespaldoContinuo, por ejemplo, para linux:

archive_command = 'scp "%p" $SLAVE_IP:"/var/lib/postgresql/9.1/archive/"'

Reiniciar el servidor principal para que actualice los cambios:

$PGBIN/pg_ctl -D data90 restart

Realizar el backup inicial físico

Similar RespaldoContinuo:

$PGBIN/psql postgres -c "SELECT pg_start_backup('replica');"
mkdir replica
chmod 700 replica
cd $PGDATA ; cp -rvdpaf !(pg_xlog) ../replica; cd ..
$PGBIN/psql postgres -c "select pg_stop_backup(), current_timestamp"

Configurar replicación en el esclavo

En recovery.conf cambiar:

standby_mode = 'on'
primary_conninfo = 'host=127.0.0.1 port=5485 user=repuser password=secreto'
#restore_command = 'cp /var/lib/postgresql/9.1/archive/%f %p'
trigger_file = '/tmp/postgresql.trigger.5485'

Descomentar el restore command para recuperación continua.

En el esclavo, revisar pg_hba.conf y postgresql.conf (cambiar port, habilitar hot_standby, deshabilitar archive_mode, wal_level, wal_keep_segments, etc.). Revisar postmaster.opts (directorio data).

Iniciar la replicación

Limpiar e Iniciar el servidor secundario:

rm replica/postmaster.pid  # borrar pid del principal
rm replica/pg_xlog -Rv
mkdir replica/pg_xlog      # recrear directorio WAL
$PGBIN/pg_ctl -D replica restart

La salida esperada debería indicar que se está replicando:

LOG:  el sistema de bases de datos fue interrumpido; última vez en funcionamiento en 2010-12-28 04:28:13 ART
LOG:  entrando al modo standby
LOG:  conexión recibida: host=127.0.0.1 port=46320
LOG:  conexión de replicación autorizada: usuario=repuser host=127.0.0.1 port=46320
LOG:  la replicación en flujo se ha conectado exitosamente al primario
LOG:  redo comienza en 0/3A000020
LOG:  el estado de recuperación consistente fue alcanzado en 0/3B000000

Probar servidores

$PGBIN/psql -p $PGPORTNEW -c "select count(*) from pgbench_history"
$PGBIN/psql -c "select count(*) from pgbench_history"
$PGBIN/pgbench -t 1000 -p 5485 correo
$PGBIN/psql -c "select count(*) from pgbench_history"
$PGBIN/psql -p $PGPORTNEW -c "select count(*) from pgbench_history"

Si al intentar conectarse al secundario aparece un error, verificar el modo de hot_standby:

FATAL:  el sistema de base de datos está iniciándose

Bibliografía

Para mayor información dirigirse a: