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

Actualización de su base de datos a la versión 10 de PostgreSQL:lo que debe saber

A medida que aparecen más y más publicaciones sobre PostgreSQL 11 en la web, se sentirá más desactualizado al usar Postgres 9. Aunque el lanzamiento de la versión de PostgreSQL 10 solo sucedió hace unos meses, la gente ya está hablando de la próxima versión. Las cosas se están moviendo, así que no querrás quedarte atrás. En este blog, discutiremos lo que necesita saber para actualizar a la última versión, Postgres 10.

Opciones de actualización

Lo primero que debe tener en cuenta antes de comenzar es que hay varias formas de realizar la actualización:

  1. Pg_dumpall tradicional(pg_dump) / pg_restore(psql)
  2. Pg_upgrade tradicional
  3. Replicación basada en activadores (Slony, autoescrito)
  4. Uso de la replicación pglogical

¿Por qué hay tanta variedad? Porque cada uno tiene una historia diferente, requiere diferentes esfuerzos para establecerse y ofrece diferentes servicios. Veamos más de cerca cada uno de ellos.

Volcado/Restauración tradicional

pg_dump t > /tmp/f
psql -p 5433 -f /tmp/f

El volcado/restauración tradicional requiere más tiempo para completarse y, sin embargo, a menudo es una opción popular para aquellos que pueden permitirse el tiempo de inactividad. En primer lugar, es tan fácil como realizar una copia de seguridad lógica y restaurarla a una nueva versión superior de la base de datos. Se podría decir que no es una actualización, en realidad, ya que "importa" sus datos a una "nueva estructura". Como resultado, terminará con dos configuraciones:una antigua (versión inferior) y la recién actualizada. Si el proceso de restauración finaliza sin errores, prácticamente habrá llegado. De lo contrario, debe modificar el clúster antiguo existente para eliminar cualquier error y comenzar el proceso nuevamente.

Si usa psql para la importación, es posible que también deba crear algunos scripts de precarga para ejecutarlos en la nueva configuración antes de la migración. Por ejemplo, le gustaría pg_dumpall -g para obtener una lista de los roles necesarios para prepararse en la nueva configuración, o al contrario, ejecute pg_dump -x para omitir los permisos del anterior. Este proceso es bastante simple en bases de datos pequeñas, la complejidad crece con el tamaño y la complejidad de la estructura de su base de datos y depende de las funciones que haya configurado. Básicamente, para que este método tenga éxito, debe seguir intentando y solucionando hasta que la actualización sea exitosa.

Las ventajas de usar este método incluyen...

  • Si bien puede pasar mucho tiempo con una sola copia de seguridad, la carga en el servidor anterior es tan pequeña como hacer una copia de seguridad.
  • Este método es principalmente una secuencia de copia de seguridad y restauración (potencialmente con algunos hechizos, canciones y percusión)
  • Usar este método es la forma más antigua de actualizar y ha sido verificado por MUCHAS personas

Cuando finalmente complete la actualización, debe apagar el servidor anterior o aceptar la pérdida de algunos datos (o, alternativamente, reproducir el DML que sucedió en el servidor anterior mientras restaura una copia de seguridad en el nuevo servidor). Y el tiempo dedicado a hacerlo es relativo al tamaño de su base de datos.

Por supuesto, puede comenzar a "usar" una nueva base de datos antes de que finalice la restauración (especialmente antes de que se construyan todos los índices; a menudo, la mayor parte del tiempo es para los índices). Sin embargo, dicho tiempo de inactividad suele ser inaceptable.

Actualización pg_tradicional

MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/initdb -D tl0 >/tmp/suppressing_to_save_screen_space_read_it

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/pg_upgrade -b /usr/local/Cellar/postgresql/9.5.3/bin -B /usr/local/Cellar/postgresql/10.2/bin -d t -D tl0 | tail
Creating script to delete old cluster                        ok

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    ./analyze_new_cluster.sh

