Les astuces SQL peuvent être utilisées pour forcer le plugin à choisir un serveur particulier dans le pool. Ceci peut aider à palier aux problèmes de bascule entre les connexions oude changement d'état des connexions.
Les astuces SQL sont des commentaires de la syntaxe SQL. Comme ils sont supposés être ignorés, ils n'interfèrent pas avec les serveurs MySQL, le proxy MySQL ou même un pare-feu.
Trois astuces SQL sont supportées par le plugin :
MYSQLND_MS_MASTER_SWITCH
indique au plugin d'exécuter une
requête sur le maitre, MYSQLND_MS_SLAVE_SWITCH
force
l'utilisation de l'esclave et MYSQLND_MS_LAST_USED_SWITCH
exécutera la requête sur le même serveur que celui utilisé pour exécuter la
requête précédente.
Le plugin scanne le début de la requête pour rechercher une astuce SQL en commentaires. Les astuces SQL ne doivent être écrites qu'au début d'une requête pour être reconnues.
Exemple #1 Configuration du plugin avec un esclave et un maitre
{ "myapp": { "master": { "master_0": { "host": "localhost", "socket": "\/tmp\/mysql.sock" } }, "slave": { "slave_0": { "host": "192.168.2.27", "port": "3306" } } } }
Exemple #2 Astuces SQL pour éviter les bascules de connexion
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno()) {
/* 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 1, exécutée sur le maitre à cause de l'astuce SQL présente */
if (!($res = $mysqli->query(sprintf("/*%s*/SELECT @myrole AS _role", MYSQLND_MS_LAST_USED_SWITCH)))) {
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 = 'master'
Dans l'exemple ci-dessus, MYSQLND_MS_LAST_USED_SWITCH
est utilisée
pour éviter la bascule du maitre vers un esclave lors de l'exécution de la requête SELECT
.
Les astuces SQL peuvent aussi être utilisée pour lancer une requête SELECT
sur le maitre. Par exemple, lorsque les esclaves sont derrière le maitre et que vous
voulez selectionner des données fraiches.
En version 1.2.0 le concept d'un niveau de service a été ajouté pour faire face aux cas où les données courantes sont demandées. Utiliser un niveau de service requiert moins d'attention et les astuce SQL ne sont plus obligatoires. Voyez les sections plus bas pour plus d'informations.
Exemple #3 Latence de réplication
<?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()));
}
/* Force l'utilisation du maitre, le maitre a toujours des données fraiches */
if (!$mysqli->query(sprintf("/*%s*/SELECT critical_data FROM important_table", MYSQLND_MS_MASTER_SWITCH))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
?>
Autre exemple concrêt : créer des tables sur un esclave. Si aucune astuce SQL n'est fournie,
le plugin va envoyer les CREATE
et INSERT
vers le maitre. L'astuce MYSQLND_MS_SLAVE_SWITCH
peut alors être
utilisée pour forcer l'utilisation d'un esclave.
Exemple #4 Création de table sur un esclave
<?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()));
}
/* Force l'utilisation d'un esclave */
if (!$mysqli->query(sprintf("/*%s*/CREATE TABLE slave_reporting(id INT)", MYSQLND_MS_SLAVE_SWITCH))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
/* Continue en utilisant cette connexion à l'esclave */
if (!$mysqli->query(sprintf("/*%s*/INSERT INTO slave_reporting(id) VALUES (1), (2), (3)", MYSQLND_MS_LAST_USED_SWITCH))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
/* N'utilisez pas MYSQLND_MS_SLAVE_SWITCH qui autoriserait la bascule vers un autre esclave ! */
if ($res = $mysqli->query(sprintf("/*%s*/SELECT COUNT(*) AS _num FROM slave_reporting", MYSQLND_MS_LAST_USED_SWITCH))) {
$row = $res->fetch_assoc();
$res->close();
printf("There are %d rows in the table 'slave_reporting'", $row['_num']);
} else {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
$mysqli->close();
?>
L'astuce SQL MYSQLND_MS_LAST_USED
interdit la bascule de connexion
et force l'utilisation de la connexion de la requête précédente.