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

Progreso en la actualización en línea

En los últimos meses he estado trabajando en la actualización en línea de bases de datos muy grandes como parte del proyecto AXLE y me gustaría compartir mis pensamientos sobre el tema y el progreso que hemos logrado recientemente.

Antes de unirme a 2ndQuadrant, solía trabajar en Skype, donde la empresa no permitía una ventana de mantenimiento para nuestras bases de datos. Esto significaba que no se permitía tiempo de inactividad para implementaciones, actualizaciones, etc. Ese tipo de regla te hace cambiar la forma en que haces las cosas. La mayoría de los cambios son pequeños, no realiza bloqueos pesados, tiene réplicas para permitir una conmutación por error rápida. Pero si bien puede hacer que sus lanzamientos sean pequeños y sin bloqueos, ¿qué sucede cuando necesita realizar una actualización de versión principal de la base de datos de PostgreSQL?

Es posible que se encuentre en una situación diferente, ya que la mayoría de las empresas tienen una ventana de actualización y, por lo tanto, es posible que tenga algún tiempo de inactividad durante la actualización. Sin embargo, esto trae dos problemas. Por un lado, a ninguna empresa le gustan los tiempos de inactividad, incluso si están permitidos. Y lo que es más importante, una vez que su base de datos crece más allá de los gigabytes en tamaño al rango de terabytes o cientos de terabytes, el tiempo de inactividad puede llevar días o incluso semanas y nadie puede darse el lujo de detener sus operaciones por tanto tiempo. El resultado es que muchas empresas a menudo se saltan actualizaciones importantes, lo que hace que la siguiente sea aún más dolorosa. Y a los desarrolladores les faltan nuevas características, mejoras de rendimiento. Ellos (las empresas) a veces incluso se arriesgan a ejecutar una versión de PostgreSQL que ya no es compatible y tiene corrupción de datos conocida o problemas de seguridad. En los siguientes párrafos, hablaré un poco sobre mi trabajo para hacer que las actualizaciones consuman menos tiempo y, como resultado, sean menos dolorosas y, con suerte, más frecuentes.

Permítanme comenzar con un poco de historia primero. Antes de PostgreSQL 9.0, la única forma de realizar una actualización de versión principal era ejecutar pg_dump y restaurar el volcado en una instancia que ejecutaba una versión más nueva de PostgreSQL. Este método requería que la estructura y todos los datos se leyeran de la base de datos y se escribieran en un archivo. Luego, lea del archivo e inserte en una nueva base de datos, los índices deben reconstruirse, etc.

Como puede imaginar, este proceso puede llevar bastante tiempo. Se realizaron mejoras en el rendimiento en 8.4 para pg_restore con la opción -j agregada donde podía especificar cuántos trabajos paralelos se ejecutarían. Esto hace posible restaurar varias tablas (índices, etc.) en paralelo, lo que hace que el proceso de restauración sea más rápido para volcados de formato personalizado. La versión 9.3 agregó una opción similar a pg_dump, mejorando aún más el rendimiento. Pero dada la rapidez con la que crecen los volúmenes de datos, la paralelización en sí misma no es suficiente para lograr una ganancia significativa en el tiempo requerido para la actualización.

Luego, en PostgreSQL 9.0, llegó una utilidad llamada pg_upgrade. Pg_upgrade vuelca solo las estructuras y las restaura en el nuevo clúster. Pero copia los archivos de datos tal como están en el disco, lo que es mucho más rápido que volcarlos en un formato lógico y luego volver a insertarlos. Esto es lo suficientemente bueno para bases de datos pequeñas porque significa un tiempo de inactividad en el rango de minutos u horas, un tiempo aceptable para muchos escenarios. También existe el modo de enlace que simplemente crea enlaces duros (puntos de unión en Windows) que hace que este proceso sea aún más rápido. Pero desde mi punto de vista personal, es demasiado peligroso ejecutar dicha configuración en un servidor maestro de producción. Explicaré brevemente por qué. Si algo sale mal, una vez que inicia su nuevo servidor que se actualizó usando el modo de enlace, de repente se encuentra sin base de datos de producción y tiene que realizar una conmutación por error, o peor aún, tiene que restaurar desde una copia de seguridad. ¡Eso significa que no solo no pudo actualizar, sino que solo provocó un tiempo de inactividad adicional! Buena suerte para obtener la aprobación la próxima vez.

