Lo primero que debemos tener es la cuenta creada con Google que nos entregue un credito inicial de 300 dolares, dar de alta una tarjeta de credito vpalida, este paso es requerido por Google, no se haran cargos al terminar los creditos que nos entrega, en lugar de eso, nuestros servicios se detendran y ya no generaran nuevos cargos, a menos que nosotros mismos actualicemos nuestro plan.
Vamos a utilizar Compute Engines para esto, no vamos a utilizar el servicio administrado que ofrece Google con Cloud SQL, en su lugar vamos a revisar como hacer la instalación de forma manual creando dos instancias en el servicio de Compute Engine de Google, cambiamos el sistema operativo a Ubuntu 20.04 LTS y el resto lo dejamos por defecto.
El nombre de las maquinas virtuales puede ser master y slave o node1 y node2, primary y replication etc, seleccionen los nombres de acuerdo a su conveniencia, generalmente vamos a indicar que una de las maquinas tendra el rol principal y la otra de secundaria, los roles van cambiar cuando se inicie el tema de failover, solo sean consistentes y recuerden los nombres dados, en mi caso yo las estoy nombrando como pg-master y pg-slave, eso me parecio buena idea al principio para explicar algunos conceptos.
Una vez iniciadas las dos instancias, ingresamos en ellas mediante SSH, cambiamos nuestro usuario a root con el comando sudo -i e ingresamos los siguientes comandos:
# Creara el archivo con la configuración del repositorio
sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
# Importamos la llave de firmado del repositorio:
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
# Uactualizamos la lista de paquetes:
sudo apt-get update
# Instalamos la versión de postgres.
# En nuestro caso seleccionamos la version 13, puedes seleccionar alguna otra depentiendo de tus necesidades:
sudo apt-get -y install postgresql-13
Para verificar las dos versiones en las dos maquinas ejecutamos alguno de los siguientes comandos:
# Este comando nos dara la salida del status del servicio
systemctl status postgresql
# o bien este comando para ver como se levanto el servicio de postgres
ps -feq | grep postgresql
Una vez instalado esto, ahora podemos conectarnos para revisar algunos comandos en postgres y validar que todo este funcionando correctamente. Hacer la prueba en ambas maquinas para revisar que todo funcione correctamente en las dos instancias.
# Primero accedemos como root
sudo -i
# Cambiamos al usuario postgres
su - postgres
# Listamos las bases actuales en postgres
psql -l
# Seleccionamos alguna de las bases
psql -d postgres
# Con el prompt de postgres listamos algunas tablas dentro de esa base, es posible que no vean ninguna tabla pero es normal
\dt+
# Salir del prompt de postgres
\q
En el primer nodo, pg-master vamos a crear una base de datos de prueba, solo en pg-master, no ejecuten los comandos en la otra maquina.
su - postgres
psql
create database demo;
\q
# Ingresar nuevamente con la base demo
psql -d demo
create table test (int serial);
\dt
insert into test (select generate_series(1,1000));
select count(*) from test;
\q
Antes de empezar con la replicacion, es necesarios conocer donde se encuentran los archivos de configuración de Postgres, los ejemplos siguientes fueron tomados de uns instalación por default de Postgres 13.x, sin embargo la ubicación puede cambiar entre versiones o dependiendo de la configuración de cada proyecto.
psql
SHOW config_file;
SHOW data_directory;
SHOW hba_file;
Vamos a continuar con el primer paso que es la replicación, cuando todo este configurado, vamos a ver los mismos datos en el otro nodo, pg-slave sin haber hecho ningun comando para crear la base o la tabla.
En el nodo pg-master hacemos lo siguiente
sudo -i
su - postgres
psql -U postgres -c 'SHOW config_file'
exit
vi /etc/postgresql/13/main/postgresql.conf
listen_addresses = '*'
wal_level = replica
synchronous_commit = off
max_wal_senders = 10
synchronous_standby_names = '*'
vi /etc/postgresql/13/main/pg_hba.conf
host replication rep_user 10.128.0.0/24 md5
su - postgres
createuser --replication -P rep_user
exit
systemctl restart postgresql
Aqui una aclaración, vamos a utilizar un mecanismo de replicacion llamado streaming, lo que significa que estaremos sincronizando mediante archivos todos los cambios hechos en un nodo, es decir una replicacion fisica, no logica que sería con transacciones, consultas sql etc. por defecto esta replicacion es asincrona, y postgres se encarga de mandar los cambios entre nodos de acuerdo a su configuración mas optima, sin embargo si nonostor forzamos a que la replicación por stream sea sincrona, lo cual se logra haciendo lo siguiente:
synchronous_commit = on
Esto igualmente funcionaria, pero si por alguna razon el nodo de replica es inaccesible, postgres intentara hacer la replica y tener esa confirmación de escritura antes de regresar una respuesta final al cliente (me refiero a un cliente de base de datos o una aplicacion por ejemplo), al no haber respuesta existosa de la replica inaccesible, postgres mandara regresara un error al cliente, es decir que aun cuando se pudiera aplicar el cambio en el nodo primario, para los clientes toda la base de datos no funcionaría, esto pasaría solo con consultas de escritura, las consultas de lectura seguirian funcionando.
Ahora vamos al nodo pg-slave
sudo -i
systemctl stop postgresql
rm -rf /var/lib/postgresql/13/main/*
su - postgres
pg_basebackup -R -h 10.128.0.10 -U rep_user -D /var/lib/postgresql/13/main -P
exit
vi /etc/postgresql/13/main/postgresql.conf
listen_addresses = '*'
hot_standby = on
systemctl start postgresql
Eso es todo, ahora podemos revisar si tenemos la misma base de datos demo en el nodo pg-slave y con los mismos registros en la tabla test.
-- En el nodo pg-master
sudo -i
su - postgres
psql -d demo
insert into test (select generate_series(1,1000));
select count(*) from test;
-- En el nodo pg-slave
sudo -i
su - postgres
psql -d demo
select count(*) from test;
-- Intentar insertar en pg-slave (error)
insert into test (select generate_series(1,1000));
ERROR
Algunas cosas que se deben aclarar hasta el momento:
- El nodo pg-slave funciona como hot_standy, lo que significa que el nodo puede ser usuado como replicacion del nodo pg-master, y ademas que un cliente puede acceder a ese nodo para consultas de solo lectura.
- Todo cambio hecho en el nodo pg-master se vera reflejado en el nodo pg-slave, si el nodo pg-slave se detiene, en cuanto este en linea nuevamente, la replicacion intentara sincronizar los nodos automaticamente, por lo que no hay necesidad de hacer el proceso de backup inicial nuevamente.
- Si se requiere tener alta disponibilidad con esta configuración, es posible crear las maquinas virtuales en diferentes zonas o incluso regiones, sin embargo habra que tomar en cuenta detalles para comunicar debido a alguna restricción de firewall que implemente Google entre las maquinas, tomar en cuenta esto.
Hasta aqui con este post, nos vemos en el siguiente para ver temas de failover.