En True Engineering, en un proyecto, ha surgido la necesidad de cambiar la versi贸n de PostgreSQL de 9.6 a 11.1.
Por qu茅 La base de datos del proyecto ya tiene un tama帽o de 1,5 Tb y est谩 creciendo. El rendimiento es uno de los principales requisitos del sistema. Y la estructura de datos en s铆 misma est谩 evolucionando: se agregan nuevas columnas, se cambian las existentes. La nueva versi贸n de Postgres ha aprendido c贸mo trabajar de manera eficiente con la adici贸n de nuevas columnas con un valor predeterminado, por lo que no hay necesidad de cercar muletas personalizadas a nivel de aplicaci贸n. Incluso en la nueva versi贸n, se agregaron varias formas nuevas de particionar tablas, lo que tambi茅n es extremadamente 煤til en condiciones de una gran cantidad de datos.
Entonces, se decide, estamos migrando. Por supuesto, puede generar una nueva versi贸n del servidor PostgreSQL en paralelo con el anterior, detener la aplicaci贸n, usar dump / restore (o pg_upgrade) para mover la base de datos y reiniciar la aplicaci贸n. Esta soluci贸n no nos conven铆a debido al gran tama帽o de la base, adem谩s, la aplicaci贸n funciona en modo de combate, y solo quedan unos minutos para el tiempo de inactividad.
Por lo tanto, decidimos probar la migraci贸n usando la replicaci贸n l贸gica en PostgreSQL usando un complemento de terceros llamado
pglogical .
En el proceso de "prueba", nos encontramos con documentaci贸n muy fragmentaria sobre este proceso (y en ruso no lo es en absoluto), as铆 como algunas trampas y matices obvios. En este art铆culo, queremos presentar nuestra experiencia en forma de tutorial.
TL; DR- Todo result贸 (no sin muletas, un art铆culo sobre ellos).
- Puede migrar dentro de la versi贸n PostgreSQL de 9.4 a 11.x, de cualquier versi贸n a cualquiera, hacia abajo o hacia arriba.
- El tiempo de inactividad es igual al tiempo que le toma a su aplicaci贸n volver a conectarse al nuevo servidor de base de datos (en nuestro caso, fue un reinicio de toda la aplicaci贸n, pero en la naturaleza, obviamente, "posibles opciones").
驴Por qu茅 no nos quedaba la soluci贸n de "frente"?
Como ya dijimos, la salida m谩s f谩cil es elevar la nueva versi贸n del servidor PostgreSQL en paralelo con la anterior, detener la aplicaci贸n, usar dump / restore (o pg_upgrade) para mover la base de datos e iniciar la aplicaci贸n nuevamente. Para bases de datos de peque帽o volumen, en principio, esta es una opci贸n bastante adecuada (o, en el caso general, el volumen no es importante cuando tiene la opci贸n de tiempo de inactividad de la aplicaci贸n durante el per铆odo de "transfusi贸n" de la base de datos del servidor antiguo al nuevo, sin importar cu谩nto tiempo sea este tiempo). Pero en nuestro caso, la base de datos ocupa aproximadamente 1,5 Tb en el disco, y moverla no es cuesti贸n de minutos, sino de varias horas. La aplicaci贸n, a su vez, funciona en modo de combate, y realmente quer铆a evitar el tiempo de inactividad durante m谩s de un par de minutos.
Tambi茅n contra esta opci贸n estaba el hecho de que usamos la replicaci贸n Maestro-Esclavo y no podemos apagar el servidor Esclavo del flujo de trabajo de manera segura. Por lo tanto, para cambiar la aplicaci贸n de la versi贸n anterior de PostgreSQL a la nueva despu茅s de la migraci贸n del servidor maestro, ser铆a necesario preparar un nuevo servidor esclavo antes de iniciar la aplicaci贸n. Y esto es unas pocas horas m谩s de tiempo de inactividad hasta que se crea el Esclavo (aunque mucho menos que la migraci贸n del Maestro).
Por lo tanto, decidimos probar la migraci贸n usando la replicaci贸n l贸gica en PostgreSQL usando un complemento de terceros llamado pglogical.
Informaci贸n general
pglogical es un sistema de replicaci贸n l贸gica que utiliza decodificaci贸n l贸gica nativa en PostgreSQL e implementado como una extensi贸n de PostgreSQL. Le permite configurar la replicaci贸n selectiva utilizando el modelo de suscripci贸n / publicaci贸n. No requiere la creaci贸n de disparadores en la base de datos o el uso de utilidades externas para la replicaci贸n.
La extensi贸n funciona en cualquier versi贸n de PostgreSQL, comenzando desde 9.4 (ya que la Decodificaci贸n l贸gica apareci贸 por primera vez en 9.4), y le permite migrar entre cualquier versi贸n compatible de PostgreSQL en cualquier direcci贸n.
Configurar manualmente la replicaci贸n usando pglogical manualmente no es muy trivial, aunque en principio es bastante posible. Afortunadamente, hay un programa de utilidad de
terceros para automatizar el proceso de configuraci贸n, que utilizaremos.
Memo de espacio en disco
Como planeamos actualizar la nueva versi贸n de PostgreSQL en los mismos servidores en paralelo con la anterior, los requisitos de disco para la base de datos en los servidores Maestro y Esclavo se duplican. Parece que esto es obvio, pero ... Solo cuide suficiente espacio libre antes de comenzar la replicaci贸n para no lamentar los a帽os gastados sin rumbo.
En nuestro caso, se requirieron modificaciones en la base de datos, m谩s el formato de almacenamiento durante la migraci贸n entre 9.6 y 11 "swells" no a favor de la 煤ltima versi贸n, por lo que el espacio en disco no tuvo que incrementarse en 2, sino en aproximadamente 2.2 veces. Alabado sea LVM, esto se puede hacer en el proceso de migraci贸n sobre la marcha.
En general, cu铆dalo.
Instalar PostgreSQL 11 en Master
Nota: Utilizamos Oracle Linux, y todo lo siguiente se agudizar谩 para esta distribuci贸n. Es posible que otras distribuciones de Linux requieran una peque帽a revisi贸n con un archivo, pero es poco probable que sea significativo.
El antiguo datadir se encuentra en
/var/lib/pgsql/9.6/data , el nuevo, respectivamente, est谩 en
/ var / lib / pgsql / 11 / dataCopie la configuraci贸n de acceso (
pg_hba.conf ) y la configuraci贸n del servidor (
postgresql.conf ) de 9.6 a 11.
Para ejecutar dos servidores PostgreSQL en la misma m谩quina, en la configuraci贸n de configuraci贸n
postgresql.conf 11, cambie el puerto a 15432 (puerto = 15432).
Aqu铆 debe pensar detenidamente qu茅 m谩s debe hacer en la nueva versi贸n de PostgreSQL espec铆ficamente en su caso, para que comience con su
postgresql.conf (y su aplicaci贸n eventualmente podr铆a funcionar con 茅l). En nuestro caso, fue necesario instalar las extensiones PostgreSQL que usamos en la nueva versi贸n. Esto est谩 m谩s all谩 del alcance del art铆culo, solo haga que el nuevo PostgreSQL se inicie, funcione y se adapte completamente a usted :)
Buscamos en
/ var / lib / pgsql / 11 / data / pg_log / . 驴Est谩 todo bien? Continuamos!
Instalar y configurar pgrepup

