sql >> Base de Datos >  >> RDS >> PostgreSQL

Actualización a PostgreSQL 11 con replicación lógica

Es hora.

Hace aproximadamente un año, publicamos PostgreSQL 10 con soporte para replicación lógica nativa. Uno de los usos de la replicación lógica es permitir la actualización con poco o ningún tiempo de inactividad entre las versiones principales de PostgreSQL. Hasta ahora, PostgreSQL 10 era la única versión de PostgreSQL con replicación lógica nativa, por lo que no había muchas oportunidades para actualizar de esta manera. (La replicación lógica también se puede usar para mover datos entre instancias en diferentes sistemas operativos o arquitecturas de CPU o con diferentes ajustes de configuración de bajo nivel, como el tamaño del bloque o la configuración regional, si lo desea, con una actualización lateral). Ahora que PostgreSQL 11 está cerca, habrá más razones para hacer uso de esta funcionalidad.

Primero comparemos las tres formas principales de actualizar una instalación de PostgreSQL:

  • pg_dump y restauración
  • pg_actualizar
  • replicación lógica

Podemos comparar estos métodos en términos de robustez, velocidad, tiempo de inactividad requerido y restricciones (y más, pero tenemos que detenernos en alguna parte para este artículo).

pg_dump and restore es posiblemente el método más robusto, ya que es el más probado y ha estado en uso durante décadas. También tiene muy pocas restricciones en términos de lo que puede manejar. Es posible construir bases de datos que no se pueden volcar ni restaurar, en su mayoría involucrando relaciones de dependencia de objetos particulares, pero esas son raras y generalmente implican prácticas desaconsejadas.

El problema con el método de volcado y restauración es, por supuesto, que efectivamente requiere tiempo de inactividad durante todo el tiempo que se ejecutan las operaciones de volcado y restauración. Si bien la base de datos de origen todavía se puede leer y escribir mientras se ejecuta el proceso, se perderán las actualizaciones de la base de datos de origen después del inicio del volcado.

pg_upgrade mejora el proceso pg_dump al mover los archivos de datos directamente sin tener que volcarlos en un formato de texto lógico. Tenga en cuenta que pg_upgrade todavía usa pg_dump internamente para copiar el esquema, pero no los datos. Cuando pg_upgrade era nuevo, se cuestionó su robustez y actualizó algunas bases de datos incorrectamente. Pero pg_upgrade ahora es bastante maduro y está bien probado, por lo que ya no es necesario dudar en usarlo por ese motivo. Mientras se ejecuta pg_upgrade, el sistema de base de datos está inactivo. Pero uno puede elegir cuánto tiempo se ejecuta pg_upgrade. En el modo de copia predeterminado, el tiempo de ejecución total se compone del tiempo para volcar y restaurar el esquema (que suele ser muy rápido, a menos que uno tenga miles de tablas u otros objetos) más el tiempo para copiar los archivos de datos, que depende de el tamaño de la base de datos (y el sistema de E/S, el sistema de archivos, etc.).

En el modo de enlace opcional, los archivos de datos están en cambio vinculados al nuevo directorio de datos, de modo que el tiempo es simplemente el tiempo para realizar una operación breve del kernel por archivo en lugar de copiar cada byte. El inconveniente es que si algo sale mal con la actualización o si necesita volver a la instalación anterior, esta operación habrá destruido su base de datos anterior. (Estoy trabajando en la mejor solución de ambos mundos para PostgreSQL 12 usando reflinks u operaciones de clonación de archivos en sistemas de archivos compatibles).

La replicación lógica es la más nueva del grupo aquí, por lo que probablemente llevará algún tiempo resolver los problemas. Si no tiene tiempo para explorar e investigar, este podría no ser el camino a seguir en este momento. (Por supuesto, la gente ha estado usando otras soluciones de replicación lógica no básicas como Slony, Londiste y pglogical para actualizar PostgreSQL durante muchos años, por lo que hay mucha experiencia con los principios, si no con los detalles).

La ventaja de usar la replicación lógica para actualizar es que la aplicación puede continuar ejecutándose en la instancia anterior mientras se realiza la sincronización de datos. Solo es necesario que haya una pequeña interrupción mientras se cambian las conexiones del cliente. Entonces, si bien una actualización que usa la replicación lógica es probablemente más lenta de principio a fin que usar pg_upgrade en modo de copia (y definitivamente más lenta que usar el modo de vínculo físico), no importa mucho, ya que el tiempo de inactividad real puede ser mucho más corto.