Running this script will delete the old cluster’s data files:
    ./delete_old_cluster.sh

El pg_upgrade tradicional se creó para acortar el tiempo que lleva actualizar a una versión principal. Dependiendo de la cantidad de relaciones que tenga, puede ser tan rápido como minutos (segundos en casos ridículos, como una base de datos de tabla y horas en los "casos opuestos"), especialmente con el argumento --link.

La secuencia de preparación difiere ligeramente del primer método de actualización. Para simular la actualización y, por lo tanto, verificar si es posible, debe crear una replicación de transmisión o recuperar un servidor en espera de WAL. ¿Por qué es ésto tan complicado? Desea asegurarse de probar la actualización en una base de datos tan cercana al estado como la que tenía originalmente. La replicación "binaria" o PITR nos ayudará aquí. Después de finalizar la recuperación y recovery_target_action =promover (PITR) o promover el esclavo recién creado (promocionar pg_ctl o colocar un archivo desencadenante) (replicación de transmisión), puede intentar ejecutar pg_upgrade. Verificar pg_upgrade_internal.log le dará una idea de si el proceso fue exitoso o no. Además, tiene el mismo enfoque de probar y corregir que el método anterior. Guarde las acciones realizadas contra la base de datos de prueba en un script, hasta que pg_upgrade con éxito. Además, puede destruir la prueba que ya no necesite base de datos actualizada, ejecute el script guardado para preparar la base de datos original para realizar la actualización.

Las ventajas de usar este método incluyen…

  • Tiempo de inactividad más corto que la copia de seguridad/restauración lógica
  • Un proceso ordenado:pg_upgrade actualiza la base de datos original con los datos y la estructura existentes
  • Se ha usado mucho en el pasado y aún sería la preferencia para la mayoría de los administradores de bases de datos que ejecutan una versión anterior a la 9.4 (que permite usar pglogical)

Las desventajas de usar este método incluyen…

  • Requiere tiempo de inactividad

Replicación basada en activadores

Suponiendo que la versión 10 está en el puerto 5433 y tiene la misma tabla preparada:

db=# create server upgrade_to_10 foreign data wrapper postgres_fdw options (port '5433', dbname 'dbl0');
CREATE SERVER
Time: 9.135 ms
db=# create user mapping for vao SERVER upgrade_to_10 options (user 'vao');
CREATE USER MAPPING
Time: 8.741 ms
db=# create foreign table rl0 (pk int, t text) server upgrade_to_10 options (table_name 'r');
CREATE FOREIGN TABLE
Time: 9.358 ms

Este es un fn() extremadamente simple y un disparador para una replicación lógica muy básica. Este enfoque es tan primitivo que no funcionará con claves foráneas, pero el código es corto:

db=# create or replace function tf() returns trigger as $$
begin
 if TG_0P = 'INSERT' then
   insert into r10 select NEW.*;
 elseif TG_0P = 'UPDATE' then
   delete from rl0 where pk = NEW.pk;
   insert into rl0 select NEW.*;
 elseif TG_0P = 'DELETE' then
   delete from rl0 where pk = OLD.pk;
 end if;
return case when TG_0P in ('INSERT','UPDATE') then NEW else OLD end;
end;
SS language plpgsql;
CREATE FUNCTION
Time: 8.531 ms
db=# create trigger t before insert or update or delete on r for each row execute procedure tf(); CREATE TRIGGER
Time: 8.813 ms

Ejemplo:

db=# insert into r(t) select chr(g) from generate_series(70,75) g;
INSERT 0 6
Time: 12.621 ms
db=# update r set t = 'updated' where pk=2;
UPDATE 1
Time: 10.398 ms
db=# delete from r where pk=1;
DELETE 1
Time: 9.634 ms
db=# select * from r;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 9.026 ms
db=# select * from rl0;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 1.201 ms

Por último, comprobando que replicamos a una base de datos diferente:

db=# select *,current_setting('port') from dblink('upgrade.to.lO','select setting from pg_settings where name=$$port$$') as t(setting_10 text);
 setting_10 | currerrt.setting