Matices:
- Como propietario de la aplicaci贸n, especificamos el usuario bajo el cual se ejecutan los servidores PostgreSQL.
- Para Base de datos, especifique template1 .
- Nombre de usuario y contrase帽a : datos para acceso de superusuario. En nuestro caso, el m茅todo de confianza se especific贸 en pg_hba.conf para las conexiones locales del usuario de postgres , por lo que puede especificar una contrase帽a arbitraria.
Configurar replicaci贸n
Obtenemos la salida de una lista de muchos par谩metros que deben configurarse seg煤n sea necesario.
Resultados de verificaci贸n de ejemplo:


Todos los errores durante la verificaci贸n deber谩n ser eliminados. En la configuraci贸n de ambos servidores se debe establecer
wal_level = LOGICAL (para que funcione la decodificaci贸n l贸gica), la configuraci贸n necesaria para el motor de replicaci贸n (n煤mero de slots y
wal_senders ). Las sugerencias de la utilidad pgrepup son bastante informativas; las preguntas no deber铆an surgir en la mayor铆a de los puntos.
Realizamos todas las configuraciones necesarias que pgrepup solicita.
En ambos archivos
pg_hba.conf agregamos permisos para el usuario que realizar谩 la replicaci贸n, todo en el indicador pgrepup:
host replication pgrepup_replication 127.0.0.1/32 md5 host all pgrepup_replication 127.0.0.1/32 md5
Agregar claves primarias
Para que la replicaci贸n funcione, se debe definir una clave primaria en todas las tablas.
En nuestro caso, PK no estaba en todas partes, por lo tanto, en el momento de la replicaci贸n, debe agregarlo y, al final de la replicaci贸n, si es necesario, eliminarlo.
Una lista de tablas sin PK, entre otras cosas, produce la
pgrepup check
. Para todas las tablas de esta lista, debe agregar una clave principal de la manera que m谩s le convenga. En nuestro caso, fue algo como:
ALTER TABLE %s ADD COLUMN temporary_pk BIGSERIAL NOT NULL PRIMARY KEY
La utilidad pgrepup tiene un comando incorporado para llevar a cabo esta operaci贸n (
pgrepup fix
), y cuando se usa, incluso se da a entender que, tras una replicaci贸n exitosa, estas columnas temporales se eliminar谩n autom谩ticamente. Pero, desafortunadamente, esta funcionalidad era tan ilusoria y encantadora con errores en grandes bases que decidimos no usarla, sino hacer esta operaci贸n manualmente ya que nos sentimos c贸modos.
Instalar extensi贸n pglogical
Las instrucciones para instalar la extensi贸n se pueden encontrar
aqu铆 . La extensi贸n debe estar instalada en ambos servidores.
Agregue la carga de la biblioteca en
postgresql.conf de ambos servidores:
shared_preload_libraries = 'pglogical'
Instalar la extensi贸n pgl_ddl_deploy
Esta es una extensi贸n auxiliar que utiliza pgrepup para la replicaci贸n l贸gica DDL.
Agregue la carga de la biblioteca en
postgresql.conf de ambos servidores:
shared_preload_libraries = 'pglogical,pgl_ddl_deploy'
Comprobaci贸n de cambios
Ahora, utilizando la
pgrepup check
, debe asegurarse de que todo est茅 bien con el servidor de destino y que todos los comentarios sobre el servidor de destino se hayan eliminado por completo.
Si todo est谩 bien, puede reiniciar el servidor anterior. Aqu铆 debe pensar c贸mo reaccionar谩 su aplicaci贸n ante el reinicio del servidor de base de datos, tal vez deber铆a detenerlo primero.
Ahora en la salida del comando, todos los elementos deben estar marcados como OK.
Parece que puedes comenzar la migraci贸n, pero ...
Corregir errores de pgrepup
Hay varios errores en la versi贸n actual de pgrepup que hacen imposible la migraci贸n. Se enviaron solicitudes de extracci贸n, pero desafortunadamente, se ignoran, por lo que deber谩 realizar correcciones manualmente.
Vamos a la carpeta de instalaci贸n de pgrepup (nuestro caso es
/usr/lib/python2.7/site-packages/pgrepup/commands/ ).
Hazlo una vez. En cada archivo
* .py , agregue los
**kwargs
faltantes en la descripci贸n de la funci贸n. Una imagen es mejor que mil palabras:

