La documentation suivantes s'applique à PECL/mysqlnd_ms >= 1.1.0-beta. Elle n'est pas valide pour les versions antérieures. Pour une documentation qui couvre les anciennes versions, raportez-vous à la documentation de la configuration pour mysqlnd_ms 1.0.x et antérieures.
Note: Historique : Fonctionnalités ajoutées en PECL/mysqlnd_ms 1.1.0-beta
La description ci-dessous s'applique à PECL/mysqlnd_ms >= 1.1.0-beta. Elle n'est pas valide pour les versions plus anciennes.
Le plugin utilise un fichier de configuration propre, qui contient les informations sur le maitre de réplication MySQL, les escalves, la politique de bascule et la stratégie de failover et l'utilisation de connexions paresseuses (lazy).
Le plugin charge son fichier de configuration au début de la requête web. Il est ensuite mis en cache mémoire et utilisé pour toute la durée de la requête web. De cette façon, il n'est pas nécessaire de redémarrer PHP après avoir déployé le fichier de configuration. Les modifications du fichier de configuration devient ainsi actives en seulement quelques minutes.
La directive de configuration PHP
mysqlnd_ms.config_file
est utilisée pour indiquer le fichier de configuration des plugins. Notez
que la directive de configuration PHP ne sera pas évaluée pour chaque requête
web. Toutefois, la modification du nom du fichier de configuration ou son
lieu de stockage nécessite un redémarrage de PHP. Cependant, aucun redémarrage
n'est nécessaire pour lire les modifications d'un fichier de configuration
déjà en place.
L'utilisation et l'analyse JSON est rapide, et l'utilisation de JSON rend simple les structures hiérarchiques par rapport au format standard php.ini.
Exemple #1 Conversion d'un hash PHP en frmat JSON
Ou sinon, un développeur peut être plus familier avec la syntaxe PHP array et ainsi, le préférer. Cet exemple montre la façon dont un développeur peut convertir un tableau PHP en JSON.
<?php
$config = array(
"myapp" => array(
"master" => array(
"master_0" => array(
"host" => "localhost",
"socket" => "/tmp/mysql.sock",
),
),
"slave" => array(),
),
);
file_put_contents("mysqlnd_ms.ini", json_encode($config, JSON_PRETTY_PRINT));
printf("Fichier mysqlnd_ms.ini créé...\n");
printf("Affichage du contenu...\n");
printf("%s\n", str_repeat("-", 80));
echo file_get_contents("mysqlnd_ms.ini");
printf("\n%s\n", str_repeat("-", 80));
?>
L'exemple ci-dessus va afficher :
Fichier mysqlnd_ms.ini créé... Affichage du contenu... -------------------------------------------------------------------------------- { "myapp": { "master": { "master_0": { "host": "localhost", "socket": "\/tmp\/mysql.sock" } }, "slave": [ ] } } --------------------------------------------------------------------------------
Un fichier de configuration de plugin consiste en une ou plusieurs sections. Les sections sont représentées par des propriétés d'objet haut-niveau de l'objet encodé dans le fichier JSON. Les sections peuvent aussi être appelées des noms de configuration.
Les applications font références aux sections par leurs noms. Les applications utilisent les noms de sections comme paramètre hôte (serveur) dans les méthodes de connexions des extensions mysqli, mysql et PDO_MYSQL. Une fois connectée, le plugin mysqlnd compare le nom de l'hôte avec tous les noms de sections du fichier de configuration du plugin. Si le nom d'hôte et le nom de la section correspondent, le plugin chargera les paramètres de cette section.
Exemple #2 Exemple d'utilisation des noms de section
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.2.27" }, "slave_1": { "host": "192.168.2.27", "port": 3306 } } }, "localhost": { "master": [ { "host": "localhost", "socket": "\/path\/to\/mysql.sock" } ], "slave": [ { "host": "192.168.3.24", "port": "3305" }, { "host": "192.168.3.65", "port": "3309" } ] } }
<?php
/* Toutes les connexions suivantes seront en balance de charge */
$mysqli = new mysqli("myapp", "username", "password", "database");
$pdo = new PDO('mysql:host=myapp;dbname=database', 'username', 'password');
$mysql = mysql_connect("myapp", "username", "password");
$mysqli = new mysqli("localhost", "username", "password", "database");
?>
Les noms de section sont des chaînes de caractères. Il est valide d'utiliser
un nom de section comme
192.168.2.1
, 127.0.0.1
ou
localhost
. Si, par exemple, une application se connecte à
localhost
et que la section de configuration
localhost
existe pour ce plugin, la sémantique de l'opération
de connexion change. L'application n'utilise plus que le serveur MySQL sur l'hôte
localhost
mais le plugin commence à effectuer un balance de
charge en suivant les règles issues de la section de configuration
localhost
. De cette façon, vous pouvez effectuer de la
balance de charge des requêtes depuis l'application sans aucune modification
du code source de l'application. Garder à l'esprit qu'une telle configuration
ne contribue pas à une meilleure lisibilité de votre code source.
L'utilisation de noms de section qui peuvent être utilisés comme noms d'hôte
doit être de dernier recours.
Chaque section de configuration contient au moins une liste de serveurs maîtres,
et une liste de serveurs esclaves. La liste des maîtres est configurée avec
le mot clé master
, alors que la liste des esclaves est configurée
avec le mot clé slave
. Le fait de ne pas fournir de liste
d'esclaves produit une erreur de type E_ERROR
(erreur fatale).
Malgré le fait que vous ne pouvez pas omettre de liste d'esclaves, elle peut être vide.
Il est possible de n'autoriser aucun esclave. Cependant, ce n'est recommandé
que pour les clusters synchrones (lire la documentation sur les
clusters supportés).
La majeure partie de la documentation parle que des clusters de réplication
MySQL asynchrones.
Les listes de maîtres et d'esclaves peuvent être optionnellement indexées par le nom symbolique du serveur qu'elles décrivent.
Exemple #3 Liste des esclaves anonymes
"slave": [ { "host": "192.168.3.24", "port": "3305" }, { "host": "192.168.3.65", "port": "3309" } ]
Une liste de serveurs anonymes est encodée en JSON array
.
Vous pouvez optionnellement utiliser les noms symboliques pour indexer
les serveurs esclaves ou maîtres de la liste des serveurs. Dans un dernier ressort,
vous pouvez utiliser le type JSON object
.
Exemple #4 Liste Maître en utilisant les noms symboliques
"master": { "master_0": { "host": "localhost" } }
Il est recommandé d'indexer la liste des serveurs avec les noms symboliques des serveurs. Les noms d'alias seront affichés dans les messages d'erreur.
L'ordre des serveurs est préservé et pris en compte par mysqlnd_ms.
Si, par exemple, vous configurez la stratégie de balance de charge round robin,
la première requête SELECT
sera exécutée sur l'esclave
qui apparaît en premier dans la liste des serveurs esclaves.
Un serveur configuré peut être décrit avec les paramètres host
,
port
, socket
, db
,
user
, password
et connect_flags
.
Il est obligatoire de définir l'hôte du serveur de base de données en utilisant le
mot clé host
. Tous les autres paramètres de configuration sont optionnels.
Exemple #5 Mot clé pour configurer un serveur
{ "myapp": { "master": { "master_0": { "host": "db_server_host", "port": "db_server_port", "socket": "db_server_socket", "db": "database_resp_schema", "user": "user", "password": "password", "connect_flags": 0 } }, "slave": { "slave_0": { "host": "db_server_host", "port": "db_server_port", "socket": "db_server_socket" } } } }
Si une configuration est omise, le plugin utilisera la valeur fournie par l'appel API de l'utilisateur pour ouvrir la connexion. Reportez-vous à l'exemple ci-dessus sur l'utilisation des noms de section.
Le format du fichier de configuration a été modifié en version 1.1.0-beta
pour permettre les filtres chaînés. Les filtres sont responsables du filtrage de la
liste de serveurs configurés afin d'identifier un serveur pour l'exécution de la
requête donnée. Les filtres sont configurés avec le mot clé filter
.
Les filtres sont exécutés par mysqlnd_ms dans l'ordre de leur apparence.
La définition de filtres est optionnel. Une section de configuration dans le
fichier de configuration du plugin n'a pas besoin d'avoir d'entrée
filters
.
Les filtres remplacent la configuration
pick[]
des précédentes versions. random
et roundrobin
fournissent la même fonctionnalité.
Exemple #6 Nouveau filtre roundrobin
, ancienne fonctionnalité
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" }, "slave_1": { "host": "192.168.78.137", "port": "3306" } }, "filters": { "roundrobin": [ ] } } }
La fonction mysqlnd_ms_set_user_pick_server() a été supprimée.
La définition d'une fonction de rappel est maintenant possible avec le filtre
user
. Quelques filtres acceptent des paramètres.
Le filtre user
requière et accepte obligatoirement le paramètre
callback
pour définir la fonction de rappel précédemment
définie via la fonction mysqlnd_ms_set_user_pick_server().
Exemple #7 Le filtre user
remplace la fonction mysqlnd_ms_set_user_pick_server()
"filters": { "user": { "callback": "pick_server" } }
La validité du fichier de configuration est vérifiée à la fois lors de la lecture du fichier de configuration mais aussi plus tard, lors de l'établissement d'une connexion. Le fichier de configuration est lu durant le démarrage de PHP. A ce stade là, une extension PHP ne peut afficher les messages d'erreurs proprement. Dans la plupart des cas, aucune erreur n'est montrée, et une connexion peut échouer sans pour autant avoir un message d'erreur adéquate. Ce problème a été résolu en version 1.5.0.
Exemple #8 Message d'erreur commun dans le cas d'une erreur dans le fichier de configuration (à partir de la version 1.5.0)
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
?>
L'exemple ci-dessus va afficher :
Warning: mysqli::mysqli(): (mysqlnd_ms) (mysqlnd_ms) Failed to parse config file [s1.json]. Please, verify the JSON in Command line code Warning: mysqli::mysqli(): (HY000/2002): php_network_getaddresses: getaddrinfo failed: Name or service not known in Command line code on line 1 Warning: mysqli::query(): Couldn't fetch mysqli in Command line code on line 1 Fatal error: Call to a member function fetch_assoc() on a non-object in Command line code on line 1
Depuis la version 1.5.0, les erreurs au démarrage sont mises en mémoire tampon,
et émises lorsqu'une tentative de connexion est réalisée. Utilisez la directive de
configuration
mysqlnd_ms.force_config_usage
pour définir le type d'erreyr à utiliser pour afficher les erreurs de la mémoire tampon.
Par défaut, une erreur de type E_WARNING
sera émise.
Exemple #9 Validation renforcée du fichier de configuration depuis la version 1.5.0
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
?>
L'exemple ci-dessus va afficher :
Warning: mysqli::mysqli(): (mysqlnd_ms) (mysqlnd_ms) Failed to parse config file [s1.json]. Please, verify the JSON in Command line code on line 1
Il peut être utile de définir
mysqlnd_ms.force_config_usage = 1
lors du débogage des erreurs du fichier de configuration. Ceci ne va pas seulement définir
le type d'erreurs de démarrage mises en mémoire tampon à E_RECOVERABLE_ERROR
mais aussi va vous aider à détecter les noms de section erronés.
Exemple #10 Erreur plus précise grâce à l'utilisation de mysqlnd_ms.force_config_usage=1
mysqlnd_ms.force_config_usage=1
<?php
$mysqli = new mysqli("invalid_section", "username", "password", "database");
?>
L'exemple ci-dessus va afficher :
Warning: mysqli::mysqli(): (mysqlnd_ms) Exclusive usage of configuration enforced but did not find the correct INI file section (invalid_section) in Command line code on line 1 line 1
Voici une explication rapide des directives de configuration qui peuvent être utilisées.
master
tableau ou object
Liste de serveurs maîtres de réplication MySQL. La liste est au
format JSON type array
pour déclarer une liste
anonyme de serveurs ou au format JSON type object
.
Reportez-vous aux exemples
ci-dessous.
La définition d'au moins un serveur maître est obligatoire. Le plugin
émettra une erreur de type E_ERROR
si l'utilisateur
n'a pas fourni de liste de serveurs maîtres dans une section
de configuration. L'erreur fatale ressemble à ceci :
(mysqlnd_ms) Section [master] doesn't exist for host
[name_of_a_config_section] in %s on line %d
.
Un serveur est décrit avec les paramètres
host
, port
,
socket
, db
,
user
, password
et
connect_flags
.
Il est obligatoire de fournir une valeur pour le paramètre
host
. Si n'importe quel autre paramètre
n'est pas fourni, il sera récupéré depuis l'appel API de
connexion. Reportez-vous aux
exemples d'utilisation
des noms de section.
Tableau de mot clé pour les serveurs dans la configuration.
Mot clé | Description | Version |
---|---|---|
host
|
Hôte du serveur de base de données. Cette donnée est obligatoire.
Le fait de ne pas le fournir émettra une erreur de type
|
Depuis la version 1.1.0. |
port
|
Port TCP/IP du serveur de base de données. |
Depuis la version 1.1.0. |
socket
|
Socket du domaine Unix du serveur de base de données. |
Depuis la version 1.1.0. |
db
|
Base de données (schemata). |
Depuis la version 1.1.0. |
user
|
Utilisateur de la base de données MySQL. |
Depuis la version 1.1.0. |
password
|
Mot de passe pour l'utilisateur de la base de données MySQL. |
Depuis la version 1.1.0. |
connect_flags
|
Drapeaux de connexion. |
Depuis la version 1.1.0. |
Le plugin supporte l'utilisation d'un seul serveur maître. Une configuration expérimentale existe pour activer le support multi-maître. Les détails ne sont pas actuellement documentés.
slave
tableau ou object
Liste un ou plusieurs serveurs esclaves de réplication MySQL. La syntaxe
est identique à la configuration des serveurs maîtres. Reportez-vous au
master
ci-dessus pour plus de détails.
Le plugin supporte l'utilisation d'un ou plusieurs esclaves.
Le fait de définit une liste de serveurs esclaves est obligatoire. Le plugin
émettra une erreur de type E_ERROR
si slave
n'est pas fourni dans une section de configuration. Le message d'erreur fatale
devrait afficher quelque chose comme
(mysqlnd_ms) Section [slave] doesn't exist for host [%s] in %s on line %d
.
Notez qu'il est valide d'utiliser une liste de serveur esclave vide. L'erreur
a été introduite pour prévenir une configuration accidentelle des esclaves
en oubliant la configuration slave
setting.
Une configuration de maîtres uniquement est toujours possible en utilisant
une liste d'esclave vide.
Si une liste d'esclave vide est configuré et une tentative est faîte
d'exécuter une requête sur un esclave, le plugin émettra une alerte du
type mysqlnd_ms) Couldn't find the appropriate slave connection.
0 slaves to choose from.
lors de l'exécution. Il est possible
qu'une autre alerte suive, comme ceci
(mysqlnd_ms) No connection selected by the last filter
.
global_transaction_id_injection
array ou objet
Configuration de GTID dans le cas de l'inclusion directe dans le serveur, et l'émulation coté client.
Mot-clé | Description | Version |
---|---|---|
fetch_last_gtid
|
Requête SQL pour recupérer le dernier GTID. La requête est lancée si le plugin a besoin de connaitre le dernier GTID. Ce peut être le cas, par exemple, pour vérifier le statut de réplication d'un esclave MySQL. Aussi utilisé avec mysqlnd_ms_get_last_gtid(). |
Depuis 1.2.0. |
check_for_gtid
|
Requête SQL pour vérifier sur un réplica a répliqué toutes les transactions
jusqu'à une certaine, recherchée. La requête est jouée lorsqu'une recherche
de réplica pouvant offrir un niveau de consistence supérieur est lancée.
La requête doit comporter un jocker |
Depuis 1.2.0. |
report_errors
|
Si oui ou non une erreur de type warning doit être levée dans le cas où une requête SQL configurée provoque une erreur. |
Depuis 1.2.0. |
on_commit
|
Emulation GTID coté client uniquement. Requête SQL a exécuter lorsqu'une transaction a fini de mettre à jour le GTID sur le maitre. Voyez quickstart pour les exemples. |
Depuis 1.2.0. |
wait_for_gtid_timeout
|
Indique au plugin d'attendre L'option peut être utilisée avec l'émulation côté client mais aussi avec la fonctionnalité des identifiants globaux de transaction de MySQL 5.6. L'attente d'un esclave pour répliquer un certain GTID nécessaire pour une consistence de session signifie également l'étranglement du client. En étranglant le client, le charge en écriture du maître est indirectement réduite. Une copie primaire basé sur le système de réplication, comme une réplication MySQL, prend plus de temps pour atteindre un statut de consistence. Ce comportement peut être désiré, par exemple, pour accroitre le nombre de copies de données pour des considérations de haute disponibilité, ou pour prévenir la surcharge du maître. |
Depuis 1.4.0. |
fabric
object
La configuration relative à MySQL Fabric. Si le plugin est utilisé avec MySQL Fabric, alors le fichier de configuration du plugin ne contiendra plus la liste des serveurs MySQL. A la place, le plugin demandera à MySQL Fabric la liste des serveurs à utiliser pour effectuer certaines tâches.
Au minimum, le fichier de configuration du plugin à utiliser avec MySQL Fabric contiendra un ou plusieurs hôtes MySQL Fabric que le plugin peut interroger. Si plus d'un hôte MySQL Fabric est configuré, le plugin utilisera la stratégie roundrobin pour effectuer son choix. Les autres stratégies ne sont actuellement pas disponible.
Exemple #11 Configuration minimale du plugin pour son utilisation avec MySQL Fabric
{ "myapp": { "fabric": { "hosts": [ { "host" : "127.0.0.1", "port" : 8080 } ] } } }
Chaque hôte MySQL Fabric est décrit en utilisant un objet JSON contenant les membres suivants.
Mot clé | Description | Version |
---|---|---|
host
|
Nom de l'hôte du serveur MySQL Fabric. |
Depuis 1.6.0. |
port
|
Le port TCP/IP sur lequel écoute le serveur MySQL Fabric pour les appels aux procédures distantes envoyées par les clients comme le plugin. |
Depuis 1.6.0. |
Le plugin utilise les flux PHP pour communiquer avec MySQL Fabric via XML RPC sur HTTP. Par défaut, aucun délai maximal d'attente n'est défini pour les communications réseaux. Aussi, le plugin utilisera les délais d'attente maximale par défaut des flux PHP. Ces valeurs ne sont pas contrôlées par le plugin lui même.
Une valeur optionnelle du délai d'attente maximale peut être définie en écrasant la valeur par défaut des flux PHP. Le fait de définir la valeur du délai d'attente maximale dans le fichier de configuration du plugin a le même effet que de définir un délai d'attente dans l'espace utilisateur PHP des connexions HTTP établies via les flux PHP.
L'unité de la valeur du délai d'attente maximale de Fabric est la seconde. L'intervalle de valeur autorisée est 0 - 65535. Cette configuration existe depuis la version 1.6.
Exemple #12 Délai d'attente maximale optionnelle pour les communications avec Fabric
{ "myapp": { "fabric": { "hosts": [ { "host" : "127.0.0.1", "port" : 8080 } ], "timeout": 2 } } }
Les transactions stickiness et la logique MySQL Fabric peuvent cohabiter. L'option stickiness désactive le chagement de serveur pendant la durée d'une transaction. Lors de l'utilisation de Fabric ainsi que du partage, l'utilisateur peut (par erreur) commencer une transaction locale sur un serveur partagé, puis, tenter de changer de serveur en utilisant soit la fonction mysqlnd_ms_fabric_select_shard(), soit la fonction mysqlnd_ms_fabric_select_global(). Dans ce cas, le plugin ne va pas rejeter la requête de changement de serveur au milieu d'une transaction, mais autoriser l'utilisateur à changer de serveur suivant la configuration stickiness de la transaction utilisée. Ceci est clairement une erreur de l'utilisation d'écrire ce genre de code.
Si les transactions stickiness sont actives, et que vous souhaitez récupérer
une alerte lors de l'appel à la fonction mysqlnd_ms_fabric_select_shard()
ou mysqlnd_ms_fabric_select_global(),
définissez le booléen trx_warn_server_list_changes
.
Exemple #13 Alerte lors de la violation des limitations des transactions
{ "myapp": { "fabric": { "hosts": [ { "host" : "127.0.0.1", "port" : 8080 } ], "trx_warn_serverlist_changes": 1 }, "trx_stickiness": "on" } }
<?php
$link = new mysqli("myapp", "root", "", "test");
/*
Pour la démo, l'appel doit échouer.
Echec ou non, nous arrivons dans un cas souhaité pour l'exemple.
*/
@mysqlnd_ms_fabric_select_global($link, 1);
$link->begin_transaction();
@$link->query("DROP TABLE IF EXISTS test");
/*
Le changement de serveurs est une erreur en raison
de l'ouverture d'une transaction locale !
*/
mysqlnd_ms_select_global($link, 1);
?>
L'exemple ci-dessus va afficher :
PHP Warning: mysqlnd_ms_fabric_select_global(): (mysqlnd_ms) Fabric server exchange in the middle of a transaction in %s on line %d
Veuillez considérer cette fonctionnalité comme expérimentale. Une modification de la syntaxe ou de la sémantique peut intervenir à tout moment.
filters
object
Liste des filtres. Un filtre est prévu pour filtrer la liste des serveurs disponibles
pour l'exécution d'une requête donnée. Ils peuvent être chaînés.
Le filtre random
et le filtre roundrobin
remplacent la directive
pick[]
utilisée dans les versions précédantes pour sélectionner une politique de balance
de charge. le filtre user
remplace la fonction
mysqlnd_ms_set_user_pick_server().
Les filtres peuvent accepter des paramètres pour redéfinir leurs actions.
Si aucune politique de balance de charge n'est définie, le plugin
prendra par défaut le filtre random_once
.
Le filtre random_once
sélectionne un serveur esclave
aléatoire lors de l'exécution de la première requête de lecture. Le serveur
esclave sera ensuite utilisé pour exécuter toutes les requêtes de
lecture seule jusqu'à la fin du script PHP. Aucune politique de balance de
charge n'est définie et ainsi, le mode par défaut prend place si
ni le filtre random
, ni le filtre roundrobin
n'est présent dans une section de configuration.
Si un filtre chaîné est configuré de tel façon qu'un filtre qui
affiche en sortie pas plus d'un serveur utilisé comme entrée pour un
filtre dont on doit passer plus d'un serveur en entrée, le plugin peut
émettre une alerte lors de l'ouverture de la connexion. L'alerte
ressemblera à quelque chose comme : (mysqlnd_ms) Error while creating
filter '%s' . Non-multi filter '%s' already created.
Stopping in %s on line %d
. En plus une erreur de code
2000
, un statut sql HY000
et un message d'erreur similaire à l'alerte peuvent être définis
sur le gestionnaire de connexion.
Exemple #14 Séquence de filtres invalide
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "filters": [ "roundrobin", "random" ] } }
<?php
$link = new mysqli("myapp", "root", "", "test");
printf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
$link->query("SELECT 1 FROM DUAL");
?>
L'exemple ci-dessus va afficher :
PHP Warning: mysqli::mysqli(): (HY000/2000): (mysqlnd_ms) Error while creating filter 'random' . Non-multi filter 'roundrobin' already created. Stopping in filter_warning.php on line 1 [2000] (mysqlnd_ms) Error while creating filter 'random' . Non-multi filter 'roundrobin' already created. Stopping PHP Warning: mysqli::query(): Couldn't fetch mysqli in filter_warning.php on line 3
random
object
Le filtre random
fournit les fonctionnalités de
sélection aléatoire et de sélection aléatoire unique pour
la politique de balance de charge, équivalent à la directive
pick[]
dans les précédentes versions.
La politique de sélection aléatoire va prendre un serveur aléatoirement lorsqu'une requête en lecture seule est exécutée. La stratégie de sélection aléatoire unique va sélectionner un serveur esclave aléatoirement et va continuer de l'utiliser pour le reste des requêtes PHP. La sélection aléatoire unique est le mode par défaut, si la balance de charge n'est pas configurée via un filtre.
Si le filtre random
ne fournit aucun argument,
la politique de balance de charge sera la sélection aléatoire.
Exemple #15 Balance de charge aléatoire avec le filtre random
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" }, "slave_1": { "host": "192.168.78.137", "port": "3306" } }, "filters": [ "random" ] } }
Optionnellement, l'argument sticky
peut être passé au filtre.
Si l'argument sticky
est défini en la chaîne de caractère
1
, le filtre suit la stratégie de sélection aléatoire unique.
Exemple #16 Balance de charge avec sélection aléatoire unique avec le filtre random
{ "filters": { "random": { "sticky": "1" } } }
A la fois le filtre random
et le filtre
roundrobin
supportent la définition d'une priorité,
un poids pour un serveur, et ce, depuis PECL/mysqlnd_ms 1.4.0.
Si l'argument weight
est passé au filtre, il doit
assigner un poids à tous les serveurs. Les serveurs doivent donner
un alias dans la liste des serveurs slave
et
master
. L'alias doit être utilisé pour référencer
les serveurs pour l'assignement d'une priorité avec l'argument weight
.
Exemple #17 Erreur de référencement
[E_RECOVERABLE_ERROR] mysqli_real_connect(): (mysqlnd_ms) Unknown server 'slave3' in 'random' filter configuration. Stopping in %s on line %d
L'utilisation d'un mauvais alias avec l'argument
weight
peut conduire à une erreur similaire
à celle de l'exemple ci-dessus.
Si weight
est omis, le poids par défaut de tous les
serveurs sera de un.
Exemple #18 Assignement d'un argument weight
pour la balance de charge
{ "myapp": { "master": { "master1":{ "host":"localhost", "socket":"\/var\/run\/mysql\/mysql.sock" } }, "slave": { "slave1": { "host":"192.168.2.28", "port":3306 }, "slave2": { "host":"192.168.2.29", "port":3306 }, "slave3": { "host":"192.0.43.10", "port":3306 }, }, "filters": { "random": { "weights": { "slave1":8, "slave2":4, "slave3":1, "master1":1 } } } } }
En moyenne, un serveur dont le poids est de deux sera sélectionné
de fois plus qu'un serveur dont le poids est de un. Différents poids
peuvent être assignés pour refléter différentes tailles de machine,
pour préférer des esclaves proches qui ont une latence réseau faible, ou
pour configurer un serveur de secours en cas d'échec. Dans ce dernier
cas, vous pouvez vouloir assigner au serveur de secours un poids
très faible par rapport aux autres serveurs. Par exemple, si l'on reprend
la configuration ci-dessus, slave3
ne recevra qu'en
moyenne huit pourcent des requêtes. Tant que les esclaves slave1
et slave2
fonctionnent, il sera utilisé rarement,
un peu à la façon d'un serveur de secours. En cas d'erreur sur l'esclave
slave1
et l'esclave slave2
,
l'utilisation de l'esclave slave3
augmentera.
Veuillez lire les notes relative au failover avant d'utiliser
l'argument weight
dans ce but.
L'intervalle de valeurs valides pour le poids est de 1 à 65535.
Les arguments inconnus sont ignorés par le filtre. Aucune alerte ni erreur n'est fourni.
Le filtre attente un ou plusieurs serveurs en entrée et ne sort qu'un
seul serveur.
Une séquence de filtre comme
random
, roundrobin
peut
émettre une alerte et un message d'erreur définis sur le
gestionnaire de connexion lors de l'exécution d'une requête.
Liste des arguments du filtre.
Mot clé | Description | Version |
---|---|---|
sticky
|
Active ou désactive la politique de balance de charge "random once". Voir ci-dessus. |
Depuis 1.2.0. |
weight
|
Assigne une priorité/un poids de balance de charge à un serveur. Voir ci-dessus pour une description. |
Depuis 1.4.0. |
roundrobin
object
Lors de l'utilisation du filtre roundrobin
,
le plugin parcourt la liste des serveurs esclaves configurés pour
y sélectionner un serveur à utiliser pour l'exécution d'une requête.
Si le plugin atteint la fin de la liste, il se replace au début
et prend le premier serveur esclave configuré.
Exemple #19 Filtre roundrobin
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "filters": [ "roundrobin" ] } }
Attends un ou plusieurs serveurs en entrée. Sort un seul serveur.
Une séquence de filtres comme
roundrobin
, random
peut émettre
une alerte et un message d'erreur définis sur le gestionnaire de connexion
lors de l'exécution d'une requête.
Liste des arguments du filtre.
Mot clé | Description | Version |
---|---|---|
weight
|
Assigne une priorité/un poids à un serveur. Repportez-vous à la section ci-dessus pour plus de détails. |
Depuis 1.4.0. |
user
object
Le filtre user
remplace la fonction
mysqlnd_ms_set_user_pick_server(),
qui a été supprimée en version 1.1.0-beta. Le filtre définit une fonction
de rappel pour la séparation définie par l'utilisateur des lectures et des écritures
ainsi que la sélection de serveurs.
Le mécanisme interne du plugin de décisions de séparation des lectures
et des écritures peut être surchargé de deux façons. La façon la plus simple
est d'ajouter en début de requête l'astuce SQL MYSQLND_MS_MASTER_SWITCH
,
MYSQLND_MS_SLAVE_SWITCH
ou
MYSQLND_MS_LAST_USED_SWITCH
. L'utilisation des astuces SQL
permet de contrôler, par exemple, si une requête doit être envoyée au serveur maître
de réplication SQL ou à un des serveurs esclaves. Avec les astuces SQL,
il n'est pas possible de sélectionner un serveur esclave en particulier pour
l'exécution d'une requête.
Le contrôle total de la sélection des serveurs peut être atteint en utilisant une fonction de rappel. Son utilisation est recommandée aux utilisateurs experts uniquement, tout simplement par la fonction de rappel doit couvrir tous les cas que doit normalement gérer le plugin.
Le plugin invoquera la fonction de rappel pour la sélection d'un serveur depuis la liste des serveurs maîtres et esclaves configurés. La fonction de rappel inspecte la requête à exécuter, sélectionne un serveur pour son exécution en retourner l'URI de l'hôte, tel que trouvé dans la liste des serveurs maîtres et esclaves.
Si les connexions paresseuses sont actives et que la fonction de rappel choisit un serveur esclave dont aucune connexion n'a été établie, et que la connexion échoue, le plugin retournera une erreur lors de la prochaine action sur la connexion échouée, par exemple, lors de l'exécution d'une requête. Il en est de la responsabilité du développeur de l'application de gérer cette erreur. Par exemple, l'application peut ré-exécuter la requête pour lancer la sélection d'un nouveau serveur et invoquer à nouveau la fonction de rappel. Ainsi, la fonction de rappel doit s'assurer de sélectionner un serveur différent, ou de vérifier la disponibilité de l'esclave, avant de retourner au plugin et ce, afin de ne pas entrer dans une boucle infinie.
Exemple #20 Définition d'une fonction de rappel
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "filters": { "user": { "callback": "pick_server" } } } }
La fonction de rappel est supposée retourner un hôte sur lequel
la requête sera exécutée. L'URI de l'hôte doit être récupérée depuis
la liste des connexions aux serveurs maîtres et esclaves. Si la fonction
de rappel retourne une valeur ni trouvée dans la liste des connexions
aux serveurs maîtres, ni trouvée dans la liste des connexions esclaves,
le plugin émettra une erreur de type E_RECOVERABLE_ERROR
.
L'erreur sera quelque chose comme :
(mysqlnd_ms) User filter callback has returned an unknown server.
The server 'server that is not in master or slave list' can neither be found
in the master list nor in the slave list
.
Si l'application attrape l'erreur afin de l'ignirer, les erreurs suivantes
seront définies sur le gestionnaire de connexion, par exemple,
(mysqlnd_ms) No connection selected by the last filter
avec
le code erreur 2000
ainsi que le statut sql HY000
.
Et enfin, une alerte peut être émise.
Le fait de référencer une fonction inexistante comme fonction de rappel
résultera en une erreur de type E_RECOVERABLE_ERROR
lorsque le plugin tentera d'utiliser la fonction de rappel. Le message
d'erreur sera quelque chose comme :
(mysqlnd_ms) Specified callback (pick_server) is
not a valid callback
. Si l'application attrape l'erreur afin
de l'ignorer, les erreurs peuvent être définies sur le gestionnaire de connexion,
par exemple,
(mysqlnd_ms) Specified callback (pick_server) is
not a valid callback
avec le code erreur 2000
ainsi que le statut sql HY000
. De plus, une alerte sera émise.
Les paramètres suivants sont passés depuiq le plugin à la fonction de rappel.
Paramètre | Description | Version |
---|---|---|
connected_host
|
URI du serveur de base de données actuellement connecté. |
Depuis la version 1.1.0. |
query
|
La requête pour laquelle un serveur doit être sélectionné. |
Depuis la version 1.1.0. |
masters
|
Liste des serveurs maîtres depuis lequel le choix sera fait. Notez que la liste des serveurs maîtres peut ne pas être identiques à la liste des serveurs maîtres configurés, si le filte n'est pas le premier dans la chaîne des filtres. Les filtres précédemment configurés peuvent avoir réduit cette liste. |
Depuis la version 1.1.0. |
slaves
|
Liste des serveurs esclaves depuis lequel le choix sera fait. Notez que la liste des serveurs esclaves peut ne pas être identiques à la liste des serveurs esclaves configurés, si le filte n'est pas le premier dans la chaîne des filtres. Les filtres précédemment configurés peuvent avoir réduit cette liste. |
Depuis la version 1.1.0. |
last_used_connection
|
URI du serveur de la connexion utilisée pour exécuter la précédente requête. |
Depuis la version 1.1.0. |
in_transaction
|
Drapeau booléen indiquant si la requête fait partie d'une
transaction ouverte. Si le mode autocommit est désactivé,
il sera définit à
La détection de la transaction est basée sur la surveillance
de l'appel de |
Depuis la version 1.1.0. |
Exemple #21 Utilisation d'une fonction de rappel
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.2.27", "port": "3306" }, "slave_1": { "host": "192.168.78.136", "port": "3306" } }, "filters": { "user": { "callback": "pick_server" } } } }
<?php
function pick_server($connected, $query, $masters, $slaves, $last_used_connection, $in_transaction)
{
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'utilisation s'est connecté sur '%s'...\n", $connected);
printf("... décision du serveur pour exécuter '%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 = $masters[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 est uniquement sur le premier esclave configuré */
printf("... accès à la table disponible uniquement sur l'esclave A détectée\n");
$ret = $slaves[0];
}
else
{
/* round robin */
printf("... quelques requêtes en lecture seul 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_connection;
break;
}
printf("... ret = '%s'\n", $ret);
return $ret;
}
$mysqli = new mysqli("myapp", "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'utilisation s'est connecté sur 'myapp'... ... décision du serveur pour exécuter 'SELECT 1 FROM DUAL' ... quelques requêtes en lecture seul pour un esclave ... ret = 'tcp://192.168.2.27:3306' L'utilisation s'est connecté sur 'myapp'... ... décision du serveur pour exécuter 'SELECT 2 FROM DUAL' ... quelques requêtes en lecture seul pour un esclave ... ret = 'tcp://192.168.78.136:3306' L'utilisation s'est connecté sur 'myapp'... ... décision du serveur pour exécuter 'SELECT * FROM table_on_slave_a_only' ... accès à la table disponible uniquement sur l'esclave A détectée ... ret = 'tcp://192.168.2.27:3306'
user_multi
object
Le filtre user_multi
diffère du filtre
user
sur un seul aspect. Sinon, leur syntaxe est
identique. Le filtre user
doit prendre et retourner
exactement un noeud pour une exécution de requête. Un filtre
chaîné se termine habituellement avec un filtre qui émet seulement un
noeud. Le filtre chaîné doit réduire la liste des candidats pour exécution
de la requête à un seul résultat. Ainsi, un seul noeud reste après l'exécution
du filtre user
.
Le filtre user_multi
est un filtre multiple.
Il retourne une liste de serveurs esclaves et maîtres. Cette liste
doit ensuite être filtrée pour identifier exactement un noeud pour
l'exécution de la requête. Un filtre multiple est habituellement
placé au haut de la chaîne de filtrage. Le filtre quality_of_service
est un autre exemple d'un filtre multiple.
La valeur retournée par un fonction de rappel pour le filtre
user_multi
doit être un tableau contenant 2 éléments. Le
premier élément contient une liste de serveurs maîtres sélectionnés.
Le second élément contient une liste de serveurs maîtres sélectionnés.
Ces listes doivent contenir les clés des serveurs esclaves et maîtres telles
que trouvées dans les listes d'esclave et de maître passées à la fonction
de rappel. L'exemple ci-dessous retourne des listes aléatoires de serveurs
maîtres et esclaves extraites depuis les fonctions d'entrée.
Exemple #22 Retourne des esclaves et des maîtres aléatoirement
<?php
function pick_server($connected, $query, $masters, $slaves, $last_used_connection, $in_transaction)
{
$picked_masters = array()
foreach ($masters as $key => $value) {
if (mt_rand(0, 2) > 1)
$picked_masters[] = $key;
}
$picked_slaves = array()
foreach ($slaves as $key => $value) {
if (mt_rand(0, 2) > 1)
$picked_slaves[] = $key;
}
return array($picked_masters, $picked_slaves);
}
?>
Le plugin émettra une erreur de type E_RECOVERABLE
si
la fonction de rappel échoue à retourner une liste de serveurs.
L'erreur contiendra ceci : (mysqlnd_ms) User multi
filter callback has not returned a list of servers to use.
The callback must return an array in %s on line %d
.
Dans le cas où la liste de serveurs n'est pas vide mais contient
des identifiants/clés de serveurs invalides, une erreur de type
E_RECOVERABLE
sera émise avec un message d'erreur
du type : (mysqlnd_ms) User multi filter callback
has returned an invalid list of servers to use.
Server id is negative in %s on line %d
, ou similaire.
Une erreur est émise concernant une liste d'esclave ou de maître vide
suivant la configuration. Si une liste de maître vide est retournée
pour une opération en écriture, le plugin émettra une alerte dont le
message sera : (mysqlnd_ms) Couldn't find the appropriate
master connection. 0 masters to choose from. Something is wrong in %s on line %d
.
Typiquement, cette alerte sera suivit d'une erreur de type E_ERROR
.
Dans le cas d'une opération en lecture et une liste d'esclave vide, le comportement
dépendra de la configuration du fail over. Si le fail over du maître
est désactivé, le plugin émettra une alerte dont le message sera
(mysqlnd_ms) Couldn't find the appropriate slave connection.
0 slaves to choose from. Something is wrong in %s on line %d
.
node_groups
object
Le filtre node_groups
vous permet de grouper
les noeuds de cluster et requêter les groupes sélectionnés, par exemple,
pour supporter le partitionnement de données. Le partitionnement de données
peut être requis pour la fragmentation manuelle, la copie primaire basée
sur les clusters fonctionnant avec plusieurs maîtres, ou pour éviter les
points chauds lors des mises à jour sur les clusters dépourvus en interne
de partitionnement. Le filtre est un filtre multiple qui retourne zéro, un
ou plusieurs serveurs. Ainsi, il doit être suivi d'autres filtres pour réduire
le nombre de candidats à un seul, pour l'exécution de la requête.
Mot clé | Description | Version |
---|---|---|
user defined node group name
|
Un ou plusieurs groupes de noeuds doivent être définis.
Un groupe de noeuds peut avoir un nom arbitraire, défini par
l'utilisateur. Le nom est utilisé en combinaison d'une astuce SQL
pour restreindre l'exécution de la requête aux noeuds listés
par le groupe de noeuds. Pour exécuter une requête sur un des serveurs
d'un groupe de noeuds, la requête doit commencer avec l'astuce SQL
Chaque entré du groupe de noeuds doit contenir une liste de serveurs
La liste des serveurs maîtres et esclaves doit correspondre, respectivement,
aux entrées de la liste des serveurs
global master
et de slave.
Le fait de référencer un serveur inconnu d'une de ces listes va émettre une
erreur de type
Exemple #23 Partitionnement manuel { "myapp": { "master": { "master_0": { "host": "localhost", "socket": "\/tmp\/mysql.sock" } }, "slave": { "slave_0": { "host": "192.168.2.28", "port": 3306 }, "slave_1": { "host": "127.0.0.1", "port": 3311 } }, "filters": { "node_groups": { "Partition_A" : { "master": ["master_0"], "slave": ["slave_0"] } }, "roundrobin": [] } } }
Veuillez noter que si un filtre chaîné génère une liste d'esclave
vide, et que la directive de configuration PHP
|
Depuis 1.5.0. |
quality_of_service
object
Le filtre quality_of_service
identifie les noeuds du cluster
capable de délivrer une certaine qualité de service. C'est un filtre multiple
qui retourne zéro, un ou plusieurs serveurs d'entrées. Aussi, Il doit être
suivi par d'autres filtres pour réduire le nombre de candidats à un seul pour
l'exécution de la requête.
Le filtre quality_of_service
a été introduit en version
1.2.0-alpha. Dans les séries 1.2, le but de ces filtres était sur l'aspect
de la qualité du service. Différents types de clusters offrent des
consistences de données par défaut différentes. Par exemple, un serveur esclave
de réplication MySQL asynchrones offre éventuellement une consistence.
L'esclave ne devrait pas être capable de délivrer les données demandées
car il n'a pas répliqué l'écriture, il peut délivrer une base de données non à jour
en raison des lags, ou bien des données à jour. Souvent, c'est acceptable.
Dans quelques cas, des niveaux de consistence élevés sont nécessaire pour
que l'application fonctionne correctement. Dans ces cas là, le filtre
quality_of_service
peut filtrer les noeuds du cluster
ne pouvant pas délivrer la qualité de service nécessaire.
Le filtre quality_of_service
peut être remplacé ou créé
au moment de l'exécution. Un appel réussi à la fonction
mysqlnd_ms_set_qos() supprime toutes les entrées pour le filtre
qos
depuis la liste des filtres, et en installe un nouveau
au tout début. Toutes les configurations peuvant être effectuées via la fonction
mysqlnd_ms_set_qos() peuvent aussi être faîtes au
niveau du fichier de configuration. Cependant, l'utilisation de la fonction
est générallement privilégiée dans ce cas. Au lieu de configurer la consistence
de la session ainsi que les niveaux hauts de consistence du service dans le fichier
de configuration du plugin, il est recommandé de définir uniquement des maîtres,
et aucun esclave. Les niveaux du service forceront l'utilisation des maîtres uniquement.
L'utilisation d'une liste d'esclave vide allège le fichier de configuration et ainsi,
en améliore la lisibilité. Le seul niveau de service pour lequel il convient
d'utiliser le fichier de configuration est la combinaison d'une consistence éventuelle
et d'un maximum d'esclaves.
Mot clé | Description | Version |
---|---|---|
eventual_consistency
|
Demande une consistence éventuelle. Autorise l'utilisation de tous les serveurs maîtres et de tous les serveurs esclaves. Les données retournées peuvent (ou pas) être des données à jour.
La consistence éventuelle accepte un paramètre optionnel
Veuillez noter que si une chaîne de filtres génère une liste vide
d'esclave, et que la directive de configuration PHP
Exemple #24 Limitation globale du lag d'un esclave { "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.2.27", "port": "3306" }, "slave_1": { "host": "192.168.78.136", "port": "3306" } }, "filters": { "quality_of_service": { "eventual_consistency": { "age":123 } } } } } |
Depuis 1.2.0. |
session_consistency
|
Demande une consistence de session (lecture de vos écritures).
Autorise l'utilisation de tous les maîtres
et de tous les esclaves qui sont synchronisés avec le maître.
Si aucun paramètre supplémentaire n'est fourni, les esclaves
filtrés seront ceux pour lesquels il n'a pas été possible
de tester leur consistence ou bien parce qu'ils lagguent.
Notez que si un chaîne de filtres génère une liste d'esclave
vide, et que la directive de configuration PHP
Les demandes temporaires de consistence de session utilisant la fonction
mysqlnd_ms_set_qos() est une alternative à l'utilisation
de |
Depuis 1.1.0. |
strong_consistency
|
Demande une consistence forte. Seuls les maîtres seront utilisés. |
Depuis 1.2.0. |
failover
A partir de 1.3.x : string.
Depuis 1.4.0 : object.
Politique de basculement. Politiques supportées :
disabled
(défaut), master
,
loop_before_master
(depuis 1.4.0).
Si aucune politique de basculement n'est définie, le plugin
ne procèdera à aucun basculement automatique
(failover=disabled
). À chaque fois que le
plugin échoue lors de la connexion à un serveur, il émettra
une alerte et définira le code et le message d'erreur sur la
connexion. Par la suite, c'est à l'application de gérer l'erreur
et, par exemple, relancera la dernière requête afin de
déclencher la sélection d'un autre serveur.
A noter : la logique de basculement automatique est appliqué seulement lors de l'ouverture des connexions. Une fois la connexion ouverte, aucune tentative automatique n'est effectuée pour la ré-ouvrir lorsqu'une erreur survient. Si, par exemple, la connexion vers le serveur est fermée, et que l'utilisateur tente d'y exécuter une requête, aucun basculement automatique ne sera tenté. En lieu et place, une erreur sera rapportée.
Lors de l'utilisation de failover=master
,
le plugin basculera implicitement vers un maître, si disponible.
Reportez-vous à la documentation de ce concept pour en apprendre
plus sur les risques de l'utilisation de failover=master
.
Exemple #25 Basculement optionnel vers un maître lors d'un échec de connexion sur un esclave (PECL/mysqlnd_ms < 1.4.0)
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "failover": "master" } }
Depuis PECL/mysqlnd_ms 1.4.0, le mot clé de configuration du basculement se réfère à un objet.
Exemple #26 Nouvelle syntaxe depuis 1.4.0
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "failover": {"strategy": "master" } } }
Mot clé | Description | Version |
---|---|---|
strategy
|
Politique de basculement. Les valeurs possibles sont :
Une valeur à
Le fait de définir le
Lors de l'utilisation de |
Depuis 1.4.0. |
remember_failed
|
Se souvenir des échecs pendant la durée d'une requête web.
Par défaut, vaut
Si défini à |
Depuis 1.4.0. Cette fonctionnalité n'est disponible qu'avec les filtres
random et roundrobin de balance de charge.
L'utilisation de cette fonctionnalité est recommandée.
|
max_retries
|
Nombre maximal de tentative de reconnexion avant d'écarter un hôte.
Défaut :
Cette configuration est utilisée pour éviter qu'un hôte
soit écarté de la liste des hôtes dès le premier échec.
Si défini à |
Depuis 1.4.0. Cette fonctionnalité n'est disponible qu'avec les filtres
random et roundrobin de balance de charge.
|
Le fait de définir failover
à une valeur
autre que disabled
, master
ou loop_before_master
n'émettra aucune alerte ni erreur.
lazy_connections
bool
Contrôle l'utilisation des connexions paresseuses. Les connexions paresseuses sont des connexions qui ne sont pas ouvertes tant que le client n'envoie pas la première connexion. Les connexions paresseuses sont activées par défaut.
Il est vivement recommandé d'utiliser les connexions paresseuses. Elles vous aident à conserver un nombre très faible de connexions ouvertes. Si vous les désactivez, et, par exemple, vous configurez un serveur MySQL maître de réplication et 2 serveurs MySQL esclaves de réplication, le plugin ouvrira trois connexions lors du premier appel à la fonction de connexion, malgré le fait que l'application n'utilise que la connexion maître.
Les connexions paresseuses représentent un risque si vous réalisez des actions qui changent le statut d'une connexion. Le plugin ne répercutera pas toutes les actions de modification du statut à toutes les connexions de la pile de connexions. Les actions répercutées seront appliquées seulement à toutes les connexions ouvertes. Les connexions paresseuses ouvertes dans le futur ne seront pas affectées. Seules quelques configurations seront "retenues" et appliquées lorsqu'une connexion paresseuse sera ouverte.
Exemple #27 Désactivation des connexions paresseuses
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "lazy_connections": 0 } }
Voir aussi server_charset
afin de prévenir
de possibles problèmes avec les chaînes échappées et des
serveurs utilisant des jeux de caractères différents.
server_charset
string
Ce paramètre a été introduit en 1.4.0. Il est recommandé de le définir lors de l'utilisation des connexions paresseuses.
L'option server_charset
a deux buts. Il agit comme
un jeu de caractères de secours à utiliser lors de l'échappement des chaînes
avant qu'une connexion ne soit établie, et il aide à éviter les erreurs
lors de l'échappement en environnements hétérogènes avec des serveurs
utilisant des jeux de caractères différents.
L'échappement des chaînes prend en compte le jeu de caractères de la connexion. L'échappement des chaînes n'est pas possible avant qu'une connexion ne soit ouverte, et que le jeu de caractères de la connexion ne soit connu. L'utilisation des connexions paresseuses retarde l'ouverture de la connexion, attendant qu'une requête ne soit envoyée.
Une application utilisant les connexions paresseuses peut tenter d'échapper
une chaîne avant d'envoyer une requête. En fait, c'est un cas commun
sachant que la chaîne de requête peut contenir la chaîne à échapper.
Cependant, en raison de l'utilisation des connexions paresseuses, aucune
connexion n'a été ouverte et l'échappement échoue. Le plugin peut rapporter
une erreur de type E_WARNING
ainsi qu'un message
de ce type : (mysqlnd_ms) string escaping doesn't work without established connection.
Possible solution is to add server_charset to your configuration
afin de vous informer de cet échec.
Le fait de définir server_charset
fera que le plugin
utilisera le jeu de caractères fourni lors de l'échappement des chaînes
effectué sur des connexions paresseuses avant d'établir une connexion réseau
vers MySQL. De plus, le plugin va forcer l'utilisation de ce jeu de caractères
lorsque la connexion est établie.
Le forcage de l'utilisation du jeu de caractères configuré pour l'échappement est réalisé pour éviter d'avoir des erreurs en utilisant un jeu de caractères pour l'échappement différent de celui utilisé ensuite pour la connexion. Cela apporte également l'avantage de ne pas avoir à aligner la configuration du jeu de caractères pour tous les serveurs utilisés. Inutile de savoir le jeu de caractères par défaut des serveurs, le plugin définiera celui configuré par défaut.
Le plugin n'empêchera pas l'utilisateur de changer le jeu de caractères
à tout moment, en utilisant la fonction set_charset()
ou une requête SQL équivalente. Veuillez noter que l'utilisation de SQL n'est
pas recommandé car il ne pourra pas être surveiller par le plugin.
L'utilisateur peut, par exemple, modifier le jeu de caractères sur un
gestionnaire de connexions paresseuses après l'échappement d'une chaîne et
avant que la connexion actuelle ne soit ouverte. Le jeu de caractères définit
par l'utilisateur sera utilisé pour tous les échappements avant que la
connexion ne soit établie. La connexion sera établie en utilisant le jeu
de caractères configuré, peu importe le jeu de caractères du serveur, et
peu importe le jeu de caractères défini par l'utilisateur auparavant. Une
fois une connexion ouverte, set_charset
n'a plus de sens.
Exemple #28 Echappement d'une chaîne sur une connexion paresseuse
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "lazy_connections": 1, "server_charset" : "utf8mb4" } }
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
$mysqli->real_escape("this will be escaped using the server_charset setting - utf8mb4");
$mysqli->set_charset("latin1");
$mysqli->real_escape("this will be escaped using latin1");
/* server_charset définit implicitement une connexion utf8mb4 */
$mysqli->query("SELECT 'This connection will be set to server_charset upon establishing' AS _msg FROM DUAL");
/* latin1 sera maintenant utilisé */
$mysqli->set_charset("latin1");
?>
master_on_write
bool
Si définit, le plugin utilisera le serveur maître uniquement après que la première requête ait été exécutée sur le maître. Les applications peuvent toujours envoyer les requêtes aux esclaves en utilisant les astuces SQL pour écraser la décision automatique.
Cette configuration permet de corriger le lag dans la réplication.
Si une application exécute une requête INSERT
,
le plugin utilisera, par défaut, le maître pour exécuter les requêtes suivantes,
y compris les requêtes SELECT
.
Ceci permet d'éviter les problèmes de lecture depuis les esclaves
qui n'ont pas encore répliqués les requêtes
INSERT
.
Exemple #29 Utilisation du maître lors d'une écriture pour consolider les lectures
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "master_on_write": 1 } }
Veuillez noter que le filtre quality_of_service
a été introduit en version 1.2.0-alpha. Il fournit un contrôle plus
fin, par exemple, pour effectuer une lecture de vos écritures, et,
il offre des fonctionnalités supplémentaires en introduisant les
niveaux de service.
Toutes les configurations de
transaction rigide,
incluant trx_stickiness=on
, seront écrasées par
master_on_write=1
.
trx_stickiness
string
Politique des transactions colantes. Les politiques supportées
sont disabled
(défaut), master
.
Cette configuration nécessite PHP 5.4.0 ou supérieure. Si utilisée sur
des versions de PHP plus anciennes, le plugin émettra une alerte de type
(mysqlnd_ms) trx_stickiness strategy is not supported before PHP 5.3.99
.
Si aucune politique de transaction colante n'est défini, ou bien si la
configuration trx_stickiness=disabled
est utilisée,
le plugin ne tiendra pas compte des transactions. Ainsi, le plugin
peut effectuer un balance de charge des connexions, et changer de connexions
en plein milieu d'une transaction. Le plugin n'est ainsi pas sécurisé sur
les transactions. Les astuces SQL peuvent être utilisées pour empécher les
changements de connexions durant une transaction.
Depuis PHP 5.4.0, la bibliothèque mysqlnd autorise le plugin à surveiller
la définition du mode autocommit
par appel à la fonction
set_autocommit()
de la bibliothèque.
Si set_stickiness=master
et
autocommit
a été désactivé par une extension PHP MySQL
en invoquant la fonction set_autocommit()
de la bibliothèque
interne mysqlnd
, le plugin tiendra compte d'un début de transaction.
Ainsi, le plugin arrêtera les balances de charge et dirigera toutes les requêtes
vers le maître tant que autocommit
est actif.
Dans ce cas, aucune astuce SQL n'est nécessaire.
Un exemple de fonction de l'API PHP MySQL appelant la fonction interne
set_autocommit()
de la bibliothèque mysqlnd
est la fonction mysqli_autocommit().
Malgré la configuration trx_stickiness=master
, le plugin
ne tiendra pas compte d'une modification du mode autocommit
réalisée par une requête SQL comme SET AUTOCOMMIT=0
ou
BEGIN
.
Depuis PHP 5.5.0, de nouvelles fonctionnalités de la bibliothèque mysqlnd permettent
de contrôler les transactions. Le niveau de contrôle correspond à celui fourni
par la requête SQL. L'API mysqli
a été modifiée pour utiliser
ces appels. Depuis la version 1.5.0, PECL/mysqlnd_ms peut surveiller non seulement
mysqli_autocommit() mais aussi mysqli_begin(),
mysqli_commit() et mysqli_rollback() pour
détecter les limites de la transaction et arrêter la balance de charge
durant une transaction.
Exemple #30 Utilisation du maître pour l'exécution des transactions
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "trx_stickiness": "master" } }
Depuis la version 1.5.0, le failover automatique ou silencieux est
désactivé pour la durée d'une transaction. Si les limites d'une
transaction ont été détectées proprement, la rigidité de la transaction
est activé et un serveur échoue, alors le plugin ne va pas tenter
d'utiliser le prochain serveur, s'il existe, suivant la politique
de failover configurée. L'utilisation doit gérer cette erreur manuellement.
Suivant la configuration, le plugin peut émettre une erreur de type
E_WARNING
comme celle-ci
(mysqlnd_ms) Automatic failover is not permitted in the middle of a transaction
.
Cette erreur peut ensuite être écrasée par un suivi des erreurs comme
(mysqlnd_ms) No connection selected by the last filter
.
Ces erreurs seront générées par la fonction exécutant la requête qui a échouée.
Exemple #31 Aucun failover automatique, utilisation d'un gestionnaire d'erreurs
<?php
/* On suppose que le failover automatique est configuré */
$mysqli = new mysqli("myapp", "username", "password", "database");
/* Défini le statut interne du plugin à in_trx = 1 */
$mysqli->autocommit(false);
/* On suppose que le serveur échoue */
if (!($res = $mysqli->query("SELECT 'Assume this query fails' AS _msg FROM DUAL"))) {
/* Gestion de l'échec de la transaction, le statut interne du plugin est toujours in_trx = 1 */
printf("[%d] %s", $mysqli->errno, $mysqli->error);
/*
Si vous utilisez l'autocommit() pour les transactions, il est préférable
de l'appeler comme ceci : autocommit(true). Sinon, le plugin pensera
que la transaction courante continue, et ainsi, toute modification
de connexion sera interdite.
*/
$mysqli->autocommit(true);
/* De plus, vous pouvez vouloir démarrer une nouvelle transaction */
$mysqli->autocommit(false);
}
/* Maintenant, utilisation du latin1 */
$mysqli->set_charset("latin1");
?>
Si un serveur échoue au milieu d'une transaction, le plugin continue à refuser le changement de connexions tant que la transaction courante n'est pas terminée. Souvenez-vous que le plugin surveille les appels API pour détecter les limites de la transaction. Aussi, vous devez, par exemple, activer le mode autocommit pour finir la transaction courante avant que le plugin ne continue à faire du balance de charge et ainsi, ne change de serveur. De plus, vous voudriez vouloir démarrer une nouvelle transaction immédiatement après, et désactiver l'autocommit.
Le fait de ne pas gérer les requêtes qui échouent, et de ne pas terminer
une transaction en échec utilisant des appels API, peuvent causer des
erreurs de ce type : Commands out of sync; you can't run this command now
.
Aussi, il est important de gérer toutes les erreurs.
transient_error
object
Cette option a été introduite en version 1.6.0.
Un noeud de cluster de bases de données peut émettre une erreur passagère au client. Le client peut alors répéter l'opération sur le même noeud, peut changer de noeud, ou peut annuler l'opération. Par définition, il est résonnable pour un client de re-tenter la même opération sur le même noeud avant de continuer.
PECL/mysqlnd_ms
peut entrer dans une boucle de tentatives
à la place de l'application. En configuration l'option
transient_error
, le plugin peut répéter l'opération
ayant échouée avec un code erreur spécifique pendant un certain nombre
de fois, avec une pause entre chaque tentative. Si l'erreur passagère
disparaît pendant l'exécution de la boucle, elle ne sera pas vue
de l'application. Sinon, l'erreur sera transmise à l'application à la
fin de la boucle.
Exemple #32 Boucle de tentative pour les erreurs passagères
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "transient_error": { "mysql_error_codes": [ 1297 ], "max_retries": 2, "usleep_retry": 100 } } }
Clé | Description | Version |
---|---|---|
mysql_error_codes
|
Liste des codes erreurs passagères. Vous pouvez y inclure
n'importe quel code erreur MySQL. Il est possible de considérer
n'importe quelle erreur comme passagère, et pas seulement
l'erreur |
Depuis 1.6.0. |
max_retries
|
Le nombre de tentatives d'une opération échouant avec une erreur passagère avant d'envoyer l'erreur à l'utilisateur.
Par défaut : |
Depuis 1.6.0. |
usleep_retry
|
Durée en millisecondes d'attente entre deux tentatives. La valeur est passée à la fonction C usleep().
Par défaut : |
Depuis 1.6.0. |
xa
object
Cette option a été introduite en 1.6.0.
Note: Expérimental
Cette fonctionnalité est actuellement en cours de développement. Il peut y avoir des bogues ou des limitations dans la fonctionnalité. Ne pas utiliser en environnement de production.
Si l'on doit stocker le nom d'utilisateur et le mot de passe d'un participant à une transaction globale dans la table des participants. Si désactivé, la collection des données incorrectes va utiliser le nom d'utilisateur et le mot de passe par défaut lors de la connexion aux participants. Tant que vous n'utilisez pas de nom d'utilisateur et de mot de passe différents pour chaque serveur MySQL, vous pouvez utiliser la configuration par défaut, faisant ainsi que vous ne stockerez pas d'informations sensibles dans le stockage de statut.
Veuillez noter que le nom d'utilisateur et le mot de passe sont stockés en clear lors de l'utilisation du stockage de statut MySQL, qui est le seul moyen de stockage actuellement. Il en est de votre responsabilité de protéger cette information sensible.
Par défaut : false
Durant la collection des données incorrectes XA, le plugin peut trouver
un serveur participant avec l'hôte localhost
enregistré.
Si la collection de données incorrectes prend place sur un autre hôte
que celui enregistré pour le participant, alors le nom d'hôte
localhost
doit résoudre un hôte différent. Toutefois,
lors de l'enregistrement de nom d'hôte de serveur participant dans le
stockage de statut, au lieu d'utiliser la valeur localhost
,
vous pouvez utiliser l'adresse IP actuelle de localhost
.
La définition de participant_localhost_ip
ne doit être
considérée que si localhost
ne peut être utilisé.
D'un point de vue de la collection des données incorrectes uniquement,
il est préférable de ne pas configurer de socket de connexion mais plutôt
de fournir un adresse IP et un port pour un noeud.
Le stockage de statut MySQL est le seul stockage de statut disponible.
Nom de la table MySQL utilisé pour stocker le statut d'une transaction globale entrant ou stoppée. Utilisez la requête SQL ci-dessous pour créer la table. Assurez-vous d'éditer le nom de la table pour la faire correspondre à votre configuration.
Par défaut : mysqlnd_ms_xa_trx
Exemple #33 Définition SQL pour la table de stockage MySQL de statut des transactions
CREATE TABLE mysqlnd_ms_xa_trx ( store_trx_id int(11) NOT NULL AUTO_INCREMENT, gtrid int(11) NOT NULL, format_id int(10) unsigned NOT NULL DEFAULT '1', state enum('XA_NON_EXISTING','XA_ACTIVE','XA_IDLE','XA_PREPARED','XA_COMMIT','XA_ROLLBACK') NOT NULL DEFAULT 'XA_NON_EXISTING', intend enum('XA_NON_EXISTING','XA_ACTIVE','XA_IDLE','XA_PREPARED','XA_COMMIT','XA_ROLLBACK') DEFAULT 'XA_NON_EXISTING', finished enum('NO','SUCCESS','FAILURE') NOT NULL DEFAULT 'NO', modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, started datetime DEFAULT NULL, timeout datetime DEFAULT NULL, PRIMARY KEY (store_trx_id), KEY idx_xa_id (gtrid,format_id,finished), KEY idx_state (state) ) ENGINE=InnoDB
Nom de la table MySQL utilisé pour stocker les participants à une transaction globale entrante ou stoppée. Utilisez la requête SQL ci-dessous pour créer la table. Assurez-vous d'éditer le nom de la table pour la faire correspondre à votre configuration.
Le stockage des informations de connexion peut être activé ou désactivé
en utilisant record_participant_credentials
Par défaut : mysqlnd_ms_xa_participants
Exemple #34 Définition SQL de la table de stockage MySQL de statut des transactions
CREATE TABLE mysqlnd_ms_xa_participants ( fk_store_trx_id int(11) NOT NULL, bqual varbinary(64) NOT NULL DEFAULT '', participant_id int(10) unsigned NOT NULL AUTO_INCREMENT, server_uuid varchar(127) DEFAULT NULL, scheme varchar(1024) NOT NULL, host varchar(127) DEFAULT NULL, port smallint(5) unsigned DEFAULT NULL, socket varchar(127) DEFAULT NULL, user varchar(127) DEFAULT NULL, password varchar(127) DEFAULT NULL, state enum('XA_NON_EXISTING','XA_ACTIVE','XA_IDLE','XA_PREPARED','XA_COMMIT','XA_ROLLBACK') NOT NULL DEFAULT 'XA_NON_EXISTING', health enum('OK','GC_DONE','CLIENT ERROR','SERVER ERROR') NOT NULL DEFAULT 'OK', connection_id int(10) unsigned DEFAULT NULL, client_errno smallint(5) unsigned DEFAULT NULL, client_error varchar(1024) DEFAULT NULL, modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (participant_id), KEY idx_xa_bqual (bqual), KEY idx_store_trx (fk_store_trx_id), CONSTRAINT mysqlnd_ms_xa_participants_ibfk_1 FOREIGN KEY (fk_store_trx_id) REFERENCES mysqlnd_ms_xa_trx (store_trx_id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB
Nom de la table MySQL utilisé pour surveiller et synchroniser les exécutions de la collection des données incorrectes. Utilisez la requête SQL ci-dessous pour créer la table. Assurez-vous d'éditer le nom de la table pour la faire correspondre à votre configuration.
Par défaut : mysqlnd_ms_xa_gc
Exemple #35 Définition SQL pour la table MySQL de stockage de statut de la collection des données incorrectes
CREATE TABLE mysqlnd_ms_xa_gc ( gc_id int(10) unsigned NOT NULL AUTO_INCREMENT, gtrid int(11) NOT NULL, format_id int(10) unsigned NOT NULL DEFAULT '1', fk_store_trx_id int(11) DEFAULT NULL, modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, attempts smallint(5) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (gc_id), KEY idx_store_trx (gtrid,format_id,fk_store_trx_id) ) ENGINE=InnoDB
Nom d'hôte du serveur MySQL.
Nom de l'utilisateur à utiliser pour la connexion au serveur MySQL.
Mot de passe à utiliser pour le serveur MySQL.
Base de données qui contiendra les tables de collection des données incorrectes. Notez que vous devez d'abord créer les tables avant d'utiliser le plugin. Les tables ne seront pas créées pendant l'exécution et la collection des données incorrectes va échouer si les tables n'existent pas.
Port du serveur MySQL.
Socket de domaine Unix pour le serveur MySQL. Notez que si vous avez plusieurs serveurs PHP, chacun d'eux va tenter de s'occuper de la collection des données incorrectes, et doit pouvoir se connecter au stockage de statut. Dans ce cas, vous devriez configurer l'adresse IP et le port pour le serveur de stockage de statut MySQL pour vous assurer que tous les serveurs PHP arrivent à le trouver.
Si l'on doit automatiquement annuler une transaction globale ouverte lorsqu'une connexion se ferme. Si actif, le comportement par défaut des transactions locales sera imité. Si un client se déconnecte, le serveur annulera toute transaction ouverte et non terminée.
Par défaut : true
Nombre maximal de collection de données incorrectes à tenter.
Les valeurs autorisées vont de 0
à 100
.
Une configuration à 0
signifie aucune limite,
tant que le stockage de statut ne force une limite. Si le stockage
de statut force une limite, on peut supposer que ce sera une valeur
supérieure à 100
. Disponible depuis 1.6.0.
Veuillez noter qu'il est très important de terminer les transactions XA en échec dans un délai raisonnable afin de permettre aux serveurs participants de libérer les ressources associées à la transaction. Le collecteur de données incorrectes embarqué n'est pas prévu pour être en échec pendant une longue période, au moins tant que les serveurs en échec redeviennent disponibles. Aussi, il peut arriver dans quelques situations qu'une action humaine soit nécessaire à cause du fait que le collecteur de données incorrectes soit stoppé ou en échec. Dans ce cas, vous devriez vouloir d'abord vérifier si la transaction ne peut pas être réparée en forçant la fonction mysqlnd_ms_xa_gc() à ignorer cette configuration, avant de gérer le problème manuellement.
Par défaut : 5
Probabiblité de la collecte des données incorrectes.
Les valeurs autorisées sont dans l'intervalle
0
à 1000
.
Une valeur de 0
désactive la collecte des
données incorrectes en arrière-plan. Malgré une valeur de
0
, il est toujours possible de lancer une
collecte de données incorrectes en appelant la fonction
mysqlnd_ms_gc(). Disponible depuis la
version 1.6.0.
La collection automatique de données incorrectes d'une transaction XA dans un statut incorrect est uniquement disponible si un stockage de statut a été configuré. Suivant ces enregistrements, il peut trouver des transactions XA bloquées où le client est en erreur, se connecter aux participants, et annuler les transactions non terminées.
La collecte des données incorrectes est lancée comme étant une partie
d'une demande de procédure d'arrêt PHP à la fin d'une requête web.
Suivant le moment où on décide de lancer la collecte des données incorrectes,
une valeur aléatoire entre 0
et 1000
est calculée. Si la valeur probability
est supérieure
ou égale à la valeur aléatoire, les routines du stockage de statut
du collecteur de données incorrectes sont appelées..
Par défaut : 5
Nombre maximal de transactions XA non terminées considérées
par la collecte des données incorrectes pendant une exécution.
Les valeurs autorisées doivent être dans l'intervalle
1
à 32768
. Disponible depuis
la version 1.6.0.
Le nettoyage d'une transaction XA non terminée prend beaucoup de temps et de ressource. La routine de collecte des données incorrectes doit se connecter à plusieurs participants d'une transaction globale en échec pour y émettre des commandes SQL pour annuler la transaction non terminée.
Par défaut : 100
Note:
La description suivante s'applique à PECL/mysqlnd_ms < 1.1.0-beta. Elle n'est pas valide pour les versions supérieures.
Le plugin utilise son propre fichier de configuration. Ce fichier contient les informations sur les serveurs maîtres de réplication MySQL, les serveurs esclaves de réplication MySQL, la politique de sélection de serveur (balance de charge), la stratégie de basculement ainsi que l'utilisation des connexions paresseuses.
La directive de configuration PHP
mysqlnd_ms.ini_file
est utilisée pou définir le fichier de configuration du plugin.
Le fichier de configuration reprend le standard du format php.ini
.
Il contient un ou plusieurs sections. Chaque section définit sa propre unité
de configuration. Il n'y a pas de section globale pour la configuration
par défaut.
Les applications se réfèrent aux sections par leurs noms. Les applications utilisent les noms de section comme paramètre de l'hôte (serveur) dans les différentes méthodes de connexion des extensions comme mysqli, mysql et PDO_MYSQL. Lors de la connexion, le plugin mysqlnd compare le nom de l'hôte avec tous les noms de section depuis le fichier de configuration du plugin. Si le nom d'hôte et le nom de section correspondent, le plugin chargera la configuration depuis cette section.
Exemple #36 Exemple d'utilisation des noms de section
[myapp] master[] = localhost slave[] = 192.168.2.27 slave[] = 192.168.2.28:3306 [localhost] master[] = localhost:/tmp/mysql/mysql.sock slave[] = 192.168.3.24:3305 slave[] = 192.168.3.65:3309
<?php
/* Toutes les sections suivantes seront soumises à la balance de charge */
$mysqli = new mysqli("myapp", "username", "password", "database");
$pdo = new PDO('mysql:host=myapp;dbname=database', 'username', 'password');
$mysql = mysql_connect("myapp", "username", "password");
$mysqli = new mysqli("localhost", "username", "password", "database");
?>
Les noms de section sont des chaînes de caractères. Il est valide d'utiliser
un nom de section comme
192.168.2.1
, 127.0.0.1
ou
localhost
. Si, par exemple, une application se
connecte à localhost
et une section de configuration
du plugin [localhost]
existe, la sémantique de l'opération
de connexion change. L'application n'utilisera plus seulement le serveur MySQL
fonctionnant sur l'hôte localhost
, mais le plugin
commencera à balancer la charge des requêtes MySQL en suivant les règles
depuis la section de configuration [localhost]
.
De cette façon, vous pouvez effectuer un balance de charge depuis une
application sans aucune modification du code source de l'application.
Les directives de configuration master[]
, slave[]
et pick[]
utilisent une syntaxe sous forme de liste.
Ces directives peuvent apparaître à plusieurs reprises dans une section de configuration.
Le plugin maintient l'ordre dans laquelle les entrées apparaîssent au moment
de leurs interprétations. Par exemple, l'exemple ci-dessous montre
les directives de configuration pour 2 slave[]
dans la
section de configuration [myapp]
. Si vous utilisez la balance
de charge round-robin pour les requêtes en lecture seule, le plugin enverra
la premère requête en lecture seule au serveur MySQLL
mysql_slave_1
parce qu'il est premier dans la liste.
La seconde requête en lecture seule sera envoyée au serveur MySQL
mysql_slave_2
parce qu'il est second sur la liste.
Les directives de configuration supportant la syntaxe sous forme de liste
sont ordonnées depuis le haut vers le bas, dans l'ordre de leurs apparissions
dans la section de configuration.
Exemple #37 Syntaxe sous forme de liste
[myapp] master[] = mysql_master_server slave[] = mysql_slave_1 slave[] = mysql_slave_2
Voici une explication brève sur les directives de configuration pouvant être utilisées.
master[]
string
URI d'un serveur de réplication MySQL maitres. L'URI est de la forme
hostname[:port|unix_domain_socket]
.
Le plugin ne supporte que l'utilisation d'un seul maitre à la fois.
Déclarer un maitre est obligatoire. Le plugin renverra une alerte à la connexion
si il ne trouve pas de maitre dans la configuration.
Ce message d'alerte peut ressembler à
(mysqlnd_ms) Cannot find master section in config
.
Aussi, le plugin renseignera sur un code d'erreur pour la connexion
HY000/2000 (CR_UNKNOWN_ERROR)
. Le message dépend de la langue
considérée.
slave[]
string
URI d'un ou plusieurs serveurs de réplication MySQL esclaves. L'URI est de la forme
hostname[:port|unix_domain_socket]
.
Le plugin supporte l'utilisation d'un ou plusieurs esclaves.
Déclarer au moins un esclave est obligatoire. Le plugin renverra une alerte à la connexion
s'il ne trouve pas au moins un esclave dans la configuration.
Ce message d'alerte peut ressembler à
(mysqlnd_ms) Cannot find slaves section in config
.
Aussi, le plugin renseignera sur un code d'erreur pour la connexion
HY000/2000 (CR_UNKNOWN_ERROR)
.Le message dépend de la langue
considérée.
pick[]
string
Politique de balance de charge (choix du serveur). Sont supportées :
random
, random_once
(defaut),
roundrobin
, user
.
Si aucune politique n'est précisée, random_once
sera utilisée.
La politique random_once
choisit un serveur esclave au hasard
lors de la première requête en lecture. Le serveur esclave sera alors utilisé pour toutes
les requêtes en lecture jusqu'à l'extinction de PHP.
La politique random
choisira un serveur esclave au hasard pour chaque
requête de lecture.
Avec roundrobin
le plugin parcourt la liste des esclaves déclarés
et les choisit un-à-un pour chaque requête. Si le plugin atteint la fin de la liste,
il prendra le premier serveur esclave configuré.
Utiliser plus d'une politique d'équilibrage par section de configuration n'est effectif
qu'avec la politique user
et avec mysqlnd_ms_set_user_pick_server(). Si la fonction utilisateur
échoue à la selection d'un serveur, le plugin se rabat sur le second choix de politique
d'équilibrage.
failover
string
Politique de gestion des incidents (failover). Sont supportées :
disabled
(défaut), master
.
Si aucune politique de gestion d'incident (failover) n'est utilisée, le plugin n'effectuera
aucun failover automatique (failover=disabled
). Dès lors que le plugin échoue
à la connexion sur un serveur, il émet un warning et change le code d'erreur et le message
d'erreur de la connexion. Après, c'est à l'application de gérer l'erreur et d'éventuellement
relancer la requête pour déclencher la selection d'un autre serveur.
Si vous utilisez failover=master
, le plugin changera vers un
esclave automatiquement en failover, si possible. Veuillez lire la documentation dans le cas
de l'utilisation de failover=master
, cela comporte des risques à connaitre.
lazy_connections
bool
Utilise ou non des connexions paresseuses. Ce sont des connexions qui ne sont pas établies tant que le client n'envoie pas d'informations vers celle-ci.
Il est fortement recommandé d'utiliser les connexions paresseuses, car elles aident à réduire le nombre de connexions simultanées ouvertes. Si vous les désactivez, et que par exemple, vous configurez un maitre de réplication et deux esclaves, le plugin ouvrira alors 3 connexions dès le premier appel alors que l'application pourrait ne vouloir utiliser que le maitre.
Les connexions parresseuses représentent par contre un problème si vous changez souvent le statut de vos connexions. En effet, le plugin ne fait suivre les ordres de changement de statut qu'aux connexions effectivement déja ouvertes, et non à celles qui sont configurées, mais pas encore ouvertes. Par exemple, si le jeu de caractères devait être changé en utilisant un appel PHP vers l'API MySQL, le plugin ne changera que pour les connexions ouvertes. Il ne se souviendra pas du jeu de caractères à appliquer aux futures connexions à établir, elles supporteront alors un autre jeu de caractères, ce qui n'est pas très intelligent, étant donné que les jeux de caractères sont utilisés dans l'échappement.
master_on_write
bool
Si utilisé, le plugin utilisera le maitre immédiatement après le premier appel à celui-ci. Les applications pourront toujours utiliser les astuces SQL pour discuter avec les esclaves.
Ce paramètre peut aider à réduire la latence de la réplication. Si une application
lance un INSERT
le plugin selectionnera par défaut le maitre pour toutes
les requêtes futures, y compris les SELECT
. Ceci aide à éviter les
problèmes de lectures sur des esclaves qui n'ont pas encore répliqué le
INSERT
précédent.
trx_stickiness
string
Politique d'accrochage des transactions. Sont supportées :
disabled
(défaut), master
.
Fonctionnalité expérimentale.
Cette fonctionnalité requiert 5.4.0 ou plus récent. Si vous utilisez PHP avant 5.4.0,
le plugin va emettre un warning comme
(mysqlnd_ms) trx_stickiness strategy is not supported before PHP 5.3.99
.
Si aucune politique d'accrochage des transactions n'est utilisée ou si
trx_stickiness=disabled
, le plugin n'est pas relatif aux transactions.
Ainsi, le plugin pourrait équilibrer les connexions et basculer d'une à l'autre
en plein milieu d'une transaction. Le plugin n'est pas sûr pour les transactions.
Des astuces SQL devraient être utilisées pour éviter de tels cas.
Depuis PHP 5.4.0, la bibliothèque mysqlnd permet au plugin de surveiller le mode
autocommit
en appelant la fonction
trx_autocommit()
. Si trx_stickiness=master
et
autocommit
que les transactions sont désactivées suite à un appel
de mysqlnd
à trx_autocommit()
, le plugin devient
sensible au début de la transaction. Il arrête alors l'équilibrage de charge automatique
et dirige les requêtes vers le maitre jusqu'à ce que autocommit
soit activé. Ainsi, aucune astuce SQL n'est requise.
Un exemple d'une fonction PHP déclenchant un appel de mysqlnd
à trx_autocommit()
est
mysqli_autocommit().
Même si trx_stickiness=master
, le plugin
ne peut être mis au courant des changements du mode autocommit
causés par
des requêtes SQL comme SET AUTOCOMMIT=0
.
Note:
Cette section s'applique pour myslqnd_ms 1.1.0 ou supérieure, et non pour la série 1.0.
La suite de test PECL/mysqlnd_ms se trouve dans le dossier tests/ des sources de la distribution. La suite de test consiste en des tests standards phpt, qui sont décrits sur le site d'assurance qualité de PHP.
L'exécution des tests nécessite la configuration d'un à 4 serveurs MySQL. Quelques tests ne se connectent pas du tout à MySQL. D'autres ne nécessitent qu'un seul serveur. D'autres, deux. Dans la plupart des cas, deux serveurs sont utilisés pour émuler la configuration d'une réplication. Dans d'autres cas, un maître et un esclave d'une configuration de réplication MySQL existante est nécessaire pour les tests. Les tests vont tenter de détecter le nombre de serveurs et le type de serveurs fournis. Si les serveurs requis ne sont pas trouvés, le test ne sera pas effecté, automatiquement.
Avant d'effectuer ces tests, éditez le fichier tests/config.inc pour configurer les serveurs MySQL à utiliser lors des tests.
Voici la configuration habituellement utilisée :
putenv("MYSQL_TEST_HOST=localhost"); putenv("MYSQL_TEST_PORT=3306"); putenv("MYSQL_TEST_USER=root"); putenv("MYSQL_TEST_PASSWD="); putenv("MYSQL_TEST_DB=test"); putenv("MYSQL_TEST_ENGINE=MyISAM"); putenv("MYSQL_TEST_SOCKET="); putenv("MYSQL_TEST_SKIP_CONNECT_FAILURE=1"); putenv("MYSQL_TEST_CONNECT_FLAGS=0"); putenv("MYSQL_TEST_EXPERIMENTAL=0"); /* émulation d'un cluster de réplication */ putenv("MYSQL_TEST_EMULATED_MASTER_HOST=". getenv("MYSQL_TEST_HOST")); putenv("MYSQL_TEST_EMULATED_SLAVE_HOST=". getenv("MYSQL_TEST_HOST")); /* cluster de réplication réel */ putenv("MYSQL_TEST_MASTER_HOST=". getenv("MYSQL_TEST_EMULATED_MASTER_HOST")); putenv("MYSQL_TEST_SLAVE_HOST=". getenv("MYSQL_TEST_EMULATED_SLAVE_HOST"));
MYSQL_TEST_HOST
, MYSQL_TEST_PORT
et
MYSQL_TEST_SOCKET
définissent le nom de l'hôte,
le port TCP/IP et le socket du domaine Unix pour le serveur de base de données
par défaut. MYSQL_TEST_USER
et MYSQL_TEST_PASSWD
contiennent le nom de l'utilisateur et le mot de passe nécessaires pour la connexion
à la base de données/schéma configurée avec MYSQL_TEST_DB
.
Tous les serveurs doivent avoir le même utilisateur de base de données de configuré
pour donner l'accès à la base de données de test.
L'utilisation de la syntaxe host
, host:port
ou
host:/path/to/socket
pour MYSQL_TEST_SLAVE_HOST
permet de définir un hôte, un port et un hôte, et un socket différent pour le
serveur esclave logique.
putenv("MYSQL_TEST_SLAVE_HOST=192.168.78.136:3307")); putenv("MYSQL_TEST_MASTER_HOST=myserver_hostname:/path/to/socket"));
Les logs de débogage mysqlnd peuvent être utilisées pour le débogage et la surveillance
de l'activité de PECL/mysqlnd_ms, vu que mysqlnd PECL/mysqlnd_ms ajoute des informations
de surveillance dans le fichier de débogage de la bibliothèque mysqlnd.
Reportez-vous à la documentation sur la directive de configuration PHP
mysqlnd.debug
pour plus d'informations détaillées sur la façon dont doit être
configurer les logs de débogage.
Exemple de configuration de cette directive pour activer les logs de débogage :
mysqlnd.debug=d:t:x:O,/tmp/mysqlnd.trace
Note:
Cette fonctionnalité n'est disponible qu'avec une compilation de PHP en mode débogage. Elle fonctionne sous Microsoft Windows si l'on utilise PHP en mode débogage et que PHP a été compilé en utilisant Microsoft Visual C version 9 et supérieure.
Les logs de débogage montrent les appels fonctions à la bibliothèque
mysqlnd et PECL/mysqlnd_ms. Les appels à mysqlnd sont habituellement préfixés
avec mysqlnd_
. Les appels internes PECL/mysqlnd commencent avec
mysqlnd_ms
.
Exemple attendu depuis les logs de débogage (connexion) :
[...] >mysqlnd_connect | info : host=myapp user=root db=test port=3306 flags=131072 | >mysqlnd_ms::connect | | >mysqlnd_ms_config_json_section_exists | | | info : section=[myapp] len=[5] | | | >mysqlnd_ms_config_json_sub_section_exists | | | | info : section=[myapp] len=[5] | | | | info : ret=1 | | | <mysqlnd_ms_config_json_sub_section_exists | | | info : ret=1 | | <mysqlnd_ms_config_json_section_exists [...]
Les logs de débogage ne sont pas uniquement utiles pour les développeurs du plugin, mais aussi pour trouver la cause d'erreurs utilisateurs. Par exemple, si votre application ne gère pas correctement les erreurs, et échoue dans l'enregistrement des messages d'erreur, le fait de vérifier les logs de débogage et de surveillance peut aider dans la recherche de la cause. L'utilisation des logs de débogage pour déboguer l'application ne doit être considérée que si aucune autre option n'est disponible. Le fait d'écrire les logs de débogage sur le disque est une opération lente et peut avoir des impacts négatifs dans les performances de l'application.
Exemple attendu depuis les logs de débogage (échec de connexion) :
[...] | | | | | | | info : adding error [Access denied for user 'root'@'localhost' (using password: YES)] to the list | | | | | | | info : PACKET_FREE(0) | | | | | | | info : PACKET_FREE(0x7f3ef6323f50) | | | | | | | info : PACKET_FREE(0x7f3ef6324080) | | | | | | <mysqlnd_auth_handshake | | | | | | info : switch_to_auth_protocol=n/a | | | | | | info : conn->error_info.error_no = 1045 | | | | | <mysqlnd_connect_run_authentication | | | | | info : PACKET_FREE(0x7f3ef63236d8) | | | | | >mysqlnd_conn::free_contents | | | | | | >mysqlnd_net::free_contents | | | | | | <mysqlnd_net::free_contents | | | | | | info : Freeing memory of members | | | | | | info : scheme=unix:///tmp/mysql.sock | | | | | | >mysqlnd_error_list_pdtor | | | | | | <mysqlnd_error_list_pdtor | | | | | <mysqlnd_conn::free_contents | | | | <mysqlnd_conn::connect [...]
Les logs de surveillance peuvent également être utilisés pour vérifier le comportement correct de PECL/mysqlnd_ms, par exemple, pour vérifier quel serveur a été sélectionné pour l'exécution de la requête et pourquoi celui-là.
Exemple attendu depuis les logs de débogage (décision du plugin) :
[...] >mysqlnd_ms::query | info : query=DROP TABLE IF EXISTS test | >_mysqlnd_plugin_get_plugin_connection_data | | info : plugin_id=5 | <_mysqlnd_plugin_get_plugin_connection_data | >mysqlnd_ms_pick_server_ex | | info : conn_data=0x7fb6a7d3e5a0 *conn_data=0x7fb6a7d410d0 | | >mysqlnd_ms_select_servers_all | | <mysqlnd_ms_select_servers_all | | >mysqlnd_ms_choose_connection_rr | | | >mysqlnd_ms_query_is_select [...] | | | <mysqlnd_ms_query_is_select [...] | | | info : Init the master context | | | info : list(0x7fb6a7d3f598) has 1 | | | info : Using master connection | | | >mysqlnd_ms_advanced_connect | | | | >mysqlnd_conn::connect | | | | | info : host=localhost user=root db=test port=3306 flags=131072 persistent=0 state=0
Dans ce cas, la requête DROP TABLE IF EXISTS test
a été exécutée. Notez que la chaîne de requête est affichée directement
dans le fichier de logs. Aussi, vous devriez restreindre l'accès à ce fichier
suivant vos contraintes de sécurité.
La requête a été soumis à la balance de charge en utilisant la politique round robin,
comme vous pouvez facilement le deviner depuis le nom de la fonction
mysqlnd_ms_choose_connection_rr
.
Elle a été envoyée au serveur maître s'exécutant sur
host=localhost user=root db=test port=3306 flags=131072 persistent=0 state=0
.
L'activité du plugin peut être surveillée en utilisant les logs de trace mysqlnd, les statistiques mysqlnd, les statistiques du plugin mysqlnd_ms, ainsi que des outils de déboggage PHP externes. L'utilisation des logs de trace devrait être limitée au débogage. Il est recommandé d'utiliser les statistiques du plugin pour la surveillance.
L'écriture d'une trace dans un log est une opération lente. Si vous utilisez un outil de débogage externe PHP, référez-vous au manuel utilisateur de ce dernier concernant les impacts sur les performances ainsi que le type d'informations collectées. Dans la plupart des cas, les outils de débogage externe PHP font des appels à la pile. Un appel à la pile, ou une trace dans les logs sont souvent plus difficiles à interpréter que les statistiques fournies par le plugin.
Les statistiques du plugin indiquent la fréquence d'utilisation d'un noeud du cluster (esclave ou maître), pourquoi le noeud a été utilisé, si les connexions paresseuses ont été utilisées et si l'injection d'un identifiant global de transaction a été effectuée. Les informations de surveillance fournies permettent à l'utilisateur de vérifier les décisions du plugin et de prévoir les ressources de son cluster suivant leur utilisation. La fonction mysqlnd_ms_get_stats() est utilisée pour accéder aux statistiques. Reportez-vous aux descriptions des fonctions pour une liste des statistiques disponibles.
Les statistiques sont collectées pour chaque processus PHP. Leur scope se limite à un processus PHP. Suivant le modèle de déploiement PHP, un processus peut servir une ou plusieurs requêtes web. Si le modèle CGI est utilisé, un processus PHP ne sert qu'une requête web. Si le modèle FastCGI ou pre-fork serveur web est utilisé, un processus PHP sert habituellement plusieurs requêtes web ; idem dans le cas d'un serveur web threadé. Notez que les threads fonctionnant en parallèle peuvent mettre à jour les statistiques en parallèle. Aussi, si un modèle de déploiement PHP threadé est utilisé, les statistiques peuvent être modifiées par plus d'un script à la fois. Un script ne peut pas être sûr de ne voir que ces propres modifications sur les statistiques.
Exemple #38 Vérification de l'activité du plugin sur un modèle de déploiement non-threadé
mysqlnd_ms.enable=1 mysqlnd_ms.collect_statistics=1
<?php
/* La balance de charge suit les règles de la section "myapp" du fichier de configuration du plugin */
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno())
/* Bien évidemment, votre gestionnaire d'erreur est meilleur... */
die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
$stats_before = mysqlnd_ms_get_stats();
if ($res = $mysqli->query("SELECT 'Read request' FROM DUAL")) {
var_dump($res->fetch_all());
}
$stats_after = mysqlnd_ms_get_stats();
if ($stats_after['use_slave'] <= $stats_before['use_slave']) {
echo "Suivant les statistiques, la requête en lecture n'a pas été exécutée sur un esclave !";
}
?>
Les statistiques sont aggrégées pour les activités de tous les plugins, et toutes les connexions gérées par le plugin. Il n'est pas possible de savoir le nombre de contribution aux statistiques d'un gestionnaire de connexion en particulier.
L'utilisation de la fonction register_shutdown_function()
ou de la directive de configuration auto_append_file
de PHP
est une façon simple de copier les statistiques dans, par exemple, un fichier
de logs, lorsque le script se termine. Au lieu d'utiliser un fichier de logs,
il est également possible d'envoyer les statistiques vers un outil de surveillance
externe pour l'enregistrement et le rendu.
Exemple #39 Enregistrement des statistiques lorsque le script se termine
mysqlnd_ms.enable=1 mysqlnd_ms.collect_statistics=1 error_log=/tmp/php_errors.log
<?php
function check_stats() {
$msg = str_repeat("-", 80) . "\n";
$msg .= var_export(mysqlnd_ms_get_stats(), true) . "\n";
$msg .= str_repeat("-", 80) . "\n";
error_log($msg);
}
register_shutdown_function("check_stats");
?>