Tenga en cuenta que la replicación lógica actualmente no replica los cambios de esquema. En este procedimiento de actualización propuesto, el esquema aún se copia a través de pg_dump, pero los cambios de esquema posteriores no se transfieren. La actualización con replicación lógica también tiene algunas otras restricciones. Ciertas operaciones no son capturadas por la replicación lógica:objetos grandes, TRUNCATE, cambios de secuencia. Discutiremos las soluciones para estos problemas más adelante.

Si tiene alguna reserva física (y si no, ¿por qué no la tiene?), también hay algunas diferencias a considerar entre los métodos. Con cualquiera de los dos métodos, debe crear nuevas copias de seguridad físicas para la instancia actualizada. Con el volcado y la restauración, así como con la replicación lógica, se pueden implementar antes de que comience la actualización, de modo que el modo de espera estará casi listo una vez que se complete la sincronización inicial de la restauración o la replicación lógica, sujeto a demoras en la replicación.

Con pg_upgrade, los nuevos recursos de reserva deben crearse después de que se complete la actualización del principal. (La documentación de pg_upgrade describe esto con más detalle). Si confía en los recursos de reserva físicos para una alta disponibilidad, los recursos de reserva deben estar en su lugar antes de cambiar a la nueva instancia, por lo que la configuración de los recursos de reserva podría afectar sus cálculos generales de tiempo.

Pero volvamos a la replicación lógica. Así es como se puede realizar la actualización con replicación lógica:

0. La instancia anterior debe estar preparada para la replicación lógica. Esto requiere algunos ajustes de configuración como se describe en http://www.postgresql.org/docs/10/static/logical-replication-config.html (principalmente wal_level = logical . Si resulta que necesita realizar esos cambios, requerirán un reinicio del servidor. Así que revisa esto bien antes de tiempo. Compruebe también que pg_hba.conf en la instancia anterior está configurado para aceptar conexiones de la nueva instancia. (Cambiar eso solo requiere una recarga).

1. Instale la nueva versión de PostgreSQL. Necesita al menos el paquete del servidor y el paquete del cliente que contiene pg_dump. Muchos embalajes ahora permiten instalar múltiples versiones una al lado de la otra. Si está ejecutando máquinas virtuales o instancias en la nube, vale la pena considerar instalar la nueva instancia en un nuevo host.

2. Configure una nueva instancia, es decir, ejecute initdb. La nueva instancia puede tener una configuración diferente a la anterior, por ejemplo, configuración regional, tamaño de segmento WAL o suma de verificación. (¿Por qué no aprovechar esta oportunidad para activar las sumas de verificación de datos?)

3. Antes de iniciar la nueva instancia, es posible que deba cambiar algunos ajustes de configuración. Si la instancia se ejecuta en el mismo host que la instancia anterior, debe configurar un número de puerto diferente. Además, transfiera cualquier cambio personalizado que haya realizado en postgresql.conf en su instancia anterior, como la configuración de memoria, max_connections , etc. Del mismo modo, crea pg_hba.conf ajustes adecuados a su entorno. Por lo general, puede comenzar copiando el pg_hba.conf archivo de la instancia anterior. Si desea utilizar SSL, configúrelo ahora.

4. Inicie la nueva instancia (vacía) y verifique que funcione a su satisfacción. Si configura la nueva instancia en un nuevo host, verifique en este punto que puede realizar una conexión a la base de datos (usando psql) desde el nuevo host a la instancia de la base de datos anterior. Lo necesitaremos en los pasos posteriores.

5. Copie las definiciones del esquema con pg_dumpall. (O puede hacerlo con pg_dump para cada base de datos por separado, pero no olvide los objetos globales como los roles).

pg_dumpall -s >schemadump.sql
psql -d postgres -f schemadump.sql

Cualquier cambio de esquema después de este punto no se migrará. Tendrías que gestionarlos tú mismo. En muchos casos, puede simplemente aplicar el DDL cambiante en ambos hosts, pero ejecutar comandos que cambian la estructura de la tabla durante una actualización probablemente sea un desafío demasiado grande.

6. En cada base de datos de la instancia de origen, cree una publicación que capture todas las tablas:

CREATE PUBLICATION p_upgrade FOR ALL TABLES;

La replicación lógica funciona por separado en cada base de datos, por lo que debe repetirse en cada base de datos. Por otro lado, no es necesario que actualice todas las bases de datos a la vez, por lo que puede actualizar una base de datos a la vez o incluso no actualizar algunas bases de datos.

