«Pro, pero no clúster» o cómo hicimos la sustitución de SGBD

«Pro, pero no clúster» o cómo hicimos la sustitución de SGBD
(c) Yandex.Imágenes

Todos los personajes son ficticios, las marcas registradas pertenecen a sus propietarios, cualquier coincidencia es casual y, en general, esta es mi «opinión subjetiva, por favor, no rompan la puerta…».

Tenemos una considerable experiencia en la traducción de sistemas de información con lógica en bases de datos de un SGBD a otro. En el contexto de la resolución del gobierno Nº 1236 del 16.11.2016, a menudo se trata de la migración de Oracle a PostgreSQL. Cómo organizar el proceso de la manera más eficiente y sin dolor — podemos contarlo por separado, hoy hablaremos sobre las peculiaridades del uso de clústeres y con qué problemas se puede encontrar al construir sistemas distribuidos altamente carga con lógica compleja en procedimientos y funciones.

Spoiler: sí, CAP, RAC y pg multimaster son soluciones muy diferentes.

Supongamos que ya has migrado toda la lógica de plsql a pgsql. Y tus pruebas de regresión son bastante aceptables, ahora estás pensando en la escalabilidad, ya que las pruebas de carga no son muy satisfactorias, especialmente en el hardware que se había previsto en el proyecto originalmente para ese otro SGBD. Supongamos que encontraste una solución de un proveedor local llamada «Postgres Professional» con una opción llamada «multimaster», que solo está disponible en la versión «maximal» de «Postgres Pro Enterprise» y, según la descripción, parece ser lo que necesitas, y a primera vista, podría dar la impresión de: «¡Oh! ¡Es perfecto en lugar de RAC! Y además con soporte técnico en nuestro país!».

Pero no te apresures a alegrarte, y a continuación describiremos por qué es importante conocer estos matices, ya que son difíciles de prever, incluso después de leer bien la documentación del producto. Evalúa si estarás dispuesto a actualizar con frecuencia las versiones del SGBD directamente en el entorno de producción, ya que algunos defectos no son compatibles con su explotación industrial y son difíciles de detectar en las pruebas.
Comienza por leer atentamente la sección «multimaster» — «limitaciones» en el sitio del fabricante.

Lo primero con lo que te puedes encontrar son las peculiaridades del funcionamiento de las transacciones en el llamado modo de «dos fases», y a veces, salvo reescribir toda la lógica de tu procedimiento, no hay otra forma de corregirlo. Aquí hay un ejemplo sencillo:

crear tabla test1 (id entero, id1 entero);
inserta en test1 valores (1, 1),(1, 2);
 
ALTER TABLE test1 ADD CONSTRAINT test1_uk UNIQUE (id,id1) DEFERRABLE INITIALLY DEFERRED;
 
actualiza test1
           set id1 =
               case id1
                 when 1
                 then 2
                 else id1 - sign(2 - 1)
               end
         where id1 between 1 and 2;

Se produce un error:

ERROR:  [MTM] La transacción MTM-1-2435-10-605783555137701 (10654) está abortada en el nodo 3. Consulta su registro para ver los detalles del error.

Después se puede luchar durante mucho tiempo con el deadlock en las versiones 10.5, 10.6 y la única salvación conocida que destruye toda la esencia del clúster es eliminar las tablas "problemáticas" del clúster, es decir, hacer make_table_local, pero eso al menos permitirá trabajar, y no dejará "paralizado" todo debido a las esperas atascadas de las confirmaciones de las transacciones. O actualizar a la versión 11.2, que debería ayudar, aunque quizás no, no olvides comprobar.

En algunas versiones, es posible que obtengas un bloqueo aún más enigmático:

username= mtm y backend_type = worker en segundo plano

Y en esta situación, solo te ayudará actualizar la versión de la base de datos a 11.2 o superior, aunque quizás no lo haga.

Algunas operaciones con índices pueden provocar errores, donde se indica claramente que el problema está en la replicación bi-direccional, en los registros de MTM verás directamente BDR. ¿De verdad 2ndQuadrant? No… compramos multimaster, esto es solo una coincidencia, es el nombre de la tecnología.

[MTM] bdr no soporta rechecks de índices
[MTM] 12124: REMOTE iniciar transacción abortada 4083
[MTM] 12124: enviar notificación de ABORT para la transacción (5467) xid local=4083 al coordinador 3
[MTM] Recibir mensaje lógico ABORT_PREPARED para la transacción MTM-3-25030-83-605694076627780 del nodo 3
[MTM] Abortando la transacción preparada MTM-3-25030-83-605694076627780 con estado InProgress del nodo 3 originId=3
[MTM] MtmLogAbortLogicalMessage nodo=3 transacción=MTM-3-25030-83-605694076627780 lsn=9fff448 

