Le plugin change la sémantique d'une connexion MySQL pour PHP. Une connexion n'est plus liée à un serveur MySQL unique, mais à un pool de connexions. Le pool est représenté par au moins une connexion maitre et zéro ou plusieurs connexions esclaves.
Chaque connexion dans le pool possède son propre état.Par exemple, les variables SQL utilisateurs, les tables temporaires et les transactions font partie de l'état. Voyez la liste complète dans pools de connexions et bascule. Si le plugin décide de basculer de connexion pour l'équilibre de la charge, l'application pourrait se retrouver avec des connexions d'états différents. Les applications doivent faire attention à ce point.
Exemple #1 Config du plugin avec un maitre et un esclave
{ "myapp": { "master": { "master_0": { "host": "localhost", "socket": "\/tmp\/mysql.sock" } }, "slave": { "slave_0": { "host": "192.168.2.27", "port": "3306" } } } }
Exemple #2 Problème possible : État de la connexion et variables SQL utilisateurs
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
/* Evidemment, votre propre gestion des erreurs serait meilleure... */
die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
/* Connexion 1, la connexion a utilisé des variables SQL, pas de SELECT, donc maitre utilisé */
if (!$mysqli->query("SET @myrole='master'")) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
/* Connexion 2, sur un esclave car de type SELECT */
if (!($res = $mysqli->query("SELECT @myrole AS _role"))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
} else {
$row = $res->fetch_assoc();
$res->close();
printf("@myrole = '%s'\n", $row['_role']);
}
$mysqli->close();
?>
L'exemple ci-dessus va afficher :
@myrole = ''
L'exemple ouvre une conneXion équilibrée et exécute deux requêtes. La première SET @myrole='master' n'est pas de type SELECT, elle est donc exécutée sur une connexion à un maitre (ici il n'y en a qu'un seul). La requête change une variable SQL qui est donc liée à la connexion. L'état de la connexion au maitre vient donc de changer.
La requête suivante, SELECT @myrole AS _role est lancée sur un esclave car elle est de type lecture seule (select). La connexion à l'esclave ne possède elle, aucune variable SQL affectée, son état est donc différent de celui de la connexion au maitre. Le script affiche donc en réponse @myrole = ''.
Il est de la responsabilité du développeur de l'application de prendre garde aux états des connexions balancées. Le plugin ne surveille pas toutes les activités des connexions, ceci serait beaucoup trop couteux en temps CPU.
Ces problèmes peuvent être contournés grâce aux astuces SQL.