El complemento cambia la semántica de un gestor de conexión de MySQL para PHP. Un gestor de conexión representa una agrupación de conexiones, en lugar de una única conexión de red cliente-servidor de MySQL. La agrupación de conexiones consiste en una conexión maestra, y opcionalmente cualquier número de conexiones esclavas.
Cada conexión de la agrupación de conexiones tiene su propio estado. Por ejemplo, las variables SQL de usuario, las tablas temporales y las transacciones, son parte del estado. Se puede encontrar un listado completo con los elementos que pertenecen al estado de una conexión en los conceptos de la documentación de agrupación e intercambio de conexiones. Si el complemento decide intercambiar conexiones para equilibrar la carga, a la aplicación se le podría proporcionar una conexión que tuviera un estado diferente. Las aplicaciones deben considerar esto.
Ejemplo #1 Configuración del complemento con un esclavo y un maestro
{ "myapp": { "master": { "master_0": { "host": "localhost", "socket": "\/tmp\/mysql.sock" } }, "slave": { "slave_0": { "host": "192.168.2.27", "port": "3306" } } } }
Ejemplo #2 Problema: estado de conexión y variables SQL de usuario
<?php
$mysqli = new mysqli("myapp", "nombre_usuario", "contraseña", "base_datos");
if (!$mysqli) {
/* Por supuesto, su manejo de errores es mejor... */
die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
}
/* Conexión 1, la conexión vincula una variable SQL de usuario, no se ejecuta ningún SELECT en el maestro */
if (!$mysqli->query("SET @myrole='master'")) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
/* Conexión 2, se ejecuta en el esclavo a causa de SELECT */
if (!($res = $mysqli->query("SELECT @myrole AS _role"))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
} else {
$fila = $res->fetch_assoc();
$res->close();
printf("@myrole = '%s'\n", $fila['_role']);
}
$mysqli->close();
?>
El resultado del ejemplo sería:
@myrole = ''
El ejemplo abre una conexión con equilibrio de carga y ejecuta dos sentencias. La primera sentencia SET @myrole='master' no comienza con la cadena SELECT. Por lo tanto, el complemento no la reconoce como una consulta de solo lectura que se ejecutaría en un esclavo. El complemento ejecuta la sentencia en una conexión al maestro. La sentencia establece una variable SQL de usuario que está vinculada a la conexión con el maestro. El estado de la conexión maestra ha sido cambiado.
La siguiente sentencia es SELECT @myrole AS _role. El complemento la reconoce como una consulta de solo lectura y la envía al esclavo. La sentencia se ejecuta en una conexión al esclavo. Esta segunda conexión no tiene ninguna variable SQL de usuario vinculada a ella. Tiene un estado diferente a la primera conexión al maestro. La variable SQL de usuario no está establecida. El script del ejemplo imprime @myrole = ''.
Es responsabilidad del desarrollador de la apliación ocuparse del estado de la conexión. El complemento no monitoriza todas las actividades de cambio de estado. La monitorización de todos los casos posibles sería una tarea intensiva de la CPU, si es que esta tarea pudiera ser realizada.
Los problemas se pueden evitar fácilmente usando sugerencias SQL.