Slony1 es un software para la replicación de datos entre servidores PostgreSQL, creando clusters formados por un nodo maestro y uno o varios nodos esclavos.

Aunque soy Debianita a muerte, muchas veces me veo obligado a usar otras distribuciones de Linux (sobre todo en el curro), como por ejemplo CentOS. Y puesto que éste artículo lo escribí hace ya varios años como chuleta personal precisamente para el curro, está hecho sobre esa distribución... pero como casi siempre en éstos casos, debería ser perfectamente válido para cualquier otro Linux.

Partimos de la base de que ya tenemos instalados y configurados los servidores de base de datos PostgreSQL en los nodos que vamos a usar.

Es de vital importancia que todos los nodos que van a formar el cluster tengan la misma codificación. Es decir, si vamos a usar UTF8, TODOS los servidores y bases de datos deben estar en UTF8, y si vamos a usar LATIN1, TODOS deben estar en LATIN1. De lo contrario, al inicializar la replicación por primera vez, se comenzaran a copiar algunas tablas, y de repente el proceso parará y empezará de nuevo a copiar la primera tabla, y así sucesivamente en un bucle sin fin, sin que ningun log muestre ninguna pista al respecto, así que hay que tenerlo muy presente antes de empezar.

En este ejemplo vamos a configurar un cluster con 2 nodos: 1 maestro y 1 esclavo.

Slony funciona notificando a los esclavos mediante un demonio, que es llamado a su vez por medio de triggers en las tablas que se van a replicar. Solo las operaciones INSERT, UPDATE o DELETE pueden ser replicadas mediante Slony (y el valor de las secuencias, por supuesto). Esto significa que los cambios en el esquema de la base de datos NO son propagados a los nodos, ni ninguna otra operación tampoco (TRUNCATE, DROP, CREATE, etc....)

Instalación

Existen paquetes precompilados de Slony1 para ésta distribucion (CentOS), por lo tanto, lo instalamos mediante su gestor de paquetes YUM:

$ sudo yum install slony1

Si no esstuviéramos utilizando los repositorios de yum necesarios o el paquete no estuviera disponible en ellos por cualquier motivo, deberemos bajar el paquete RPM manualmente desde la URL http://main.slony.info/downloads e instalarlo con:

$ sudo rpm -i <nombrepaquete>

Una vez instalado, los archivos de configuración se guardan en /etc/slon.conf y /etc/slon_tools.conf.

Hay que crear primero el usuario que vamos a usar para la sincronización en todos los nodos del cluster. Dicho usuario debe tener permisos de superuser en el servidor de base de datos. Tambien habrá que configurar los permisos de PostgreSQL para poder conectarse con este usuario desde el servidor maestro del cluster.

Para eso, creamos el usuario en el servidor PostgreSQL (en nuestro ejemplo, vamos a crear el usuario slony), por lo que iniciamos la consola de PostgreSQL y ejecutamos la query para crear el usuario:

$ sudo su postgres -
postgres@server:~$ psql
psql (9.3.4)
Type "help" for help.

postgres=# CREATE USER slony superuser password 'test';
CREATE ROLE
postgres=# \q