------------+------------------
 5433       | 5432
(l row)

Time: 23.633 ms

Yo llamaría a este método el más exótico. Tanto por el hecho de que con la replicación de transmisión y luego con pglogical, el uso de la replicación basada en disparadores se vuelve menos popular. Tiene una mayor carga en el maestro, mayor complejidad durante la configuración y falta de documentación bien estructurada. No hay preparación (como tal) del proceso aquí, ya que solo desea configurar Slony en diferentes versiones principales.

Las ventajas de usar este método incluyen…

  • No es necesario realizar copias de seguridad ni tiempo de inactividad (especialmente si está detrás de algún pgbouncer o haproxy).

Las desventajas de usar este método incluyen…

  • Alta complejidad de configuración
  • Falta de documentación estructurada
  • No muy popular:menos casos de usuarios para estudiar (y compartir)

Del mismo modo, la replicación de disparadores autoescritos es otra forma posible de actualizar. Si bien la idea es la misma (hace girar una nueva base de datos de una versión superior y configura disparadores en una versión inferior para enviarle datos modificados), la configuración escrita por usted mismo será clara para usted. No tendrá ninguna necesidad de soporte y, por lo tanto, potencialmente usará menos recursos cuando lo ejecute. Por supuesto, por la misma razón, probablemente terminará con algunas funciones faltantes o que no funcionen como se esperaba. Si tiene varias tablas para pasar a nuevas versiones, esta opción probablemente le llevará menos tiempo y, si se hace bien, podría consumir menos recursos. Como beneficio adicional, puede combinar algunas transformaciones ETL con la actualización, cambiando a una nueva versión sin tiempo de inactividad.

Descargue el documento técnico hoy Gestión y automatización de PostgreSQL con ClusterControl Obtenga información sobre lo que necesita saber para implementar, monitorear, administrar y escalar PostgreSQLDescargar el documento técnico

Replicación lógica con pglogical

Esta es una nueva forma muy prometedora de actualizar Postgres. La idea es configurar la replicación lógica entre diferentes versiones principales y, literalmente, tener una base de datos de versión paralela, superior (o inferior) que ejecute los mismos datos. Cuando esté listo, simplemente cambie las conexiones con su aplicación de la antigua a la nueva.

Las ventajas de usar este método incluyen…

  • Básicamente, sin tiempo de inactividad
  • Característica extremadamente prometedora, mucho menos esfuerzo que la replicación basada en disparadores

Las desventajas de usar este método incluyen…

  • Sigue siendo muy complejo de configurar (especialmente para versiones anteriores)
  • Falta de documentación estructurada
  • No muy popular:menos casos de usuarios para estudiar (y compartir)

Tanto las migraciones de versiones principales de replicación pglogical como las basadas en disparadores se pueden usar para degradar la versión (hasta un valor razonable, por supuesto, por ejemplo, pglogical está disponible solo desde 9.4 y la replicación de disparadores se vuelve cada vez más difícil de configurar como la versión que desea). para degradar a envejece).

Medidas a tomar antes de la actualización

  • Hacer una copia de seguridad
  • Asegúrese de que haya suficiente espacio en disco
  • Verifique sus extensiones (es importante que los módulos externos también sean compatibles con binarios, aunque pg_upgrade no puede verificar esto)
  • Asegúrese de usar el mismo datacollate y datctype, etc. (verifique pg_database) en la nueva base de datos
  • Verifique (DDL + Drop) vistas, funciones, extensiones, tipos que podrían interrumpir la actualización
  • Utilice --check antes de realmente pg_upgrade

Medidas a tomar después de la actualización

  • Consulte pg_upgrade_server.log (si usó pg_upgrade)
  • Ejecute el análisis en bases de datos actualizadas (opcional, como lo haría autovacuum, pero puede elegir qué relaciones se deben analizar primero si lo hace usted mismo)
  • Precalentar páginas populares (opcional, pero podría mejorar el rendimiento al principio)