Comprom茅tete
aqu铆 .
Hacer dos. En
setup.py hacemos una b煤squeda de "sh -c", dos entradas, todos los comandos de shell de varias l铆neas deben hacerse de una sola l铆nea.
Comprom茅tete
aqu铆 .
Comience la migraci贸n
Con este comando, pgrepup prepara ambos servidores para iniciar la replicaci贸n, crea un usuario, configura pglogical y transfiere el esquema de la base de datos.

脡l dijo: "隆Vamos!" y agit贸 su mano:

La replicaci贸n se est谩 ejecutando. La situaci贸n actual se puede ver usando el
pgrepup status
:

Aqu铆 vemos que dos bases de datos ya se han movido y la replicaci贸n est谩 en progreso, y una todav铆a est谩 en proceso de moverse. Ahora solo queda tomar caf茅 y esperar hasta que se bombee todo el volumen de la base de datos original.
En el camino, puede mirar m谩s profundamente en la fachada de pgrepup y ver qu茅 sucede debajo del cap贸. Para las mentes inquisitivas, aqu铆 hay una lista de consultas como punto de partida:
SELECT * FROM pg_replication_origin_status ORDER BY remote_lsn DESC; SELECT *,pg_xlog_location_diff(s.sent_location,s.replay_location) byte_lag FROM pg_stat_replication s; SELECT query FROM pg_stat_activity WHERE application_name='subscription_copy'
Teniendo mucho caf茅 (en el servidor de prueba al escribir este art铆culo, la migraci贸n de ~ 700Gb de datos dur贸 alrededor de un d铆a), finalmente vemos la siguiente imagen:

