XA/Distributed transactions

Note: Nécessité de version

Les fonctions relatives à XA ont été introduites en PECL/mysqlnd_ms version 1.6.0-alpha.

Note: Ce que les premiers adaptateurs voulaient

Cette fonctionalité est actuellement en cours de développement. Il peut y avoir des problèmes et/ou des limitations dans la fonctionalité. Ne pas utiliser en environnement de production, malgré le fait que les premiers tests indiquent une qualité satisfaisante.

Merci de contacter l'équipe de développement si vous êtes intéressé par cette fonctionalité. Nous sommes à la recherche de retours utilisateurs pour compléter la fonctionalité.

Voici une liste des restrictions actuelles de la fonctionalité.

  • Cette fonctionalité n'est pour l'instant pas compatible avec le support MySQL Fabric. Ceci devrait s'arranger d'ici peu.

    Les identifiants de transaction XA sont actuellement restreints à des nombres. Cette limitation devrait bientôt disparaître ; ce n'est qu'une simplification induite lors de l'implémentation initiale.

Note: Restrictions du serveur MySQL

Le support XA par le serveur MySQL a quelques limitations. La plus notable est que le binaire d'historisation du serveur peut rater des modifications effectuées par les transactions XA en cas de certaines erreurs. Veuillez vous rapporter au manuel de MySQL pour plus de détails.

Les transactions distribuées/XA peuvent impliquer plusieurs serveurs MySQL. Aussi, elles peuvent paraître comme un outil parfait pour les clusters partagés MySQL, par exemple, les clusters gérés avec MySQL Fabric. PECL/mysqlnd_ms cache la plupart des commandes SQL qui contrôlent les transactions XA, et réalise automatiquement des tâches administratives en cas d'erreur, pour fournir à l'utilisateur une API compréhensive. Les utilisateurs doivent configurer le plugin avec prudence, et faire attention aux restrictions des serveurs avant d'utiliser cette fonctionalité.

Exemple #1 Masque général pour les transactions XA

<?php
$mysqli 
= new mysqli("myapp""username""password""database");

/* On commence ! */
mysqlnd_ms_xa_begin($mysqli/* xa id */);

/* Exécution de plusieurs requêtes sur divers serveurs */
$mysqli->query("UPDATE some_table SET col_a = 1");
...

/* Validaiton ! */
mysqlnd_ms_xa_commit($link1);
?>

Les transactions XA utilisent un protocole de validation en deux phases. Ce protocole est bloquant. Pendant la première phase, les serveurs participants commencent une transaction et le client réalise son travail. Cette phase est suivie par une seconde phase de vote. Pendant le vote, les serveurs font d'abord la promesse ferme qu'ils sont prêts à réaliser le travail y compris s'il survient une erreur innatendue. Si un serveur crash pendant cette phase, il va appeler de nouveau la transaction interrompue après son redémarrage, et va attendre que le client décide si la transaction doit être validée ou annulée.

Si un client qui a initié une transaction globale crash après que l'appel aux serveurs participants demandant leurs promesses de validation ne soit réalisé, alors les serveurs doivent attendre une décision. Les serveurs ne sont pas autorisés à prendre de façon unilatérale une décision sur la transaction.

Un crash du client, une déconnection d'un participant, un crash serveur ou une erreur serveur durant la première phase n'est pas critique. Dans la plupart des cas, le serveur va oublier la transaction XA et réaliser une annulation. De plus, le plugin va tenter de contacter un maximum de participants pour les informer d'annuler immédiatement le travail. Il n'est pas possible de désactiver cette annulation implicite réalisée par PECL/mysqlnd_ms dans le cas d'erreurs survenues pendant la première phase du protocole. Ce comportement a été décidé afin de conserver une implémentation simple.

Une erreur pendant la seconde phase du protocole de validation peut engendrer une situation plus sévère. Dans tous les cas, les serveurs ne vont pas oublier la transactions en cours (mais pas terminées). Le plugin ne va pas tenter de résoudre ce problème immédiatement, mais va attendre le passage en arrière plan du collecteur de données incorrectes pour s'assurer de la progression du protocole de validation. Il est supposé que cette solution prend un temps signification, car il inclue le temps d'attente d'un serveur participant pour redémarrer après un crash. Cette durée passée peut être plus longue qu'un développeur et un utilisateur peuvent prétendre lors d'une tentative de validation d'une transaction globale avec la fonction mysqlnd_ms_xa_commit(). Aussi, la fonction va retourner avec une transation globale non terminée qui va continuer de demander toute l'attention. Faites attention à ce moment précis, tout n'est pas propre, sachant que la transaction globale peut toujours être validée ou annulée plus tard.

