(PECL mysqlnd_ms < 1.1.0)
mysqlnd_ms_set_user_pick_server — Establece una llamada de retorno para la división de lectura/escritura definida por el usuario
$function
) : bool
Establece una llamada de retorno para la división de lectura/escritura definida por el usuario.
El complemento invocará a la llamada de retorno solamente si pick[]=user
el la regla predeterminada para elegir servidores en la sección relevante del fichero de
configuración del complemento.
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.
function
La función a llamar. Se pueden invocar también métodos de clases
de forma estática usando esta función pasando
array($nombre_clase, $nombre_método)
a este parámetro.
Además, los métodos de clases de una instancia de objeto se pueden llamar pasando
array($instancia_objeto, $nombre_método)
a este parámetro.
El equipo anfitrión donde ejecutar la consulta. El URI del equipo anfigrión se toma
de las listas de maestros y esclavos configurados pasadas a la función de llamada de retorno.
Si la llamada de retorno devuelve un valor que no se encuentra ni en las listas de conexión a
maestros ni en la de esclavos, el complemento usará el segundo método de elección configurado
mediante el ajuste pick[]
del fichero de configuración del complemento.
Si no se proporciona un segundo método de elección, el complemento usará el método interno
predeterminado de seleccionar un servidor.
Nota:
mysqlnd_ms_set_user_pick_server() está disponible con PECL mysqlnd_ms < 1.1.0. Ha sido reemplazado por el filtro
user
. Por favor, revise el Historial de cambios para las notas sobre actualizaciones.
Ejemplo #1 Ejemplo de mysqlnd_ms_set_user_pick_server()
[myapp] master[] = localhost slave[] = 192.168.2.27:3306 slave[] = 192.168.78.136:3306 pick[] = user
<?php
function pick_server($connected, $query, $master, $slaves, $last_used)
{
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;
break;
}
printf("... ret = '%s'\n", $ret);
return $ret;
}
mysqlnd_ms_set_user_pick_server("pick_server");
$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:
User has connected to 'myapp'... ... deciding where to run 'SELECT 1 FROM DUAL' ... some read-only query for a slave ... ret = 'tcp://192.168.2.27:3306' User has connected to 'myapp'... ... deciding where to run 'SELECT 2 FROM DUAL' ... some read-only query for a slave ... ret = 'tcp://192.168.78.136:3306' User has connected to 'myapp'... ... deciding where to run 'SELECT * FROM table_on_slave_a_only' ... access to table available only on slave A detected ... ret = 'tcp://192.168.2.27:3306'
user