Si utilizas tablas temporales, a pesar de las afirmaciones: "La extensión multimaster realiza la replicación de datos de forma completamente automática. Puedes realizar transacciones de escritura simultáneamente y trabajar con tablas temporales en cualquier nodo del clúster."

Entonces, de hecho, descubrirás que la replicación no funciona para todas las tablas utilizadas en el procedimiento, si en el código hay creación de una tabla temporal, e incluso el uso de multimaster.remote_functions no ayudará, tendrás que actualizar o reescribir tu lógica en el procedimiento. Si necesitas usar simultáneamente dos extensiones multimaster y pg_pathman en "Postgres Pro Enterprise" v 10.5, verifica que en este sencillo ejemplo:

CREAR TABLA medición (
    city_id         int no nulo,
    logdate         fecha no nula,
    peaktemp        int,
    unitsales       int
) PARTICIONADO POR RANGO (logdate);

CREAR TABLA medición_y2019m06 PARTICIÓN DE medición PARA VALORES DESDE ('2019-06-01') HASTA ('2019-07-01');
insertar en medición valores (1, to_date('27.06.2019', 'dd.mm.yyyy'), 1, 1);
insertar en medición valores (2, to_date('28.06.2019', 'dd.mm.yyyy'), 1, 1);
insertar en medición valores (3, to_date('29.06.2019', 'dd.mm.yyyy'), 1, 1);
insertar en medición valores (4, to_date('30.06.2019', 'dd.mm.yyyy'), 1, 1);

En los registros de los nodos de la base de datos comienzan a aparecer errores como estos:

…
 PATHMAN_CONFIG no contiene la relación 23245
> find_in_dynamic_libpath: intentando "\/opt\/…\/ent-10\/lib\/pg_pathman"
> find_in_dynamic_libpath: intentando "\/opt\/\/…\/ent-10\/lib\/pg_pathman.so"
> DEPURACIÓN: find_in_dynamic_libpath: intentando "\/opt\/…\/ent-10\/lib\/pg_pathman"
> find_in_dynamic_libpath: intentando "\/opt\/…\/ent-10\/lib\/pg_pathman.so"
> PrepareTransaction(1) nombre: unnamed; blockState: PREPARE; state: INPROGR, xid\/subid\/cid: 6919\/1\/40
> StartTransaction(1) nombre: unnamed; blockState: DEFAULT; state: INPROGR, xid\/subid\/cid: 0\/1\/0
> cambiado a la línea de tiempo 1 válida hasta 0\/0
…
Transacción MTM-1-13604-7-612438856339841 (6919) está abortada en el nodo 2. Verifique su registro para ver los detalles del error.
...
[MTM] 28295: INICIO REMOTO abortar transacción 7017
…
[MTM] 28295: enviar notificación ABORTAR para la transacción (6919) xid local=7017 al coordinador 1

Puede averiguar de qué se trata estos errores en el soporte técnico; no lo compró en vano.

¿Qué hacer? ¡Correcto! Actualizar a "Postgres Pro Enterprise" a v 11.2

Es importante saber que la secuencia, al ser un objeto de una base de datos replicable, no tiene un valor continuo en todo el clúster; cada secuencia es local para cada nodo y si tienes campos con restricciones únicas que utilizan secuencias, solo puedes incrementar el número equivalente al nodo en el clúster, ya que el incremento será más rápido cuántos más nodos haya en el clúster, y el int se agotará más rápido de lo que pensabas. Para facilitar el trabajo con las secuencias, en el producto encontrarás incluso una función alter_sequences, que hará los incrementos necesarios en cada secuencia en todos los nodos, pero ten en cuenta que la función no funcionará en todas las versiones. Por supuesto, puedes escribirla tú mismo, tomando como base el código de GitHub o modificándolo directamente en la base de datos. A su vez, los campos de tipo serial o bigserial funcionarán de manera más correcta, pero para usarlos probablemente tendrás que reescribir el código de tus procedimientos y funciones. Posiblemente a alguien le sea útil la función monotonic_sequences.

Hasta la versión 11.2 de "Postgres Pro Enterprise", la replicación solo funcionará si hay claves primarias únicas; tenlo en cuenta al desarrollar.

