## Astuces SQL

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.