«Pro, mais pas cluster» ou comment nous avons remplacé notre SGBD

«Pro, mais pas cluster» ou comment nous avons remplacé notre SGBD
(c) Yandex.Images

Tous les personnages sont fictifs, les marques sont la propriété de leurs propriétaires, toute coïncidence est fortuite et en gros, c'est mon « jugement subjectif, veuillez ne pas frapper à la porte...».

Nous avons une vaste expérience de la traduction de systèmes d'information avec une logique dans la base de données d'un SGBD à un autre. Dans le cadre de l'arrêté gouvernemental n°1236 du 16.11.2016, il s'agit souvent d'une migration d'Oracle vers Postgresql. Comment organiser le processus de manière maximisée efficace et sans douleur — nous pouvons expliquer cela séparément, aujourd'hui nous parlerons des particularités de l'utilisation de clusters et des problèmes que l'on peut rencontrer lors de la construction de systèmes distribués à forte charge avec une logique complexe dans les procédures et les fonctions.

Spoiler – en effet, RAC et pg multimaster sont des solutions très différentes.

Supposons que vous ayez déjà migré toute la logique de plsql vers pgsql. Vos tests de régression sont tout à fait corrects, maintenant vous pensez bien sûr à l'extension, car vos tests de charge ne sont pas très satisfaisants, surtout sur le matériel qui a été alloué au projet initialement, pour cet autre SGBD. Supposons que vous ayez trouvé une solution d'un fournisseur national «Postgres Professional» avec une option appelée «multimaster», qui n'est disponible que dans la version «maximale» de «Postgres Pro Enterprise» et dont la description semble très proche de ce dont vous avez besoin, et lors d'une première étude superficielle, vous pourriez penser: «Oh! C'est parfait à la place de RAC! Et en plus avec un support technique dans le pays!».

Mais ne vous précipitez pas à vous réjouir, et nous allons décrire pourquoi ces nuances sont à connaître, car il est difficile de les prévoir, même après avoir bien lu la documentation sur le produit. Évaluez si vous serez prêt à mettre à jour souvent les versions du SGBD directement sur le site de production, car certains défauts ne sont pas compatibles avec l'exploitation industrielle et il est difficile de les détecter lors des tests.
Commencez par une lecture attentive de la section «multimaster» — «limitations» sur le site du fabricant.

La première chose à laquelle vous pourriez être confronté, ce sont les particularités du fonctionnement des transactions en mode «à deux phases», et parfois, à part réécrire toute la logique de votre procédure, rien d'autre ne peut corriger cela. Voici un exemple simple:

créer une table test1 (id entier, id1 entier);
inserer dans test1 des valeurs (1, 1),(1, 2);
 
ALTER TABLE test1 ADD CONSTRAINT test1_uk UNIQUE (id,id1) DEFERRABLE INITIALLY DEFERRED;
 
mettre à jour test1
           définir id1 =
               cas id1
                 quand 1
                 alors 2
                 sinon id1 - signe(2 - 1)
               fin
         où id1 entre 1 et 2;

Une erreur se produit :

ERREUR :  [MTM] La transaction MTM-1-2435-10-605783555137701 (10654) est abonnée sur le nœud 3. Vérifiez son journal pour plus de détails sur l'erreur.

Il est possible de se battre longtemps avec le deadlock dans les versions 10.5, 10.6 et la seule solution connue qui tue toute la notion de cluster consiste à retirer des tables "problématiques" du cluster, c'est-à-dire à faire make_table_local, mais cela vous permet au moins de travailler et de ne pas bloquer le tout à cause de l'attente de la validation des transactions. Ou bien mettez à jour vers la version 11.2, qui devrait aider, peut-être que non, n'oubliez pas de vérifier.

Dans certaines versions, vous pourriez rencontrer un verrouillage encore plus mystérieux :

username= mtm et backend_type = travailleur d'arrière-plan

Dans cette situation, seule une mise à jour de la version du SGBD vers 11.2 et supérieure vous aidera, ou peut-être que cela ne fonctionnera pas.

Certaines opérations sur les index peuvent entraîner des erreurs, où il est clairement indiqué que le problème concerne la réplication bidirectionnelle, dans les journaux MTM vous verrez directement BDR. Ne dites pas que c'est 2ndQuadrant ? Non… nous avons acheté multimaster, c'est juste une coïncidence, c'est le nom de la technologie.

[MTM] bdr ne prend pas en charge les re-vérifications d'index
[MTM] 12124 : Démarrer la transaction à distance pour l'annuler 4083
[MTM] 12124 : envoyer la notification D'ABORT pour la transaction (5467) xid local=4083 au coordinateur 3
[MTM] Recevoir le message logique ABORT_PREPARED pour la transaction MTM-3-25030-83-605694076627780 du nœud 3
[MTM] Annuler la transaction préparée MTM-3-25030-83-605694076627780 avec un statut InProgress du nœud 3 originId=3
[MTM] MtmLogAbortLogicalMessage node=3 transaction=MTM-3-25030-83-605694076627780 lsn=9fff448 