Editamos ahora el archivo pg_hba.conf de PostgreSQL, que es donde se configura el acceso de los usuarios, habilitando el usuario que acabamos de crear (especificando todo el rango de IP's de nuestra red, y seleccionando MD5 como tipo de password en dicha configuración):

# "local" is for Unix domain socket connections only
local   all         all                               ident sameuser
# Slony
host    all         slony       172.26.0.0/24         md5
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5
# IPv6 local connections:
host    all         all         ::1/128               ident sameuser

Probamos a conectarnos con dicho usuario desde la consola de PostgreSQL (comando psql), y una vez que hayamos comprobado que funciona, editamos el archivo slon_tools.conf para configurar los nodos, tablas y secuencias que formarán el cluster de replicación..

Definimos el nombre del cluster en la variable $CLUSTER_NAME:

$CLUSTER_NAME = 'test_replication';

Después, añadimos tantos nodos como servidores vayan a componer nuestro cluster. En el primer nodo definiremos el servidor MAESTRO, y en los sucesivos los esclavos:

add_node(node     => 1,
    host     => 'borg01',
    dbname   => 'testdb',
    port     => 5432,
    user     => 'slony',
    password => 'replicapass'
);

add_node(node     => 2,
    host     => 'borg02',
    dbname   => 'testdb',
    port     => 5432,
    user     => 'slony',
    password => 'replicapass'
);

Comentamos el resto de lineas de los nodos, ya que solo configuraremos estos 2 servidores, y luego especificamos las tablas (en nuestro caso lo haremos con la tabla de ejemplo ads) y secuencias (en nuestro caso ads_id_seq) que queremos sincronizar entre los servidores:

"pkeyedtables" => [
    'ads',
],
"sequences" => [
    'ads_id_seq',
],

Es muy importante tener en cuenta que en pkeyedtables hay que especificar todas las tablas que vamos a replicar SIEMPRE Y CUANDO dichas tablas tengan definida una PRIMARY_KEY. Si tenemos alguna tabla que NO tiene una clave primaria, pero tiene un índice único (y que no admita NULL) en lugar de especificarla en pkeyedtables lo haremos en keyedtables, indicando ademas el nombre del índice, de esta forma:

"keyedtables" => {
    'tablasinpk' => 'nombre_indice',
},

Después, copiamos éste archivo a ambos servidores (maestro y esclavo).

Todas las tablas y secuencias que queramos sincronizar entre ambos servidores deben estar ya creadas en todos los nodos del cluster. Es decir, según nuestro ejemplo, la tabla ads y la secuencia ads_id_seq deben existir y ser iguales en ambos servidores (maestro y esclavo) antes de iniciar el proceso de replicación. Resumiendo: el modelo de datos debe estar creado en todos los servidores, ya que lo único que se replica con Slony son los datos, no el esquema.

Inicialización del cluster

Ahora que slony esta configurado correctamente en todos los servidores, y las bases de datos, usuarios y secuencias estan tambien creados en todos ellos, iniciamos el cluster desde el servidor maestro con el comando:

$ slonik_init_cluster  | slonik

Después, iniciamos los demonios slon en cada servidor, primero con el comando slon_start y luego con el demonio del sistema /etc/init.d/slony1. En nuestro ejemplo, ejecutamos desde el servidor maestro (borg01) el nodo 1:

$ sudo slon_start 1
$ sudo /etc/init.d/slony1 start

Y el nodo 2 desde el servidor esclave (borg02) con el comando:

$ sudo slon_start 2
$ sudo /etc/init.d/slony1 start

Despues, iniciamos el proceso de replicacion, ejecutando el siguiente comando desde el servidor maestro:

$ slonik_create_set 1 | slonik

Y por último, añadimos el esclavo al proceso de replicacion, con el comando:

$ slonik_subscribe_set 1 2 | slonik

Si tuvieramos más servidores esclavos, habría que ejecutar ese comando en cada uno de ellos, especificando el nodo que estamos suscribiendo en ese momento, por ejemplo:

$ slonik_subscribe_set 1 3 | slonik
$ slonik_subscribe_set 1 4 | slonik

Y así sucesivamente...

Ahora ya deberíamos tener nuestro cluster activo y funcionando. La primera vez, sobre todo si las tablas son grandes, suele tardar un buen rato en terminar la sincronización inicial, ya que lo primero que hará Slony será TRUNCATE de todas las tablas de los servidores esclavos, para irlas rellenando con los datos del maestro desde cero, por lo que a veces el proceso puede tardar un poco.

A partir de ese momento, todas las querys de inserción/modificación que ejecutemos en el servidor MAESTRO en la tabla que hemos configurado para la replicación, se transmitirán tambien a las tablas del servidor ESCLAVO.

Monitorización de la replicación

Slony crea un nuevo esquema en cada uno de los servidores, llamado _$CLUSTER_NAME (el nombre que especificamos en la variable $CLUSTER_NAME, con el guion-bajo delante). En dicho esquema se guarda la informacion que slony necesita para replicar los datos.

Además, en ese esquema tambien encontraremos un par de vistas que nos seran muy utiles para ver el estado del cluster y la replicacion, sobre todo una llamada sl_status, en la que se indican los nodos a los que se estan replicando, el lag de tiempo de replicación que existe entre cada uno de ellos y el maestro, etc...

Con esta query veremos toda esa informacion:

SELECT
    st_origin,
    st_received,
    st_last_event,
    st_last_received,
    st_last_event_ts,
    st_last_received_ts,
    st_lag_time
FROM
    _replication.sl_status
ORDER BY
    2;

Si tuvieramos que modificar la estructura de alguna tabla de nuestro cluster ya replicado, habría que utilizar los scripts de Slony que se encargan de transmitir dichos cambios al resto de los nodos, pero eso mejor lo dejamos para otro dia, jejejee...

No hace falta que os recuerde que en la web oficial de Slony hay mucha y muy detallada documentación sobre todos los comandos y funciones, así que es le primer sitio que debeis leer si estais montando una replicación de éste tipo.

Alaaaaaaaaaaaaaaaaaaaaaaa

Referencias