Les erreurs pendant la seconde phase peuvent être annulées, gérées par vous même, ou résolues par la logique du collecteur de données incorrectes. Les ignorer n'est pas recommandé, sachant que vous pouvez avoir des transactions globales non terminées sur vos serveurs qui bloquent les ressources indéfiniement. La gestion de ces erreurs nécessite de connaître les participants, vérifier leurs statuts, et leur envoyer les requêtes SQL appropriées. Il n'existe pas d'appel API permettant de retrouver ces informations. Vous devez configurer un stockage de statuts et y enregistrer les actions du plugin pour retrouver l'information.

Veuillez lire la section de démarrage rapide ainsi que les options du fichier de configuration pour un exemple de configuration d'un stockage de statuts. En plus de configurer un stockage de statuts, vous devez configurer quelques tables SQL. Les définitions de ces tables sont fournies dans la description des options de configuration du plugin.

La mise en place et la configuration d'un stockage de statut est également un prérequis à l'utilisation du collecteur de données incorrectes interne pour les transactions XA qui échoue pendant la seconde phase de la validation. L'enregistrement des informations sur les transactions XA entrantes est une tâche supplémentaire inévitable. Cette tâche consiste à mettre à jour le stockage de statuts après chaque opération qui modifie le statut de la transaction globale (démarrage, validation, annulation, erreurs et arrêt), après chaque ajout de participants (hôte, optionnellement, nom d'utilisateur et mot de passe de connexion) ainsi que toutes modifications de statuts des participants. Notez que, suivant la configuration, et votre politique de sécurité, ces enregistrements peuvent être très sensibles. Il est recommandé de restreindre l'accès au stockage de statuts. A moins que le stockage de statuts devienne surchargé, l'enregistrement des informations de statut contribue à la charge globale mais son impact reste très limité.

Il est possible que les efforts que vous prendrez pour implémenter vos propres routines pour gérer les transactions XA en échec pendant la seconde phase de validation excèdent les bénéfices de l'utilisation de la fonctionalité XA de PECL/mysqlnd_ms. Aussi, le manuel n'abordera que l'utilisation du collecteur de données incorrectes interne.

Le collecteur de données incorrectes peut être lancé manuellement et automatiquement en arrière plan. Vous pouvez vouloir utiliser la fonction mysqlnd_ms_xa_gc() immédiatement après un échec de validation pour tenter de résoudre le souci, mais réouvrir les transactions globales aussi tôt que possible. Vous pouvez aussi décider de désactiver le collecteur de données incorrectes automatique d'arrière plan, implémenter vos propres règles d'appel au collecteur de données incorrectes interne, et l'appeler lorsque vous le souhaitez.

Par défaut, le plugin va démarrer le collecteur de données incorrectes en suivant une probabilité définie par la méthode RSHUTDOWN interne à l'extension. Le requête d'arrêt est appelé après la fin de votre script. Le moment du démarrage du collecteur de données incorrectes est déterminé en calculant une valeur aléatoire comprise dans l'intervalle 1...1000 et en la comparant avec l'option de configuration probability (défaut : 5). Si l'option de configuration est supérieure ou égale à la valeur aléatoire, le collecteur de données incorrectes sera lancé.

Une fois démarré, le collecteur de données incorrectes agira jusqu'à max_transactions_per_run (défaut : 100) enregistrements de transactions globales. Les enregistrements incluent les transactions terminées avec succès, mais aussi, les transactions XA non terminées. Les enregistrements pour les transactions terminées avec succès sont supprimés, et on tente de résoudre les transactions non terminées. Il n'y a aucune statistique permettant de trouver la balance juste entre la conservation de l'exécution courte du collecteur de données incorrectes en limitant le nombre de transactions considérées par exécution, et le fait d'éviter l'échec du collecteur de données incorrectes faisant qu'un grand nombre d'enregistrements ne soit réalisé.

Pour chaque transaction XA en échec, le collecteur de données incorrectes va tenter max_retries (défaut : 5) fois de la terminer. Après cela, PECL/mysqlnd_ms va rendre la main. Il y a deux raisons à cela. Soit un serveur participant a crashé, et est devenu inaccessible pendant les max_retries invocations du collecteur de données incorrectes, ou bien, il y a un cas où le collecteur de données incorrectes internes ne peut pas faire face. Le dernier cas peut être considéré comme un bogue. Cependant, vous pouvez forcer manuellement plusieurs exécutions du collecteur de données incorrectes en appelant la fonction mysqlnd_ms_xa_gc() avec le jeu de paramètres approprié. Si l'exécution de ces fonctions échoue dans la résolution de la situation, alors le problème doit être réglé par un opérateur.

La fonction mysqlnd_ms_get_stats() fournit quelques statistiques sur le nombre de transactions XA qui ont été démarrées, validées, échouées ou annulées.