Si vous utilisez des tables temporaires, malgré les assurances : « L'extension multimaster effectue la réplication des données de manière entièrement automatique. Vous pouvez effectuer simultanément des transactions d'écriture et travailler avec des tables temporaires sur n'importe quel nœud du cluster ».

Alors en fait, vous obtiendrez que la réplication ne fonctionne pas sur toutes les tables utilisées dans la procédure, si le code contient la création d'une table temporaire, et même l'utilisation de multimaster.remote_functions ne vous aidera pas, vous devrez mettre à jour ou réécrire votre logique dans la procédure. Si vous devez utiliser simultanément deux extensions multimaster et pg_pathman dans le cadre de « Postgres Pro Enterprise » v 10.5, vérifiez que dans cet exemple simple :

CRÉER UNE TABLE measurement (
    city_id         int non nul,
    logdate         date non nul,
    peaktemp        int,
    unitsales       int
) PARTITIONNER PAR PLAGE (logdate);

CRÉER UNE TABLE measurement_y2019m06 PARTITION DE measurement POUR VALEURS DE ('2019-06-01') À ('2019-07-01');
insérer dans measurement valeurs (1, to_date('27.06.2019', 'dd.mm.yyyy'), 1, 1);
insérer dans measurement valeurs (2, to_date('28.06.2019', 'dd.mm.yyyy'), 1, 1);
insérer dans measurement valeurs (3, to_date('29.06.2019', 'dd.mm.yyyy'), 1, 1);
insérer dans measurement valeurs (4, to_date('30.06.2019', 'dd.mm.yyyy'), 1, 1);

Dans les journaux sur les nœuds du SGBD, des erreurs commencent à apparaître :

…
 PATHMAN_CONFIG ne contient pas la relation 23245
> find_in_dynamic_libpath : essaie "\/opt\/…\/ent-10\/lib\/pg_pathman"
> find_in_dynamic_libpath : essaie "\/opt\/…\/ent-10\/lib\/pg_pathman.so"
> DÉBOGGAGE :  find_in_dynamic_libpath : essaie "\/opt\/…\/ent-10\/lib\/pg_pathman"
> find_in_dynamic_libpath : essaie "\/opt\/…\/ent-10\/lib\/pg_pathman.so"
> PrepareTransaction(1) nom : sans nom ; blockState : PREPARE ; état : INPROGR, xid\/subid\/cid : 6919\/1\/40
> StartTransaction(1) nom : sans nom ; blockState : DEFAULT ; état : INPROGR, xid\/subid\/cid : 0\/1\/0
> bascule vers la chronologie 1 valable jusqu'à 0\/0
…
La transaction MTM-1-13604-7-612438856339841 (6919) est annulée sur le nœud 2. Vérifiez son journal pour voir les détails de l'erreur.
...
[MTM] 28295 : ABORTER la transaction distante 7017
…
[MTM] 28295 : envoyer une notification ABORTER pour la transaction (6919) xid local=7017 au coordinateur 1

Vous pourrez connaître l'origine de ces erreurs en contactant le support technique, ce n'est pas pour rien que vous l'avez acheté.

Que faire ? Correct ! Mettre à jour vers «Postgres Pro Enterprise» vers v 11.2

Il est également important de savoir que la séquence, étant un objet d'une base de données répliquée, n'a pas de valeur globale dans tout le cluster, chaque séquence est locale à chaque nœud et si vous avez des champs avec des contraintes d'unicité et utilisez la séquence, vous pouvez seulement effectuer un incrément équivalent au numéro du nœud dans le cluster, car autant de nœuds dans le cluster, autant plus vite votre séquence augmentera, et un int se terminera plus vite que vous ne l'aviez prévu. Pour simplifier le travail avec les séquences dans le produit, vous trouverez même la fonction alter_sequences, qui fera les incréments nécessaires pour chaque séquence sur tous les nœuds, mais soyez prêt, car la fonction ne fonctionnera pas dans toutes les versions. Bien sûr, vous pouvez l'écrire vous-même, en vous basant sur le code de github ou en le modifiant directement dans le SGBD. Par ailleurs, les champs de type serialbigserial fonctionneront de manière plus correcte, mais pour les utiliser, vous devrez probablement réécrire le code de vos procédures et fonctions. Peut-être que la fonction monotonic_sequences sera utile à certains.

Jusqu'à la version 11.2 de «Postgres Pro Enterprise», la réplication ne fonctionnera qu'en présence de clés primaires uniques, tenez-en compte lors du développement.

