mirror of
https://github.com/php/doc-es.git
synced 2026-03-30 03:12:07 +02:00
git-svn-id: https://svn.php.net/repository/phpdoc/es/trunk@337843 c90b9560-bf6c-de11-be94-00142212c4b1
3779 lines
155 KiB
XML
3779 lines
155 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: b2640f8900175a34675e303ac3f8878aff8d4a54 Maintainer: seros Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
|
|
<chapter xml:id="mysqlnd-ms.setup" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
&reftitle.setup;
|
|
|
|
<section xml:id="mysqlnd-ms.requirements">
|
|
&reftitle.required;
|
|
<para>
|
|
<literal>PHP 5.3.6</literal> o posterior.
|
|
Alguna funcionalidad avanzada requiere <literal>PHP 5.4.0</literal> o posterior.
|
|
</para>
|
|
<para>
|
|
El complemento de replicación y equilibrado de carga <literal>mysqlnd_ms</literal>
|
|
admite todas las aplicaciones de PHP y todas las extensiones de MySQL para PHP disponibles
|
|
(<link linkend="ref.mysqli">mysqli</link>,
|
|
<link linkend="ref.mysql">mysql</link>,
|
|
<link linkend="ref.pdo-mysql">PDO_MYSQL</link>).
|
|
La extensión de MySQL para PHP debe ser configurada para que utilice
|
|
<link linkend="book.mysqlnd">mysqlnd</link> para poder
|
|
usar el complemento <literal>mysqlnd_ms</literal> para
|
|
<link linkend="book.mysqlnd">mysqlnd</link>.
|
|
</para>
|
|
</section>
|
|
|
|
&reference.mysqlnd-ms.configure;
|
|
&reference.mysqlnd-ms.ini;
|
|
|
|
<section xml:id="mysqlnd-ms.plugin-ini-json">
|
|
<title xmlns="http://docbook.org/ns/docbook">Fichero de configuración del complemento (>=1.1.x)</title>
|
|
|
|
<para>
|
|
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 <link linkend="mysqlnd-ms.plugin-ini-v1">mysqlnd_ms 1.0.x y anteriores</link>.
|
|
</para>
|
|
|
|
<section xml:id="mysqlnd-ms.plugin-ini-json-introduction">
|
|
<title>Introdución</title>
|
|
|
|
|
|
<note>
|
|
<title>Registro de cambios: Característica añadida en PECL/mysqlnd_ms 1.1.0-beta</title>
|
|
<para>
|
|
La descripción de abajo se aplica a PECL/mysqlnd_ms >= 1.1.0-beta.
|
|
No es válida para versiones anteriores.
|
|
</para>
|
|
</note>
|
|
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
La directiva de configuración de PHP
|
|
<link linkend="ini.mysqlnd-ms.config-file"><literal>mysqlnd_ms.config_file</literal></link>
|
|
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.
|
|
</para>
|
|
<para>
|
|
El uso y el análisis de <acronym>JSON</acronym> es eficiente, ya que con <acronym>JSON</acronym>
|
|
es más sencillo expresar estructuras de datos jerárquicas que con el formato estándar de
|
|
<filename>php.ini</filename>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Convertir un array de PHP (hash) al formato JSON</title>
|
|
<para>
|
|
O alternativamente, un desarrollador puede preferir la sintaxis de <type>array</type>s por estar
|
|
más familiarizado con ella. Este ejemplo demuestra cómo un desarrolador podría convertir un
|
|
array de PHP a <acronym>JSON</acronym>.
|
|
</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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));
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
mysqlnd_ms.ini file created...
|
|
Dumping file contents...
|
|
--------------------------------------------------------------------------------
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost",
|
|
"socket": "\/tmp\/mysql.sock"
|
|
}
|
|
},
|
|
"slave": [
|
|
|
|
]
|
|
}
|
|
}
|
|
--------------------------------------------------------------------------------
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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 <acronym>JSON</acronym>. Las secciones también podrían
|
|
llamarse <emphasis>nombres de configuración</emphasis>.
|
|
</para>
|
|
<para>
|
|
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
|
|
<link linkend="ref.mysqli">mysqli</link>,
|
|
<link linkend="ref.mysql">mysql</link> y
|
|
<link linkend="ref.pdo-mysql">PDO_MYSQL</link>. Durante la conexión,
|
|
el complemento de <link linkend="book.mysqlnd">mysqlnd</link> 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.
|
|
</para>
|
|
<para xml:id="mysqlnd-ms.plugin-ini-json.using-section">
|
|
<example>
|
|
<title>Ejemplo del uso de nombres de sección</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Los nombres de sección son cadenas de texto. Es válido usar nombres de sección como
|
|
<literal>192.168.2.1</literal>, <literal>127.0.0.1</literal> o
|
|
<literal>localhost</literal>. Si, por ejemplo, una aplicación
|
|
se conexta a <literal>localhost</literal> y existe una sección de configuración
|
|
del complemento llamada <literal>localhost</literal>, 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
|
|
<literal>localhost</literal>, sino que el complemento iniciará el equilibrado de carga
|
|
de las consultas MySQL siguiendo las reglas de la sección de configuración
|
|
<literal>localhost</literal>. 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.
|
|
</para>
|
|
<para xml:id="mysqlnd-ms.plugin-ini-json.server-list-syntax">
|
|
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
|
|
<literal>master</literal>, mientras que la lista de esclavos se configura con la
|
|
palabra clave <literal>slave</literal>. El no proporcionar una lista de esclavos resultará
|
|
en un error fatal de nivel <constant>E_ERROR</constant>, 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
|
|
<link linkend="mysqlnd-ms.supportedclusters">clústeres admitidos</link>.
|
|
La parte principal de esta documentación se centra en el uso de
|
|
clústeres de replicación MySQL asincrónicos.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Lista de esclavos anónimos</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
"slave": [
|
|
{
|
|
"host": "192.168.3.24",
|
|
"port": "3305"
|
|
},
|
|
{
|
|
"host": "192.168.3.65",
|
|
"port": "3309"
|
|
}
|
|
]
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Una lista de servidores anónimos está codificada por el tipo <literal>array de JSON</literal>.
|
|
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 <literal>objeto de JSON</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Lista de maestros usando nombres simbólicos</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Se recomienda indexar las listas de servidores con nombres de servidores simbólicos.
|
|
Los sobrenombres se mostrarán en los mensajes de error.
|
|
</para>
|
|
<para>
|
|
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 <literal>SELECT</literal> será ejecutada en el esclavo
|
|
que aparece en primer lugar en la lista de servidores esclavos.
|
|
</para>
|
|
<para>
|
|
Un servidor configurado puede ser descrito con <literal>host</literal>,
|
|
<literal>port</literal>, <literal>socket</literal>, <literal>db</literal>,
|
|
<literal>user</literal>, <literal>password</literal> y <literal>connect_flags</literal>.
|
|
Es obligatorio establecer el equipo anfitrión del servidor de la base de datos mediante la palabra clave
|
|
<literal>host</literal>. Todos los demás ajustes son opcionales.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Palabras clave para configurar un servidor</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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
|
|
<link linkend="mysqlnd-ms.plugin-ini-json.using-section">ejemplo de uso de nombres de sección</link> de arriba.
|
|
</para>
|
|
<para>
|
|
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 <literal>filter</literal>. É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 <literal>filters</literal>.
|
|
</para>
|
|
<para>
|
|
Los filtros reemplazan al ajuste
|
|
<link linkend="ini.mysqlnd-ms-plugin-config.pick"><literal>pick[]</literal></link>
|
|
de versiones anteriores. Los nuevos filtros <literal>random</literal> y
|
|
<literal>roundrobin</literal> proporcionan la misma funcionalidad.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>El nuevo filtro <literal>roundrobin</literal>, funcionalidad antigua</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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": [
|
|
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
La función
|
|
<function>mysqlnd_ms_set_user_pick_server</function>
|
|
ha sido eliminada. El establecimiento de una llamada de retorno ahora se realiza con el filtro
|
|
<literal>user</literal>. Algunos filtros aceptan parámetros. El filtro <literal>user</literal>
|
|
requiere y acepta el parámetro obligatorio <literal>callback</literal>
|
|
para establecer la llamada de retorno que antes se establecía a través de la función <function>mysqlnd_ms_set_user_pick_server</function>.
|
|
<example>
|
|
<title>El filtro <literal>user</literal> reemplaza a <function>mysqlnd_ms_set_user_pick_server</function></title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
"filters": {
|
|
"user": {
|
|
"callback": "pick_server"
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para xml:id="mysqlnd-ms.plugin-ini-json.debug_config">
|
|
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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Mensaje de error común en caso de problemas con el fichero de configuración (hasta la versión 1.5.0)</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$mysqli = new mysqli("myapp", "username", "password", "database");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
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
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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
|
|
<link linkend="ini.mysqlnd-ms.force-config-usage"><literal>mysqlnd_ms.force_config_usage</literal></link>
|
|
para establecer el tipo de error usado para mostrar errores almacenados en búfer. Por omisión, se emitirá
|
|
un error de tipo <literal>E_WARNING</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Validación mejorada del fichero de configuración desde 1.5.0</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$mysqli = new mysqli("myapp", "username", "password", "database");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
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
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Puede ser útil establecer <link linkend="ini.mysqlnd-ms.force-config-usage"><literal>mysqlnd_ms.force_config_usage = 1</literal></link>
|
|
al depurar errores potenciales del fichero de configuración. Esto no solo convertirá el tipo de errores
|
|
del arranque almacenados en búfer a <literal>E_RECOVERABLE_ERROR</literal>, sino que también
|
|
ayudará a detectar nombres de seccones mal escritas.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Error posiblemente más preciso debido a <literal>mysqlnd_ms.force_config_usage=1</literal></title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
mysqlnd_ms.force_config_usage=1
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$mysqli = new mysqli("invalid_section", "username", "password", "database");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
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
|
|
]]>
|
|
</screen>
|
|
|
|
</example>
|
|
</para>
|
|
</section>
|
|
|
|
<section xml:id="mysqlnd-ms.plugin-ini-json-reference">
|
|
<title>Directivas de configuración</title>
|
|
|
|
<para>
|
|
He aquí una breve explicación de las directivas de configuración que se pueden usar.
|
|
</para>
|
|
<para>
|
|
<variablelist>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.master">
|
|
<term>
|
|
<parameter>master</parameter>
|
|
<type>array o object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Lista de los servidores maestros de replicación MySQL. La lista es
|
|
del tipo <literal>array de JSON</literal>, para declarar una lista anónima
|
|
de servidores, o del tipo <literal>objeto de JSON</literal>.
|
|
Por favor, véanse los
|
|
<link linkend="mysqlnd-ms.plugin-ini-json.server-list-syntax">ejemplos de arriba</link>.
|
|
</para>
|
|
<para>
|
|
Es obligatorio establecer al menos un servidor maestro. El complemento emitirá un
|
|
error de tipo <literal>E_ERROR</literal> si el usuario no ha proporcionado
|
|
una lista de servidores maestros en una sección de configuración.
|
|
El error fatal puede ser
|
|
<literal>(mysqlnd_ms) Section [master] doesn't exist for host [name_of_a_config_section] in %s on line %d</literal>
|
|
((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).
|
|
</para>
|
|
<para>
|
|
Un servidor se describe con las palabras clave
|
|
<literal>host</literal>, <literal>port</literal>,
|
|
<literal>socket</literal>, <literal>db</literal>,
|
|
<literal>user</literal>, <literal>password</literal> y
|
|
<literal>connect_flags</literal>. Es obligatorio
|
|
proporcionar al menos un valor para <literal>host</literal>. 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:
|
|
<link linkend="mysqlnd-ms.plugin-ini-json.using-section">ejemplo de uso de nombres de sección</link>.
|
|
</para>
|
|
<para xml:id="mysqlnd-ms.plugin-ini-json.server-config-keywords">
|
|
Tabla de las palabras clave de configuración del servidor.
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>host</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
El equipo anfitrión servidor de las bases de datos. Es un ajuste obligatorio.
|
|
Si no se proporcina causará un error de tipo <literal>E_RECOVERABLE_ERROR</literal>
|
|
cuando el complemento intente conectarse al servidor. El mensaje de error puede ser
|
|
<literal>(mysqlnd_ms) Cannot find [host] in [%s] section in config in %s on line %d</literal>
|
|
((mysqlnd_ms) No se pudo encontrar [host] en la sección [%s] de configuración en %s en la línea %d).
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>port</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
El puerto TCP/IP del servidor de las bases de datos.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>socket</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
El socket de dominio Unix del servidor de las bases de datos.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>db</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
La base de datos (esquema).
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>user</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
El usuario de la base de datos MySQL.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>password</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
La constraseña del usuario de la base de datos MySQL.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>connect_flags</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Banderas de conexión.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.slave">
|
|
<term>
|
|
<parameter>slave</parameter>
|
|
<type>array o object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
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
|
|
<link linkend="ini.mysqlnd-ms-plugin-config-v2.master"><literal>master</literal></link>
|
|
más arriba para más detalles.
|
|
</para>
|
|
<para>
|
|
El complemento admite el uso de uno o más servidores esclavos.
|
|
</para>
|
|
<para>
|
|
Es obligatorio establecer una lista de servidores esclavos. El complemento notificará
|
|
un error de tipo <literal>E_ERROR</literal> si no se proporciona
|
|
<literal>slave</literal> para una sección de configuración. El mensaje de error fatal puede ser
|
|
<literal>(mysqlnd_ms) Section [slave] doesn't exist for host [%s] in %s on line %d</literal>
|
|
((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 <literal>slave</literal>.
|
|
Es posible configurar un único maestro si se utiliza una lista de servidores esclavos vacía.
|
|
</para>
|
|
<para>
|
|
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
|
|
<literal>(mysqlnd_ms) Couldn't find the appropriate slave connection. 0 slaves to choose from.</literal>
|
|
((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 <literal>(mysqlnd_ms) No connection selected by the last filter</literal>
|
|
((mysqlnd_ms) El último filtro no seleccionó ninguna conexión).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.gtid">
|
|
<term>
|
|
<parameter>global_transaction_id_injection</parameter>
|
|
<type>array o object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>fetch_last_gtid</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
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 <function>mysqlnd_ms_get_last_gtid</function>.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.2.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>check_for_gtid</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
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 <literal>#GTID</literal>,
|
|
el cual es reemplazado con el identificador de transacciones global buscado
|
|
por el complemento. Por favor, revise los ejemplos de la
|
|
<link linkend="mysqlnd-ms.quickstart.gtid">guía rápica</link>.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.2.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>report_errors</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Si se ha de emitir un error de tipo 'warning' si ocurriera un problema mientras
|
|
se ejecuta cualquiera de las sentencias SQL configuradas.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.2.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>on_commit</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
(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
|
|
<link linkend="mysqlnd-ms.quickstart.gtid">guía rápida</link>.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.2.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>wait_for_gtid_timeout</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Ordena al complemento que espere hasta <literal>wait_for_gtid_timeout</literal>
|
|
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 <literal>wait_for_gtid_timeout</literal>.
|
|
El complemento llama a <literal>sleep(1)</literal> para dormir un segundo entre
|
|
cada dos obtenciones.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.4.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.fabric">
|
|
<term>
|
|
<parameter>fabric</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Configuración mínima del complemento para usar con MySQL Fabric</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"fabric": {
|
|
"hosts": [
|
|
{
|
|
"host" : "127.0.0.1",
|
|
"port" : 8080
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Cada host de MySQL Fabric está descrito usando un objeto de JSON con los siguientes
|
|
miembros.
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>host</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Nombre del host de MySQL Fabric.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.6.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>port</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
El puerto TCP/IP en el que el host de MySQL Fabric escucha
|
|
para llamadas de procedimientos remotos enviados por clientes como
|
|
el complemento.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.6.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Tiempo de espera opcional para la comunicación con Fabric</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"fabric": {
|
|
"hosts": [
|
|
{
|
|
"host" : "127.0.0.1",
|
|
"port" : 8080
|
|
}
|
|
],
|
|
"timeout": 2
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
La <link linkend="ini.mysqlnd-ms-plugin-config-v2.trx-stickiness">adhesión de transacciones</link>
|
|
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
|
|
<function>mysqlnd_ms_fabric_select_shard</function> o
|
|
<function>mysqlnd_ms_fabric_select_global</function>. 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.
|
|
</para>
|
|
<para>
|
|
Si la adhesión de transacciones está habilitada y se obtiene un error de tipo
|
|
advertencia al llamar a <function>mysqlnd_ms_fabric_select_shard</function> o
|
|
<function>mysqlnd_ms_fabric_select_global</function>,
|
|
estblezca la bandera booleana <literal>trx_warn_server_list_changes</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Advertencias sobre la violación de límites de transacciones</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"fabric": {
|
|
"hosts": [
|
|
{
|
|
"host" : "127.0.0.1",
|
|
"port" : 8080
|
|
}
|
|
],
|
|
"trx_warn_serverlist_changes": 1
|
|
},
|
|
"trx_stickiness": "on"
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
PHP Warning: mysqlnd_ms_fabric_select_global(): (mysqlnd_ms) Fabric server exchange in the middle of a transaction in %s on line %d
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Por favor, considere la característica como experimental. Podrían cambiarse la sintaxis y la semántica.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.filters">
|
|
<term>
|
|
<parameter>filters</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
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 <literal>random</literal> y <literal>roundrobin</literal>
|
|
reemplazan a la directiva
|
|
<link linkend="ini.mysqlnd-ms-plugin-config.pick"><literal>pick[]</literal></link>
|
|
usada en versiones anteriores para seleccionar una política de equilibrado de carga.
|
|
El filtro <literal>user</literal> reemplaza a la función
|
|
<function>mysqlnd_ms_set_user_pick_server</function>.
|
|
</para>
|
|
<para>
|
|
Los filtros pueden aceptar parámetros para refinar sus acciones.
|
|
</para>
|
|
<para>
|
|
Si no está establecida una política de equilibrado de carga, el complemento asumirá el valor predeterminado
|
|
<literal>random_once</literal>. La política <literal>random_once</literal>
|
|
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 <literal>random</literal> ni
|
|
<literal>roundrobin</literal> son parte de la sección de configuración.
|
|
</para>
|
|
<para>
|
|
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: <literal>(mysqlnd_ms) Error while creating filter '%s' . Non-multi filter '%s' already created.
|
|
Stopping in %s on line %d</literal>
|
|
((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 <literal>2000</literal>, el estado sql <literal>HY000</literal>,
|
|
y un mensaje de error similar a la advertencia, sobre el gestor de conexión.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Secuencia de filtros inválida</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"filters": [
|
|
"roundrobin",
|
|
"random"
|
|
]
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$enlace = new mysqli("myapp", "root", "", "test");
|
|
printf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
|
|
$enlace->query("SELECT 1 FROM DUAL");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
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
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.filter-random">
|
|
<term>
|
|
Filtro: <parameter>random</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
El filtro <literal>random</literal> introduce las políticas de equilibrado de carga
|
|
"aleatoria" y "aleatoria una vez", establecidas a través de la directiva
|
|
<link linkend="ini.mysqlnd-ms-plugin-config.pick"><literal>pick[]</literal></link>
|
|
en versiones anteriores.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Si al filtro <literal>random</literal> no se le proporciona ningún argumento,
|
|
permanecerá la política de equilibrado de carga aleatoria.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Equilibrado de carga aleatorio con el filtro <literal>random</literal></title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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"
|
|
]
|
|
}
|
|
}
|
|
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Opcionalmente, se puede pasar el argumento <literal>sticky</literal> al
|
|
filtro. Si se establece el parámetro <literal>sticky</literal> al string
|
|
<literal>1</literal>, el filtro seguirá la estrategia de equilibrado de carga
|
|
"aleatoria una vez".
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Equilibrado de carga "aleatoria una vez" con el filtro <literal>random</literal></title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"filters": {
|
|
"random": {
|
|
"sticky": "1"
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Los filtros <literal>random</literal> y <literal>roundrobin</literal>
|
|
admiten el establecimiento de una prioridad, un peso para un servidor, desde
|
|
PECL/mysqlnd_ms 1.4.0. Si se pasa el argumento <literal>weight</literal>
|
|
al filtro, debe asginar un peso para todos los servidores. A los servidores se les
|
|
debe proporcionar un sobrenombre en las listas de servidores <literal>slave</literal> y
|
|
<literal>master</literal> respectivamente. El alias debe usarse
|
|
para hacer referencia a servidores para asignarles una prioridad con <literal>weight</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Error de referencia</title>
|
|
<screen>
|
|
<![CDATA[
|
|
[E_RECOVERABLE_ERROR] mysqli_real_connect(): (mysqlnd_ms) Unknown server 'slave3' in 'random' filter configuration. Stopping in %s on line %d
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Usar un sobrenombre erróneo con <literal>weight</literal> podría resultar en
|
|
un error similar al mostrado arriba.
|
|
</para>
|
|
<para>
|
|
Si se omite <literal>weight</literal>, el peso predeterminado de
|
|
todos los servidores es uno.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Asignar <literal>weight</literal> para el equilibrado de carga</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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, <literal>slave3</literal> obtendrá solamente el ocho
|
|
por ciento de las peticiones como media. Mientras que <literal>slave1</literal>
|
|
y <literal>slave2</literal> 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 <literal>slave1</literal>
|
|
y de <literal>slave2</literal>, el uso de <literal>slave3</literal>
|
|
aumenta. Por favor, revise las notas sobre la tolerancia a fallos antes de usar
|
|
<literal>weight</literal> de esta manera.
|
|
</para>
|
|
<para>
|
|
El rango de valores válidos del peso es de 1 a 65535.
|
|
</para>
|
|
<para>
|
|
Los argumentos desconocidos son ingnorados. No se dan advertencias ni errores.
|
|
</para>
|
|
<para>
|
|
Espera uno o más servidores como entrada. Produce un servidor.
|
|
Una secuencia de filtros como
|
|
<literal>random</literal>, <literal>roundrobin</literal>, puede
|
|
causar una advertencia y establecer un mensaje de error sobre el gestor de
|
|
conexión cuando se ejecute una sentencia.
|
|
</para>
|
|
<para>
|
|
Listado de los argumentos del filtro.
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>sticky</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Habilita o deshabilita la política de equilibrado de carga
|
|
"aleatoria una vez". Véase más arriba.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.2.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>weight</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Asigna un peso o prioridad de equilibrado de carga a
|
|
un servidor. Por favor, véase la descripción de arriba.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.4.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.filter-roundrobin">
|
|
<term>
|
|
Filtro: <parameter>roundrobin</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Si se utiliza el filtro <literal>roundrobin</literal>, 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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Filtro <literal>roundrobin</literal></title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"filters": [
|
|
"roundrobin"
|
|
]
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Espera uno o más servidores como entrada. Produce un servidor.
|
|
Una secuencia de filtros como
|
|
<literal>roundrobin</literal>, <literal>random</literal>, puede
|
|
causar una advertencia y establecer un mensaje de error sobre el gestor de
|
|
conexión cuando se ejecute una sentencia.
|
|
</para>
|
|
<para>
|
|
Listado de los argumentos del filtro.
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>weight</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Asigna un peso o prioridad de equilibrado de carga a
|
|
un servidor. Por favor, véase la descipción de
|
|
<link linkend="ini.mysqlnd-ms-plugin-config-v2.filter-random">arriba</link>.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.4.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.filter-user">
|
|
<term>
|
|
Filtro: <parameter>user</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
El filtro <literal>user</literal> reemplaza a la función
|
|
<function>mysqlnd_ms_set_user_pick_server</function>,
|
|
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.
|
|
</para>
|
|
<para>
|
|
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 <constant>MYSQLND_MS_MASTER_SWITCH</constant>,
|
|
<constant>MYSQLND_MS_SLAVE_SWITCH</constant> o
|
|
<constant>MYSQLND_MS_LAST_USED_SWITCH</constant>. 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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Establecer una llamada de retorno</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"filters": {
|
|
"user": {
|
|
"callback": "pick_server"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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 <literal>E_RECOVERABLE_ERROR</literal>. El error puede ser
|
|
<literal>(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</literal>
|
|
((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,
|
|
<literal>(mysqlnd_ms) No connection selected by the last filter</literal>
|
|
((mysqlnd_ms) El último filtro no seleccionó ninguna conexión) con el código de error <literal>2000</literal>
|
|
y el estado sql <literal>HY000</literal>. Además se puede emitir una advertencia.
|
|
</para>
|
|
<para>
|
|
Si se hace referencia a una función inexistente como llamada de retorno, resultará
|
|
en cualquier error de tipo <literal>E_RECOVERABLE_ERROR</literal> siempre que
|
|
el complemento intente invocar a dicha función. El mensaje de error puede ser como:
|
|
<literal>(mysqlnd_ms) Specified callback (pick_server) is not a valid callback</literal>
|
|
((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,
|
|
<literal>(mysqlnd_ms) Specified callback (pick_server) is
|
|
not a valid callback</literal> con el código de error <literal>2000</literal>
|
|
y el estado sql <literal>HY000</literal>. Admás se puede emitir una advertencia.
|
|
</para>
|
|
<para>
|
|
Los siguientes parámetros son pasados desde el complemento a la llamada de retorno.
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Parámetro</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>connected_host</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
El URI del servidor de las bases de datos conectado actualmente.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>query</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
La consulta de la sentencia para la cual un servidor necesita
|
|
ser elegido.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>masters</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>slaves</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>last_used_connection</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
El URI del servidor de la conexión usada donde ejecutar la sentencia
|
|
anterior.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>in_transaction</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Bandera booleana que indica si la sentencia es
|
|
parte de una transacción abierta. Si el modo 'autocommit' está desactivado,
|
|
se establecerá a &true;. Si no,
|
|
se establecerá a &false;.
|
|
</para>
|
|
<para>
|
|
La detección de transacciones está basada en la monitorización de la
|
|
llamada a <literal>set_autocommit</literal> 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
|
|
<link linkend="mysqlnd-ms.pooling">agrupación e intercambio de conexiones</link>
|
|
para más detalles.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
<para>
|
|
<example>
|
|
<title>Utilizar una llamada de retorno</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
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'
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.filter-user-multi">
|
|
<term>
|
|
Filtro: <parameter>user_multi</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
El filtro <literal>user_multi</literal> se diferencia de <literal>user</literal>
|
|
en un único aspecto. De otro modo su sintaxix sería idéntica.
|
|
El filtro <literal>user</literal> 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 <literal>user</literal>.
|
|
</para>
|
|
<para>
|
|
El filtro <literal>user_multi</literal> 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 <literal>quality_of_service</literal>
|
|
es otro ejemplo de filtro múltiple.
|
|
</para>
|
|
<para>
|
|
El valor devuelto por la llamada de retorno establecido por <literal>user_multi</literal> 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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Devolver maestros y esclavos aleatorios</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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);
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
El complemento emitirá un error de tipo <literal>E_RECOVERABLE</literal> si la llamada de retorno falla al devolver
|
|
la lista de servidores. El error puede ser <literal>(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</literal>
|
|
((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 <literal>E_RECOVERABLE</literal> con un mensaje de error como
|
|
<literal>(mysqlnd_ms) User multi filter callback has returned an invalid list of servers to use.
|
|
Server id is negative in %s on line %d</literal>
|
|
((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.
|
|
</para>
|
|
<para>
|
|
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
|
|
<literal>(mysqlnd_ms) Couldn't find the appropriate master connection. 0 masters to choose from. Something is wrong in %s on line %d</literal>
|
|
((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 <literal>E_ERROR</literal>.
|
|
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 <literal>(mysqlnd_ms) Couldn't find the appropriate
|
|
slave connection. 0 slaves to choose from. Something is wrong in %s on line %d</literal>
|
|
((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).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.filter-node-groups">
|
|
<term>
|
|
Filtro: <parameter>node_groups</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
El filtro <literal>node_groups</literal> 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.
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>nombre del grupo de nodos definido por el usuario</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
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
|
|
<literal>/*user defined node group name*/</literal>.
|
|
Observe que no están permitidos espacios en blanco en
|
|
<literal>user defined node group name</literal>. Ya que
|
|
<literal>user defined node group name</literal> se usa tal cual
|
|
como parte de una sugerencia SQL, debería elegirse el nombre que siga
|
|
las normas del lenguaje SQL.
|
|
</para>
|
|
<para>
|
|
Cada entrada del grupo de nodos debe contener una lista de servidores
|
|
<literal>master</literal>. Están permitidos servidores <literal>slave</literal> adicionales.
|
|
El no proporcionar una lista de <literal>master</literal> a un grupos de nodos
|
|
<literal>name_of_group</literal> podría causar un
|
|
error de tipo <constant>E_RECOVERABLE_ERROR</constant> como
|
|
<literal>(mysqlnd_ms) No masters configured in node group 'name_of_group' for 'node_groups' filter</literal>.
|
|
</para>
|
|
<para>
|
|
La lista de servidores maestros y esclavos debe hacer referencia a las entradas
|
|
correspondientes en la lista de servidores
|
|
<link linkend="ini.mysqlnd-ms-plugin-config-v2.master">global de maestros</link>
|
|
y <link linkend="ini.mysqlnd-ms-plugin-config-v2.slave">esclavos</link> respectivamente.
|
|
Hacer referencia a un servidor desconocido en ambas listas de
|
|
servidores podría causar un error <constant>E_RECOVERABLE_ERROR</constant> como
|
|
<literal>(mysqlnd_ms) Unknown master 'server_alias_name' (section 'name_of_group') in 'node_groups' filter configuration</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Particionamiento manual</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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": []
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Observe que si una cadena de filtros
|
|
genera una lista de esclavos vacía y la directiva de configuración de PHP
|
|
<literal>mysqlnd_ms.multi_master=0</literal> se usa, el complemento podría
|
|
emitiri una advertencia.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.5.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.filter-qos">
|
|
<term>
|
|
Filtro: <parameter>quality_of_service</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
El filtro <literal>quality_of_service</literal> 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.
|
|
</para>
|
|
<para>
|
|
El filtro <literal>quality_of_service</literal> 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, <literal>quality_of_service</literal> puede ignorar los nodos del clúster
|
|
que no proporcionen la calidad de servicio necesaria.
|
|
</para>
|
|
<para>
|
|
El filtro <literal>quality_of_service</literal> puede ser reemplazado o creado
|
|
en tiempo de ejecución. Una llamada exitosa a
|
|
<function>mysqlnd_ms_set_qos</function>
|
|
elimina todas las entradas de los filtros <literal>qos</literal> 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
|
|
<function>mysqlnd_ms_set_qos</function>
|
|
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.
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>eventual_consistency</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Solicita la consistencia final. Permite el uso de todos los
|
|
servidores maestros y esclavos. Los datos devueltos pueden o no ser actuales.
|
|
</para>
|
|
<para>
|
|
La consistencia final acepta el parámetro opcional <literal>age</literal>.
|
|
Si se proporciona <literal>age</literal>, el complemento considerará
|
|
para la lectura solamente los esclavos que la replicación MySQL notifique
|
|
que tengan una demora menor o igual a <literal>age</literal>.
|
|
La demora de replicación se mide usando <literal>SHOW SLAVE STATUS</literal>.
|
|
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
|
|
<link linkend="mysqlnd-ms.qos-consistency">sección de conceptos de calidad de servicio</link>.
|
|
</para>
|
|
<para>
|
|
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
|
|
<literal>mysqlnd_ms.multi_master=0</literal>, el complemento podría
|
|
emitir una advertencia.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Límite global de la demora de los esclavos</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.2.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>session_consistency</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
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
|
|
<literal>mysqlnd_ms.multi_master=0</literal>, el complemento podría
|
|
emitir una advertencia.
|
|
</para>
|
|
<para>
|
|
La solicitud temporal de la consistencia de sesión usando
|
|
<function>mysqlnd_ms_set_qos</function> es una alternativa
|
|
a usar <literal>master_on_write</literal>.
|
|
<literal>master_on_write</literal> 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.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.1.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>strong_consistency</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Solitica la consistencia fuerte. Solamente serán usados los maestros.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.2.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.failover">
|
|
<term>
|
|
<parameter>failover</parameter>
|
|
Hasta, e incluyendo 1.3.x: <type>string</type>.
|
|
Desde 1.4.0: <type>object</type>.
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Política de la tolerancia a fallos. Políticas admitidas:
|
|
<literal>disabled</literal> (predeterminada), <literal>master</literal>,
|
|
<literal>loop_before_master</literal> (desde 1.4.0).
|
|
</para>
|
|
<para>
|
|
Si no se establece ninguna política de tolerancia a fallos, el complemento no realizará ninguna
|
|
tolerancia a fallos automática (<literal>failover=disabled</literal>). 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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Si se usa <literal>failover=master</literal>, 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 <literal>failover=master</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Tolerancia a fallos opcional en el maestro al fallar una conexión a un esclavo</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"failover": "master"
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Desde PECL/mysqlnd_ms 1.4.0 la palabra clave de la configuración de la tolerancia a fallos
|
|
se refiere a un objeto.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Nueva sintaxis desde 1.4.0</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"failover": {"strategy": "master" }
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>strategy</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Política de tolerancia a fallos. Valores posibles:
|
|
<literal>disabled</literal> (predeterminado), <literal>master</literal>,
|
|
<literal>loop_before_master</literal>
|
|
</para>
|
|
<para>
|
|
El valor <literal>disabled</literal> deshabilita la tolerancia a fallos automática.
|
|
</para>
|
|
<para>
|
|
Establecer <literal>master</literal> 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.
|
|
</para>
|
|
<para>
|
|
Si se usa <literal>loop_before_master</literal> 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.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.4.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>remember_failed</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Recuerda los fallos durante una petición web. Predeterminado:
|
|
<literal>false</literal>.
|
|
</para>
|
|
<para>
|
|
Si se establece a <literal>true</literal> 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.
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
Desde 1.4.0. La característica solamente está disponible junto con
|
|
con los filtros de equilibrado de carga <literal>random</literal> y
|
|
<literal>roundrobin</literal>. Se recomienda el uso del ajuste.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>max_retries</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Número máximo de intentos de conexión antes de saltarse un equipo anfitrión.
|
|
Predeterminado: <literal>0</literal> (sin límite).
|
|
</para>
|
|
<para>
|
|
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 <literal>n > 0</literal>,
|
|
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 <literal>n</literal> veces en las rondas de equilibrado de carga futuras
|
|
antes de ser eliminado.
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
Desde 1.4.0. La característica solamente está disponible junto con
|
|
con los filtros de equilibrado de carga <literal>random</literal> y
|
|
<literal>roundrobin</literal>.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
<para>
|
|
Establecer <literal>failover</literal> a cualquier valor distinto de
|
|
<literal>disabled</literal>, <literal>master</literal> o
|
|
<literal>loop_before_master</literal>
|
|
no emitirá ninguna advertencia o error.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.lazy-connections">
|
|
<term>
|
|
<parameter>lazy_connections</parameter>
|
|
<type>bool</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Deshabilitar las conexiones retardadas</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"lazy_connections": 0
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Por favor, véase también <literal>server_charset</literal> para superar problemas
|
|
potenciales con el escapado de cadenas de texto y con servidores que utilicen conjuntos de
|
|
caracteres diferentes del predeterminado.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.server-charset">
|
|
<term>
|
|
<parameter>server_charset</parameter>
|
|
<type>string</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Este ajuste ha sido introducido en la versión 1.4.0. Se recomienda establecerlo
|
|
si se van a usar conexiones retardadas.
|
|
</para>
|
|
<para>
|
|
El ajuste <literal>server_charset</literal> 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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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
|
|
<literal>E_WARNING</literal> y un mensaje como <literal>(mysqlnd_ms)
|
|
string escaping doesn't work without established connection.
|
|
Possible solution is to add server_charset to your configuration</literal>
|
|
((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.
|
|
</para>
|
|
<para>
|
|
Establecer <literal>server_charset</literal> 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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
El complemento no impide al usuario cambiar el conjunto de caracteres en cualquier momento
|
|
mediante la llamada a <function>set_charset</function> 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,
|
|
<literal>set_charset</literal> ya no tiene sentido.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Escapado de cadenas de texto sobre un gestor de conexiones retardadas</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"lazy_connections": 1,
|
|
"server_charset" : "utf8"
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.master-on-write">
|
|
<term>
|
|
<parameter>master_on_write</parameter>
|
|
<type>bool</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Este ajuste puede ser útil con la demora de replicación. Si una aplicación ejecuta
|
|
un <literal>INSERT</literal>, el complemento usará, de manera predeterminada, el
|
|
maestro para ejecutar todas las sentencias siguientes, incluidas las
|
|
sentencias <literal>SELECT</literal>. Esto ayuda a evitar problemas con
|
|
las lecturas desde los esclavos que no hayan replicado aún el
|
|
<literal>INSERT</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>master_on_write para lecturas consistentes</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"master_on_write": 1
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Por favor, observe que el filtro <literal>quality_of_service</literal> 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
|
|
<link linkend="mysqlnd-ms.qos-consistency">niveles de servicio</link>.
|
|
</para>
|
|
<para>
|
|
Todos los ajustes de <link linkend="ini.mysqlnd-ms-plugin-config-v2.trx-stickiness">adhesión de transacciones</link>,
|
|
incluyendo <literal>trx_stickiness=on</literal>, son invalidados por <literal>master_on_write=1</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.trx-stickiness">
|
|
<term>
|
|
<parameter>trx_stickiness</parameter>
|
|
<type>string</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Política de adhesión de transacciones. Las políticas admitidas son:
|
|
<literal>disabled</literal> (predeterminada), <literal>master</literal>.
|
|
</para>
|
|
<para>
|
|
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 <literal>(mysqlnd_ms) trx_stickiness strategy is not supported before PHP 5.3.99</literal>
|
|
((mysqlnd_ms) La estrategia trx_stickiness no está soportada antes de PHP 5.3.99).
|
|
</para>
|
|
<para>
|
|
Si no se establece ningun política de adhesión de transacciones o
|
|
si se establece <literal>trx_stickiness=disabled</literal>,
|
|
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.
|
|
</para>
|
|
<para>
|
|
A partir de PHP 5.4.0, la bibliteca mysqlnd permite al complemento monitorizar
|
|
el modo <literal>autocommit</literal> mediante las llamadas a la función
|
|
<literal>set_autocommit()</literal> de la biblioteca.
|
|
Si se establece <literal>set_stickiness=master</literal> y se deshabilita
|
|
<literal>autocommit</literal> mediante una extensión de MySQL para PHP que
|
|
invoque la llamada a la función interna <literal>set_autocommit()</literal>
|
|
de la biblioteca <literal>mysqlnd</literal>, 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
|
|
<literal>autocommit</literal> sea habilitado. Por lo tanto, no son necesarias las sugerencias SQL.
|
|
</para>
|
|
<para>
|
|
Un ejemplo de una función de la API de MySQL para PHP que llama a la función interna
|
|
<literal>set_autocommit()</literal> de la biblioteca <literal>mysqlnd</literal> es
|
|
<function>mysqli_autocommit</function>.
|
|
</para>
|
|
<para>
|
|
Aunque se establezca <literal>trx_stickiness=master</literal>, el complemento
|
|
no puede considerar los cambios del modo <literal>autocommit</literal> causados
|
|
por sentencias SQL como <literal>SET AUTOCOMMIT=0</literal> o <literal>BEGIN</literal>.
|
|
</para>
|
|
<para>
|
|
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 <literal>mysqli</literal> ha sido modificada para usar
|
|
dichas llamadas. Desde la versión 1.5.0, PECL/mysqlnd_ms puede monitorizar no solo
|
|
<function>mysqli_autocommit</function>, sino también <function>mysqli_begin</function>,
|
|
<function>mysqli_commit</function> y <function>mysqli_rollback</function> para
|
|
detectar los límites de transacciones y detener el equilibrado de carga durante
|
|
una transacción.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Utilizar el maestro para ejecutar transacciones</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"myapp": {
|
|
"master": {
|
|
"master_0": {
|
|
"host": "localhost"
|
|
}
|
|
},
|
|
"slave": {
|
|
"slave_0": {
|
|
"host": "192.168.78.136",
|
|
"port": "3306"
|
|
}
|
|
},
|
|
"trx_stickiness": "master"
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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 <literal>E_WARNING</literal> como
|
|
<literal>(mysqlnd_ms) Automatic failover is not permitted in the middle of a transaction</literal>.
|
|
Este error podría ser sobrescrito por errores siguientes como
|
|
<literal>(mysqlnd_ms) No connection selected by the last filter</literal>.
|
|
Esos errores serán generados por la función de consulta que falló.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Sin tolerancia a fallos automáticia, inconveniente al manejar errores</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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 <literal>Commands out of sync; you can't run this command now</literal>.
|
|
Por lo tanto, es importante manejar todos los errores.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.transient_error">
|
|
<term>
|
|
<parameter>transient_error</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
El ajuste ha sido introducido en la versión 1.6.0.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
<literal>PECL/mysqlnd_ms</literal> puede realizar el bucle de
|
|
reintento en nombre de la aplicación.
|
|
Configurando <literal>transient_error</literal>, 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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Bucle de reintentos para errores transitorios</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
{
|
|
"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
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<colspec colwidth="1*"/>
|
|
<colspec colwidth="7*"/>
|
|
<colspec colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry>Palabra clave</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<literal>mysql_error_codes</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
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 <literal>1297</literal>
|
|
(<literal>HY000 (ER_GET_TEMPORARY_ERRMSG),
|
|
Message: Got temporary error %d '%s' from %s</literal>).
|
|
Antes de añadir otros códigos, excepto el <literal>1297</literal>, a la lista,
|
|
asegúrese de que el clúster admite un nuevo intento sin impactar
|
|
sobre el estado de la aplicación.
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.6.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>max_retries</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Cuántas veces reintentar una operación que
|
|
falla con un error transitorio antes de reenviar el
|
|
fallo al usuario.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>1</literal>
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.6.0.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<literal>usleep_retry</literal>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Milisegundos a dormir antes de reintentar el error transitorio.
|
|
El valor es pasado a la función <function>usleep</function> en C,
|
|
de ahí el nombre.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>100</literal>
|
|
</para>
|
|
</entry>
|
|
<entry>Desde 1.6.0.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.xa">
|
|
<term>
|
|
<parameter>xa</parameter>
|
|
<type>object</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Este ajuste ha sido introducido en la versión 1.6.0.
|
|
</para>
|
|
<para>
|
|
<note>
|
|
<title>Experimental</title>
|
|
<para>
|
|
Esta característica está actualmente en desarrollo. Podrían existir problemas y/o
|
|
limitaciones. No la use en entornos de producción.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>state_store</term>
|
|
<listitem>
|
|
<variablelist xml:id="ini.mysqlnd-ms-plugin-config-v2.xa.state-store">
|
|
<varlistentry>
|
|
<term>record_participant_credentials</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>false</literal>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>participant_localhost_ip</term>
|
|
<listitem>
|
|
<para>
|
|
Durante la recolección de basura de XA, el complemento podría encontrar un servidor
|
|
participante para el cual haya sido anotado el host
|
|
<literal>localhost</literal>. 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 <literal>localhost</literal> 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 <literal>localhost</literal> debe
|
|
ser reemplazado con la dirección IP real de <literal>localhost</literal>.
|
|
</para>
|
|
<para>
|
|
El establecimiento de <literal>participant_localhost_ip</literal> solamente debería
|
|
ser considerado si el empleo <literal>localhost</literal> 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.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>mysql</term>
|
|
<listitem>
|
|
<para>
|
|
El almacén de estado de MySQL es el único almacén de estado disponible.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>global_trx_table</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>mysqlnd_ms_xa_trx</literal>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Definición SQL para la tabla de transacciones de almacenamiento de estado de MySQL</title>
|
|
<programlisting role="sql">
|
|
<![CDATA[
|
|
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
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>participant_table</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Se pueden habilitar y deshabilitar el almacenamiento de credenciales con
|
|
<literal>record_participant_credentials</literal>
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>mysqlnd_ms_xa_participants</literal>
|
|
</para>
|
|
<example>
|
|
<title>Definición SQL para la tabla de transacciones de almacenamiento de estado de MySQL</title>
|
|
<programlisting role="sql">
|
|
<![CDATA[
|
|
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
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>garbage_collection_table</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>mysqlnd_ms_xa_gc</literal>
|
|
</para>
|
|
<example>
|
|
<title>Definición SQL para la tabla de transacciones de almacenamiento de estado de MySQL</title>
|
|
<programlisting role="sql">
|
|
<![CDATA[
|
|
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
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>host</term>
|
|
<listitem>
|
|
<para>
|
|
Nombre de host del servidor de MySQL.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>user</term>
|
|
<listitem>
|
|
<para>
|
|
Nombre del usuario empleado para conectarse al servidor de MySQL.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>password</term>
|
|
<listitem>
|
|
<para>
|
|
Contraseña para el usuario del servidor de MySQL.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>db</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>port</term>
|
|
<listitem>
|
|
<para>
|
|
Puerto del servidor de MySQL.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>socket</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>rollback_on_close</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>true</literal>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config-v2.xa.gc">
|
|
<term>garbage_collection</term>
|
|
<listitem>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>max_retries</term>
|
|
<listitem>
|
|
<para>
|
|
Número máximo de ejecuciones de la recolección de basura antes de rendirse.
|
|
Los valores permitidos van de <literal>0</literal> hasta <literal>100</literal>.
|
|
Un valor de <literal>0</literal> 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 <literal>100</literal>.
|
|
Disponible desde 1.6.0.
|
|
</para>
|
|
<para>
|
|
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 <function>mysqlnd_ms_xa_gc</function>
|
|
para que ignore el ajuste, antes de tratarlo manualmente.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>5</literal>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>probability</term>
|
|
<listitem>
|
|
<para>
|
|
Probabilidad de la recolección de basura.
|
|
Los valores permitidos van desde <literal>0</literal> a <literal>1000</literal>.
|
|
Un valor de <literal>0</literal> deshabilita la recolección de basura
|
|
automática en segundo plano. Aún estableciendo un valor de <literal>0</literal>,
|
|
es posible ocasionar la recolección de basura llamando a
|
|
<function>mysqlnd_ms_gc</function>.
|
|
Disponible desde 1.6.0.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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 <literal>0</literal> y
|
|
<literal>1000</literal>. Si el valor de <literal>probability</literal> es mayor
|
|
o igual al valor aleatorio, se invocan a las rutinas de la recolección de basura
|
|
del almacén de estados.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>5</literal>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>max_transactions_per_run</term>
|
|
<listitem>
|
|
<para>
|
|
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 <literal>1</literal> hasta <literal>32768</literal>.
|
|
Dsiponible desde 1.6.0.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Predeterminado: <literal>100</literal>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</section>
|
|
|
|
<section xml:id="mysqlnd-ms.plugin-ini-v1">
|
|
<title xmlns="http://docbook.org/ns/docbook">Fichero de configuración del complemento (<= 1.0.x)</title>
|
|
<note>
|
|
<para>
|
|
La descripción de abajo se aplica a PECL/mysqlnd_ms < 1.1.0-beta.
|
|
No es válida para versiones posteriores.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
La directiva de configuración de PHP
|
|
<link linkend="ini.mysqlnd-ms.ini-file"><literal>mysqlnd_ms.ini_file</literal></link>
|
|
se usa para establecer el fichero de configuración del complemento.
|
|
</para>
|
|
<para>
|
|
El fichero de configuración imita el estándar del formato de <literal>php.ini</literal>.
|
|
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.
|
|
</para>
|
|
<para>
|
|
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
|
|
<link linkend="ref.mysqli">mysqli</link>,
|
|
<link linkend="ref.mysql">mysql</link> y
|
|
<link linkend="ref.pdo-mysql">PDO_MYSQL</link>. Durante la conexión,
|
|
el complemento de <link linkend="book.mysqlnd">mysqlnd</link> 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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Ejemplo del uso de nombres de sección</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
[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
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Los nombres de sección son cadenas de texto. Es válido usar nombres de sección como
|
|
<literal>192.168.2.1</literal>, <literal>127.0.0.1</literal> o
|
|
<literal>localhost</literal>. Si, por ejemplo, una aplicación
|
|
se conexta a <literal>localhost</literal> y existe una sección de configuración
|
|
del complemento llamada <literal>[localhost]</literal>, 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
|
|
<literal>localhost</literal>, sino que el complemento iniciará el equilibrado de carga
|
|
de las consultas MySQL siguiendo las reglas de la sección de configuración
|
|
<literal>[localhost]</literal>. 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.
|
|
</para>
|
|
<para>
|
|
Las directivas de configuración <literal>master[]</literal>, <literal>slave[]</literal>
|
|
y <literal>pick[]</literal> 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 <literal>slave[]</literal>
|
|
en la sección de configuración <literal>[myapp]</literal>.
|
|
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
|
|
<literal>mysql_slave_1</literal> ya que es el primero de la lista.
|
|
La segunda consulta de solo lectura será enviada al servidor MySQL
|
|
<literal>mysql_slave_2</literal> 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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Sintaxis de lista</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
[myapp]
|
|
master[] = mysql_master_server
|
|
slave[] = mysql_slave_1
|
|
slave[] = mysql_slave_2
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
He aquí una breve explicación de las directivas de configuración que se pueden usar.
|
|
</para>
|
|
<para>
|
|
<variablelist>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config.master">
|
|
<term>
|
|
<parameter>master[]</parameter>
|
|
<type>string</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
URI de un servidor maestro de replicación MySQL. El URI sigue la sintaxis
|
|
<literal>hostname[:port|unix_domain_socket]</literal>.
|
|
</para>
|
|
<para>
|
|
El complemento admite el uso de un único servidor maestro.
|
|
</para>
|
|
<para>
|
|
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 <literal>(mysqlnd_ms) Cannot find master section in config</literal>
|
|
((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
|
|
<literal>HY000/2000 (CR_UNKNOWN_ERROR)</literal>. El mensaje de error
|
|
correspondiente depende de la configuración del lenguaje.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config.slave">
|
|
<term>
|
|
<parameter>slave[]</parameter>
|
|
<type>string</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
URI de uno o más servidores esclavos de replicación MySQL. El URI sigue la sintaxis
|
|
<literal>hostname[:port|unix_domain_socket]</literal>.
|
|
</para>
|
|
<para>
|
|
El complemento admite el uso de uno o más servidores esclavos.
|
|
</para>
|
|
<para>
|
|
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 <literal>(mysqlnd_ms) Cannot find slaves section in config</literal>
|
|
((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
|
|
<literal>HY000/2000 (CR_UNKNOWN_ERROR)</literal>. El mensaje de error
|
|
correspondiente depende de la configuración del lenguaje.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config.pick">
|
|
<term>
|
|
<parameter>pick[]</parameter>
|
|
<type>string</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
La política de equilibrado de carga (selección de servidores). Políticas soportadas:
|
|
<literal>random</literal>, <literal>random_once</literal> (predeterminada),
|
|
<literal>roundrobin</literal>, <literal>user</literal>.
|
|
</para>
|
|
<para>
|
|
Si no se establece ninguna política de equilibrado de carga, el complemento usará como predeterminada
|
|
<literal>random_once</literal>. La política <literal>random_once</literal>
|
|
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.
|
|
</para>
|
|
<para>
|
|
La política <literal>random</literal> eligirá un servidor aleatorio siempre que
|
|
se ejecute una sentencia de solo lectura.
|
|
</para>
|
|
<para>
|
|
Si se usa
|
|
<literal>roundrobin</literal> 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.
|
|
</para>
|
|
<para>
|
|
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 <literal>user</literal>
|
|
y <function>mysqlnd_ms_set_user_pick_server</function> 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.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config.failover">
|
|
<term>
|
|
<parameter>failover</parameter>
|
|
<type>string</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Política de tolerancia de fallos. Políticas admitidas:
|
|
<literal>disabled</literal> (predeterminada), <literal>master</literal>.
|
|
</para>
|
|
<para>
|
|
Si no se establece ninguna política de tolerancia a fallos, el complemento no realizará ninguna
|
|
tolerancia a fallos automática (<literal>failover=disabled</literal>). 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.
|
|
</para>
|
|
<para>
|
|
Si se usa <literal>failover=master</literal>, 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 <literal>failover=master</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config.lazy-connections">
|
|
<term>
|
|
<parameter>lazy_connections</parameter>
|
|
<type>bool</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config.master-on-write">
|
|
<term>
|
|
<parameter>master_on_write</parameter>
|
|
<type>bool</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Este ajuste puede ser útil con la demora de replicación. Si una aplicación ejecuta
|
|
un <literal>INSERT</literal>, el complemento usará, de manera predeterminada, el
|
|
maestro para ejecutar todas las sentencias siguientes, incluidas las
|
|
sentencias <literal>SELECT</literal>. Esto ayuda a evitar problemas con
|
|
las lecturas desde los esclavos que no hayan replicado aún el
|
|
<literal>INSERT</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry xml:id="ini.mysqlnd-ms-plugin-config.trx-stickiness">
|
|
<term>
|
|
<parameter>trx_stickiness</parameter>
|
|
<type>string</type>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Política de adhesión de transacciones. Las políticas admitidas son:
|
|
<literal>disabled</literal> (predeterminada), <literal>master</literal>.
|
|
</para>
|
|
<para>
|
|
Característica experimental.
|
|
</para>
|
|
<para>
|
|
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 <literal>(mysqlnd_ms) trx_stickiness strategy is not supported before PHP 5.3.99</literal>
|
|
((mysqlnd_ms) La estrategia trx_stickiness no está soportada antes de PHP 5.3.99).
|
|
</para>
|
|
<para>
|
|
Si no se establece ningun política de adhesión de transacciones o
|
|
si se establece <literal>trx_stickiness=disabled</literal>,
|
|
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.
|
|
</para>
|
|
<para>
|
|
A partir de PHP 5.4.0, la bibliteca mysqlnd permite al complemento monitorizar
|
|
el modo <literal>autocommit</literal> mediante las llamadas a la función
|
|
<literal>set_autocommit()</literal> de la biblioteca.
|
|
Si se establece <literal>set_stickiness=master</literal> y se deshabilita
|
|
<literal>autocommit</literal> mediante una extensión de MySQL para PHP que
|
|
invoque la llamada a la función interna <literal>set_autocommit()</literal>
|
|
de la biblioteca <literal>mysqlnd</literal>, 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
|
|
<literal>autocommit</literal> sea habilitado. Por lo tanto, no son necesarias las sugerencias SQL.
|
|
</para>
|
|
<para>
|
|
Un ejemplo de una función de la API de MySQL para PHP que llama a la función interna
|
|
<literal>trx_autocommit()</literal> de la biblioteca <literal>mysqlnd</literal> es
|
|
<function>mysqli_autocommit</function>.
|
|
</para>
|
|
<para>
|
|
Aunque se establezca <literal>ser_stickiness=master</literal>, el complemento
|
|
no puede considerar los cambios del modo <literal>autocommit</literal> causados
|
|
por setnencias SQL como <literal>SET AUTOCOMMIT=0</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</section>
|
|
|
|
<section xml:id="mysqlnd-ms.testing">
|
|
<title xmlns="http://docbook.org/ns/docbook">Probar el complemento</title>
|
|
<note>
|
|
<para>
|
|
Esta sección se aplica a la versión mysqlnd_ms 1.1.0 o posterior, no a la serie 1.0.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
El conjunto de pruebas de PECL/mysqlnd_ms se encuentra en el directorio <filename>tests/</filename>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Antes de ejecutar las pruebas, edite <filename>tests/config.inc</filename> para
|
|
configurar los servidores MySQL a usar durante las mismas.
|
|
</para>
|
|
<para>
|
|
La configuracion más básica es como sigue.
|
|
<programlisting>
|
|
<![CDATA[
|
|
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"));
|
|
]]>
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
<literal>MYSQL_TEST_HOST</literal>, <literal>MYSQL_TEST_PORT</literal> y
|
|
<literal>MYSQL_TEST_SOCKET</literal> 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.
|
|
<literal>MYSQL_TEST_USER</literal> y <literal>MYSQL_TEST_PASSWD</literal>
|
|
contienen el usuario y la contraseña necesarios para conectarse a la base de datos o esquema
|
|
configurado con <literal>MYSQL_TEST_DB</literal>. 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.
|
|
</para>
|
|
<para>
|
|
Con la sintaxis <literal>host</literal>, <literal>host:puerto</literal> o <literal>host:/ruta/al/socket</literal>
|
|
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.
|
|
<programlisting>
|
|
<![CDATA[
|
|
putenv("MYSQL_TEST_SLAVE_HOST=192.168.78.136:3307"));
|
|
putenv("MYSQL_TEST_MASTER_HOST=myserver_hostname:/path/to/socket"));
|
|
]]>
|
|
</programlisting>
|
|
</para>
|
|
</section>
|
|
|
|
<section xml:id="mysqlnd-ms.debugging">
|
|
<title xmlns="http://docbook.org/ns/docbook">Depuración y rastreo</title>
|
|
<para>
|
|
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
|
|
<link linkend="ini.mysqlnd.debug"><literal>mysqlnd.debug</literal></link>
|
|
de PHP para una descripción detallada
|
|
de cómo configurar el registro de depuración.
|
|
</para>
|
|
<para>
|
|
Ejemplo de ajuste de configuración para activar el registro de depuración:
|
|
<programlisting>
|
|
<![CDATA[
|
|
mysqlnd.debug=d:t:x:O,/tmp/mysqlnd.trace
|
|
]]>
|
|
</programlisting>
|
|
<note>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
<para>
|
|
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
|
|
<literal>mysqlnd_</literal>. Las llamadas internas a PECL/mysqlnd comienzan con
|
|
<literal>mysqlnd_ms</literal>.
|
|
</para>
|
|
<para>
|
|
Extracto de ejemplo del registro de depuración (conectar):
|
|
<programlisting>
|
|
<![CDATA[
|
|
[...]
|
|
>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
|
|
[...]
|
|
]]>
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Extracto de ejemplo del registro de depuración (fallo de conexión):
|
|
<programlisting>
|
|
<![CDATA[
|
|
[...]
|
|
| | | | | | | 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
|
|
[...]
|
|
]]>
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
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é.
|
|
</para>
|
|
<para>
|
|
Extracto de ejemplo del registro de depuración (decisión del complemento):
|
|
<programlisting>
|
|
<![CDATA[
|
|
[...]
|
|
>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
|
|
]]>
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
En este caso, la sentencia <literal>DROP TABLE IF EXISTS test</literal> 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.
|
|
</para>
|
|
<para>
|
|
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 <literal>>mysqlnd_ms_choose_connection_rr</literal>.
|
|
Ha sido enviada a un servidor maestro que se ejecuta en
|
|
<literal>host=localhost user=root db=test port=3306 flags=131072 persistent=0 state=0</literal>.
|
|
</para>
|
|
</section>
|
|
|
|
<section xml:id="mysqlnd-ms.monitoring">
|
|
<title xmlns="http://docbook.org/ns/docbook">Monitorización</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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 <function>mysqlnd_ms_get_stats</function>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Comprobar la actividad del complemento en un modelo de desarrollo sin hilos</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
mysqlnd_ms.enable=1
|
|
mysqlnd_ms.collect_statistics=1
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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!";
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Utilizar la función de PHP <function>register_shutdown_function</function> o la
|
|
directiva de configuración de PHP <literal>auto_append_file</literal> 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.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Registrar las estadístcias durante el cierre</title>
|
|
<programlisting role="ini">
|
|
<![CDATA[
|
|
mysqlnd_ms.enable=1
|
|
mysqlnd_ms.collect_statistics=1
|
|
error_log=/tmp/php_errors.log
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|