Ahora, muchas personas que no pueden permitirse tiempos de inactividad prolongados para las actualizaciones utilizan las soluciones de replicación basadas en activadores como Slony o Londiste para realizar la actualización. Esta es una buena solución porque puede replicar sus datos mientras el servidor original se está ejecutando y luego cambiar con un tiempo de inactividad mínimo. Sin embargo, en la práctica existen varios problemas. Una de ellas es que las soluciones basadas en disparadores a menudo son difíciles de configurar, especialmente si lo hace solo una vez cada dos años y solo para realizar la actualización. También es fácil pasar por alto una tabla o agregar tablas en el orden incorrecto y, por lo tanto, no obtener la copia completa. He sido testigo de esto en la práctica y las personas que realizaban la actualización trabajaban diariamente con la replicación basada en activadores . Otro problema es que las soluciones basadas en activadores agregan una carga considerable a la base de datos de origen, lo que a veces hace que la actualización sea imposible debido a que el servidor de la base de datos se sobrecarga una vez que se activa la replicación. Y por último, pero a menudo no menos importante, la replicación basada en disparadores puede tardar mucho tiempo en mover los datos al nuevo servidor. En la última ocasión en que participé en un proyecto de actualización, la solución basada en activadores tardó alrededor de un mes en copiar la base de datos y ponerse al día con los cambios. Sí, un mes.

Con PostgreSQL 9.4 llega la función de decodificación lógica que ofrece un nuevo comienzo para diseñar una nueva y mejor solución de problemas de actualización en línea. Lo que hicimos, como parte del proyecto AXLE, fue crear una herramienta que combina la decodificación lógica con las técnicas descritas anteriormente. La solución resuelve la mayoría de los problemas de los enfoques anteriores. La extensión PostgreSQL de replicación unidireccional (UDR para abreviar) realiza la replicación lógica mediante la decodificación lógica del registro de escritura anticipada (WAL). Gracias a esto, el impacto en el servidor maestro está casi a la par con la replicación de transmisión física, por lo que la carga adicional causada por la actualización en curso es mínima en el sistema en ejecución. También proporciona herramientas para inicializar nuevos nodos, tanto mediante copia de seguridad física como lógica. Incluso puede convertir el modo de espera físico existente en modo de espera UDR. Y debido a que es un sistema de replicación lógica, es posible diseñarlo de manera que admita la replicación entre versiones.

Lo que todo esto significa es que ahora podemos usar UDR en combinación con pg_upgrade para realizar una actualización en línea de la versión principal de PostgreSQL con un tiempo de inactividad mínimo, en una cantidad breve de tiempo absoluto y con un impacto mínimo en el sistema en ejecución.

Un ejemplo de cómo se puede ver esto en la práctica:

  • Hacer pg_basebackup de la instancia existente.
  • Configure la replicación UDR entre la instancia original y la creada por basebackup.
  • Pg_actualizar la nueva instancia.
  • Deje que UDR reproduzca los cambios que ocurrieron mientras tanto.
  • Cambie el tráfico a la nueva instancia.

Para obtener instrucciones más detalladas, consulte la guía de actualización en línea de UDR en la wiki de PostgreSQL. Las fuentes UDR están disponibles en el repositorio 2ndquadrant_bdr en el servidor git de PostgreSQL (bdr-plugin/next branch).

Finalmente, dado que UDR no es solo una herramienta de actualización en línea sino también una solución de replicación, puede usarse para sus necesidades de replicación normales, en lugar de la replicación de transmisión física. Además, ofrece varias ventajas, como la capacidad de crear tablas temporales, replicar desde varias bases de datos OLTP en una base de datos de almacenamiento de datos grandes o replicar solo una parte de la base de datos.

Mi esperanza es que este esfuerzo signifique que las consideraciones de tiempo de inactividad ya no sean un problema cuando se trata de actualizar PostgreSQL 9.4 y superior a una nueva versión principal.

La investigación que condujo a estos resultados ha recibido financiación del Séptimo Programa Marco de la Unión Europea (FP7/2007-2013) bajo el acuerdo de subvención n° 318633.