Il convient de mentionner séparément les particularités de fonctionnement de npgsql dans une solution de cluster, ces problèmes ne se posent pas sur un nœud unique, mais sont bien présents dans un multimaster.
Dans certaines versions, vous pouvez rencontrer une erreur :

Détails de l'exception : Npgsql.PostgresException : 25001 : commande SET TRANSACTION ISOLATION LEVEL 
Description : Une exception non gérée est survenue lors de l'exécution de la demande web actuelle. Veuillez consulter la trace de la pile pour plus d'informations sur l'erreur et sur son origine dans le code. 

Que peut-on faire ? Il suffit de ne pas utiliser certaines versions. Il est nécessaire de les connaître, car l'erreur n'apparaît pas dans une seule version, et même après sa première correction, vous pouvez encore y être confronté ultérieurement. Il est donc important d'être prêt, et de préférer couvrir tous les défauts identifiés de la SGBD que le fabricant corrige avec des tests de régression distincts. Autrement dit, il faut se fier mais vérifier.

Si l'application utilise npgsql et passe d'un nœud à l'autre en pensant qu'ils sont tous identiques, cela peut entraîner une erreur :

EXCEPTION : Npgsql.PostgresException (0x80004005) : XX000 : échec de la recherche dans le cache pour le type ...

Cette erreur se produira parce que la liaison est exécutée

(NpgsqlConnection.GlobalTypeMapper.MapComposite<SomeType>("some_composite_type");) 

des types composites lors du démarrage de l'application pour toutes les connexions. En conséquence, vous obtenez un identifiant d'un certain nœud, et lorsqu'une requête est faite sur un autre nœud, il ne correspond pas, entraînant ainsi une erreur. Ainsi, travailler de manière transparente avec des types composites dans un cluster pour certaines applications sera impossible sans réécritures supplémentaires du côté de l'application (si vous y parvenez).

Comme nous le savons tous, l'évaluation globale de l'état du cluster est très importante pour le diagnostic et les mesures opérationnelles. Dans le produit, vous pourrez trouver certaines fonctions qui devraient vous faciliter la vie, mais parfois elles peuvent donner des résultats totalement différents de ce que vous et même le fabricant attendez.

Par exemple :

select mtm.collect_cluster_info();
sur chaque nœud renvoie le même résultat :
(1,En ligne,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 ligne,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 ligne,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:09")

Mais pourquoi dans le champ LiveNodes est inscrit le nombre 2 partout, alors que selon la description du fonctionnement du multimaster, cela devrait correspondre à AllNodes=3 ? Réponse : il faut mettre à jour la version de la SGBD.

Et soyez prêt à collecter des journaux sur tous les nœuds, car vous verrez généralement « l'erreur se trouve dans le journal d'un autre nœud ». L'assistance technique acceptera tous les défauts que vous aurez identifiés et vous informera de la disponibilité d'une nouvelle version à installer, parfois nécessitant un arrêt du service, parfois pendant longtemps (cela dépend du volume de votre SGBD). Il ne faut pas s'attendre à ce que les problèmes d'exploitation dérangent beaucoup le fournisseur, et que la mise à jour due à des défauts identifiés se fasse avec la participation de représentants du fournisseur. En fait, il n'est même pas nécessaire d'impliquer des représentants du fournisseur, car au final vous pourriez vous retrouver avec un cluster en production démonté sans sauvegarde.

En fait, dans la licence du produit commercial, le fabricant avertit honnêtement : « Ce logiciel est fourni sur la base du principe de la 'situation actuelle' et la société à responsabilité limitée 'Postgres Professionnel' n'est pas tenue de fournir un suivi, un support, des mises à jour, des extensions ou des modifications. »

Si vous n'avez pas encore deviné de quel produit il s'agit, toute cette expérience a été obtenue suite à une exploitation d'un an de la base Postgres Pro Enterprise. Vous pouvez tirer vos propres conclusions, c'est si brut que des champignons poussent.

Mais cela serait déjà la moitié du mal, si les problèmes qui surviennent étaient résolus rapidement et à temps.

Mais cela ne se produit justement pas. Apparemment, le fabricant n'a pas assez de ressources pour résoudre rapidement les bogues identifiés.

Seuls les utilisateurs enregistrés peuvent participer au sondage. Connectez-vous, s'il vous plaît.

Avez-vous de l'expérience dans la transition d'un SGBD étranger/propriétaire vers un SGBD libre/national ?

  • 21,3%Oui, positif10

  • 10,6%Oui, négatif5

  • 21,3%Non, pas changé de SGBD10

  • 4,3%SGBD changé, mais rien n'a changé2

  • 42,6%Voir les résultats20

47 utilisateurs ont voté. 12 utilisateurs se sont abstenus.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster