Fichier de configuration du plugin (>=1.1.x)

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.

Introduction

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($configJSON_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

Directives de configuration

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 E_RECOVERABLE_ERROR lorsque le plugin tentera de se connecter au serveur. Le message d'erreur ressemblera à ceci : (mysqlnd_ms) Cannot find [host] in [%s] section in config in %s on line %d.

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 #GTID qui sera remplacé par le GTID recherché par le plugin. Voyez le quickstart pour les exemples.

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 wait_for_gtid_timeout secondes pour attraper un esclave lors d'une recherche d'esclaves qui peuvent délivrer une consistence de session. Cette option limite le temps consacré pour interroger le statut de l'esclave. Si cette interrogation prend trop de temps, le temps passé au total peut dépasser la valeur de l'option wait_for_gtid_timeout. Le plugin appel sleep(1) pour attendre une seconde entre deux demandes.

L'option peut être utilisée avec l'émulation côté client mais aussi avec la fonctionalité 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($link1);
$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($link1);
?>

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 fonctionalité 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

Filtre : 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.
Filtre : 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.
Filtre : 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 à TRUE, FALSE sinon.

La détection de la transaction est basée sur la surveillance de l'appel de set_autocommit sur la bibliothèque mysqlnd. La surveillance n'est pas possible avant PHP 5.4.0. Reportez-vous à la pile et au changement de connexion pour plus de détails.

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'

Filtre : 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(02) > 1)
      
$picked_masters[] = $key;
  }
  
$picked_slaves = array()
  foreach (
$slaves as $key => $value) {
    if (
mt_rand(02) > 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.

Filtre : 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 /*user defined node group name*/. Veuillez noter qu'aucun espace n'est autorisé autour de user defined node group name. En raison du fait que user defined node group name est utilisé tel que comme partie d'une astuce SQL, vous devez choisir le nom valide avec le langage SQL.

Chaque entré du groupe de noeuds doit contenir une liste de serveurs master. Les serveurs slave sont également autorisés. Le fait de ne pas fournir de liste de master pour un groupe de noeuds name_of_group va émettre une erreur de type E_RECOVERABLE_ERROR comme celle-ci (mysqlnd_ms) No masters configured in node group 'name_of_group' for 'node_groups' filter.

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 E_RECOVERABLE_ERROR comme celle-ci (mysqlnd_ms) Unknown master 'server_alias_name' (section 'name_of_group') in 'node_groups' filter configuration.

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 mysqlnd_ms.multi_master=0 est utilisé, le plugin peut émettre une alerte.

Depuis 1.5.0.
Filtre : 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 age. Si le paramètre age est fourni, le plugin considère seulement les esclaves pour la lecture pour lesquels la réplication MySQL rapporte d'un lag serveur inférieur ou égal à la valeur du paramètre age. Le lag de réplication est mesuré en utilisant SHOW SLAVE STATUS. Si le plugin échoue dans la récupération du lag de réplication, l'esclave testé sera ignoré. Des détails ainsi que des astuces de l'implémentation sont fournis dans la section sur la qualité de service.

Veuillez noter que si une chaîne de filtres génère une liste vide d'esclave, et que la directive de configuration PHP mysqlnd_ms.multi_master=0 est utilisée, le plugin peut émettre une alerte.

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 mysqlnd_ms.multi_master=0 est utilisé, le plugin peut émettre une alerte.

Les demandes temporaires de consistence de session utilisant la fonction mysqlnd_ms_set_qos() est une alternative à l'utilisation de master_on_write. master_on_write est plutôt utilisé pour envoyer plus de requêtes au maître que nécessaires. L'application devrait être capable de continuer l'opération à un niveau de consistence moindre après avoir subit des lectures critiques.

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 : disabled (par défaut), master, loop_before_master

Une valeur à disabled désactivera le basculement automatique.

Le fait de définir le master indique au plugin de tenter une connexion vers ce maître lors d'une erreur de connexion vers l'esclave. Si la connexion au maître échoue, le plugin sortira de la boucle de basculement et une erreur sera retournée à l'utilisateur.

Lors de l'utilisation de loop_before_master et qu'une requête esclave est faîte, le plugin tentera une connexion aux autres esclabes avant de basculer vers le maître. Si plusieurs maîtres sont fournis, et que la gestion des multi-maîtres est activée, le plugin parcourra la liste des maîtres et tentera de s'y connecter avant de retourner une erreur à l'utilisateur.

Depuis 1.4.0.
remember_failed

Se souvenir des échecs pendant la durée d'une requête web. Par défaut, vaut false.

Si défini à true, le plugin va se souvenir des hôtes ayant échoués, et les écartera dans toutes les balances de charge réalisées pendant la durée de la requête web courante.

Depuis 1.4.0. Cette fonctionalité n'est disponible qu'avec les filtres random et roundrobin de balance de charge. L'utilisation de cette fonctionalité est recommandée.
max_retries

Nombre maximal de tentative de reconnexion avant d'écarter un hôte. Défaut : 0 (aucune limite).

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 à n > 0, le pluginva conserver le noeud dans la liste des noeuds y compris après une tentative de connexion échouée. Le noeud ne sera pas supprimé immédiatement de la liste des esclaves et de la liste des maîtres après le premier échec de connexion, mais n tentatives suivantes seront réalisées dans les futures balances de charge avant d'être réellement écarté.

Depuis 1.4.0. Cette fonctionalité 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" : "utf8"
    }
}
<?php
$mysqli 
= new mysqli("myapp""username""password""database");
$mysqli->real_escape("this will be escaped using the server_charset setting - utf8");
$mysqli->set_charset("latin1");
$mysqli->real_escape("this will be escaped using latin1");
/* server_charset définit implicitement une connexion utf8 */
$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 fonctionalité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 1297 (HY000 (ER_GET_TEMPORARY_ERRMSG), Message: Got temporary error %d '%s' from %s). Avant d'ajouter d'autres codes erreurs, autre que 1297, à cette liste, assurez-vous que votre cluster supporte une nouvelle tentative sans impacter le statut de votre application.

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 : 1

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 : 100

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.

state_store
record_participant_credentials

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

participant_localhost_ip

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.

mysql

Le stockage de statut MySQL est le seul stockage de statut disponible.

global_trx_table

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

participant_table

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
garbage_collection_table

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
host

Nom d'hôte du serveur MySQL.

user

Nom de l'utilisateur à utiliser pour la connexion au serveur MySQL.

password

Mot de passe à utiliser pour le serveur MySQL.

db

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

Port du serveur MySQL.

socket

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.

rollback_on_close

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

garbage_collection
max_retries

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

probability

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

max_transactions_per_run

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

Fichier de configuration du plugin (<= 1.0.x)

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.

Testing

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"));

Débogage et surveillance

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.

Monitoring

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");
?>