La siguiente documentación se aplica a PECL/mysqlnd_ms >= 1.1.0-beta. No es válida para versiones anteriores. Para la documentación que cubre versiones anterires, ver la documentación de configuración para mysqlnd_ms 1.0.x y anteriores.
Nota: Registro de cambios: Característica añadida en PECL/mysqlnd_ms 1.1.0-beta
La descripción de abajo se aplica a PECL/mysqlnd_ms >= 1.1.0-beta. No es válida para versiones anteriores.
El complemento usa su propio fichero de configuración. Este guarda información sobre el servidor maestro de replicación MySQL, los servidores esclavos de replicación MySQL, la política de elección (equilibrado de carga), la estrategia de tolerancia a fallos, y el uso de conexiones retardadas.
El complemento carga su fichero de configuración al comienzo de una petición web. Entonces, es almacenado en la memoria caché y utilizado durante el resto de la petición web. De esta forma, no hay necesidad de reiniciar PHP después de utilizar el fichero de configuración. Los cambios de éste estarán activos casi instantáneamente.
La directiva de configuración de PHP mysqlnd_ms.config_file se utiliza para establecer el fichero de configuración del complemento. Observe que dicha direcitiva no puede ser evaluada para cada petición web. Por lo tanto, el cambio del nombre del fichero de configuración del complemento o de su ubicación puede requerir el reinicio de PHP. Sin embargo, no es necesario tal reinicio para leer los cambios si se actualiza un fichero de configuración del complemento ya existente.
El uso y el análisis de JSON es eficiente, ya que con JSON es más sencillo expresar estructuras de datos jerárquicas que con el formato estándar de php.ini.
Ejemplo #1 Convertir un array de PHP (hash) al formato JSON
O alternativamente, un desarrollador puede preferir la sintaxis de arrays por estar más familiarizado con ella. Este ejemplo demuestra cómo un desarrolador podría convertir un array de PHP a JSON.
<?php
$config = array(
"myapp" => array(
"master" => array(
"master_0" => array(
"host" => "localhost",
"socket" => "/tmp/mysql.sock",
),
),
"slave" => array(),
),
);
file_put_contents("mysqlnd_ms.ini", json_encode($config, JSON_PRETTY_PRINT));
printf("mysqlnd_ms.ini file created...\n");
printf("Dumping file contents...\n");
printf("%s\n", str_repeat("-", 80));
echo file_get_contents("mysqlnd_ms.ini");
printf("\n%s\n", str_repeat("-", 80));
?>
El resultado del ejemplo sería:
mysqlnd_ms.ini file created... Dumping file contents... -------------------------------------------------------------------------------- { "myapp": { "master": { "master_0": { "host": "localhost", "socket": "\/tmp\/mysql.sock" } }, "slave": [ ] } } --------------------------------------------------------------------------------
Un fichero de configuración del complemento consta de una o más secciones. Éstas están representadas por las propiedades de nivel superior del objeto codificado en el fichero JSON. Las secciones también podrían llamarse nombres de configuración.
Las aplicciones hacen referencia a las secciones por su nombre. Las aplicaciones usan los nombres de las secciones como el parámetro 'host' (servidor) de los distintos métodos de conexión de las extensiones mysqli, mysql y PDO_MYSQL. Durante la conexión, el complemento de mysqlnd compara el nombre del equipo anfitrión con todos los nombres de las secciones del fichero de configuración del complemento. Si el nombre del equipo anfitrión y el nombre de la sección coinciden, el complemento cargará la configuración de esa sección.
Ejemplo #2 Ejemplo del uso de nombres de sección
{ "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
/* Todas las conexiones siguientes tendrán equilibrado de carga */
$mysqli = new mysqli("myapp", "nombre_usuario", "contraseña", "base_datos");
$pdo = new PDO('mysql:host=myapp;dbname=base_datos', 'nombre_usuario', 'contraseña');
$mysql = mysql_connect("myapp", "nombre_usuario", "contraseña");
$mysqli = new mysqli("localhost", "nombre_usuario", "contraseña", "base_datos");
?>
Los nombres de sección son cadenas de texto. Es válido usar nombres de sección como 192.168.2.1, 127.0.0.1 o localhost. Si, por ejemplo, una aplicación se conexta a localhost y existe una sección de configuración del complemento llamada localhost, la semántica de la operación de conexión se cambia. La aplicación ya no usará únicamente el servidor MySQL que se ejecuta en el equipo anfitrión localhost, sino que el complemento iniciará el equilibrado de carga de las consultas MySQL siguiendo las reglas de la sección de configuración localhost. De esta manera se puede realizar el equilibrado de carga de consultas desde una aplicación sin cambiar el código fuente de la misma. Recuerde que tal configuración puede no contribuir a la legibilidad global del código fuente de las aplicaciones. El uso de nombres de sección combinado con nombres de equipos anfitriones debería ser el último recurso.
Cada sección de configuración contiene, como mínimo, una lista de sevidores maestros
y una lista de servidores esclavos. La lista de maestros se configura con la palabra clave
master, mientras que la lista de esclavos se configura con la
palabra clave slave. El no proporcionar una lista de esclavos resultará
en un error fatal de nivel E_ERROR
, aunque la lista de esclavos
puede estar vacía. Es posible prohibir esclavos. Sin embargo, esto solo se recomienda
para clústeres sincrónicos. Véanse también los
clústeres admitidos.
La parte principal de esta documentación se centra en el uso de
clústeres de replicación MySQL asincrónicos.
Las listas de servidores maestros y esclavos se pueden indexar opcionalmente mediante nombres simbólicos para los servidores que describen. De forma alternativa, se puede utlizar un array con descripciones de los servidores esclavos y maestros.
Ejemplo #3 Lista de esclavos anónimos
"slave": [ { "host": "192.168.3.24", "port": "3305" }, { "host": "192.168.3.65", "port": "3309" } ]
Una lista de servidores anónimos está codificada por el tipo array de JSON. Opcionalmente, se pueden usar los nombres simbólicos para indexar los servidores esclavos o maestros de una lista de servidores, realizándolo mediante el tipo objeto de JSON.
Ejemplo #4 Lista de maestros usando nombres simbólicos
"master": { "master_0": { "host": "localhost" } }
Se recomienda indexar las listas de servidores con nombres de servidores simbólicos. Los sobrenombres se mostrarán en los mensajes de error.
mysqlnd_ms preserva el orden de los servidores y lo toma en cuenta. Si, por ejemplo, se configura una estrategia de equilibrado de carga de rotación, la primera sentencia SELECT será ejecutada en el esclavo que aparece en primer lugar en la lista de servidores esclavos.
Un servidor configurado puede ser descrito con host, port, socket, db, user, password y connect_flags. Es obligatorio establecer el equipo anfitrión del servidor de la base de datos mediante la palabra clave host. Todos los demás ajustes son opcionales.
Ejemplo #5 Palabras clave para configurar un servidor
{ "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 se omite un ajuste, el complemento usará el valor proporcionado por la llamada a la API hecha por el usuario utilizada para abrir la conexión. Véase el ejemplo de uso de nombres de sección de arriba.
El formato del fichero de configuración ha sido cambiado en la versión 1.1.0-beta para tener en cuenta los filtros encadencados. Los filtros son los responsables de filtrar la lista de servidores configurados para identificar un servidor para que ejecute una sentencia dada. Los filtros se configuran con la palabra clave filter. Éstos son ejecutados por mysqlnd_ms en el orden en que aparecen. La definción de filtros es opcional. Una sección de configuración del fichero de configuración del complemento no necesita tener una entrada filters.
Los filtros reemplazan al ajuste pick[] de versiones anteriores. Los nuevos filtros random y roundrobin proporcionan la misma funcionalidad.
Ejemplo #6 El nuevo filtro roundrobin, funcionalidad antigua
{ "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 función mysqlnd_ms_set_user_pick_server() ha sido eliminada. El establecimiento de una llamada de retorno ahora se realiza con el filtro user. Algunos filtros aceptan parámetros. El filtro user requiere y acepta el parámetro obligatorio callback para establecer la llamada de retorno que antes se establecía a través de la función mysqlnd_ms_set_user_pick_server().
Ejemplo #7 El filtro user reemplaza a mysqlnd_ms_set_user_pick_server()
"filters": { "user": { "callback": "pick_server" } }
La validez del fichero de configuración se realiza tanto al leerlo como cuando más tarde se establece una conexión. El fichero de configuración se lee durante la petición de arranque de PHP. En esta primera etapa, una extensión de PHP podría no mostrar mensajes de error apropiadamente. En el peor de los casos, no se mostrará ningún error y un intento de conexión fallará sin un mensaje de error adecuado. Este problema ha sido solventado en la versión 1.5.0.
Ejemplo #8 Mensaje de error común en caso de problemas con el fichero de configuración (hasta la versión 1.5.0)
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
?>
El resultado del ejemplo sería:
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
Desde la versión 1.5.0, los errores al arrancar son además almacenados en búfer y emitidos cuando se realiza un intento de conexión. Use la directiva de configuración mysqlnd_ms.force_config_usage para establecer el tipo de error usado para mostrar errores almacenados en búfer. Por omisión, se emitirá un error de tipo E_WARNING.
Ejemplo #9 Validación mejorada del fichero de configuración desde 1.5.0
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
?>
El resultado del ejemplo sería:
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
Puede ser útil establecer mysqlnd_ms.force_config_usage = 1 al depurar errores potenciales del fichero de configuración. Esto no solo convertirá el tipo de errores del arranque almacenados en búfer a E_RECOVERABLE_ERROR, sino que también ayudará a detectar nombres de seccones mal escritas.
Ejemplo #10 Error posiblemente más preciso debido a mysqlnd_ms.force_config_usage=1
mysqlnd_ms.force_config_usage=1
<?php
$mysqli = new mysqli("invalid_section", "username", "password", "database");
?>
El resultado del ejemplo sería:
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
He aquí una breve explicación de las directivas de configuración que se pueden usar.
master
array o object
Lista de los servidores maestros de replicación MySQL. La lista es del tipo array de JSON, para declarar una lista anónima de servidores, o del tipo objeto de JSON. Por favor, véanse los ejemplos de arriba.
Es obligatorio establecer al menos un servidor maestro. El complemento emitirá un error de tipo E_ERROR si el usuario no ha proporcionado una lista de servidores maestros en una sección de configuración. El error fatal puede ser (mysqlnd_ms) Section [master] doesn't exist for host [name_of_a_config_section] in %s on line %d ((mysqlnd_ms) La sección [master] no existe para el equipo anfitrión [nombre_de_una_sección_de_configurción] en %s en la línea %d).
Un servidor se describe con las palabras clave host, port, socket, db, user, password y connect_flags. Es obligatorio proporcionar al menos un valor para host. Si no se proporcionan cualesquiera de los otros valores, se tomarán de la llamada de conexión del usuario a la API, véase también: ejemplo de uso de nombres de sección.
Tabla de las palabras clave de configuración del servidor.
Palabra clave | Descripción | Versión |
---|---|---|
host |
El equipo anfitrión servidor de las bases de datos. Es un ajuste obligatorio. Si no se proporcina causará un error de tipo E_RECOVERABLE_ERROR cuando el complemento intente conectarse al servidor. El mensaje de error puede ser (mysqlnd_ms) Cannot find [host] in [%s] section in config in %s on line %d ((mysqlnd_ms) No se pudo encontrar [host] en la sección [%s] de configuración en %s en la línea %d). |
Desde 1.1.0. |
port |
El puerto TCP/IP del servidor de las bases de datos. |
Desde 1.1.0. |
socket |
El socket de dominio Unix del servidor de las bases de datos. |
Desde 1.1.0. |
db |
La base de datos (esquema). |
Desde 1.1.0. |
user |
El usuario de la base de datos MySQL. |
Desde 1.1.0. |
password |
La constraseña del usuario de la base de datos MySQL. |
Desde 1.1.0. |
connect_flags |
Banderas de conexión. |
Desde 1.1.0. |
El complemento únicamente admite el uso de un servidor maestro. Existe un ajuste experimental para habilitar el soporte de múltiples maestros. Los detalles no están documentados. El ajuste sólo se menciona para desarrollo.
slave
array o object
Lista de uno o más servidores esclavos de replicación MySQL. La sintaxis es idéntica a la de lo servidores maestros, véase master más arriba para más detalles.
El complemento admite el uso de uno o más servidores esclavos.
Es obligatorio establecer una lista de servidores esclavos. El complemento notificará un error de tipo E_ERROR si no se proporciona slave para una sección de configuración. El mensaje de error fatal puede ser (mysqlnd_ms) Section [slave] doesn't exist for host [%s] in %s on line %d ((mysqlnd_ms) La sección [slave] no existe para el equipo anfitrión [%s] en %s en la línea %d). Observe que es válido usar una lista de servidores esclavos vacía. Este error ha sido introducido para evitar que no se establezcan esclavos de forma accidental si se olvida el ajuste slave. Es posible configurar un único maestro si se utiliza una lista de servidores esclavos vacía.
Si se configura una lista de esclavos vacía y se intenta ejecutar una sentencia en un esclavo, el complemento podría emitir una advertencia como (mysqlnd_ms) Couldn't find the appropriate slave connection. 0 slaves to choose from. ((mysqlnd_ms) No se pudo encontrar la conexión esclava apropiada. 0 esclavos de donde elegir) durante la ejecución de la sentencia. Es posible que le siga otra advertencia, como (mysqlnd_ms) No connection selected by the last filter ((mysqlnd_ms) El último filtro no seleccionó ninguna conexión).
global_transaction_id_injection
array o object
La configuración del identificador de transacciones global está relacionada tanto con el uso de la característica del ID de transacciones global interno del servidor como con la emulación en el lado del cliente.
Palabra clave | Descripción | Versión |
---|---|---|
fetch_last_gtid |
Senetencia SQL para acceder al último identificador de transaccioens global. La sentencia SQL se ejecuta si el complemento necesita conocer el identificador de transacciones global más reciente. Este puede ser el caso cuando, por ejemplo, se comprueba el estado de un esclavo de Replicación MySQL. También se usa con mysqlnd_ms_get_last_gtid(). |
Desde 1.2.0. |
check_for_gtid |
Sentencia SQL para comprobar si una réplica ha replicado todas las transacciones hasta, e incluyendo a, la buscada. La sentencia SQL se ejecuta cuando se buscan réplicas que pueden ofrecer un nivel mayor de consistencia que la consistencia final. La sentencia puede contener el parámetro de sustitución #GTID, el cual es reemplazado con el identificador de transacciones global buscado por el complemento. Por favor, revise los ejemplos de la guía rápica. |
Desde 1.2.0. |
report_errors |
Si se ha de emitir un error de tipo 'warning' si ocurriera un problema mientras se ejecuta cualquiera de las sentencias SQL configuradas. |
Desde 1.2.0. |
on_commit |
(Solamente para la emulación del ID de transacciones global en el lado del cliente). Sentencia SQL a ejecutar cuando una transacción finaliza y acutaliza el número de secuencia del identificador de transacciones global en el maestro. Por favor, vea los ejemplo de la guía rápida. |
Desde 1.2.0. |
wait_for_gtid_timeout |
Ordena al complemento que espere hasta wait_for_gtid_timeout segundos para que un esclavo se ponga al día cuando se busquen esclavos que puedan proporcionar la consistencia de sesión. Este ajuste limita el tiempo empleado en obtener el estados de los esclavos. Si dicha obtención toma mucho tiempo, el tiempo de espera total empleado puede exceder wait_for_gtid_timeout. El complemento llama a sleep(1) para dormir un segundo entre cada dos obtenciones. El ajuste se puede usar junto con la emulación en el lado del cliente del complemento y la característica del identificador de transacciones global del lado del servidore de MySQL 5.6. La espera de que un esclavo replique un GTID en particular necesario para la consistencia de sesión también signifiva estrangular el cliente. El estrangulamiento del cliente reduce indirectamente la carga de escrigura del maestro. A un sistema de replicación basado en copia primaria,, como la Replicación MySQL, se le da más tiempo para alcanzar un estado consistente. Esto puede ser útil, por ejemplo, para aumentar el número de copias de datos para consideraciones de alta disponibilidad, o para prevenir que el maestro sea sobrecargado. |
Desde 1.4.0. |
fabric
object
Ajustes relacionados con MySQL Fabric. Si el complemento se usa junto con MySQL Fabric, el fichero de configuración del complemento no contendrá las listas de servidores de MySQL. En su lugar, el complemento preguntará a MySQL Fabric sobre qué listas de servidores usar para realizar cierta tarea.
Una configuración mínima del complemento para usar con MySQL Fabric contendrá una lista de uno o más hosts de MySQL Fabric que el complemento puede consultar. Si se configura más de un host de MySQL Fabric, el complemento usará una estrategia de rotación para elegir entre ellos. No está disponible ninguna otra estrategia actualmente.
Ejemplo #11 Configuración mínima del complemento para usar con MySQL Fabric
{ "myapp": { "fabric": { "hosts": [ { "host" : "127.0.0.1", "port" : 8080 } ] } } }
Cada host de MySQL Fabric está descrito usando un objeto de JSON con los siguientes miembros.
Palabra clave | Descripción | Versión |
---|---|---|
host |
Nombre del host de MySQL Fabric. |
Desde 1.6.0. |
port |
El puerto TCP/IP en el que el host de MySQL Fabric escucha para llamadas de procedimientos remotos enviados por clientes como el complemento. |
Desde 1.6.0. |
El complemento utiliza flujos de PHP para comunicarse con MySQL Fabric a través de XML RPC sobre HTTP. Por omisión, no se establecen tiempos de espera para la comunicación en red. Así, el valor predeterminado del complemento es el tiempo de espera predeterminado del flujo de PHP. Dichos valores predeterminados están fuera del alcance del complemento.
Se puede establecer un tiempo de espera opcional para sobrescribir el predeterminado del flujo de PHP. Establecer el tiempo de espera en el fichero de configuración del complemento tiene el mismo efecto que establecer un tiempo de espera para la conexión HTTP del espacio de usuario de PHP establecida a través de flujos de PHP.
La unidad del valor del tiempo de espera de Fabric del complemento es el segundo. El rango de valores permitidos es de 0 a 65535. Este ajuste existe desde la versión 1.6.
Ejemplo #12 Tiempo de espera opcional para la comunicación con Fabric
{ "myapp": { "fabric": { "hosts": [ { "host" : "127.0.0.1", "port" : 8080 } ], "timeout": 2 } } }
La adhesión de transacciones y la lógica de MySQL Fabric puden entrar en conflicto. La opción de adhesión deshabilita el cambio entre srevidores durante una transacción. Al usar Fabric y fragmentación, el usuario podría (erróneamente) iniciar una transacción local en un fragmento y luego intentar cambiar a un fragmento diferente usando mysqlnd_ms_fabric_select_shard() o mysqlnd_ms_fabric_select_global(). En este caso, el complemento no rechazará la petición de cambiar de servidor en mitad de una transacción, sino que permitirá al usuario cambiar a otro servidor independientemente de la configuración de adhesión de transacciones usada. Obviamente, es un error de usuario escribir tal código.
Si la adhesión de transacciones está habilitada y se obtiene un error de tipo advertencia al llamar a mysqlnd_ms_fabric_select_shard() o mysqlnd_ms_fabric_select_global(), estblezca la bandera booleana trx_warn_server_list_changes.
Ejemplo #13 Advertencias sobre la violación de límites de transacciones
{ "myapp": { "fabric": { "hosts": [ { "host" : "127.0.0.1", "port" : 8080 } ], "trx_warn_serverlist_changes": 1 }, "trx_stickiness": "on" } }
<?php
$enlace = new mysqli("myapp", "root", "", "test");
/*
Para la demostración, la llamada posría fallar.
Si falla o no, nos introduciremos en el estado
necesario para el ejemplo.
*/
@mysqlnd_ms_fabric_select_global($enlace, 1);
$enlace->begin_transaction();
@$enlace->query("DROP TABLE IF EXISTS test");
/*
¡Cambiar de servidor/fragmento es un error debido a la
transacción local abierta!
*/
mysqlnd_ms_select_global($enlace, 1);
?>
El resultado del ejemplo sería:
PHP Warning: mysqlnd_ms_fabric_select_global(): (mysqlnd_ms) Fabric server exchange in the middle of a transaction in %s on line %d
Por favor, considere la característica como experimental. Podrían cambiarse la sintaxis y la semántica.
filters
object
Lista de filtros. Un filtro es el responsable de filtrar la lista de servidores disponibles que puedan ejecutar una setentcia dada. Los filtros se pueden encadenar. Los filtros random y roundrobin reemplazan a la directiva pick[] usada en versiones anteriores para seleccionar una política de equilibrado de carga. El filtro user reemplaza a la función mysqlnd_ms_set_user_pick_server().
Los filtros pueden aceptar parámetros para refinar sus acciones.
Si no está establecida una política de equilibrado de carga, el complemento asumirá el valor predeterminado random_once. La política random_once elige un servidor aleatorio al ejecutar la primera sentencia de solo lectura. Este servidor esclavo se usará para todas las sentencias de solo lectura hasta que finalice la ejecución del script de PHP. No se establece ninguna política de equilibrado de carga y, por lo tanto, toma lugar el valor predeterminado si ni random ni roundrobin son parte de la sección de configuración.
Si una cadena de filtros es configurada de modo que la salida de un filtro que no produzca más de un servidor sea usada como entrada para otro filtro al que se le debería proporcionar más de un servidor, el complemento podría emitir una advertencia sobre una conexión abierta. La advertencia podría ser: (mysqlnd_ms) Error while creating filter '%s' . Non-multi filter '%s' already created. Stopping in %s on line %d ((mysqlnd_ms) Error al crear el filtro '%s' . No se ha creado aún el filtro múltiple '%s'. Detenido en %s en la línea %d). Además, se puede establecer un error de código 2000, el estado sql HY000, y un mensaje de error similar a la advertencia, sobre el gestor de conexión.
Ejemplo #14 Secuencia de filtros inválida
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "filters": [ "roundrobin", "random" ] } }
<?php
$enlace = new mysqli("myapp", "root", "", "test");
printf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
$enlace->query("SELECT 1 FROM DUAL");
?>
El resultado del ejemplo sería:
PHP Warning: mysqli::mysqli(): (HY000/2000): (mysqlnd_ms) Error while creating filter 'random' . Non-multi filter 'roundrobin' already created. Stopping in filter_warning.php on line 1 [2000] (mysqlnd_ms) Error while creating filter 'random' . Non-multi filter 'roundrobin' already created. Stopping PHP Warning: mysqli::query(): Couldn't fetch mysqli in filter_warning.php on line 3
random
object
El filtro random introduce las políticas de equilibrado de carga "aleatoria" y "aleatoria una vez", establecidas a través de la directiva pick[] en versiones anteriores.
La política "aleatoria" eligirá un servidor aleatorio siempre que se vaya a ejecutar una sentencia de solo lectura. La estrategia "aleatoria una vez" elige un servidor esclavo aleatorio una vez y continuará usándolo para el resto de la petición web. "Aleatoria una vez" es la predeterminada, si el equilibrado de carga no está configurado a través de un filtro.
Si al filtro random no se le proporciona ningún argumento, permanecerá la política de equilibrado de carga aleatoria.
Ejemplo #15 Equilibrado de carga aleatorio con el filtro 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" ] } }
Opcionalmente, se puede pasar el argumento sticky al filtro. Si se establece el parámetro sticky al string 1, el filtro seguirá la estrategia de equilibrado de carga "aleatoria una vez".
Ejemplo #16 Equilibrado de carga "aleatoria una vez" con el filtro random
{ "filters": { "random": { "sticky": "1" } } }
Los filtros random y roundrobin admiten el establecimiento de una prioridad, un peso para un servidor, desde PECL/mysqlnd_ms 1.4.0. Si se pasa el argumento weight al filtro, debe asginar un peso para todos los servidores. A los servidores se les debe proporcionar un sobrenombre en las listas de servidores slave y master respectivamente. El alias debe usarse para hacer referencia a servidores para asignarles una prioridad con weight.
Ejemplo #17 Error de referencia
[E_RECOVERABLE_ERROR] mysqli_real_connect(): (mysqlnd_ms) Unknown server 'slave3' in 'random' filter configuration. Stopping in %s on line %d
Usar un sobrenombre erróneo con weight podría resultar en un error similar al mostrado arriba.
Si se omite weight, el peso predeterminado de todos los servidores es uno.
Ejemplo #18 Asignar weight para el equilibrado de carga
{ "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 } } } } }
Como promedio, un servidor al que se le asigne un peso de dos será seleccionado el doble que un servidor al que se la haya asignado un peso de uno. Se pueden asignar diferentes pesos para reflejar diferentes tipos de máquinas, para preferir coubicar esclavos que tienen una latencia de red baja o para configurar un servidor de tolerancia a fallos de emergencia. En este último caso, se podría asignar al servidor de emergencia un peso muy bajo en relación con los demás servidores. Por ejemplo, dada la configuración de arriba, slave3 obtendrá solamente el ocho por ciento de las peticiones como media. Mientras que slave1 y slave2 estén ejecutándose, se usarán con poca frecuencia, de forma similar a un servidor de tolerancia a fallos de emergencia. Si ocurre un fallo de slave1 y de slave2, el uso de slave3 aumenta. Por favor, revise las notas sobre la tolerancia a fallos antes de usar weight de esta manera.
El rango de valores válidos del peso es de 1 a 65535.
Los argumentos desconocidos son ingnorados. No se dan advertencias ni errores.
Espera uno o más servidores como entrada. Produce un servidor. Una secuencia de filtros como random, roundrobin, puede causar una advertencia y establecer un mensaje de error sobre el gestor de conexión cuando se ejecute una sentencia.
Listado de los argumentos del filtro.
Palabra clave | Descripción | Versión |
---|---|---|
sticky |
Habilita o deshabilita la política de equilibrado de carga "aleatoria una vez". Véase más arriba. |
Desde 1.2.0. |
weight |
Asigna un peso o prioridad de equilibrado de carga a un servidor. Por favor, véase la descripción de arriba. |
Desde 1.4.0. |
roundrobin
object
Si se utiliza el filtro roundrobin, el complemento iterará sobre la lista de servidores esclavos configurados para elegir un servidor para que ejecute una sentencia. Si el complemento alcanza el final de la lista, volverá al inicio de la misma y eligirá el primer servidor esclavo configurado.
Ejemplo #19 Filtro roundrobin
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "filters": [ "roundrobin" ] } }
Espera uno o más servidores como entrada. Produce un servidor. Una secuencia de filtros como roundrobin, random, puede causar una advertencia y establecer un mensaje de error sobre el gestor de conexión cuando se ejecute una sentencia.
Listado de los argumentos del filtro.
Palabra clave | Descripción | Versión |
---|---|---|
weight |
Asigna un peso o prioridad de equilibrado de carga a un servidor. Por favor, véase la descipción de arriba. |
Desde 1.4.0. |
user
object
El filtro user reemplaza a la función mysqlnd_ms_set_user_pick_server(), la cual ha sido eliminada en la versión 1.1.0-beta. El filtro establece una llamada de retorno para la división de lectura-escritura y la selección del servidor definidas por el usuario.
Las decisiones del mecanismo interno de división de consultas de lecura-escritura pueden ser
sobrescritas de dos maneras. La más sencilla es anteponer a una consulta
las sugerentecias SQL MYSQLND_MS_MASTER_SWITCH
,
MYSQLND_MS_SLAVE_SWITCH
o
MYSQLND_MS_LAST_USED_SWITCH
. Al utilizar sugerencias SQL se puede
controlar, por ejemplo, si una consulta debería ser enviada al servidor maestro de replicación
MySQL o a uno de los servidores esclavos. Mediante la ayuda de sugenrencias SQL no es
posible elegir un esclavo en particular para que ejecute una consulta.
Se puede obtener control total en la selección del servidor usando una función de llamada de retorno. Solamente se recomienda el uso de una llamada de retorno para usuarios expertos, ya que ésta ha de cubrir todos los casos que de otro modo manejaría el complemento.
El complemento invorcará a la función de llamada de retorno para seleccionar un servidor de las listas de servidores maestros y esclavos configurados. La función de llamada de retorno inspeccionará la consulta a ejecutar y eligirá un servidor para que ejecute dicha consulta, devolviendo el URI del equipo anfitrión, tal como lo encontró en la lista de maestros y esclavos.
Si las conexiones retardadas están habilitadas y la llamada de retorno elige un servidor esclavo para el que hasta ahora no se ha establecido una conexión, y el establecimiento de la conexión al esclavo falla, el complemento devolverá un error sobre la siguiente acción en la conexión fallida, por ejemplo, al ejecutar una consulta. Es responsabilidad del desarrollador de la aplicación manejar el error. Por ejemplo, la aplicación podría re-ejecutar la consulta para desencadenar una nueva selección de un servidor y una nueva invocación a la llamada de retorno. Si lo hace, la llamada de retorno debe asegurarse de seleccionar un esclavo diferente, o comprobar la disponibilidad del esclavo, antes de devolver el resultado al complemento para evitar un bucle infinito.
Ejemplo #20 Establecer una llamada de retorno
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "filters": { "user": { "callback": "pick_server" } } } }
Se espera que la llamada devuelva un equipo anfitrión donde ejecutar la consulta. El URI del equipo anfitrión se tomará de las listas de conexión maestras y esclavas pasadas a la función de llamada de retorno. Si ésta devuelve un valor que no se encuentra el las listas de conexión maestras ni en las esclavas, el complemento emitirá un error de tipo E_RECOVERABLE_ERROR. El error puede ser (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 ((mysqlnd_ms) La llamada de retorno del filtro de usuario ha devuelto un servidor desconocido. El servidor 'servidor que no está en la lista de maestros o esclavos' no se puede encontrar en ni en la lista de maestros ni en la de esclavos). Si la aplicación captura el error para ignorarlo, los errores siguientes pueden ser establecidos en el gestor de conexión, por ejemplo, (mysqlnd_ms) No connection selected by the last filter ((mysqlnd_ms) El último filtro no seleccionó ninguna conexión) con el código de error 2000 y el estado sql HY000. Además se puede emitir una advertencia.
Si se hace referencia a una función inexistente como llamada de retorno, resultará en cualquier error de tipo E_RECOVERABLE_ERROR siempre que el complemento intente invocar a dicha función. El mensaje de error puede ser como: (mysqlnd_ms) Specified callback (pick_server) is not a valid callback ((mysqlnd_ms) La llamada de retorno (pick_server) no es una llamada de retorno válida). Si la aplicación captura el error para ignorarlo, los errores siguientes pueden ser establecidos en el gestor de conexión, por ejemplo, (mysqlnd_ms) Specified callback (pick_server) is not a valid callback con el código de error 2000 y el estado sql HY000. Admás se puede emitir una advertencia.
Los siguientes parámetros son pasados desde el complemento a la llamada de retorno.
Parámetro | Descripción | Versión |
---|---|---|
connected_host |
El URI del servidor de las bases de datos conectado actualmente. |
Desde 1.1.0. |
query |
La consulta de la sentencia para la cual un servidor necesita ser elegido. |
Desde 1.1.0. |
masters |
La lista de servidores maestros de donde elegir. Observe que la lista de servidores maestros puede no ser idéntica a la lista de servidores maestros configurados si el filtro no es el primero en la cadena de filtros. Los filtros ejecutados anteriormente puede haber reducido la lista de maestros. |
Desde 1.1.0. |
slaves |
La lista de servidores esclavos de donde elegir. Observe que la lista de servidores maestros puede no ser idéntica a la lista de servidores maestros configurados si el filtro no es el primero en la cadena de filtros. Los filtros ejecutados anteriormente puede haber reducido la lista de maestros. |
Desde 1.1.0. |
last_used_connection |
El URI del servidor de la conexión usada donde ejecutar la sentencia anterior. |
Desde 1.1.0. |
in_transaction |
Bandera booleana que indica si la sentencia es
parte de una transacción abierta. Si el modo 'autocommit' está desactivado,
se establecerá a La detección de transacciones está basada en la monitorización de la llamada a set_autocommit de la biblioteca mysqlnd . La monitorización no era posible antes de PHP 5.4.0. Por favor, vea la argumentación de los conceptos sobre agrupación e intercambio de conexiones para más detalles. |
Desde 1.1.0. |
Ejemplo #21 Utilizar una llamada de retorno
{ "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);
/* predeterminado: volver a la lógica interna del comlemento */
$ret = NULL;
printf("El usuario se ha conectado a '%s'...\n", $connected);
printf("... decidiendo dónde ejecutar '%s'\n", $query);
$where = mysqlnd_ms_query_is_select($query);
switch ($where)
{
case MYSQLND_MS_QUERY_USE_MASTER:
printf("... usando el maestro\n");
$ret = $masters[0];
break;
case MYSQLND_MS_QUERY_USE_SLAVE:
/* SELECT or SQL hint for using slave */
if (stristr($query, "FROM table_on_slave_a_only"))
{
/* una tabla que está únicamente en el primer esclavo configurado */
printf("... detectado un acceso a la tabla únicamente disponible en el esclavo A\n");
$ret = $slaves[0];
}
else
{
/* rotativo */
printf("... alguna consulta de solo lectura para un esclavo\n");
$ret = $slaves[$slave_idx++ % $num_slaves];
}
break;
case MYSQLND_MS_QUERY_LAST_USED:
printf("... usando el último esclavo utilizado\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();
?>
El resultado del ejemplo sería:
El usuario se ha conectado a 'myapp'... ... decidiendo dónde ejecutar 'SELECT 1 FROM DUAL' ... alguna consulta de solo lectura para un esclavo ... ret = 'tcp://192.168.2.27:3306' El usuario se ha conectado a 'myapp'... ... decidiendo dónde ejecutar 'SELECT 2 FROM DUAL' ... alguna consulta de solo lectura para un esclavo ... ret = 'tcp://192.168.78.136:3306' El usuario se ha conectado a 'myapp'... ... decidiendo dónde ejecutar 'SELECT * FROM table_on_slave_a_only' ... detectado un acceso a la tabla únicamente disponible en el esclavo A ... ret = 'tcp://192.168.2.27:3306'
user_multi
object
El filtro user_multi se diferencia de user en un único aspecto. De otro modo su sintaxix sería idéntica. El filtro user debe elegir y devolver exactamente un nodo para la ejecución de sentecias. Una cadena de filtros normalmente finaliza con un filtro que emite un único nodo. La cadena de filtros reduciría la lista de candidatos para la ejecución de sentencias a uno. Este es el caso, sólo queda un nodo, después de haber ejecutado el filtro user.
El filtro user_multi es un filtro múltiple. Devuelve una lista de servidors esclavos y una lista de servidores maestros. La lista necesita más filtración para identificar exactamente un nodo para la ejecución de sentencias. Un filtro múltiple normalmente se coloca al principio de la cadenda de filtros. El filtro quality_of_service es otro ejemplo de filtro múltiple.
El valor devuelto por la llamada de retorno establecido por user_multi debe ser un array con dos elementos. El primero contiene una lista de los servidores maestros seleccionados. El segundo contiene una lista de los servidores esclavos seleccionados. Las listas contendrán las claves de los servidores maestros y esclavos tal como se encontraron en las listas de esclavos y maestros pasadas a la llamada de retorno. El ejemplo de abajo devuelve listas de maestros y esclavos aleatorios extraídas de la entrada de la función.
Ejemplo #22 Devolver maestros y esclavos aleatorios
<?php
function pick_server($connected, $query, $masters, $slaves, $last_used_connection, $in_transaction)
{
$maestros_elegidos = array()
foreach ($masters as $clave => $valor) {
if (mt_rand(0, 2) > 1)
$maestros_elegidos[] = $key;
}
$esclavos_elegidos = array()
foreach ($slaves as $clave => $valor) {
if (mt_rand(0, 2) > 1)
$esclavos_elegidos[] = $clave;
}
return array($maestros_elegidos, $esclavos_elegidos);
}
?>
El complemento emitirá un error de tipo E_RECOVERABLE si la llamada de retorno falla al devolver la lista de servidores. El error puede ser (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 ((mysqlnd_ms) La llamada de retorno del filtro de usuario no ha devuelto una lista de servidores a usar. La llamada de retorno debe devolver un array en %s en la línea %d). En caso de que la lista de servidores no esté vacía pero contenga claves/ids de servidores no válidos, e lanzaráun error de tipo E_RECOVERABLE con un mensaje de error como (mysqlnd_ms) User multi filter callback has returned an invalid list of servers to use. Server id is negative in %s on line %d ((mysqlnd_ms) La llamada de retorno del filtro de usuario ha devuelto una lista de servidores a usar no válida. El id del servidor es negativo en %s en la línea %d), o similar.
La emisión de un error en caso de que la lista de esclavos o de maestros esté vacía depende de la configuración. Si se devuelve una lista de maestros vacía para una operación de escritura, es probable que el complemento emita una advertencia como (mysqlnd_ms) Couldn't find the appropriate master connection. 0 masters to choose from. Something is wrong in %s on line %d ((mysqlnd_ms) No se pudo encontrar la conexión maestra apropiada. 0 maestros donde elegir. Algo está mal en %s en la línea %d). Normalmente también es seguida de un error de tipo E_ERROR. En el caso de una operación de lectura con una lista de servidores vacía, el comportamiento depende de la configuración de la tolerancia a fallos. Si ésta está habilitada en el maestro, no debería aparecer ningún error. Si está desactivada en el maestro, el complemento emitirá una advertencia como (mysqlnd_ms) Couldn't find the appropriate slave connection. 0 slaves to choose from. Something is wrong in %s on line %d ((mysqlnd_ms) No se pudo encontrar la conexión esclava apropiada. 0 esclavos donde elegir. Algo está mal en %s en la línea %d).
node_groups
object
El filtro node_groups permite agrupas nodos de clúster y consultar grupos seleccionados, por ejemplo, para dar soporte al particionamiento de datos. El particionamiento de datos puede ser neceario para la fragmentación manual, copia primaria basada el clústeres ejecutándose en múltiples maestros, o para evitar puntos calientes en actualizaciones de cualquier clúster que no posea particionamiento interno. El filtro es un filtro múltiple que devuelve cero, uno o múltiples servidores de su entrada. Así, le deben seguir otros filtros para reducir el número de candidatos a uno por ejecución de sentencia.
Palabra clave | Descripción | Versión |
---|---|---|
nombre del grupo de nodos definido por el usuario |
Se debe definir uno o más grupos de nodos. Un grupos de nodos puede tener un nombre arbitrario definido por el usuario. El nombre se usa junto con una sugerencia SQL para restringir la ejecución de consultas a los nodos enumerados para el grupo de nodos. Para ejecutar una consulta en cualquier servidor de un grupo de nodos, esta debe comenzar con la sugerencia SQL /*user defined node group name*/. Observe que no están permitidos espacios en blanco en user defined node group name. Ya que user defined node group name se usa tal cual como parte de una sugerencia SQL, debería elegirse el nombre que siga las normas del lenguaje SQL.
Cada entrada del grupo de nodos debe contener una lista de servidores
master. Están permitidos servidores slave adicionales.
El no proporcionar una lista de master a un grupos de nodos
name_of_group podría causar un
error de tipo
La lista de servidores maestros y esclavos debe hacer referencia a las entradas
correspondientes en la lista de servidores
global de maestros
y esclavos respectivamente.
Hacer referencia a un servidor desconocido en ambas listas de
servidores podría causar un error
Ejemplo #23 Particionamiento manual { "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": [] } } } Observe que si una cadena de filtros genera una lista de esclavos vacía y la directiva de configuración de PHP mysqlnd_ms.multi_master=0 se usa, el complemento podría emitiri una advertencia. |
Desde 1.5.0. |
quality_of_service
object
El filtro quality_of_service identifica nodos del clúster capaces de proporcionar una calidad de servicio en particular. Es un filtro múltiple que devuelve cero, uno o múltiples de los servidores que se le proporcionen. Por lo tanto, deben seguirle otros filtros para reducir el número de candidatos a uno para la ejecución de sentecnias.
El filtro quality_of_service ha sido introducido en la versión 1.2.0-alpha. En las serires 1.2, el filtro se centra en el aspecto de la consistencia de la calidad del servicio. Diferentes tipos de clústeres ofrecen diferentes consistencias de datos predeterminadas. Por ejemplo, un esclavo de replicación MySQL asíncrono ofrece consistencia final. El esclavo podría no proporcionar los datos solicitados debido a que no ha replicado la escritura, podría servir una base de datos antigua debido a su demora, o podría servir información actual. A menudo, esto es aceptable. En algunos casos son necesarios niveles de consistencia mayor para que la aplicación funcione correctamente. En tales casos, quality_of_service puede ignorar los nodos del clúster que no proporcionen la calidad de servicio necesaria.
El filtro quality_of_service puede ser reemplazado o creado en tiempo de ejecución. Una llamada exitosa a mysqlnd_ms_set_qos() elimina todas las entradas de los filtros qos existentes de la lista de filtros e instala uno nuevo al principo de la misma. Todas los ajustes que se pueden hacer a través de mysqlnd_ms_set_qos() también pueden realizarse en el fichero de configuración del complemento. Sin embargo, el uso de la función es de lejos el caso más común. En lugar de establecer los niveles de servicios de consistencia de sesión y de consistencia fuerte en el fichero de configuración del complemento, se recomienda definir solamente maestros, y no esclavos. Ambos niveles de servicio forzarán el uso de maestros solamente. Usar una lista de esclavos vacía abrevia el fichero de configuración, y así se mejora su legibilidad. El único nivel de servicio en el que existe un caso para la definición en el fichero de configuración del complemento es la combinación de consistencia final y demora máxima de esclavos.
Palabra clave | Descripción | Versión |
---|---|---|
eventual_consistency |
Solicita la consistencia final. Permite el uso de todos los servidores maestros y esclavos. Los datos devueltos pueden o no ser actuales. La consistencia final acepta el parámetro opcional age. Si se proporciona age, el complemento considerará para la lectura solamente los esclavos que la replicación MySQL notifique que tengan una demora menor o igual a age. La demora de replicación se mide usando SHOW SLAVE STATUS. Si el complemento falla al recuperar la demora de replicación, saltará el esclavo comprobado. Los detalles de implementación y algunos consejos se proporcionan en la sección de conceptos de calidad de servicio. Por favor, observe que si una cadena de filtros genera un lista vacía de esclavos y se usa la directiva de configuración de PHP mysqlnd_ms.multi_master=0, el complemento podría emitir una advertencia.
Ejemplo #24 Límite global de la demora de los esclavos { "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 } } } } } |
Desde 1.2.0. |
session_consistency |
Solicita la consistencia de sesión (lectura de sus escrituras). Permite el uso de todos los maestros y todos los esclavos que están sincronizados con el maestro. Si no se proporcionan más parámetros, los esclavos son filtrados debido a que no existe una manera fiable de comprobar si un esclavo se a puesto al día con respecto al maestro o si está retrasado. Por favor, observe que si una cadena de filtros genera una lista de esclavos vacía y se usa la directiva de configuración de PHP mysqlnd_ms.multi_master=0, el complemento podría emitir una advertencia. La solicitud temporal de la consistencia de sesión usando mysqlnd_ms_set_qos() es una alternativa a usar master_on_write. master_on_write probablemente envía más sentencias al maestro de las necesarias. La aplicación puede continuar la operación en un nivel de consistencia más bajo después de haber realizado algunas lecturas críticas. |
Desde 1.1.0. |
strong_consistency |
Solitica la consistencia fuerte. Solamente serán usados los maestros. |
Desde 1.2.0. |
failover
Hasta, e incluyendo 1.3.x: string.
Desde 1.4.0: object.
Política de la tolerancia a fallos. Políticas admitidas: disabled (predeterminada), master, loop_before_master (desde 1.4.0).
Si no se establece ninguna política de tolerancia a fallos, el complemento no realizará ninguna tolerancia a fallos automática (failover=disabled). Siempre que el complemento falle al conectarse a un servidor, emitirá una advertencia y establecerá el código y el mensaje del error de conexión. A partir de entonces, es responsabilidad de la aplicación manejar el error y, por ejemplo, reenviar la última sentencia para provocar la selección de otro servidor.
Observe que la lógica de tolerancia a fallos automática se aplica al abrir conexiones solamente. Una vez que una conexión ha sido abierta, no se realizan intentos automáticos para reabrirla en caso de error. Si, por ejemplo, si la conexión a un servidor se cierra y el usuario intenta ejecutar una sentencia sobre dicha conexión, no se intentará la tolerancia a fallos automática. En su lugar se notificará un error.
Si se usa failover=master, el complemento implícitamente usará la tolerancia a fallos del maestro. Por favor, revise la documentación de conceptos para informarse sobre los problemas y riesgos potenciales del uso de failover=master.
Ejemplo #25 Tolerancia a fallos opcional en el maestro al fallar una conexión a un esclavo
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "failover": "master" } }
Desde PECL/mysqlnd_ms 1.4.0 la palabra clave de la configuración de la tolerancia a fallos se refiere a un objeto.
Ejemplo #26 Nueva sintaxis desde 1.4.0
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "failover": {"strategy": "master" } } }
Palabra clave | Descripción | Versión |
---|---|---|
strategy |
Política de tolerancia a fallos. Valores posibles: disabled (predeterminado), master, loop_before_master El valor disabled deshabilita la tolerancia a fallos automática. Establecer master ordena al complemento a intentar conectarse a un maestro en caso de un error de conexión esclava. Si el intento de conexión maestra falla, el comlemento se saldrá del bucle de tolerancia a fallos y devolverá un error al usuario. Si se usa loop_before_master y se realiza una petición a un esclavo, el complemento intentará conectarse a otro esclavo antes realizar la tolerancia a fallos en un maestro. Si se dan múltiples maestros y está habilitado el multimaestro, el complemento también iterará sobre la lista de maestros e intentará conectarse antes de devolver un error al usuario. |
Desde 1.4.0. |
remember_failed |
Recuerda los fallos durante una petición web. Predeterminado: false. Si se establece a true el complemento recordará los equipos anfitriones fallidos y los saltará en todos los equilibrados de carga futuros realizados para la duración de la petición web actual. |
Desde 1.4.0. La característica solamente está disponible junto con con los filtros de equilibrado de carga random y roundrobin. Se recomienda el uso del ajuste. |
max_retries |
Número máximo de intentos de conexión antes de saltarse un equipo anfitrión. Predeterminado: 0 (sin límite). Este ajuste se usa para prevenir que los equipos anfitriones sean elegidos de la lista host si ocurre un primer fallo. Si se establece a n > 0, el complemento guardará el nodo en la lista de nodos incluso después de un intento de conexión fallido. El nodo no será eliminado inmediatamente de las lista de esclavos y maestros respectivamente después del primer fallo de conexión, pero en su lugar se intentará conectar hasta n veces en las rondas de equilibrado de carga futuras antes de ser eliminado. |
Desde 1.4.0. La característica solamente está disponible junto con con los filtros de equilibrado de carga random y roundrobin. |
Establecer failover a cualquier valor distinto de disabled, master o loop_before_master no emitirá ninguna advertencia o error.
lazy_connections
bool
Controla el uso de conexiones retardadas. Las conexiones retardadas son conexiones que no se abren antes de que un cliente envíe la primera conexión. Las conexiones retardadas son las predeterminadas.
Se recomeinda encarecidamente usar conexiones retardadas. Éstas ayudan a mantener bajo el número de conexiones abiertas. Si se desabilitan las conexiones retardas y, por ejemplo, se configura un servidor maestro de replicación MySQL y dos esclavos de replicación MySQL, el complemento abrirá tres conexiones en la primera llamada a la función de conexión, aunque la aplicación podría usar solamente la conexión maestra.
Las conexiones retardadas revelan un riesgo si se realizan un gran uso de acciones que cambian el estado de una conexión. El complemento no resolverá todas las acciones de cambio de estado de todas las conexiones de la agrupación de conexiones. Las pocas acciones resueltas son aplicadas solamente a conexiones ya abiertas. Las conexiones retardadas abiertas en el futuro no son afectadas. Solamente algunos ajustes son "recordados" y aplicados cuando las conexiones retardadas son abiertas.
Ejemplo #27 Deshabilitar las conexiones retardadas
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "lazy_connections": 0 } }
Por favor, véase también server_charset para superar problemas potenciales con el escapado de cadenas de texto y con servidores que utilicen conjuntos de caracteres diferentes del predeterminado.
server_charset
string
Este ajuste ha sido introducido en la versión 1.4.0. Se recomienda establecerlo si se van a usar conexiones retardadas.
El ajuste server_charset sirve para dos propósitos. Actúa como conjunto de caracteres alternativo para su uso con el escapado de cadenas de texo realizado antes de que se haya establecido una conexión, y ayuda a evitar problemas de escapado en entornos heterogéneos con servidores que utilizan diferentes conjuntos de caracteres predeterminados.
El escapado de cadenas de texto toma en cuenta el conjunto de caracteres de una conexión. El escapado de cadenas de texto no es posible antes de que una conexión haya sido abierta y se conozca el conjunto de caracteres de de la conexión. El uso de conexiones retardadas demora la apertura real de conexiones hasta que se envíe una sentencia.
Una aplicación que utilice conexiones retardadas puede intentar escapar una cadena de texto antes de nviar una setencia. De hecho, esto debería ser un caso común, ya que la sentencia podría contener la cadena de texto que va a ser escapada. Sin embargo, debido a la característica de conexiones retardadas, aún no se ha abierto ninguna conexión y el escapado falla. El complemento podría notificar un error de tipo E_WARNING y un mensaje como (mysqlnd_ms) string escaping doesn't work without established connection. Possible solution is to add server_charset to your configuration ((mysqlnd_ms) el escapado de cadenas de texto no funciona sin establecer una conexión. Una posible solución es añadir server_charset a la configuración) para informar del problema.
Establecer server_charset hace que el complemento use el conjunto de caracteres dado para el escapado de cadenas de texto realizado sobre gestores de conexines retardadas antes de establecer una conexión de red a MySQL. Además, el complemento forzará el uso del conjunto de caracteres cuando la conexión sea establecida.
El forzado del uso del conjunto de caracteres utilizado para el escapado se realiza para prevenir los problemas de usar un conjunto de caracteres diferente para el escapado que el usado después para la conexión. Esto tiene el benificio adicional de eliminar la necesidad de ajustar la configuración del conjunto de caracteres de todos los servidores usados. No importa cuál sea el conjunto de caracteres predeterminado de cualquier servidor, el complemento establecerá el configurado como el predeterminado.
El complemento no impide al usuario cambiar el conjunto de caracteres en cualquier momento mediante la llamada a set_charset() o las setencias SQL correspondientes. Por favor, observe que el uso de SQL no se recomienda ya que no puede ser monitorizado por el complemento. El usuario puede, por ejemplo, cambiar el conjunto de caracteres sobre un gestor de conexiones retaradadas después de escapar una cadena de texto y antes de abrir la conexión real. El conjunto de caracteres establecido por el usuario será usado para cualquier escapado subsiguiente antes de que se establezca la conexión. Ésta será establecida usando el conjunto de caracteres configurado, sin importar cuál es el conjunto de caracteres del servidor ni cuál ha establecido el usuario antes. Una vez que una conexión ha sido abierta, set_charset ya no tiene sentido.
Ejemplo #28 Escapado de cadenas de texto sobre un gestor de conexiones retardadas
{ "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", "nombre_usuario", "contraseña", "base_datos");
$mysqli->real_escape("esto será escapado usando el ajuste server_charset - utf8");
$mysqli->set_charset("latin1");
$mysqli->real_escape("esto será escapado usando latin1");
/* conjunto de caracteres del servidor implícitamente establecido - conexión utf8 */
$mysqli->query("SELECT 'Esta conexión será fijada a server_charset durante su establecimiento' AS _msg FROM DUAL");
/* latin1 se usará de aquí en adelante */
$mysqli->set_charset("latin1");
?>
master_on_write
bool
Si se establece, el complemento usará únicamente el servidor maestro después de que se haya ejecutado la primera sentencia en el maestro. Las aplicaciones aún pueden enviar sentencias a los esclavos usando sugerencias SQL para invalidar la decisión automática.
Este ajuste puede ser útil con la demora de replicación. Si una aplicación ejecuta un INSERT, el complemento usará, de manera predeterminada, el maestro para ejecutar todas las sentencias siguientes, incluidas las sentencias SELECT. Esto ayuda a evitar problemas con las lecturas desde los esclavos que no hayan replicado aún el INSERT.
Ejemplo #29 master_on_write para lecturas consistentes
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "master_on_write": 1 } }
Por favor, observe que el filtro quality_of_service fue introducido en la versión 1.2.0-alpha. Proporciona mayor control sobre, por ejemplo, la realización de la lectura se sus escrituras y ofrece funcionalidad adicional introduciendo los niveles de servicio.
Todos los ajustes de adhesión de transacciones, incluyendo trx_stickiness=on, son invalidados por master_on_write=1.
trx_stickiness
string
Política de adhesión de transacciones. Las políticas admitidas son: disabled (predeterminada), master.
Este ajuste requiere la versión 5.4.0 o posterior. Si se usa con una versión de PHP anterior a la 5.4.0, el complemetno emitirá una advertencia como (mysqlnd_ms) trx_stickiness strategy is not supported before PHP 5.3.99 ((mysqlnd_ms) La estrategia trx_stickiness no está soportada antes de PHP 5.3.99).
Si no se establece ningun política de adhesión de transacciones o si se establece trx_stickiness=disabled, el complemento no considerará las transacciones. Por lo tanto, el complemento podrá realizar el equilibrado de carga de conexiones y el intercambio de conexiones en mitad de una trasacción. El complemento no es seguro con las transacciones. Se deben usar sugerencias SQL para evitar el intercambio de conexiones durante una transacción.
A partir de PHP 5.4.0, la bibliteca mysqlnd permite al complemento monitorizar el modo autocommit mediante las llamadas a la función set_autocommit() de la biblioteca. Si se establece set_stickiness=master y se deshabilita autocommit mediante una extensión de MySQL para PHP que invoque la llamada a la función interna set_autocommit() de la biblioteca mysqlnd, hará que el complemento considere el comienzo de una transacción. Luego, el complemento detiene el equilibrado de carga y dirige todas las setencias al servidor maestro hasta que autocommit sea habilitado. Por lo tanto, no son necesarias las sugerencias SQL.
Un ejemplo de una función de la API de MySQL para PHP que llama a la función interna set_autocommit() de la biblioteca mysqlnd es mysqli_autocommit().
Aunque se establezca trx_stickiness=master, el complemento no puede considerar los cambios del modo autocommit causados por sentencias SQL como SET AUTOCOMMIT=0 o BEGIN.
A partir de PHP 5.5.0, la biblioteca mysqlnd introduce llamadas adicionales a la API en C para controlar transacciones. El nivel de control coincide con el ofrecido por sentencias SQL. La API mysqli ha sido modificada para usar dichas llamadas. Desde la versión 1.5.0, PECL/mysqlnd_ms puede monitorizar no solo mysqli_autocommit(), sino también mysqli_begin(), mysqli_commit() y mysqli_rollback() para detectar los límites de transacciones y detener el equilibrado de carga durante una transacción.
Ejemplo #30 Utilizar el maestro para ejecutar transacciones
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "trx_stickiness": "master" } }
Desde la versión 1.5.0, la tolerancia a fallos automática y silenciosa está deshabilitada durante una transacción. Si los límites de una transacción han sido detectados apropiadamente, la adhesión de transacciones está habilitada y un servidor falla, el complemento no intentará realizar la tolerancia a fallos en el siguiente servidor, si lo hubiera, sin importar la configuración de la política de tolerancia a fallos. El usuario debe manejar el error de forma manual. Dependiendo de la configuración, el complemento podría emitir un error de tipo E_WARNING como (mysqlnd_ms) Automatic failover is not permitted in the middle of a transaction. Este error podría ser sobrescrito por errores siguientes como (mysqlnd_ms) No connection selected by the last filter. Esos errores serán generados por la función de consulta que falló.
Ejemplo #31 Sin tolerancia a fallos automáticia, inconveniente al manejar errores
<?php
/* supuesto: configurada la tolerancia a fallos automática */
$mysqli = new mysqli("myapp", "username", "password", "database");
/* establece el estado interno del complemento a in_trx = 1 */
$mysqli->autocommit(false);
/* supuesto: el servidor falla */
if (!($res = $mysqli->query("SELECT 'Assume this query fails' AS _msg FROM DUAL"))) {
/* manejar el fallo de la transacción, el estado interno del complemento aún es in_trx = 1 */
printf("[%d] %s", $mysqli->errno, $mysqli->error);
/*
Si se usa autocommit() basado en la detección de transacciones, es un
DEBER llamar a autocommit(true). De lo contrario el complemento asume
que la transacción actual continua y los cambios de
la conexión permanecen prohibidos.
*/
$mysqli->autocommit(true);
/* Igualmente, querrá iniciar una nueva transacción */
$mysqli->autocommit(false);
}
/* latin1 de ahora en adelante */
$mysqli->set_charset("latin1");
?>
Si un servidor falla en mitad de una transacción, el complemento continua rechazando el intercambio de conexiones hasta que haya finalizado la transacción en curso. Recuerde que el complemento monitoriza las llamadas a la API para detectar los límites de las transacciones. Por tanto, se ha de, por ejemplo, habilitar el modo auto commit para finalizar la transacción actual antes de que el complemento continue equilibrando la carga e intercambiando el servidor. De igual modo, querrá iniciar una nueva transacción inmediantamente a partir de aquí y deshabilitar de nuevo el modo auto commit.
El no manejar las consultas fallidas y no finalizar una transacción fallida usando las llamadas a la API, podría causar que todos los comandos siguientes emitan errores como Commands out of sync; you can't run this command now. Por lo tanto, es importante manejar todos los errores.
transient_error
object
El ajuste ha sido introducido en la versión 1.6.0.
Un nodo de un clúster de una base de datos podría replicar un error transitorio a un cliente. El cliente puede entonces repetir la operación sobre el mismo nodo, recurrir a otro nodo diferente o abortar la operación. Por definición, es seguro que un cliente reintente la misma operación sobre el mismo nodo antes de rendirse.
PECL/mysqlnd_ms puede realizar el bucle de reintento en nombre de la aplicación. Configurando transient_error, el complemento puede ser instruido para que repita las operaciones que fallen con ciertos códigos de error para un número máximo de veces con una pausa entre cada reintento. Si el error transitorio desaparece durante la ejecución del bucle, se oculta a la aplicación. De lo contrario, el error es reenviado a la aplicación al finalizar el bucle.
Ejemplo #32 Bucle de reintentos para errores transitorios
{ "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 } } }
Palabra clave | Descripción | Versión |
---|---|---|
mysql_error_codes |
La lista de los códigos de errores transitorios. Se podría añadir cualquier código de error de MySQL a la lista. Es posible considerar cualquier error como transitorio, no únicamente el 1297 (HY000 (ER_GET_TEMPORARY_ERRMSG), Message: Got temporary error %d '%s' from %s). Antes de añadir otros códigos, excepto el 1297, a la lista, asegúrese de que el clúster admite un nuevo intento sin impactar sobre el estado de la aplicación. |
Desde 1.6.0. |
max_retries |
Cuántas veces reintentar una operación que falla con un error transitorio antes de reenviar el fallo al usuario. Predeterminado: 1 |
Desde 1.6.0. |
usleep_retry |
Milisegundos a dormir antes de reintentar el error transitorio. El valor es pasado a la función usleep() en C, de ahí el nombre. Predeterminado: 100 |
Desde 1.6.0. |
xa
object
Este ajuste ha sido introducido en la versión 1.6.0.
Nota: Experimental
Esta característica está actualmente en desarrollo. Podrían existir problemas y/o limitaciones. No la use en entornos de producción.
Si almacenar el nombre de usuario y la contraseña de un participante de una transacción global en la tabla de participantes. Si está desacivado, la recolección de basura utilizará el nombre de usuario y contraseña predeterminados al conectarse a los participantes. A menos que se esté utilizando un nombre de usuario y contraseña diferentes para cada servidor de MySQL, se pueden emplear los predeterminados y evitar el almacenamiento de información sensible en el almacén de estado.
Observe que el nombre de usuario y la contraseña se almacenan en texto claro al usar el almacén de estado de MySQL, el cual es el único disponible. Es su responsabilidad proteger esta información sensible.
Predeterminado: false
Durante la recolección de basura de XA, el complemento podría encontrar un servidor participante para el cual haya sido anotado el host localhost. Si la recolección de basura toma lugar en otro host que no sea que haya escrito el registro de participantes en el almacén de estado, el nombre de host localhost ahora se resuelve a un host diferente. Por tanto, al anotar un nombre de host de un servidor participante en el almacén de estado, un valor de localhost debe ser reemplazado con la dirección IP real de localhost.
El establecimiento de participant_localhost_ip solamente debería ser considerado si el empleo localhost no se puede evitar. Solamente desde el punto de vista de la recolección de basura, es preferible no configurar ninguna conexión de socket, sino porprocionar una dirección IP y un puerto para un nodo.
El almacén de estado de MySQL es el único almacén de estado disponible.
Nombre de la tabla de MySQL empleada para almacenar el estado de una transacción global en curso o abortada. Use la sentencia SQL de abajo para para crear la tabla. Asegúrese de editar el nombre de la tabla para que coincida con su configuración.
Predeterminado: mysqlnd_ms_xa_trx
Ejemplo #33 Definición SQL para la tabla de transacciones de almacenamiento de estado de MySQL
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
Nombre de la tabla de MySQL empleada para almacenar los participantes de una transacción global en curso o abortada. Use la sentencia SQL de abajo para para crear la tabla. Asegúrese de editar el nombre de la tabla para que coincida con su configuración.
Se pueden habilitar y deshabilitar el almacenamiento de credenciales con record_participant_credentials
Predeterminado: mysqlnd_ms_xa_participants
Ejemplo #34 Definición SQL para la tabla de transacciones de almacenamiento de estado de MySQL
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
Nombre de la tabla de MySQL empleada para rastrear y sincronizar ejecuciones de recolección de basura. en curso o abortada. Use la sentencia SQL de abajo para para crear la tabla. Asegúrese de editar el nombre de la tabla para que coincida con su configuración.
Predeterminado: mysqlnd_ms_xa_gc
Ejemplo #35 Definición SQL para la tabla de transacciones de almacenamiento de estado de MySQL
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
Nombre de host del servidor de MySQL.
Nombre del usuario empleado para conectarse al servidor de MySQL.
Contraseña para el usuario del servidor de MySQL.
Base de datos que guarda las tablas de recolección de basura. Observe que se han de crear las tablas de recolección de basura antes de utilzar el complemento. Las tablas no serán creadas implícitamente durante el tiempo de ejecución, por lo que la recolección de basura fallará si las tablas no existen.
Puerto del servidor de MySQL.
Socket de dominio Unix del servidor de MySQL. Observe que si se tiene variaor servidores de PHP, cada uno intentará realizar la recolección de basura, siendo necesario que sean capces de conectarse al almacén de estado. En este caso, podría ser preferible configurar una dirección IP y un puerto para el servidor de almancen de estado de MySQL para asegurarse de que los servidores de PHP se pueden conectar a él.
Si revertir automáticamente una transacción global abierta cuando se cierre una conexión. Si está habilitado, imita el comportamiento predeterminado de las transacciones locales. Si un cliente se desconecta, el servidor revertirá cualquier transacción abierta y no finalizada.
Predeterminado: true
Número máximo de ejecuciones de la recolección de basura antes de rendirse. Los valores permitidos van de 0 hasta 100. Un valor de 0 significa sin límite, a menos que el almacén de estado fuerce uno. Si el almacén fuerza un límite, se suponeque podría ser significativamente mayor de 100. Disponible desde 1.6.0.
Obsérvese que es importante finalizar las transacciones XA fallidas dentro de un tiempo razonable para que los servidores participantes liberen recursos vinculados a la transacción. Es poco probable que la recolección de basura falle por un período grande siempre y cuando los servidores caídos estén disponibles de nuevo rápidamente. Todavía podría darse una situación donde se requiera la intervención humana debido a que la recolección de basura interna se detuvo o falló. En este caso, se podría comprobar primero si la transacción no se puede arreglar aún forzando a mysqlnd_ms_xa_gc() para que ignore el ajuste, antes de tratarlo manualmente.
Predeterminado: 5
Probabilidad de la recolección de basura. Los valores permitidos van desde 0 a 1000. Un valor de 0 deshabilita la recolección de basura automática en segundo plano. Aún estableciendo un valor de 0, es posible ocasionar la recolección de basura llamando a mysqlnd_ms_gc(). Disponible desde 1.6.0.
La recolección de basura de transacciones XA obsoletas solamente está disponible si se ha configurado un almacén de estados. El almacén de estados es responsable de seguir la pista a las transacciones XA. Basándose en sus registros, puede encontrar transacciones XA bloqueadas a causa de la desconexión del cliente, conectarse a los participantes y revertir las transacciones no finalizadas.
La recolección de basura se desencadena como parte de un procedimiento de apagado de solicitud de PHP al final de una petición web. Esto es, después de haber finalizado el script de PHP. Para decidir si se ejecuta la recolección de basura se computa un valor aleatorio entre 0 y 1000. Si el valor de probability es mayor o igual al valor aleatorio, se invocan a las rutinas de la recolección de basura del almacén de estados.
Predeterminado: 5
Número máximo de transacciones XA no finalizadas consideradas por la recolección de basura durante una ejecución. Los valores permitidos van desde 1 hasta 32768. Dsiponible desde 1.6.0.
Limpiar una transacción XA no finalizada toma una cantidad de tiempo y recursos considerables. La rutina de recolección de basura podría tener que conectarse a varios participantes de una transacción global fallida para enviar los comandos SQL necesarios para revertir la transacción no finalizada.
Predeterminado: 100
Nota:
La descripción de abajo se aplica a PECL/mysqlnd_ms < 1.1.0-beta. No es válida para versiones posteriores.
El complemento usa su propio fichero de configuración. Éste guarda información sobre el servidor maestro de replicación MySQL, los servidores esclavos de replicación MySQL, la política de elección (equilibrado de carga), la estrategia de tolerancia a fallos, y el uso de conexiones retardadas.
La directiva de configuración de PHP mysqlnd_ms.ini_file se usa para establecer el fichero de configuración del complemento.
El fichero de configuración imita el estándar del formato de php.ini. Consiste en una o más secciones. Cada sección define su propia unidad de ajustes. No existe una sección global para ajustes globales.
Las aplicciones hacen referencia a las secciones por su nombre. Las aplicaciones usan los nombres de las secciones como el parámetro 'host' (servidor) de los distintos métodos de conexión de las extensiones mysqli, mysql y PDO_MYSQL. Durante la conexión, el complemento de mysqlnd compara el nombre del equipo anfitrión con todos los nombres de las secciones del fichero de configuración del complemento. Si el nombre del equipo anfitrión y el nombre de la sección coinciden, el complemento cargará la configuración de esa sección.
Ejemplo #36 Ejemplo del uso de nombres de sección
[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
/* Todas las conexiones siguientes tendrán equilibrado de carga */
$mysqli = new mysqli("myapp", "nombre_usuario", "contraseña", "base_datos");
$pdo = new PDO('mysql:host=myapp;dbname=base_datos', 'nombre_usuario', 'contraseña');
$mysql = mysql_connect("myapp", "nombre_usuario", "contraseña");
$mysqli = new mysqli("localhost", "nombre_usuario", "contraseña", "base_datos");
?>
Los nombres de sección son cadenas de texto. Es válido usar nombres de sección como 192.168.2.1, 127.0.0.1 o localhost. Si, por ejemplo, una aplicación se conexta a localhost y existe una sección de configuración del complemento llamada [localhost], la semántica de la operación de conexión se cambia. La aplicación ya no usará únicamente el servidor MySQL que se ejecuta en el equipo anfitrión localhost, sino que el complemento iniciará el equilibrado de carga de las consultas MySQL siguiendo las reglas de la sección de configuración [localhost]. De esta manera se puede realizar el equilibrado de carga de consultas desde una aplicación sin cambiar el código fuente de la misma.
Las directivas de configuración master[], slave[] y pick[] usan una sintaxis similar a una lista. Las directivas de configuración que admiten la sintaxis de lista pueden aparecer varias veces en la sección de configuración. El complemento mantiene el orden en el que aparecen las entradas cuando las interpreta. Por ejemplo, el ejemplo de abajo muestra dos directivas de configuración slave[] en la sección de configuración [myapp]. Si se realiza el equilibrado de carga rotativo para consultas de solo lectura, el complemento enviará la primera consulta de solo lectura al servidor MySQL mysql_slave_1 ya que es el primero de la lista. La segunda consulta de solo lectura será enviada al servidor MySQL mysql_slave_2 ya que es el segundo de la lista. Los resultados de las directivas de configuración que admiten la sintaxis de lista están ordenados de arriba a abajo según su aparación dentro de la sección de configuración.
Ejemplo #37 Sintaxis de lista
[myapp] master[] = mysql_master_server slave[] = mysql_slave_1 slave[] = mysql_slave_2
He aquí una breve explicación de las directivas de configuración que se pueden usar.
master[]
string
URI de un servidor maestro de replicación MySQL. El URI sigue la sintaxis hostname[:port|unix_domain_socket].
El complemento admite el uso de un único servidor maestro.
Es obligatorio establece un servidor esclavo. El complemento notificará una advertencia sobre la conexión si el usuario ha fallado al proporcionar un servidor esclavo en la sección de configuración. La advertencia podría ser (mysqlnd_ms) Cannot find master section in config ((mysqlnd_ms) No se pudo encontrar una sección de maestros en la configuración). Además, el complemento puede establecer un código de error para el gestor de conexión tal como HY000/2000 (CR_UNKNOWN_ERROR). El mensaje de error correspondiente depende de la configuración del lenguaje.
slave[]
string
URI de uno o más servidores esclavos de replicación MySQL. El URI sigue la sintaxis hostname[:port|unix_domain_socket].
El complemento admite el uso de uno o más servidores esclavos.
Es oblligatorio establecer un servidor esclavo. El complemento notificará una advertencia sobre la conexión si el usuario ha fallado al proporcionar al menos un servidor esclavo en la sección de configuración. La advertencia podría ser (mysqlnd_ms) Cannot find slaves section in config ((mysqlnd_ms) No se pudo encontrar una sección de esclavos en la configuración). Además, el complemento puede establecer un código de error para el gestor de conexión tal como HY000/2000 (CR_UNKNOWN_ERROR). El mensaje de error correspondiente depende de la configuración del lenguaje.
pick[]
string
La política de equilibrado de carga (selección de servidores). Políticas soportadas: random, random_once (predeterminada), roundrobin, user.
Si no se establece ninguna política de equilibrado de carga, el complemento usará como predeterminada random_once. La política random_once elige un servidor esclavo aleatorio al ejecutar la primera sentencia de solo lectura. Este servidor esclavo será utilizado para todas las sentencias de solo lectura hasta que finalice la ejecución del script de PHP.
La política random eligirá un servidor aleatorio siempre que se ejecute una sentencia de solo lectura.
Si se usa roundrobin el complemento iterará sobre la lista de servidores esclavos configurados para elegir uno para la ejecución de sentencias. Si el complemento alcanza el final de la lista, volverá al comienzo de la misma y eligirá el primer servidor esclavo configurado.
El establecimiento de más de una política de equilibrado de carga en una sección de configuración solamente tiene sentido si se usa user y mysqlnd_ms_set_user_pick_server() juntos. Si la llamada de retorno del usuario falla al elegir un servidor, el complemento volverá a la segunda política de equilibrado de carga cofigurada.
failover
string
Política de tolerancia de fallos. Políticas admitidas: disabled (predeterminada), master.
Si no se establece ninguna política de tolerancia a fallos, el complemento no realizará ninguna tolerancia a fallos automática (failover=disabled). Siempre que el complemento falle al conectarse a un servidor, emitirá una advertencia y establecerá el código y el mensaje del error de conexión. A partir de entonces, es responsabilidad de la aplicación manejar el error y, por ejemplo, reenviar la última sentencia para provocar la selección de otro servidor.
Si se usa failover=master, el complemento implícitamente usará la tolerancia a fallos de un esclavo. Por favor, revise la documentación de conceptos para informarse sobre los problemas y riesgos potenciales del uso de failover=master.
lazy_connections
bool
Controla el uso de conexiones retardadas. Las conexiones retardadas son conexiones que no se abren antes de que un cliente envíe la primera conexión. Las conexiones retardadas son las predeterminadas.
Se recomeinda encarecidamente usar conexiones retardadas. Éstas ayudan a mantener bajo el número de conexiones abiertas. Si se desabilitan las conexiones retardas y, por ejemplo, se configura un servidor maestro de replicación MySQL y dos esclavos de replicación MySQL, el complemento abrirá tres conexiones en la primera llamada a la función de conexión, aunque la aplicación podría usar solamente la conexión maestra.
Las conexiones retardadas revelan un riesgo si se realizan un gran uso de acciones que cambian el estado de una conexión. El complemento no resolverá todas las acciones de cambio de estado de todas las conexiones de la agrupación de conexiones. Las pocas acciones resueltas son aplicadas solamente a conexiones ya abiertas. Las conexiones retardadas abiertas en el futuro no son afectadas. Si, por ejemplo, se cambia el conjunto de caracteres de la conexión usando una llamada a la API de MySQL para PHP, el complemento cambiará el conjunto de caracteres de todas las conexiones abiertas en uso. No recordraá el cambio del conjunto de caracteres para aplicarlo en las conexiones retardadas abiertas en el futuro. Como resultado, la agrupación de conexiones interna guardaría conexiones que usarían diferencites conjuntos de caracteres. Esto no es lo deseado. Recuerde que los conuntos de caracteres se toman en cuenta para el escapado.
master_on_write
bool
Si se establece, el complemento usará únicamente el servidor maestro después de que se haya ejecutado la primera sentencia en el maestro. Las aplicaciones aún pueden enviar sentencias a los esclavos usando sugerencias SQL para invalidar la decisión automática.
Este ajuste puede ser útil con la demora de replicación. Si una aplicación ejecuta un INSERT, el complemento usará, de manera predeterminada, el maestro para ejecutar todas las sentencias siguientes, incluidas las sentencias SELECT. Esto ayuda a evitar problemas con las lecturas desde los esclavos que no hayan replicado aún el INSERT.
trx_stickiness
string
Política de adhesión de transacciones. Las políticas admitidas son: disabled (predeterminada), master.
Característica experimental.
Este ajuste requiere la versión 5.4.0 o posterior. Si se usa con una versión de PHP anterior a la 5.4.0, el complemetno emitirá una advertencia como (mysqlnd_ms) trx_stickiness strategy is not supported before PHP 5.3.99 ((mysqlnd_ms) La estrategia trx_stickiness no está soportada antes de PHP 5.3.99).
Si no se establece ningun política de adhesión de transacciones o si se establece trx_stickiness=disabled, el complemento no considerará las transacciones. Por lo tanto, el complemento podrá realizar el equilibrado de carga de conexiones y el intercambio de conexiones en mitad de una trasacción. El complemento no es seguro con las transacciones. Se deben usar sugerencias SQL para evitar el intercambio de conexiones durante una transacción.
A partir de PHP 5.4.0, la bibliteca mysqlnd permite al complemento monitorizar el modo autocommit mediante las llamadas a la función set_autocommit() de la biblioteca. Si se establece set_stickiness=master y se deshabilita autocommit mediante una extensión de MySQL para PHP que invoque la llamada a la función interna set_autocommit() de la biblioteca mysqlnd, hará que el complemento considere el comienzo de una transacción. Luego, el complemento detiene el equilibrado de carga y dirige todas las setencias al servidor maestro hasta que autocommit sea habilitado. Por lo tanto, no son necesarias las sugerencias SQL.
Un ejemplo de una función de la API de MySQL para PHP que llama a la función interna trx_autocommit() de la biblioteca mysqlnd es mysqli_autocommit().
Aunque se establezca ser_stickiness=master, el complemento no puede considerar los cambios del modo autocommit causados por setnencias SQL como SET AUTOCOMMIT=0.
Nota:
Esta sección se aplica a la versión mysqlnd_ms 1.1.0 o posterior, no a la serie 1.0.
El conjunto de pruebas de PECL/mysqlnd_ms se encuentra en el directorio tests/ de la distribución del código fuente. El conjunto de pruebas consiste en unas pruebas phpt estándar, que están descriptas en la página web de PHP Quality Assurance Teams.
La ejecución de las pruebas requiere configurar de uno a cuatro servidores MySQL. Algunas pruebas no se conectan a MySQL de ningún mofo. Otras requieren un servidor. Algunas requieren dos servidores distintos. En algunos casos se usan dos servidores para emular una configuración de replicación. En otros casos se requieren un maestro y un esclavo existentes de una configuración de replicación MySQL. Las pruebas intentarán detectar cuántos servidores y qué tipo de servidores se dan. Si no se encuentran los servidores requeridos, la prueba será saltada automáticamente.
Antes de ejecutar las pruebas, edite tests/config.inc para configurar los servidores MySQL a usar durante las mismas.
La configuracion más básica es como sigue.
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"); /* replication cluster emulation */ putenv("MYSQL_TEST_EMULATED_MASTER_HOST=". getenv("MYSQL_TEST_HOST")); putenv("MYSQL_TEST_EMULATED_SLAVE_HOST=". getenv("MYSQL_TEST_HOST")); /* real replication cluster */ 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 y MYSQL_TEST_SOCKET definen el nombre del equipo anfitrión, el puerto TCP/IP y el socket de dominio Unix del servidor de la base de datos predeterminado. MYSQL_TEST_USER y MYSQL_TEST_PASSWD contienen el usuario y la contraseña necesarios para conectarse a la base de datos o esquema configurado con MYSQL_TEST_DB. Todos los servidores configurados han de tener el mismo usuario de base de datos configurado para proporcionar el acceso a la base de datos de prueba.
Con la sintaxis host, host:puerto o host:/ruta/al/socket se puede establecer un equipo anfitrión, un equipo anfitrión y un puerto o un equipo anfitrión y un socket suplentes para cualquier servidor.
putenv("MYSQL_TEST_SLAVE_HOST=192.168.78.136:3307")); putenv("MYSQL_TEST_MASTER_HOST=myserver_hostname:/path/to/socket"));
El registro de depuración de mysqlnd se puede usar para depurar y rastrear las actividades de PECL/mysqlnd_ms. Al igual que mysqlnd, PECL/mysqlnd_ms añade información de rastreo al fichero de depuración de la bibliteca mysqlnd. Por favor, lea la directiva de configuración mysqlnd.debug de PHP para una descripción detallada de cómo configurar el registro de depuración.
Ejemplo de ajuste de configuración para activar el registro de depuración:
mysqlnd.debug=d:t:x:O,/tmp/mysqlnd.trace
Nota:
Esta característica solamente está disponible con una construcción de depuración de PHP. Funciona en Microsoft Windows si se usa una construcción de depuración de PHP y PHP fue compilado usando Microsoft Visual C versión 9 y superior.
El registro de depuración muestra las llamadas a las funciones de la biblioteca mysqlnd y del complemento PECL/mysqlnd_ms, similar a un registro de rastreo. Las llamadas de la biblioteca mysqlnd normalmente están prefijadas con mysqlnd_. Las llamadas internas a PECL/mysqlnd comienzan con mysqlnd_ms.
Extracto de ejemplo del registro de depuración (conectar):
[...] >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 [...]
El registro de depuración no sólo es útila para los desarrolladores del complemento, sino también para encontrar la causa de los errores ocurridos. Por ejemplo, si una aplicación no maneja apropiadamente los errores y falla al registrar mensajes de error, la revisión del registro de depuración y rastreo podría ayudar a encontrar la causa. El uso del registro de depuración para depurar problemas de una aplicación debería considerarse solamente si no está disponible ninguna otra opción. Escribir el registro de depuración en el disco es una operación lenta y podría tener un impacto negativo sobre el rendimiento de la aplicación.
Extracto de ejemplo del registro de depuración (fallo de conexión):
[...] | | | | | | | 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 [...]
El registro de rastreo también se puede usar para verificar el comportamiento correcto del mismo PECL/mysqlnd_ms, por ejemplo, para comprobar qué servidor ha sido seleccionado para la ejecución de una consulta y por qué.
Extracto de ejemplo del registro de depuración (decisión del complemento):
[...] >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
En este caso, la sentencia DROP TABLE IF EXISTS test ha sido ejecutada. Observe que el string de la sentencia se muestra en el fichero de registro. Se podrían tomar medidas para restringir el acceso al registro por consideraciones de seguridad.
La sentencia ha sido equilibrada en carga usando la política de rotación ('round robin'), como se puede adivinar fácilmente del nombre de la función >mysqlnd_ms_choose_connection_rr. Ha sido enviada a un servidor maestro que se ejecuta en host=localhost user=root db=test port=3306 flags=131072 persistent=0 state=0.
La actividad del complemento se puede monitorizar usando el registro de rastreo de mysqlnd, las estadísticas de mysqlnd, las estadísticas del complemento mysqlnd_ms y herramientas de depuración externas de PHP. El uso del registro de rastreo debería limitarse a la depuración. Se recomienda usar las estadísticas del complemento para la monitorización.
La escritura de un registro de rastreo es una operación lenta. Si se usa una herramiento de depuración externa de PHP, consulte el manual del proveedor para el impacto de rendimiento y el tipo de información recopilada. En la mayoría de los casos, las herramientas de depuración externas proporcionarán pilas de llamadas. A menudo, es más difícil interpretar una pila de llamadas o un registro de rastreo que las estadísticas proporcionadas por el complemento.
Las estadísticas del complemento indican con qué frecuencia se ha usado un tipo de clúster (esclavo o maestro), por qué se ha usado el nodo, si se han usado conexiones retardadas y si se ha realizado una inyección de ID de transacciones global. La información de la monitorización proporcionada permite al usuario verificar las decisiones del complemento y planear los recursos del clúster basándose en el patrón de uso. La función mysqlnd_ms_get_stats() se usa para acceder a las estadísticas. Por favor, vea las descripciones de las funciones para obtener una lista de las estadísticas disponibles.
Las estadísticas se recopilan en función de cada proceso de PHP. Su alcance es un proceso de PHP. Dependiendo del modelo de desarrollo de PHP, un proceso puede servir una o múltiples peticiones web. Si se usa el modelo CGI, un proceso de PHP sirve una petición web. Si se usa FastCGI o modelos de servidores web prebifurcados, un modelo de PHP normalmente servirá múltiples peticiones web. Lo mismo ocurre en el caso de un servidor web con subprocesos. Observe que los hilos ejecutados en paralelo podrían actualizar las estadísticas en paralelo. Por lo tanto, si se usa un modelo de desarrolo de PHP con hilos, las estadísticas podrían ser modificadas por más de un script al mismo tiempo. Un script no puede depender del hecho de que vea solamente sus propios cambios realizados a las estadísticas.
Ejemplo #38 Comprobar la actividad del complemento en un modelo de desarrollo sin hilos
mysqlnd_ms.enable=1 mysqlnd_ms.collect_statistics=1
<?php
/* Equilibrado de carga siguiendo las reglas de la sección "myapp" del fichero de configuración del complemento (no se muestra) */
$mysqli = new mysqli("myapp", "nombre_usuario", "contraseña", "base_datos");
if (mysqli_connect_errno())
/* Por supuesto, su manejo de errores es más agradable... */
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 "Según las estadísticas, ¡la petición de lectura no se ha ejecutado en un esclavo!";
}
?>
Las estadísticas se agregan para todas las actividades del complemento y todas las conexión manejadas por el mismo. No es posible indicar cuánto contribuye un gestor de conexión en particular para el total de las estadísticas.
Utilizar la función de PHP register_shutdown_function() o la directiva de configuración de PHP auto_append_file es posiblemente más sencillo para volcar las estadísticas, por ejemplo, a un fichero de registro cuando un script finaliza. En lugar de usar un fichero de registro, también es posible enviar las estadísticas a una herramienta externa de monitorización para su registro y visualización.
Ejemplo #39 Registrar las estadístcias durante el cierre
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");
?>