7. En cada base de datos de la instancia de destino, cree una suscripción que se suscriba a la publicación recién creada. Asegúrese de hacer coincidir correctamente las bases de datos de origen y de destino.

CREATE SUBSCRIPTION s_upgrade CONNECTION 'host=oldhost port=oldport dbname=dbname ...' PUBLICATION p_upgrade;

Establezca los parámetros de conexión según corresponda.

8. Ahora espere hasta que las suscripciones hayan copiado los datos iniciales y se hayan puesto al día con el editor. Puede verificar el estado de sincronización inicial de cada tabla en una suscripción en el catálogo del sistema pg_subscription_rel (busque r =listo en la columna srsubstate ). El estado general de la replicación se puede comprobar en pg_stat_replication en el lado de envío y pg_stat_subscription en el lado receptor.

9. Como se mencionó anteriormente, los cambios de secuencia no se replican. Una posible solución para esto es copiar los valores de secuencia usando pg_dump. Puede obtener un volcado de los valores de secuencia actuales usando algo como esto:

pg_dump -d dbname --data-only -t '*_seq' >seq-data.sql

(Esto supone que todos los nombres de secuencia coinciden con *_seq y ninguna tabla coincide con ese nombre. En casos más complicados, también podría seguir la ruta de crear un volcado completo y extraer los datos de secuencia de la tabla de contenido del volcado).

Dado que las secuencias pueden avanzar a medida que hace esto, tal vez cambie el seq-data.sql archivo para agregar un poco de holgura a los números.

Luego restaure ese archivo a la nueva base de datos usando psql.

10. Showtime:Cambie las aplicaciones a las nuevas instancias. Esto requiere pensar un poco antes de tiempo. En el escenario más simple, detiene sus programas de aplicación, cambia la configuración de conexión, reinicia. Si utiliza un proxy de conexión, puede cambiar la conexión allí. También puede cambiar las aplicaciones cliente una por una, tal vez para probar un poco las cosas o aliviar la carga en el nuevo sistema. Esto funcionará siempre que las aplicaciones sigan apuntando al servidor antiguo y las que apuntan al servidor nuevo no tengan escrituras conflictivas. (En ese caso, estaría ejecutando un sistema multimaestro, al menos por un corto tiempo, y ese es otro orden de complejidad).

11. Cuando se completa la actualización, puede desmantelar la configuración de replicación. En cada base de datos de la nueva instancia, ejecute

DROP SUBSCRIPTION s_upgrade;

Si ya cerró la instancia anterior, esto fallará porque no podrá llegar al servidor remoto para eliminar la ranura de replicación. Consulte la página del comando man DROP SUBSCRIPTION para saber cómo proceder en esta situación.

También puede colocar las publicaciones en la instancia de origen, pero eso no es necesario ya que una publicación no retiene ningún recurso.

12. Finalmente, elimine las instancias antiguas si ya no las necesita.

Algunos comentarios adicionales sobre soluciones para cosas que la replicación lógica no admite. Si está utilizando objetos grandes, puede moverlos usando pg_dump, por supuesto, siempre que no cambien durante el proceso de actualización. Esta es una limitación significativa, por lo que si es un gran usuario de objetos grandes, es posible que este método no sea para usted. Si su aplicación emite TRUNCATE durante el proceso de actualización, esas acciones no se replicarán. Tal vez pueda modificar su aplicación para evitar que haga eso en el momento de la actualización, o puede sustituirlo por ELIMINAR. PostgreSQL 11 admitirá la replicación TRUNCATE, pero eso solo funcionará si tanto la instancia de origen como la de destino son PostgreSQL 11 o posteriores.

Algunos comentarios finales que realmente se aplican a todos los proyectos de actualización:

  • Las aplicaciones y todos los programas cliente de base de datos deben probarse con una nueva versión principal de PostgreSQL antes de ponerlos en producción.
  • Con ese fin, también debe probar el procedimiento de actualización antes de ejecutarlo en el entorno de producción.
  • Escriba las cosas o mejore el guión y automatice tanto como sea posible.
  • Asegúrese de que su configuración de respaldo, sistemas de monitoreo y cualquier herramienta y script de mantenimiento se ajusten adecuadamente durante el procedimiento de actualización. Idealmente, estos deben estar en su lugar y verificados antes de que se realice el cambio.

Con eso en mente, buena suerte y comparte tus experiencias.