(PECL mysqlnd_ms < 1.1.0)
mysqlnd_ms_set_user_pick_server — Définit une fonction de rappel utilisateur pour la séparation lecture/écriture
$function
)Définit une fonction de rappel utilisateur pour la séparation lecture/écriture. Le plugin appellera cette fonction uniquement si pick[]=user est la règle par défaut pour la sélection de serveur dans la section révélante du fichier de configuration du plugins.
Le mécanisme interne de décision sur la séparation lecture/écriture du
plugin peut être écrasé de 2 façons. La plus simple est d'ajouter en début
de requête SQL l'astuce MYSQLND_MS_MASTER_SWITCH
,
MYSQLND_MS_SLAVE_SWITCH
ou
MYSQLND_MS_LAST_USED_SWITCH
. L'utilisation d'astuces SQL
permet de contrôler, par exemple, si la requête doit être envoyée au serveur
MySQL maître de réplication ou à un des serveurs esclaves. Avec l'aide des astuces
SQL, il n'est pas possible de sélectionner un serveur esclave particulier
pour l'exécution de la requête.
Le contrôle total sur la sélection de serveur peut être atteint en utilisant une fonction de rappel. Son utilisation est recommandée par les utilisateurs expérimentés uniquement par le fait que la fonction de rappel couvre tous les cas pouvant être gérés par le plugin.
Le plugin invoquera la fonction de rappel pour sélectionner un serveur depuis la liste des serveurs maîtres et esclaves configurés. La fonction de rappel inspecte la requête à exécuter, et sélectionne un serveur utilisé pour l'exécution de la requête en retournant l'URI de l'hôte, tel que trouvé dans la liste des serveurs maîtres et esclaves.
Si les connexions paresseuses sont activées, si la fonction de rappel choisit un serveur esclave pour lequel aucune connexion n'a été établie, et que la connexion échoue, le plugin retournera une erreur lors de la prochaine action sur la connexion ayant échouée, par exemple, lors de l'exécution d'une requête.. Il en est de la responsabilité de l'application de gérer cette erreur. Par exemple, l'application peut ré-exécuter la requête pour forcer la sélection d'un nouveau serveur et ainsi provoquer l'invocation de la fonction de rappel. Si c'est le cas, la fonction de rappel doit s'assurer de sélectionner un esclave différent, ou vérifier la disponibilité de l'esclave choisi, avant de retourner le résultat au plugin, et ce, afin d'éviter une boucle infinie.
function
La fonction à appeler. Les méthodes de la classe peuvent aussi être invoquées statiquement en utilisant cette fonction en passant array($classname, $methodname) dans ce paramètre. De plus, les méthodes de la classe d'une instance d'objet peuvent être appelées en passant array($objectinstance, $methodname) dans ce paramètre.
Hôte sur lequel la requête sera exécutée. L'URI de l'hôte sera issue de la liste des connexions maîtres et esclaves passée à la fonction de rappel. Si la fonction de rappel retourne une valeur ni trouvée dans le maître, ni dans les esclaves de la liste, le plugin se retournera sur la seconde méthode de sélection configurée via la configuration pick[] du fichier de configuration du plugin. Si aucune seconde méthode de sélection n'est fournie, le plugin se retournera alors vers la méthode de sélection interne.
Note:
mysqlnd_ms_set_user_pick_server() est disponible avec PECL mysqlnd_ms < 1.1.0. La fonction a été remplacée par un filtre utilisateur. Reportez-vous aux modifications de versions.
Exemple #1 Exemple avec mysqlnd_ms_set_user_pick_server()
[myapp] master[] = localhost slave[] = 192.168.2.27:3306 slave[] = 192.168.78.136:3306 pick[] = user
<?php
function pick_server($connected, $query, $master, $slaves, $last_used)
{
static $slave_idx = 0;
static $num_slaves = NULL;
if (is_null($num_slaves))
$num_slaves = count($slaves);
/* défaut : retour à la logique interne du plugin */
$ret = NULL;
printf("L'utilisateur est connecté sur '%s'...\n", $connected);
printf("... décision du serveur pour l'exécution de la requête '%s'\n", $query);
$where = mysqlnd_ms_query_is_select($query);
switch ($where)
{
case MYSQLND_MS_QUERY_USE_MASTER:
printf("... utilisation du maître\n");
$ret = $master[0];
break;
case MYSQLND_MS_QUERY_USE_SLAVE:
/* SELECT ou astuce SQL pour l'utilisation d'un esclave */
if (stristr($query, "FROM table_on_slave_a_only"))
{
/* une table qui n'est configuré que sur le premier esclave configuré */
printf("... accès à une table disponible que sur l'esclave A détecté\n");
$ret = $slaves[0];
}
else
{
/* tentative */
printf("... quelques requêtes en lectures seules pour un esclave\n");
$ret = $slaves[$slave_idx++ % $num_slaves];
}
break;
case MYSQLND_MS_QUERY_LAST_USED:
printf("... utilisation du dernier serveur utilisé\n");
$ret = $last_used;
break;
}
printf("... ret = '%s'\n", $ret);
return $ret;
}
mysqlnd_ms_set_user_pick_server("pick_server");
$mysqli = new mysqli("myapp", "root", "root", "test");
if (!($res = $mysqli->query("SELECT 1 FROM DUAL")))
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
$res->close();
if (!($res = $mysqli->query("SELECT 2 FROM DUAL")))
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
$res->close();
if (!($res = $mysqli->query("SELECT * FROM table_on_slave_a_only")))
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
$res->close();
$mysqli->close();
?>
L'exemple ci-dessus va afficher :
L'utilisateur est connecté sur 'myapp'... ... décision du serveur pour l'exécution de la requête 'SELECT 1 FROM DUAL' ... quelques requêtes en lectures seules pour un esclave ... ret = 'tcp://192.168.2.27:3306' L'utilisateur est connecté sur 'myapp'... ... décision du serveur pour l'exécution de la requête 'SELECT 2 FROM DUAL' ... quelques requêtes en lectures seules pour un esclave ... ret = 'tcp://192.168.78.136:3306' L'utilisateur est connecté sur 'myapp'... ... décision du serveur pour l'exécution de la requête 'SELECT * FROM table_on_slave_a_only' ... accès à une table disponible que sur l'esclave A détecté ... ret = 'tcp://192.168.2.27:3306'