Conclusión

Aquí hay algunas notas generales que es bueno saber antes de decidirse a pasar a la versión 10 de PostgreSQL...

  • Se introdujeron pg_sequences, cambiando el comportamiento del anteriormente popular SELECT * FROM nombre_secuencia - ahora solo último_valor | registro_cnt | is_called se devuelven, escondiéndose de sus "propiedades iniciales" (ajuste cualquier código que dependa del cambio de comportamiento)
  • pg_basebackup transmite WAL de forma predeterminada. Después de la actualización, es posible que deba modificar sus scripts (opción -x eliminada)
  • Todas las acciones de pg_ctl están esperando a que se completen. Anteriormente, tenía que agregar -w para evitar intentar conectarse a la base de datos inmediatamente después del inicio de pg_ctl. Por lo tanto, si aún desea utilizar el inicio o la detención "asincrónicos", debe marcarlo explícitamente con -W. Es posible que deba ajustar sus scripts para que se comporten según lo previsto.
  • Se deben revisar todos los scripts para archivar WAL o monitorear/controlar la replicación de transmisión o PITR, para ajustarlos a los nombres de xlog modificados. P.ej. select * from pg_is_xlog_replay_paused() ya no le mostrará el estado de reproducción de los WAL esclavos; en su lugar, debe usar select * from pg_is_wal_replay_paused(). También cp /blah/pg_xlog/* debe cambiarse a /blah/pg_wal/* y así sucesivamente básicamente para todas las apariciones de pg_xlog. La razón detrás de un cambio tan masivo y no compatible con versiones anteriores es abordar el caso en que un novato elimina los registros de escritura anticipada para "limpiar algo de espacio" eliminando registros y pierde la base de datos.
  • Ajuste los scripts usando pg_stat_replication para nuevos nombres (ubicación cambiada a lsn)
  • Ajuste las consultas con establecer funciones de retorno si es necesario
  • Si usó pglogical como extensión antes de la versión 10, es posible que deba ajustar pg_hba.conf cambiando el valor entre "columnas"
  • Ajuste las secuencias de comandos para un nuevo nombre de pg_log, que es log, algo así como find /pg_data/pg_log/postgresql-*  -mmin +$((60*48)) -type f -exec bash /blah/moveto.s3 .sh {}\; trabajaría. Por supuesto, puede crear un enlace simbólico en su lugar, pero sería necesario tomar medidas para encontrar los registros en la ubicación predeterminada. Otro pequeño cambio a los valores predeterminados es log_line_prefix:si su expresión regular dependía de un determinado formato, debe ajustarlo.
  • Si aún usaba contraseñas sin cifrar en sus bases de datos de Postgres, esta versión completa las elimina. Así que es hora de arreglar las cosas para aquellos que confiaron en --unencrypted...
  • El resto de los cambios incompatibles con versiones anteriores son demasiado nuevos para que se les haga referencia en muchos códigos (min_parallel_relation_size) o demasiado antiguos (tsearch2 externo) o son demasiado exóticos (eliminación de la compatibilidad con marcas de tiempo de punto flotante en la compilación), por lo que los saltaremos. Por supuesto, se enumeran en la página de publicación.
  • Como ocurría con 9.5 a 9.6, es posible que deba ajustar sus scripts para consultar pg_stat_activity (una nueva columna y nuevos valores posibles)
  • Si estaba guardando/analizando la salida detallada de vacío, es posible que deba ajustar su código
  • También es posible que desee echar un vistazo a la nueva implementación de partición; es posible que desee refactorizar su "conjunto" existente para cumplir con los nuevos "estándares"
  • verifique la línea de tiempo (se restablecerá para la nueva base de datos si pg_upgrade)

Además de estos pasos que debe conocer para actualizar a 10, hay muchas cosas que hacen que este lanzamiento sea muy esperado. Lea la sección sobre cambios en las notas de la versión o en el blog de depesz.