Y eso significa que es hora de preparar un nuevo Esclavo.
Instalar PostgreSQL 11 en Slave
Aqu铆 todo es simple y de acuerdo con el libro de texto, sin matices.
Copie la configuraci贸n de acceso (
pg_hba.conf ) y la configuraci贸n del servidor (
postgresql.conf ) de 9.6 a 11. En la configuraci贸n de la versi贸n
postgresql.conf 11, cambie el puerto a 15432 (puerto = 15432)
# Master SELECT *,pg_wal_lsn_diff(s.sent_lsn,s.replay_lsn) AS byte_lag FROM pg_stat_replication s; # Slave SELECT now()-pg_last_xact_replay_timestamp();
Subtotales
Despu茅s de todos estos procedimientos, obtenemos este complicado esquema de replicaci贸n:

Aqu铆, como verificaci贸n final (y, al final, es simplemente hermosa), puede hacer alguna ACTUALIZACI脫N en la base de datos maestra 9.6 y ver c贸mo se replica en los otros tres servidores.

Cambiar la aplicaci贸n a la nueva versi贸n de PostgreSQL
Hasta ahora, nuestra aplicaci贸n no ha sospechado nada sobre la nueva versi贸n de PostgreSQL, es hora de solucionarlo. Las opciones aqu铆 dependen fundamentalmente de solo dos cosas:
驴Superar谩 los nuevos servicios en los mismos puertos en los que trabajaban los antiguos,
y si su aplicaci贸n requiere un reinicio al reiniciar el servidor de bases de datos.
Por diversi贸n, responderemos ambas preguntas "s铆" y procederemos.
Paramos la aplicaci贸n.
# , , : SELECT * FROM pg_stat_activity;


Devolvemos el puerto est谩ndar en la configuraci贸n
postgresql.conf de la nueva versi贸n a Master and Slave.
En el nuevo Slave, tambi茅n cambiamos el puerto al est谩ndar en
recovery.conf .
En el camino, hay una sugerencia de pecado para cambiar a煤n m谩s el puerto en la versi贸n antigua inactiva:
Exponemos el puerto no est谩ndar en
postgresql.conf de la versi贸n anterior a Master y Slave.
En el viejo Slave, tambi茅n cambiamos el puerto a uno no est谩ndar en
recovery.conf .
Revisa los registros.
Verifique el estado de replicaci贸n en el maestro.
SELECT *,pg_wal_lsn_diff(s.sent_lsn,s.replay_lsn) AS byte_lag FROM pg_stat_replication s;
Lanzamos la aplicaci贸n. Estamos felices por media hora.
Y finalmente, literatura 煤til sobre el tema:Buena suerte