Las sugerencias SQL pueden forzar a una consulta a elegir un servidor específico de la agrupación de conexiones. Proporcionan al complemento una recomendación para utilizar un servidor indicado, lo que puede resolver problemas causados por intercambios de conexión y estados de conexión.
Las sugerencias SQL son comentarios que siguen el estándar. Ya que los comentarios SQL son ignorados por sistemas de procesamiento SQL, no interfieren con otros programas como el Servidor MySQL, el Proxy MySQL, o un cortafuegos.
El complemento admite tres sugerencias SQL: La
sugerencia MYSQLND_MS_MASTER_SWITCH
hace que el complemento ejecute una
sentencia en el maestro, MYSQLND_MS_SLAVE_SWITCH
fuerza el uso del esclavo, y
MYSQLND_MS_LAST_USED_SWITCH
ejecutará una sentencia en
el mismo servidor que se utilizó con la sentencia anterior.
El complemento examina el comienzo de una sentencia para la existencia de una sugerencia SQL. Las sugerencias SQL solo son reconocidas si aparecen al comienzo de la sentencia.
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 Sugerencias SQL para evitar el intercambio de conexión
<?php
$mysqli = new mysqli("myapp", "nombre_usuario", "contraseña", "base_datos");
if (mysqli_connect_errno()) {
/* 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 1, se ejecuta en el maestro debido a la sugerencia SQL */
if (!($res = $mysqli->query(sprintf("/*%s*/SELECT @myrole AS _role", MYSQLND_MS_LAST_USED_SWITCH)))) {
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 = 'master'
En el ejemplo de arriba, el uso de MYSQLND_MS_LAST_USED_SWITCH
evita
el intercambio de sesión desde el maestro al esclavo al ejecutar la sentencia
SELECT.
Las sugerencias SQL también se pueden usar para ejecutar sentencias SELECT en el servidor maestro de MySQL. Esto podría ser necesario si los servidores esclavos de MySQL están normalmente detrás del maestro, pero no se necesitan datos actuales del clúster.
En la versión 1.2.0, el concepto de nivel de servicio ha sido introducido para dirigir casos en los que no son necesarios datos actuales. El uso de un nivel de servicio requiere menos atención y elimina la necesidad de usar sugerencias SQL para este caso. Se puede encontrar más información más abajo en la sección de nivel de servicio y consistencia.
Ejemplo #3 Enfrentarse a la demora de replicación
<?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()));
}
/* Forzar el uso del maestro, el maestro siempre tiene datos recientes y actuales */
if (!$mysqli->query(sprintf("/*%s*/SELECT critical_data FROM important_table", MYSQLND_MS_MASTER_SWITCH))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
?>
Un caso de uso puede incluir la creación de tablas en un esclavo.
Si no se proporciona una sugenrencia SQL, el complemento enviará las sentencias
CREATE e INSERT al maestro. Utilice la
sugerencia SQL MYSQLND_MS_SLAVE_SWITCH
si quiere
ejecutar tales sentencias en un esclavo, por ejemplo, para construir tablas de
informes temporales.
Ejemplo #4 Creación de una tabla en un esclavo
<?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()));
}
/* Forzar el uso del esclavo */
if (!$mysqli->query(sprintf("/*%s*/CREATE TABLE informes_esclavo(id INT)", MYSQLND_MS_SLAVE_SWITCH))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
/* Continuar usando esta conexión esclava en particular */
if (!$mysqli->query(sprintf("/*%s*/INSERT INTO informes_esclavo(id) VALUES (1), (2), (3)", MYSQLND_MS_LAST_USED_SWITCH))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
/* ¡No usar MYSQLND_MS_SLAVE_SWITCH, ya que permitiría el intercambio con otro esclavo! */
if ($res = $mysqli->query(sprintf("/*%s*/SELECT COUNT(*) AS _num FROM informes_esclavo", MYSQLND_MS_LAST_USED_SWITCH))) {
$fila = $res->fetch_assoc();
$res->close();
printf("Hay %d filas en la tabla 'informes_esclavo'", $fila['_num']);
} else {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
$mysqli->close();
?>
La sugerencia SQL MYSQLND_MS_LAST_USED
prohíbe el intercambio de una
conexión, por lo que fuerza el uso de la conexión utilizada anteriormente.