Es importante mencionar las características del funcionamiento de npgsql específicamente en la solución de clúster, estos problemas no surgen en un nodo único, pero sí están presentes en un entorno de múltiples maestros.
En algunas versiones, se puede encontrar el error:

Detalles de la excepción: Npgsql.PostgresException: 25001: comando SET TRANSACTION ISOLATION LEVEL 
Descripción: Se produjo una excepción no controlada durante la ejecución de la solicitud web actual. Por favor, revise el seguimiento de la pila para obtener más información sobre el error y su origen en el código. 

¿Qué se puede hacer? Simplemente no use ciertas versiones. Es importante conocerlas, ya que el error no aparece en una sola versión, e incluso después de su primera corrección, puede volver a encontrarse con él más adelante. También hay que estar preparado para esto y es mejor cubrir todos los defectos identificados de la base de datos que el fabricante corrige con pruebas específicas de regresión. Es decir, confía, pero verifica.

Si la aplicación utiliza npgsql y cambia entre nodos pensando que son todos iguales, puede surgir el error:

EXCEPCIÓN: Npgsql.PostgresException (0x80004005): XX000: la búsqueda en caché falló para el tipo ...

Este error ocurrirá porque se está realizando un mapeo

(NpgsqlConnection.GlobalTypeMapper.MapComposite("some_composite_type");) 

de tipos compuestos al iniciar la aplicación para todas las conexiones. Como resultado, se obtiene un identificador de un nodo específico, y al consultar otro nodo, no coincide, lo que provoca un error, por lo que trabajar transparentemente con tipos compuestos en un clúster será imposible para algunas aplicaciones sin reescrituras adicionales en el lado de la aplicación (si logras hacerlo).

Como todos sabemos, la evaluación general del estado del clúster es muy importante para el diagnóstico y la toma de medidas operativas durante su funcionamiento. En el producto, encontrará algunas funciones que deberían facilitarle la vida, pero a veces pueden proporcionar resultados muy diferentes a lo que usted, e incluso el propio fabricante, espera.

Por ejemplo:

select mtm.collect_cluster_info();
en cada nodo devuelve el mismo resultado:
(1,En línea,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:06")
(2,En línea,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:06")
(3,En línea,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:09")

Pero, ¿por qué en el campo LiveNodes está siempre el número 2, aunque según la descripción del funcionamiento del múltiples maestros debería corresponder al número AllNodes=3? Respuesta: debe actualizar la versión de la base de datos.

Y estén listos para recopilar registros de todos los nodos, ya que normalmente verán "el error está en el registro de otro nodo". El soporte técnico aceptará todos los defectos que ustedes identifiquen y comunicará la disponibilidad de la próxima versión, que a veces deberá instalarse deteniendo el servicio, a veces por un tiempo prolongado (depende del volumen de su base de datos). No deben esperar que los problemas de explotación preocupen mucho al proveedor, y que la actualización debido a los defectos identificados se realice con la participación de representantes del proveedor; de hecho, ni siquiera deben involucrar a los representantes del proveedor, ya que al final pueden terminar con un clúster desarmado en producción sin copia de seguridad.

En la licencia del producto comercial, el fabricante advierte honestamente: "Este software se proporciona sobre la base del principio de 'tal como está' y la sociedad de responsabilidad limitada 'Postgres Profesional' no está obligada a proporcionar mantenimiento, soporte, actualizaciones, extensiones o cambios".

Si aún no se han dado cuenta de qué producto se trata, toda esta experiencia se adquirió a lo largo de un año de explotación de la base de datos Postgres Pro Enterprise. Pueden sacar sus propias conclusiones, es tan inmaduro que los hongos están brotando.

Pero eso sería solo una parte del problema si se solucionaran los problemas que surgen de manera oportuna y efectiva.

Pero eso es precisamente lo que no está ocurriendo. Al parecer, el fabricante no tiene suficientes recursos para solucionar rápidamente los errores identificados.

Solo los usuarios registrados pueden participar en la encuesta. Inicie sesión, por favor.

¿Tienen experiencia en la transición de un SGBD extranjero/proprietario a uno libre/nacional?

  • 21,3%Sí, positiva10

  • 10,6%Sí, negativa5

  • 21,3%No, no hemos cambiado el SGBD10

  • 4,3%Sí cambiamos el SGBD, pero no ha cambiado nada2

  • 42,6%Ver resultados20

Votaron 47 usuarios. 12 usuarios se abstuvieron.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster