Capítulo 6. Replicación en MySQL
Anterior |  | Siguiente

## Capítulo 6. Replicación en MySQL

Las capacidades de replicación que permiten a las bases de datos de un servidor MySQL ser duplicadas en otro se introdujeron en MySQL 3.23.15. Este capítulo describe las características de replicación proporcionadas por MySQL . Presenta conceptos de replicación, muestra cómo preparar servidores de replicación, y sirve como referencia para las opciones de replicación disponibles. También proporciona una lista de preguntas frecuentes (con respuestas), y consejos para resolver problemas.

Para una descripción de la sintaxis de comandos SQL relacionados con replicación, consulte Sección 13.6, “Sentencias de replicación”.

Sugerimos que visite nuestra página web http://www.mysql.com frecuentemente así como que chequee para revisiones de este capítulo. La replicación está siendo mejorada constantemente, y actualizamos frecuentemente el manual con la información más actual.

## 6.1. Introducción a la replicación

Las características de MySQL 5 soportan replicación asíncrona unidireccional: un servidor actúa como maestro y uno o más actúan como esclavos. (Esto contrasta con la replicación síncrona que es una característica de MySQL Cluster — consulte Capítulo 16, MySQL Cluster). El servidor maestro escribe actualizaciones en el fichero de log binario, y mantiene un índice de los ficheros para rastrear las rotaciones de logs. Estos logs sirven como registros de actualizaciones para enviar a los servidores esclavos. Cuando un esclavo se conecta al maestro, informa al maestro de la posición hasta la que el esclavo ha leído los logs en la última actualización satisfactoria. El esclavo recibe cualquier actualización que han tenido lugar desde entonces, y se bloquea y espera para que el master le envíe nuevas actualizaciones.

Un esclavo servidor puede servir como maestro si quiere preparar una cadena de replicaciones de replicación.

Tenga en cuenta que cuando usa replicación, todas las actualizaciones de las tablas que se replican deben realizarse en el servidor maestro. De otro modo, debe ser cuidadoso para evitar conflictos entre actualizaciones que hacen los usuarios a las tablas en el maestro y las actualizaciones que hacen en las tablas de los esclavos.

La replicación unidireccional tiene beneficios para la robustez, velocidad, y administración del sistema:

- La robustez se incrementa con un escenario maestro/esclavo. En caso de problemas con el maestro, puede cambiar al esclavo como copia de seguridad.

- Puede conseguirse un mejor tiempo de respuesta dividiendo la carga de consultas de clientes a procesar entre los servidores maestro y esclavo. Se puede enviar consultas `SELECT` al esclavo para reducir la carga de proceso de conultas del maestro. Sin embargo, las sentencias que modifican datos deben enviarse siempre al maestro, de forma que el maestro y el esclavo no se desincronicen. Esta estrategia de balanceo de carga es efectiva si dominan consultas que no actualizan datos, pero este es el caso más habitual.

- Otro beneficio de usar replicación es que puede realizar copias de seguridad usando un servidor esclavo sin molestar al maestro. El maestro continúa procesando actualizaciones mientras se realiza la copia de seguridad. Consulte Sección 5.8.1, “Copias de seguridad de bases de datos”.

## 6.2. Panorámica de la implementación de la replicación

La replicación en MySQL se basa en un servidor maestro que toma nota de todos los cambios en las bases de datos (actualizaciones, borrados, y así) en los logs binarios. Por lo tanto, para usar replicación, debe activar el log binario en el servidor maestro. Consulte Sección 5.10.3, “El registro binario (Binary Log)”.

Cada servidor esclavo recibe del maestro las actualizaciones guardadas que el maestro ha guardado en su log binario, de forma que el esclavo puede ejecutar las mismas actualizaciones en su copia de los datos.

Es extremadamente importante tener en cuenta que el log binario simplemente es un registro que comienza en un punto fijo en el tiempo en el que activa el log binario. Cualquier esclavo que inicialice necesita copias de las bases de datos del maestro tal y como estaban en el momento en que activó el log binario en el maestro. Si arranca sus esclavos con bases de datos que no están en el mismo estado que las del maestro cuando arrancó el log binario, es muy posible que fallen sus esclavos.

Una forma de copiar los datos del maestro al esclavo es usar el comando `LOAD DATA FROM MASTER` . Tenga en cuenta que `LOAD DATA FROM MASTER` funciona sólo si todas las tablas en el maestro usan el motor de almacenamiento `MyISAM`. Además, este comando adquiere un bloqueo de lectura global, así que no se puede actualizar el maestro mientras las tablas se transfieren al esclavo. Cuando implementemos la copia en caliente sin bloqueo, ya no será necesario el bloqueo global de lectura.

Debido a estas limitaciones, recomendamos que en este punto use `LOAD DATA FROM MASTER` sólo si el conjunto de datos en el maestro es relativamente pequeño, o si se puede realizar un bloqueo de lectura prolongado en el maestro. Mientras que la velocidad real de `LOAD DATA FROM MASTER` puede variar de sistema a sistema, una buena regla de estimar cuánto tarda es 1 segundo por 1MB de datos. Esta es una estimación aproximada, pero puede encontrar que es bastante buena si tanto el maestro como el esclavo son equivalentes a Pentium 700MHz y conectados mediante una red a 100Mbps .

Tras inicializar el esclavo con una copia de los datos del maestro, se conecta al maestro y espera a procesar actualizaciones. Si el maestro falla, o el esclavo pierde conectividad con el maestro, el esclavo sigue intentando conectar periódicamente hasta que es capaz de reanudar la espera de actualizaciones. El intervalo de reintento lo controla la opción `--master-connect-retry`. Por defecto es de 60 segundos.

Cada esclavo registra dónde lo dejó. El servidor maestro tiene conocimiento de cuántos esclavos hay o cuántos están activos en un momento dado.

## 6.3. Detalles de la implementación de la replicación

Las capacidades de replicación de MySQL están implementadas usando tres flujos (uno en el servidor maestro y dos en el esclavo). Cuando se ejecuta un `START SLAVE`, el esclavo crea un flujo de entrada/salida, que conecta al maestro y le pide que envíe los comandos guardados en su log binario. El maestro crea un flujo para enviar los contenidos del log binario al esclavo. Este flujo puede identificarse como el flujo `Binlog Dump` en la salida de `SHOW PROCESSLIST` en el maestro. El flujo de entrada/salida del esclavo lee lo que el flujo `Binlog Dump` del maestro envía y copia estos datos en ficheros locales, llamados logs retardados, en el directorio de datos del esclavo. El tercer flujo es el flujo SQL, que crea el esclavo para leer los logs retardados y para ejecutar las actualizaciones que contiene.

En la descripción precedente, hay tres flujos por esclavo. Un maestro que tiene varios esclavos crea un flujo para cada esclavo conectado; cada esclavo tiene sus propios flujos de entrada/salida y SQL.

Leer dos comandos y ejecutarlos se divide en dos tareas independientes. La tarea de leer comandos no se ralentiza si la ejecución es lenta. Por ejemplo, si el servidor esclavo no ha estado en ejecución durante un periodo de tiempo, su flujo de entrada/salida puede tratar rápidamente todos los contenidos del log binario del maestro cuando arranca el esclavo, incluso si el flujo SQL se realentiza mucho. Si el esclavo para antes que el flujo SQL haya ejecutado todos los comandos tratados, el flujo de entrada/salida ha tratado todo de forma que hay una copia de los comandos almacenada localmente en los logs retardados, preparados para ejecutarse la siguiente vez que arranque el esclavo. Esto permite que se purguen los logs binarios del maestro, ya que no necesita esperar que los esclavos traten sus contenidos.

El comando `SHOW PROCESSLIST` proporciona información que le dice qué está ocurriendo en el maestro y en el esclavo teniendo en cuenta la replicación.

El siguiente ejemplo ilustra cómo los tres flujos se muestran en `SHOW PROCESSLIST`.

En el servidor maestro, la salida de `SHOW PROCESSLIST` tiene este aspecto:

    mysql> SHOW PROCESSLIST\G
    *************************** 1. row ***************************
         Id: 2
       User: root
       Host: localhost:32931
         db: NULL
    Command: Binlog Dump
       Time: 94
      State: Has sent all binlog to slave; waiting for binlog to
             be updated
       Info: NULL

Aquí, el flujo 2 es un flujo de replicación para un esclavo conectado. La información indica que todas las actualizaciones se han enviado al esclavo y que el maestro está esperando más actualizaciones.

En el servidor esclavo, la salida para `SHOW PROCESSLIST` tiene este aspecto:

    mysql> SHOW PROCESSLIST\G
    *************************** 1. row ***************************
         Id: 10
       User: system user
       Host:
         db: NULL
    Command: Connect
       Time: 11
      State: Waiting for master to send event
       Info: NULL
    *************************** 2. row ***************************
         Id: 11
       User: system user
       Host:
         db: NULL
    Command: Connect
       Time: 11
      State: Has read all relay log; waiting for the slave I/O
             thread to update it
       Info: NULL

Esta información indica que el flujo 10 es el flujo de entrada/salida que se comunica con el maestro, y el flujo 11 es el flujo SQL que procesa las actualizaciones almacenadas en los logs retardados. Cuando se ejecuta `SHOW PROCESSLIST` ambos flujos estaban en espera de actualizaciones nuevas.

Tenga en cuenta que los valores en la columna `Time` pueden mostrar la diferencia de tiempo en la comparación del esclavo con el maestro. Consulte Sección 6.9, “Preguntas y respuestas sobre replicación”.

### 6.3.1. Estados de los subprocesos del maestro de replicación

La siguiente lista muestra los estados más comunes que puede ver en la columna `State` del flujo maestro `Binlog Dump` . Si no ve ningún flujo `Binlog Dump` en un servidor maestro, esto significa que la replicación no está corriendo — esto es, que no hay ningún esclavo conectado.

- `Envío de eventos del binlog al esclavo`

  Los logs binarios consisten en eventos, donde un evento usualmente es una actualicación más otra información. El flujo lee un evento del log binario y lo envía al esclavo.

- `Finished reading one binlog; switching to next binlog`

  El flujo ha acabado de leer un fichero de log binario y está abriendo el siguiente para enviar al esclavo.

- `Has sent all binlog to slave; waiting for binlog to be updated`

  El flujo ha leído todas las actualizaciones destacadas del log binario y las ha enviado al esclavo. El flujo ahora está en espera, esperando nuevos eventos en el log binario que resulten en nuevas actualizaciones en el maestro.

- `Waiting to finalize termination`

  Estado muy breve que ocurre cuando el flujo está parando.

### 6.3.2. Estados de proceso E/S (I/O) del esclavo de replicación

La siguiente lista muestra los estados más comunes que puede ver en la columna `State` para un flujo de entrada/salida en el servidor esclavo. Este estado también aparece en la columna `Slave_IO_State` mostrada por `SHOW SLAVE STATUS`. Esto significa que puede obtener una vista muy buena de lo que ocurre simplemente usando este comando.

- `Connecting to master`

  El flujo trata de conectar al maestro.

- `Checking master version`

  Estado que ocurre brevemente, inmediatamente tras establecer la conexión con el maestro.

- `Registering slave on master`

  Estado que ocurre brevemente, inmediatamente tras establecer la conexión con el maestro.

- `Requesting binlog dump`

  Estado que ocurre brevemente, inmediatamente tras establecer la conexión con el maestro. El flujo envía al maestro una petición para los contenidos de su log binario, comenzando por el nombre del log binario pedido y la posición.

- `Waiting to reconnect after a failed binlog dump request`

  Si la petición del volcado del log binario falla (debido a una desconexión), el flujo pasa a este estado mientras duerme, luego trata de reconectar periódicamente. El intervalo entre reintentos puede especificarse usando la opción `--master-connect-retry` .

- `Reconnecting after a failed binlog dump request`

  El flujo está tratando de reconectar con el maestro.

- `Waiting for master to send event`

  El flujo ha conectado con el maestro y está esperando a que lleguen los eventos del log binario. Esto puede tardar un tiempo largo si el maestro está en espera. Si la espera dura `slave_read_timeout` segundos, se produce un timeout. En este punto, el flujo considera la conexión rota e intenta reconectar.

- `Queueing master event to the relay log`

  El flujo ha leído un evento y lo está copiando en el log retardado para que el flujo SQL pueda procesarlo.

- `Waiting to reconnect after a failed master event read`

  Un error ocurre durante la lectura (debido a una desconexión). El flujo duerme durante `master-connect-retry` segundos antes de intentar reconectar.

- `Reconnecting after a failed master event read`

  El flujo trata de reconectar con el maestro. Cuando la conexión se vuelve a establecer, el estado pasa a `Waiting for master to send event`.

- `Waiting for the slave SQL thread to free enough relay log space`

  Está usando un valor `relay_log_space_limit` distinto a cero, y el log retardado ha crecido hasta que su tamaño combinado escede este valor. El flujo de entrada/salida está en espera hasta que el flujo SQL libera suficiente espacio procesando los contenidos del log retardado de forma que pueda leer algunos ficheros de log retardado.

- `Waiting for slave mutex on exit`

  Estado que ocurre brevemente al parar el flujo.

### 6.3.3. Estados del flujo SQL de un esclavo de replicación

La siguiente lista muestra los estados más comunes que puede ver en la columna `State` para el flujo SQL del servidor esclavo:

- `Reading event from the relay log`

  El flujo ha leído un evente del log retardado para que el evento pueda ser procesado.

- `Has read all relay log; waiting for the slave I/O thread to update it`

  El flujo ha procesado todos los eventos en los ficheros de log retardado y está esperando que el flujo de entrada/salida escriba nuevos eventos en el log retardado.

- `Waiting for slave mutex on exit`

  Estado breve que ocurre cuando el flujo está parándose.

La columna `State` para el flujo de entrada/salida también puede mostrar el texto de un comando. Esto indica que el flujo ha leído un evento del log retardado, ha extraído el comando de él y lo ha ejecutado.

### 6.3.4. Ficheros de replicación, retardados y de estado

Por defecto, los logs retardados se nombran usando nombres de ficheros de la forma ``host_name`-relay-bin.`nnnnnn``, donde `host_name` es el nombre del servidor esclavo y `nnnnnn` es un número de secuencia. Los ficheros de logs retardados sucesivos en MySQL 5.0 se crean usando números de secuencia sucesivos, comenzando a partir de `000001`. El esclavo guarda los logs retardados en unso en un fichero índice. El nombre del índice del log retardado por defecto es ``host_name`-relay-bin.index`. Por defecto, estos ficheros se crean en el directorio de datos del esclavo. Por defecto los nombres de fichero pueden cambiarse con las opciones de servidor `--relay-log` y `--relay-log-index` . Consulte Sección 6.8, “Opciones de arranque de replicación”.

Los logs retardados tienen el mismo formato que los logs binarios, y pueden leerse usando mysqlbinlog. Un log retardado se borra automáticamente por el flujo SQL en cuanto ha ejecutado todos sus eventos y no los necesita más. No hay mecanismo explícito para borrar logs retardados, ya que el flujo SQL se encarga de ello. Sin embargo, `FLUSH LOGS` rota los logs retardados, lo que influye cuando el flujo SQL los borra.

Un log retardado se crea bajo las siguientes condiciones:

- En MySQL 5.0, se crea un nuevo log retardado cada vez que arranca el flujo de entrada/salida.

- Cuando los logs se vuelcan; por ejemplo, con `FLUSH LOGS` o mysqladmin flush-logs.

- Cuando el tamaño del log retardado actual es demasiado grande. El significado de "muy grande" se determina así:

  - `max_relay_log_size`, si `max_relay_log_size` > 0

  - `max_binlog_size`, si `max_relay_log_size` = 0

Un servidor esclavo de replicación crea dos pequeños ficheros adicionales en el directorio de datos. Estos ficheros de estado se llaman `master.info` y `relay-log.info` por defecto. Contienen información como la mostrada en la salida del comando `SHOW SLAVE STATUS` (consulte Sección 13.6.2, “Sentencias SQL para el control de servidores esclavos” para una descripción de este comando). Como ficheros en disco, sobreviven una parada del servidor esclavo. La siguiente vez que arranca el servidor esclavo, lee estos ficheros para determinar hasta dónde ha procesado los logs binarios del maestro y sus propios logs retardados.

El fichero `master.info` lo actualiza el flujo de entrada/salida. En MySQL 5.0, la correspondencia entre las líneas en el fichero y las columnas mostradas por`SHOW SLAVE STATUS` es la siguiente:

Línea | Descripción
1 | Número de líneas en el fichero
2 | `Master_Log_File`
3 | `Read_Master_Log_Pos`
4 | `Master_Host`
5 | `Master_User`
6 | Contraseña (no mostrada por `SHOW SLAVE STATUS`)
7 | `Master_Port`
8 | `Connect_Retry`
9 | `Master_SSL_Allowed`
10 | `Master_SSL_CA_File`
11 | `Master_SSL_CA_Path`
12 | `Master_SSL_Cert`
13 | `Master_SSL_Cipher`
14 | `Master_SSL_Key`

El fichero `relay-log.info` lo actualiza el flujo SQL. La correspondencia entre las líneas en el fichero y las columnas mostradas por `SHOW SLAVE STATUS` se muestran aquí:

Línea | Descripción
1 | `Relay_Log_File`
2 | `Relay_Log_Pos`
3 | `Relay_Master_Log_File`
4 | `Exec_Master_Log_Pos`

Cuando hace una copia de seguridad de los datos del esclavo, debe incluir también estos dos ficheros, junto con sus ficheros de log retardado. Son necesarios para reanudar la replicación tras restaurar los datos del esclavo. Si pierde los logs retardados pero todavía tiene el fichero `relay-log.info` , puede examinarlo para determinar hasta dónde ha ejecutado el flujo SQL en el log binario del maestro. Luego puede usar `CHANGE MASTER TO` con las opciones `MASTER_LOG_FILE` y `MASTER_LOG_POS` para decirle al esclavo que vuelva a leer los logs binarios a partir de ese punto. Por supuesto, esto requiere que los logs binarios existan en el servidor maestro.

Si su esclavo está sujeto a replicación de comandos `LOAD DATA INFILE` , también debe incluir en la copia de seguridad cualquier fichero `SQL_LOAD-*` que existe en el directorio que el esclavo usa para este propósito. El esclavo necesita estos ficheros para reanudar replicación de cualquier operación `LOAD DATA INFILE` interrumpida. La localización del directorio se especifica usando la opción `--slave-load-tmpdir` . Si valor por defecto, si no se especifica, es el valor de la variable `tmpdir` .

## 6.4. Cómo montar la replicación

Aquí hay una breve descripción de cómo inicializar una replicación completa de su servidor MySQL. Asume que quiere replicar todas las bases de datos en el maestro y no tiene una replicación préviamente configurarda. Necesita parar el servidor maestro brevemente para completar los pasos descritos aquí.

Este procedimiento está escrito en términos de inicializar un esclavo único, pero puede usarlo para inicializar múltiples esclavos.

Mientras este método es el más directo para inicializar un esclavo, no es el único. Por ejemplo, si tiene una muestra de los datos del maestro, y el maestro tiene su ID de servidor y el log binario activo, puede preparar un esclavo sin parar el maestro o incluso sin bloquear actualizaciones para ello. Para más detalles, consulte Sección 6.9, “Preguntas y respuestas sobre replicación”.

Si quiere administrar la inicialización de una replicación MySQL, sugerimos que lea este capítulo entero y pruebe todos los comandos mencionados en Sección 13.6.1, “Sentencias SQL para el control de servidores maestros” y Sección 13.6.2, “Sentencias SQL para el control de servidores esclavos”. También debe familiarizarse con las opciones de arranque de replicación descritas en Sección 6.8, “Opciones de arranque de replicación”.

Nota: este procedimiento y algunos de los comandos de replicación SQL mostrados en secciones posteriores necesita el privilegio `SUPER`.

1. Asegúrese de que las versiones de MySQL instalado en el maestro y en el esclavo son compatibles según dice la tabla mostrada en Sección 6.5, “Compatibilidad entre versiones de MySQL con respecto a la replicación”. Idealmente, debe usar la versión más reciente de MySQL en maestro y servidor.

   Por favor no reporte bugs hasta que ha verificado que el problema está presente en la última versión de MySQL.

2. Prepare una cuenta en el maestro que pueda usar el esclavo para conectar. Este cuenta debe tener el privilegio `REPLICATION SLAVE` . Si la cuenta se usa sólo para replicación (lo que se recomienda), no necesita dar ningún privilegio adicional. (Para información sobre preparar cuentas de usuarios y privilegios, consulte Sección 5.7, “Gestión de la cuenta de usuario MySQL”.)

   Suponga que su dominio es `mydomain.com` y que quiere crear una cuenta con un nombre de usuario de `repl` que puedan usar los esclavos para acceder al maestro desde cualquier equipo en su dominio usando una contraseña de `slavepass`. Para crear la cuenta, use el comando `GRANT`:

       mysql> GRANT REPLICATION SLAVE ON *.*
           -> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';

   Si quiere usar los comandos `LOAD TABLE FROM MASTER` o `LOAD DATA FROM MASTER` desde el servidor esclavo, necesita dar a esta cuenta privilegios adicionales:

   - De a la cuenta el privilegio global `SUPER` y `RELOAD` .

   - De el privilegio `SELECT` para todas las tablas que quiere cargar. Cualquier tabla maestra desde la que la cuenta no puede hacer un `SELECT` se ignoran por `LOAD DATA FROM MASTER`.

3. Si usa sólo tablas `MyISAM` , vuelque todas las tablas y bloquee los comandos de escritura ejecutando un comando `FLUSH TABLES WITH READ LOCK` :

       mysql> FLUSH TABLES WITH READ LOCK;

   Deje el cliente en ejecución desde el que lanza el comando `FLUSH TABLES` para que pueda leer los efectos del bloqueo. (Si sale del cliente, el bloqueo se libera.) Luego tome una muestra de los datos de su servidor maestro.

   La forma más fácil de crear una muestra es usar un programa de archivo para crear una copia de seguidad binaria de las bases de datos en su directorio de datos del maestro. Por ejemplo. use tar en Unix, o PowerArchiver, WinRAR, WinZip, o cualquier software similar en Windos. Para usar tar para crear un archivo que incluya todas las bases de datos, cambie la localización en el directorio de datos del maestro, luego ejecute el comando:

       shell> tar -cvf /tmp/mysql-snapshot.tar .

   Si quiere que el archivo sólo incluya una base de datos llamada `this_db`, use este comando:

       shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db

   Luego copie el archivo en el directorio `/tmp` del servidor esclavo. En esa máquina, cambie la localización al directorio de datos del esclavo, y desempaquete el fichero usando este comando:

       shell> tar -xvf /tmp/mysql-snapshot.tar

   Puede no querer replicar la base de datos `mysql` si el servidor esclavo tiene un conjunto distinto de cuentas de usuario a la existente en el maestro. En tal caso, debe excluírla del archivo. Tampoco necesita incluir ningún fichero de log en el archivo, o los ficheros `master.info` o `relay-log.info` files.

   Mientras el bloqueo de `FLUSH TABLES WITH READ LOCK` está en efecto, lee el valor del nombre y el desplazamiento del log binario actual en el maestro:

       mysql > SHOW MASTER STATUS;
       +---------------+----------+--------------+------------------+
       | File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
       +---------------+----------+--------------+------------------+
       | mysql-bin.003 | 73       | test         | manual,mysql     |
       +---------------+----------+--------------+------------------+

   La columna `File` muestra el nombre del log, mientras que `Position` muestra el desplazamiento. En este ejemplo, el valor del log binario es `mysql-bin.003` y el desplazamiento es 73. Guarde los valores. Los necesitará más tarde cuando inicialice el servidor. Estos representan las coordenadas de la replicación en que el esclavo debe comenzar a procesar nuevas actualizaciones del maestro.

   Una vez que tiene los datos y ha guardado el nombre y desplazamiento del log, puede reanudar la actividad de escritura en el maestro:

       mysql> UNLOCK TABLES;

   Si está usando tablas `InnoDB` , debería usar la herramienta `InnoDB Hot Backup`. Realiza una copia consistente sin bloquear el servidor maestro, y guarda el nombre y desplazamiento del log que se corresponden a la copia para usarlo posteriormente en el esclavo. `InnoDB Hot Backup` es una herramienta no libre (comercial) que no está incluída en la distribución de MySQL estándar. Consulte la página web de `InnoDB Hot Backup` en http://www.innodb.com/manual.php para información detallada.

   Sin la herramienta `Hot Backup` , la forma más rápida de hacer una copia binaria de los datos de las tablas `InnoDB` es parar el maestro y copiar los ficheros de datos `InnoDB`, ficheros de log, y ficheros de definición de tablas (ficheros `.frm`). Para guardar los nombres de ficheros actual y desplazamientos, debe ejecutar el siguiente comando antes de parar el servidor:

       mysql> FLUSH TABLES WITH READ LOCK;
       mysql> SHOW MASTER STATUS;

   Luego guarde el nombre del log y el desplazamiento desde la salida de `SHOW MASTER STATUS` como se mostró antes. Tras guardar el nombre del log y el desplazamiento, pare el servidor sin bloquear las tablas para asegurarse que el servidor para con el conjunto de datos correspondiente al fichero de log correspondiente y desplazamiento:

       shell> mysqladmin -u root shutdown

   Una alternativa que funciona para tablas `MyISAM` y `InnoDB` es realizar un volcado SQL del maestro en lugar de una copia binaria como se describe en la discusión precedente. Para ello, puede usar mysqldump --master-data en su maestro y cargar posteriormente el fichero de volcado SQL en el esclavo. Sin embargo, esto es más lento que hacer una copia binaria.

   Si el maestro se ha ejecutado previamente sin habilitar `--log-bin` , el nombre del log y las posiciones mostradas por `SHOW MASTER STATUS` o mysqldump --master-data están vacíos. En ese caso, los valores que necesita usar posteriormente cuando especifica el fichero de log del esclavo y la posición son una cadena vacía (`''`) y `4`.

4. Asegúrese que la sección `[mysqld]` del fichero `my.cnf` en el maestro incluye una opción `log-bin` . Esta sección debe también tener la opción `server-id=master_id` , donde `master_id` debe ser un entero positivo de 1 a 2^32 - 1. Por ejemplo:

       [mysqld]
       log-bin=mysql-bin
       server-id=1

   Si estas opciones no están presentes, añádalas y reinicie el servidor.

5. Pare el servidor que se vaya a usar como esclavo y añada lo siguiente a su fichero `my.cnf` :

       [mysqld]
       server-id=slave_id

   El valor `slave_id` , como el valor `master_id` , debe ser un entero positivo de 1 a 2^32 - 1. Además, es muy importante que el ID del esclavo sea diferente del ID del maestro. Por ejemplo:

       [mysqld]
       server-id=2

   Si está preparando varios esclavos, cada uno debe tener un valor de `server-id` único que difiera del maestro y de cada uno de los otros esclavos. Piense en los valores de `server-id` como algo similar a las direcciones IP: estos IDs identifican unívocamente cada instancia de servidor en la comunidad de replicación.

   Si no especifica un `server-id`, se usa 1 si no ha definido un `master-host`, de otro modo se usa 2. Tenga en cuenta que en caso de omisión de `server-id`, un maestro rechaza conexiones de todos los esclavos, y un esclavo rechaza conectar a un maestro. Por lo tanto, omitir el `server-id` es bueno sólo para copias de seguridad con un log binario.

6. Si ha hecho una copia de seguridad binara de los datos del maestro, cópielo en el directorio de datos del esclavo antes de arrancar el esclavo. Asegúrese que los privilegios en los ficheros y directorios son correctos. El usuario que ejecuta el servidor MySQL debe ser capaz de leer y escribir los ficheros, como en el maestro.

   Si hizo una copia de seguridad usando mysqldump, arranque primero el esclavo (consulte el siguiente paso).

7. Arranque el esclavo. Si ha estado replicando préviamente, arranque el esclavo con la opción `--skip-slave-start` para que no intente conectar inmediatamente al maestro. También puede arrancar el esclavo con la opción `--log-warnings` (activada por defecto en MySQL 5.0), para obtener más mensajes en el log de errores acerca de problemas (por ejemplo, problemas de red o conexiones). En MySQL 5.0, las conexiones abortadas no se loguean en el log de errores a no ser que el valor sea mayor que 1.

8. Si hace una copia de seguridad de los datos del maestro usando mysqldump, cargue el fichero de volcado en el esclavo:

       shell> mysql -u root -p < dump_file.sql

9. Ejecute los siguientes comandos en el esclavo, reemplazando los valores de opciones con los valores relevantes para su sistema:

       mysql> CHANGE MASTER TO
           ->     MASTER_HOST='master_host_name',
           ->     MASTER_USER='replication_user_name',
           ->     MASTER_PASSWORD='replication_password',
           ->     MASTER_LOG_FILE='recorded_log_file_name',
           ->     MASTER_LOG_POS=recorded_log_position;

   La siguiente tabla muestra la longitud máxima para las opciones de cadenas de carácteres:

   `MASTER_HOST` | 60
   `MASTER_USER` | 16
   `MASTER_PASSWORD` | 32
   `MASTER_LOG_FILE` | 255

10. Arranque el flujo esclavo:

        mysql> START SLAVE;

Una vez realizado este procedimiento, el esclavo debe conectar con el maestro y atapar cualquier actualización que haya ocurrido desde que se obtuvieron los datos.

Si ha olvidado asignar un valor para `server-id` en el maestro, los esclavos no son capaces de conectar.

Si olvida asignar un valor para `server-id` en el esclavo, obtiene el siguiente error en el log de errores:

    Warning: You should set server-id to a non-0 value if master_host is set;
    we will force server id to 2, but this MySQL server will not act as a slave.

También encuentra mensajes de error en el log de errores del esclavo si no es capaz de replicar por ninguna otra razón.

Una vez que un esclavo está replicando, puede encontrar en su directorio de datos un fichero llamado `master.info` y otro llamado `relay-log.info`. El esclavo usa estos dos ficheros para saber hasta que punto ha procesado el log binario del maestro. No borre o edite estos ficheros, a no ser que realmente sepa lo que hace y entienda las implicaciones. Incluso en tal caso, es mejor que use el comando `CHANGE MASTER TO`.

Nota: El contenido de `master.info` subedita algunas de las opciones especificadas en línea de comandos o en `my.cnf`. Consulte Sección 6.8, “Opciones de arranque de replicación” para más detalles.

Una vez que tiene una copia de los datos, puede usarlo para actualizar otros esclavos siguiendo las porciones del procedimiento descrito. No necesita otra muestra de los datos del maestro; puede usar la misma para todos los esclavos.

Nota: para la mayor durabilidad y consistencia posible en una inicialización de replicación usando `InnoDB` con transacciones debe usar `innodb_flush_logs_at_trx_commit=1`, `sync-binlog=1`, y `innodb_safe_binlog` en su fichero `my.cnf` del maestro.

## 6.5. Compatibilidad entre versiones de MySQL con respecto a la replicación

Nota: El formato del log binario tal y como se implementa en MySQL 5.0 es considerablemente distinto al usado en versiones previas. Los cambios principales se hicieron en MySQL 5.0.3 (para mejoras en el tratamiento de conjuntos de carácteres y `LOAD DATA INFILE`) y 5.0.4 (para mejoras en el tratamiento de zonas horarias). Esto tiene consecuencias tremendas en actualizar servidores en un entorno de replicación, como se describe en Sección 6.6, “Aumentar la versión de la replicación”.

Recomendamos usar la versión de MySQL más reciente disponible, ya que las capacidades de replicación se mejoran contínuamente. También recomendamos usar la misma versión para el maestro y el servidor. Recomendamos actualizar el maestro y esclavo que tengan versiones alfa o beta a versiones de producción. La replicación desde un maestro con versión 5.0.3 a un esclavo 5.0.2 falla; dsde un maestro 5.0.4 a un esclavo 5.0.3 también fallará. En general, los esclavos ejecutando MySQL 5.0.x pueden usarse con maestro antiguos (incluso aquéllos ejecutando MySQL 3.23, 4.0, or 4.1), pero no al revés.

La información precedente pertenece a la compatibilidad de replicación a nivel de protocolo. También puede haber restricciones de compatibilidad a nivel de SQL, como se discute en Sección 6.7, “Características de la replicación y problemas conocidos”.

## 6.6. Aumentar la versión de la replicación

Cuando actualiza servidores que participan en una actualización de replicación, el procedimiento para actualizar depende en la versión actual del servidor y la versión que está actualizando.

### 6.6.1. Aumentar la versión de la replicación a 5.0

Esta sección se aplica para actualizar replicaciones de MySQL 3.23, 4.0, o 4.1 a 5.0. Un servidor 4.0 debe ser 4.0.3 o posterior.

Cuando actualice un maestro desde MySQL 3.23, 4.0, o 4.1 a 5.0, primero debe asegurarse que todos los esclavos de su maestro están usando la misma versión 5.0.x . Si no es así, debe primero actualizar todos los esclavos. Para actualizar cada esclavo, párelo, actualícelo a la versión 5.0.x apropiado, reinícielo, y reinicie la replicación. El esclavo 5.0 es capaz de leer los logs retardados antiguos escritos antes de la actualización y ejecutar los comandos que contiene. Los logs retardados creados por el esclavo tras la actualización están en formato 5.0.

Una vez que se han actualizado los esclavos, pare el maestro, actualícelo a la misma versión 5.0.x que los esclavos, y reinícielo. El maestro 5.0 es capaz de leer los antiguos logs binarios escritos antes de la actualización y enviarlos a los esclavos 5.0. Los esclavos reconocen el antiguo formato y lo tratan apropiadamente. Los logs binarios creados por el maestro después de la actualización están en formato 5.0. Estos también son reconocidos por los esclavos 5.0.

En otras palabras, no hay medidas a tomar cuando se actualiza a 5.0, excepto que los esclavos deben ser 5.0 antes que pueda actualizar el maestro a 5.0. Tenga en cuenta que bajar de una versión 5.0 a una antigua no funciona tan sencillamente: debe asegurarse que cualquier log binario 5.0 o log retardado ha sido procesado por completo, para que pueda borrarlos antes de cambiar de versión.

## 6.7. Características de la replicación y problemas conocidos

En general, la compatibilidad de la replicación en nivel SQL requiere que cualquier característica usada sea soportado tanto por el maestro como por los servidores esclavos. Por ejemplo, la función `TIMESTAMPADD()` se implementó en MySQL 5.0.0. Si usa esta función en el maestro, no puede replicar a un servidor esclavo que sea más antiguo que MySQL 5.0.0. Si planea usar replicación entre 5.0 y versiones prévias de MySQL debe consultar el Manual de referencia de MySQL 4.1 para información acerca de las características de replicación en versiones prévias de MySQL.

La siguiente lista proporciona detalles acerca de qué se soporta y qué no. Información específica adicional de `InnoDB` acerca de replicación se da en Sección 15.6.5, “`InnoDB` y replicación MySQL”. Aspectos de replicación acerca de rutinas almacenadas y disparadores se describen en Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.

- La replicación se da correctamente con `AUTO_INCREMENT`, `LAST_INSERT_ID()`, y `TIMESTAMP` .

- Las funciones `USER()`, `UUID()`, y `LOAD_FILE()` se replican sin cambios y no funcionan correctamente con el esclavo.

- Las funciones que tratan bloqueos a nivel de usuario: `GET_LOCK()`, `RELEASE_LOCK()`, `IS_FREE_LOCK()`, `IS_USED_LOCK()` se replican sin que el esclavo sepa el contexto de concurrencia del maestro; así que estas funciones no deben usarse para insertar en una tabla del maestro ya que el contexto del esclavo puede diferir (p.e. no haga `INSERT INTO mytable VALUES(GET_LOCK(...))`).

- Las variables `FOREIGN_KEY_CHECKS`, `SQL_MODE`, `UNIQUE_CHECKS`, and `SQL_AUTO_IS_NULL` se replican todas en MySQL 5.0. La variable `TABLE_TYPE`, también conocida como `STORAGE_ENGINE` no se replica todavía, lo que es bueno para replicación entre distintos motores de almacenamiento.

- A partir de MySQL 5.0.3 (maestro y esclavo), la replicación funciona bien incluso si el maestro y el esclavo tienen distintos conjuntos de carácteres globalres. A partir de MySQL 5.0.4 (maestro y esclavo), la replicación funciona bien incluso si el maestro y el esclavo tienen distintas variables de zonas horarias.

- Lo siguiente se aplica para replicación entre servidores MySQL usando distintos conjuntos de carácteres:

  1. Debe siempre usar las mismas colaciones y conjuntos de carácteres globales (`--default-character-set`, `--default-collation`) en el maestro y esclavo. De otro modo, puede obtener errores de claves duplicadas en el esclavo, debido a que una clave que se trata como única en el conjunto de carácteres del maestro puede no ser único en el conjunto de carácteres del esclavo.

  2. Si el maestro es anterior a MySQL 4.1.3, el conjunto de carácteres de la sesión nunca debería ser distinto al del valor global (en otras palabras, no use `SET NAMES`, `SET CHARACTER SET`, y así) ya que este cambio del conjunto de carácteres no es conocido por el esclavo. Si tanto el maestro coom el esclavo son de la versión 4.1.3 o posterior, la sesión puede cambiar los valores locales del conjunto de carácteres (tales como `NAMES`, `CHARACTER SET`, `COLLATION_CLIENT`, y `COLLATION_SERVER`) ya que estos cambios se escriben en el log binario y son conocidos por el esclavo. Sin embargo, la sesión no puede cambiar estos valores globales ya que el maestro y esclavo deben tener conjuntos de carácteres idénticos.

  3. Si tiene bases de datos en el maestro con distintos conjuntos de carácteres al valor global de `collation_server` , debe diseñar su comando `CREATE TABLE` que no se base en el conjunto de carácteres por defecto de la base de datos, ya que actualmente hay un bug (Bug#2326); una solución es poner el conjunto de carácteres y colación explícitamente en `CREATE TABLE`.

- Tanto el maestro como el esclavo deben tener la misma zona horaria. De otro modo algunos comandos, por ejemplo comandos que usen `NOW()` o `FROM_UNIXTIME()` no se replicarán apropiadamente. Se podría poner una zona horaria en que el servidor MySQL se ejecute usando la opción `--timezone=`timezone_name`` del script `mysqld_safe` o asignando un valor a la variable de entorno `TZ`. Tanto el maestro como el esclavo deben tener la misma zona horaria para las conexiones; esto es, el parámetro `--default-time-zone` debe tener el mismo valor para maestro y servidor.

- `CONVERT_TZ(...,...,@global.time_zone)` no se replica apropiadamente. `CONVERT_TZ(...,...,@session.time_zone)` se replica apropiadamente sólo si el maestro y esclavo son de la versión 5.0.4 o posterior.

- Las variables de sesión no se replican apropiadamente cuando se usan en comandos que actualizan tablas; por ejemplo: `SET MAX_JOIN_SIZE=1000; INSERT INTO mytable VALUES(@MAX_JOIN_SIZE);` no insertará los mismos datos en el maestro y el esclavo. Esto no se aplica a `SET TIME_ZONE=...; INSERT INTO mytable VALUES(CONVERT_TZ(...,...,@time_zone))`, que se arregla en MySQL 5.0.4.

- Es posible replicar tablas transaccionales en el maestro usando tablas no transaccionales en el esclavo. Por ejemplo, puede replicar una tabla maestra `InnoDB` como una tabla esclava `MyISAM` . Sin embargo, si lo hace, hay problemas si el esclavo se para en medio de un bloque `BEGIN`/`COMMIT` , ya que el esclavo reinicia al principio del bloque `BEGIN` . Este tema se encuentra en la lista de temas pendientes y se arreglará próximamente.

- Los comandos de actualización que se refieren a variables de usuario (esto es, variables de la forma `@`var_name``) se replican correctamente en MySQL 5.0; sin embargo esto no es cierto para versiones prévias a 4.1. Tenga en cuenta que los nombres de las variables de usuario no son sensibles a mayúsculas desde MySQL 5.0; debe tener esto en cuenta cuando prepare una replicación entre 5.0 y versiones antiguas.

- Los esclavos MySQL 5.0 pueden conectar a maestros 5.0 usando SSL.

- En MYSQL 5.0 (desde 5.0.3), hay una variable de sistema global `slave_transaction_retries`: Si el flujo SQL del esclavo de replicación falla al ejecutar una transacción debido a un deadlock `InnoDB` o excede el `innodb_lock_wait_timeout` de InnoDB o `TransactionDeadlockDetectionTimeout` o `TransactionInactiveTimeout` de NDB, automáticamente reintenta `slave_transaction_retries` veces antes de parar con un error. El valor por defecto en MySQL 5.0 es 10. A partir de MySQL 5.0.4, el número total de reintentos pueden verse en la salida de `SHOW STATUS`; consulte Sección 5.3.4, “Variables de estado del servidor”.

- Si `DATA DIRECTORY` o `INDEX DIRECTORY` se usa en un comando `CREATE TABLE` en el maestro, la cláusula se usa en el esclavo. Esto puede causar problemas si no existe el directorio correspondiente en el sistema de ficheros del esclavo o existe pero no es accesible en el esclavo. MySQL 5.0 soporta una opción `sql_mode` llamada `NO_DIR_IN_CREATE`. Si el esclavo se ejecuta con este modo SQL , ignora estas cláusulas al replicar el comando `CREATE TABLE` . El resultado es que los datos `MyISAM` y ficheros índice se crean en el directorio de la base de datos de la tabla.

- Es posible que los datos del maestro y el esclavo diverjan si se diseña una consulta tal que la modificación de los datos no sea determinista; esto es, si se deja a criterio del optimizador de consultas. (Esto no es generalmente una buena práctica en ningún caso, incluso fuera de la replicación.) Para una explicación detallada de este tema consulte Sección A.8.4, “Cuestiones abiertas en MySQL”.

- Lo siguiente se aplica sólo si el maestro o el esclavo están ejecutando la versión 5.0.3 o anterior: Si se interrumpe un `LOAD DATA INFILE` en el maestro (violación de integridad, conexión muerta, o así), el esclavo ignora el `LOAD DATA INFILE` totalmente. Esto significa que si este comando inserta o actualiza registros en tablas de forma permanente antes de interrumpirse, estas modificaciones no se replican en el esclavo.

- `FLUSH LOGS`, `FLUSH MASTER`, `FLUSH SLAVE`, y `FLUSH TABLES WITH READ LOCK` no se loguean ya que cualquiera de ellos puede causar problemas al replicarse en un esclavo.) Para un ejemplo de sintaxis, consulte Sección 13.5.5.2, “Sintaxis de `FLUSH`”. En MySQL 5.0, `FLUSH TABLES`, `ANALYZE TABLE`, `OPTIMIZE TABLE`, y `REPAIR TABLE` se escriben en el log binario y por lo tanto se replican en los esclavos. Esto no es un problema normalmente porque estos comandos no modifican los datos de las tablas. Sin embaargo, esto puede causar dificultades bajo ciertas circunstancias. Si replica las tablas de privilegios en la base de datos `mysql` y actualiza estas tablas directamente sin usar `GRANT`, debe ejecutar un comando `FLUSH PRIVILEGES` en los esclavos para poner los nuevos privilegios en efecto. Además, si usa `FLUSH TABLES` cuando queda una tabla `MyISAM` que es parte de una tabla `MERGE` , debe ejecutar un `FLUSH TABLES` manualmente en los esclavos. En MySQL 5.0, estos comandos se escriben en el log binario a no ser que especifique `NO_WRITE_TO_BINLOG` o su alias `LOCAL`.

- MySQL sólo soporta un maestro y varios esclavos. En el futuro planeamos añadir un algoritmo de voto para cambiar el maestro automáticamente en caso de problemas con el maestro actual. También planeamos introducir procesos agentes para ayudar a realizar balanceo de carga mandando consultas `SELECT` a distintos esclavos.

- Cuando un servidor para y reinicia, sus tablas `MEMORY` (`HEAP`) se vacían . En MySQL 5.0, el maestro replica este efecto como sigue: La primera vez que el maestro usa cada tabla `MEMORY` tras arrancar, lo notifica a los esclavos que la tabla necesita vacíar escribiendo un comando `DELETE FROM` para esa tabla en el log binario. Consulte Sección 14.3, “El motor de almacenamiento `MEMORY` (`HEAP`)” para más información.

- Las tablas temporales se replican excepto en el caso donde para el esclavo (no sólo los flujos esclavos) y ha replicado tablas temporales que se usan en actualizaciones que no se han ejecutado todavía en el esclavo. Si para el esclavo, las tablas temporales necesitadas por estas actualizaciones no están disponibles cuando el esclavo se reinicia. Para evitar este problema, no pare el esclavo mientras tiene tablas temporales abiertas. En lugar de eso, use el siguiente procedimiento:

  1. Ejecute un comando `STOP SLAVE` .

  2. Use `SHOW STATUS` para chequear el valor de la variable `Slave_open_temp_tables` .

  3. Si el valor es 0, ejecute un comando mysqladmin shutdown para parar el esclavo.

  4. Si el valor no es 0, reinicie los flujos esclavos con `START SLAVE`.

  5. Repita el procedimiento posteriormente para comprobar si tiene mejor suerte la próxima vez.

  Planeamos arreglar este problema en el futuro cercano.

- Es correcto conectar servidores de modo circular en una relación maestro/esclavo con la opción `--log-slave-updates`. Tenga en cuenta, sin embargo, que varios comandos no funcionan correctamente en esta clase de inicialización a no ser que su código cliente esté escrito para tener en cuenta que pueden ocurrir actualizaciones en distintas secuencias de diferentes servidores.

  Esto significa que puede crear una inicialización como esta:

      A -> B -> C -> A

  Los IDs de los servidores se codifican en los logs binarios de eventos, así que el servidor A conoce cuando un evento que lee fue creado originalmente por sí mismo y no ejecuta el evento ( a no ser que el servidor A se iniciara con la opción `--replicate-same-server-id`, que tiene significado sólo en inicializaciones raras). Por lo tanto, no hay bucles infinitos. Sin embargo, esta inicialización circular funciona sólo si no realiza actualizaciones conflictivas entre tablas. En otras palabras, si inserta datos tanto en A y C, no debe insertar un registro en A que pueda tener una clave que entre en conflicto con un registro insertado en C. Tampoco debe actualizar el mismo registro en dos servidores si el orden de las actualizaciones es significativo.

- Si un comando en el esclavo produce un error, el flujo esclavo SQL termina, y el esclavo escribe un mensaje en su log de errores. Luego debe conectar al esclavo manualmente, arreglar el problema (por ejemplo, una tabla no existente), y luego ejecutar `START SLAVE`.

- Es correcto parar un maestro y reiniciarlo posteriormente. Si un esclavo pierde su conexión con el maestro, el esclavo trata de reconectar inmediatamente. Si falla, el esclavo reintenta periódicamente. (Por defecto reinicia cada 60 segundos. Esto puede cambiarse con la opción `--master-connect-retry` .) El esclavo también es capaz de tratar con problemas de conectividad de red. Sin embargo, el esclavo se da cuenta del problema de red sólo tras no recibir datos del maestro durante `slave_net_timeout` segundos. Si los problemas son cortos, puede decrementar `slave_net_timeout`. Consulte Sección 5.3.3, “Variables de sistema del servidor”.

- Parar el esclavo (correctamente) es seguro, ya que toma nota de dónde lo dejó. Las paradas no correctas pueden producir problemas, especialmente si la caché de disco no se volcó a disco antes que parara el sistema. La tolerancia a fallos del sistema se incrementa generalmente si tiene proveedores de corriente ininterrumpidos. Las paradas no correctas del maestro pueden causar inconsistencias entre los contenidos de tablas y el log binario en el maestro; esto puede evitarse usando tablas `InnoDB` y la opción `--innodb-safe-binlog` en el maestro. Consulte Sección 5.10.3, “El registro binario (Binary Log)”.

- Debido a la naturaleza no transaccional de las tablas `MyISAM`, es posible tener un comando que actualice parcialmente una tabla y retorne un código de error. Esto puede ocurrir, por ejemplo, en una inserción de varios registros que tenga un registro que viole una clave, o si una actualización larga se mata tras actualizar algunos de los registros. Si esto ocurre en el maestro, el flujo esclavo sale y para hasta que el administrador de base de datos decida qué hacer acerca de ello a no ser que el código de error se legitime y la ejecución del comando resulte en el mismo código de error. Si este comportamiento de validación de código de error no es deseable, algunos o todos los errores pueden ser ignorados con la opción `--slave-skip-errors` .

- Si actualiza tablas transaccionales para tablas no transaccionales dentro de una secuencia `BEGIN`/`COMMIT` , las actualizaciones del log binario pueden desincronizarse si la tabla no transaccional se actualiza antes de que acabe la transacción. Esto se debe a que la transacción se escribe en el log binario sólo cuando acaba.

- En situaciones donde las transacciones mezclan actualizaciones transaccionales y no transaccionales, el orden de los comandso en el log binario es correcto , y todos los comandos necesarios se escriben en el log binario incluso en caso de un `ROLLBACK`). Sin embargo, cuando una segunda conexión actualiza la tabla no transaccional antes que la primera transacción se complete, los comandos pueden loguearse fuera de orden, ya que la actualización de la segunda conexión se escribe inmediatamente al ejectarse, sin tener en cuenta el estado de la transacción que se ejecuta en la primera conexión.

## 6.8. Opciones de arranque de replicación

Tanto en el maestro como el esclavo, debe usar la opción `server-id` para establecer un ID de replicación único para cada servidor. Debe elegir un entero positivo único en el rango de 1 a 2^32 - 1 para cada maestro y esclavo. Ejemplo: `server-id=3`

Las opciones que puede usar en el maestro para controlar el logueo binario se describen en Sección 5.10.3, “El registro binario (Binary Log)”.

La siguiente tabla describe las opciones que puede usar en servidores esclavos de replicación MySQL 5.0. Puede especificar estas opciones por línea de comandos o en un fichero de opciones.

Algunas opciones de replicación del esclavo se tratan de forma especial, en el sentido que se ignoran si existe un fichero `master.info` cuando el esclavo arranca y contiene valores para las opciones. Las siguientes opciones se tratan de este modo:

- `--master-host`

- `--master-user`

- `--master-password`

- `--master-port`

- `--master-connect-retry`

- `--master-ssl`

- `--master-ssl-ca`

- `--master-ssl-capath`

- `--master-ssl-cert`

- `--master-ssl-cipher`

- `--master-ssl-key`

El fichero `master.info` en formato 5.0 incluye valores correspondientes a las opciones SSL. Además, el formato del fichero incluye como primer línea el número de líneas en el fichero. Si actualiza de un servidor antiguo a uno nuevo, el nuevo servidor actualiza el fichero `master.info` al nuevo formato automáticamente cuando arranca. Sin embargo, si baja de versión un servidor nuevo a una versión antigua, debe borrar la primera línea manualmente antes de arrancar el servidor antiguo la primera vez.

Si no existe un fichero `master.info` cuando arranca el esclavo, usa los valores para estas opciones que se especifican en el fichero de opciones o en línea de comandos. Esto ocurre cuando arranca el servidor como un esclavo de replicación la primera vez, o cuando ha ejecutado `RESET SLAVE` y luego ha parado y rearrancado el esclavo.

Si el fichero `master.info` existe cuando el esclavo arranca, el servidor ignora estas opciones. En su lugar, usa los valores encontrados en el fichero `master.info` .

Si reinicia el esclavo con valores distintos de las opciones de arranque que corresponden a los valores en el fichero `master.info` , los valores diferentes no tienen efecto, ya que el servidor continúa usando el fichero `master.info` . Para usar valores distintos, debe reiniciar tras borrar el fichero `master.info` o (preferiblemente) use el comando `CHANGE MASTER TO` para reiniciar los valores mientras el esclavo está corriendo.

Soponga que especifica estas opciones en su fichero `my.cnf` :

    [mysqld]
    master-host=some_host

La primera vez que arranca el servidor como esclavo de replicación, lee y usa esta opción del fichero `my.cnf`. El servidor guarda el valor en el fichero `master.info` . La siguiente vez que arranque el servidor, lee el valor de la máquina maestra sólo desde el fichero `master.info` e ignora el valor en el fichero de opciones. Si modifica el fichero `my.cnf` para especificar un equipo maestro distinto a `some_other_host`, el cambio todavía no tiene efecto. Debe usar `CHANGE MASTER TO` en su lugar.

Debido a que el servidor da una precedencia al fichero `master.info` sobre las opciones de arranque descritas, puede no usar las opciones de arranque para estos valores, y en su lugar especificarlos usando el comando `CHANGE MASTER TO` . Consulte Sección 13.6.2.1, “Sintaxis de `CHANGE MASTER TO`”.

Este ejemplo muestra un uso más extensivo de las opciones de arranque para configurar un esclavo:

    [mysqld]
    server-id=2
    master-host=db-master.mycompany.com
    master-port=3306
    master-user=pertinax
    master-password=freitag
    master-connect-retry=60
    report-host=db-slave.mycompany.com

La siguiente lista describe opciones de arranque para controlar la replicación: Muchas de estas opciones pueden cambiarse con el servidor en ejecución usando el comando `CHANGE MASTER TO`. Otras, tales como las opciones `--replicate-*`, sólo pueden cambiarse cuando arranca el esclavo. Planeamos arreglar esto.

- `--log-slave-updates`

  Normalmente, las actualizaciones recibidas por un servidor maestro por un esclavo no se loguean en el log binario. Esta opción le dice al esclavo que loguee las actualizaciones realizadas por el flujo SQL en el log binario del esclavo. Para que esta opción tenga efecto, el esclavo debe arrancarse con la opción `--log-bin` para permitir logueo binario. `--log-slave-updates` se usa cuando quiere encadenar servidores de replicación . Por ejemplo, puede hacer una inicialización como esta:

      A -> B -> C

  Esto es , A sirve como maestro para el esclavo B, y B sirve como maestro para el esclavo C. Para que funcione, B debe ser tanto maestro como esclavo. Debe arrancar tanto A como B con `--log-bin` para permitir logueo binario, y B con la opción `--log-slave-updates` .

- `--log-warnings`

  Hace que el esclavo muestre más mensajes en el log de errores acerca de qué está haciendo. Por ejemplo, le advierte que ha podido reconectar tras un error de red, y le informa cada vez que arrancan los flujos del esclavo. Esta opción está activada por defecto en MySQL 5.0; para desactivarla, use `--skip-log-warnings`. En MySQL 5.0, las conexiones abortadas no se loguean en el log de errores a no ser que el valor sea mayor que 1.

  Tenga en cuenta que los efectos de esta opción no están limitados a replicación. Produce advertencias a través de un espectro de actividades de servidor.

- `--master-connect-retry=`seconds``

  Número de segundos que el flujo esclavo duerme antes de reintentar conectar al maestro en caso que caiga el maestro o se pierda la conexión. El valor en el fichero `master.info` tiene precedencia si puede leerse. Si no está especificado, por defecto es 60.

- `--master-host=`host``

  El nombre de equipo o número IP del maestro. Si no se da esta opción, el flujo esclavo no arranca. El valor en `master.info` tiene precedencia si puede leerse.

- `--master-info-file=`file_name``

  Nombre a usar para el fichero en que el esclavo guarda información acerca del maestro. El nombre por defecto es `mysql.info` en el directorio de datos.

- `--master-password=`password``

  Contraseña de la cuenta que el flujo esclavo usa para autenticar al conectar al maestro. El valor en el fichero `master.info` tiene precedencia si puede leerse. Si no está asignado, se asume la contraseña vacía.

- `--master-port=`port_number``

  El puerto TCP/IP en que está escuchando el maestro. El valor en el fichero `master.info` tiene precedencia si puede leerse. Si no está asignado, se usa la especificación compilada. Si no ha cambiado las opciones de configure debería ser 3306.

- `--master-ssl`, `--master-ssl-ca=`file_name`` , `--master-ssl-capath=`directory_name`` , `--master-ssl-cert=`file_name`` , `--master-ssl-cipher=`cipher_list`` , `--master-ssl-key=`file_name``

  Estas opciones se usan para preparar una conexión de replicación segura al maestro usando SSL. Sus significados son los mismos que los de las opciones correspondientes `--ssl`, `--ssl-ca`, `--ssl-capath`, `--ssl-cert`, `--ssl-cipher`, `--ssl-key` descritas en Sección 5.7.7.5, “Opciones relativas a SSL”. Los valores en el fichero `master.info` tienen precedencia si pueden leerse.

- `--master-user=`username``

  El nombre de usuario que el flujo esclavo usa para autenticar al conectar con el maestro. En MySQL 5.0, esta cuenta debe tener el privilegio `REPLICATION SLAVE` . El valor en el fichero `master.info` , si puede leerse, tiene precedencia. Si el usuario maestro no está inicializado, se asume el usuario `test` .

- `--max-relay-log-size=`#``

  Para rotar el log retardado automáticamente. Consulte Sección 5.3.3, “Variables de sistema del servidor”.

- `--read-only`

  Esta opción hace que el esclavo no permita ninguna actualización excepto de flujos esclavos o de usuarios con el privilegio `SUPER` . Esto puede ser útil para asegurar que un servidor esclavo no acepta actualizaciones de los clientes.

- `--relay-log=`file_name``

  El nombre para el log retardado. El nombre por defecto es ``host_name`-relay-bin.`nnnnnn``, donde `host_name` es el nombre del esclavo y `nnnnnn` indica que los logs retardados se crean en secuencia enumerada. Puede especificar la opción para crear nombres de logs retardados independientes del nombre de la máquina, o si sus logs retardados tieneden a ser grandes ( y no quiere decrementar `max_relay_log_size`) y necesita ponerlos en algún área distinta del directorio de datos, o si quiere incrementar la velocidad balanceando carga entre discos.

- `--relay-log-index=`file_name``

  Localización y nombre que deben usarse para el fichero índice del log retardado. El nombre por defecto es ``host_name`-relay-bin.index`, donde `host_name` es el nombre del esclavo.

- `--relay-log-info-file=`file_name``

  El nombre a usar por el fichero en que el esclavo guarda información acerca del log retardado. El nombre por defecto es `relay-log.info` en el directorio de datos.

- `--relay-log-purge={0|1}`

  Desactiva o activa la purga automática del log retardado en cuanto no se necesitan más. El valor por defecto es 1 (activado). Esta es una variable global que puede cambiarse dinámicamente con `SET GLOBAL relay_log_purge`.

- `--relay-log-space-limit=`#``

  Especifica un límite superior del tamaño total de todos los logs retardados en el esclavo (un valor de 0 significa que no hay limitación de tamaño). Esto es útil para un esclavo con espacio de disco limitado. Cuando se alcanza el límite, el flujo de entrada/salida para de leer eventos del log binario del maestro hasta que el flujo SQL borra algunos logs retardados no usados. Tenga en cuenta que este límite no es absoluto: Hay casos donde el flujo SQL necesita más eventos antes que pueda borrar logs retardados. En tal caso, el flujo de entrada/salida excede el límite hasta que es posible para el flujo SQL borrar algunos logs retardados. (El no hacerlo causaría un deadlock.) No debe asignar `--relay-log-space-limit` un valor menor al doble del valor de `--max-relay-log-size` (o `--max-binlog-size` si `--max-relay-log-size` es 0). En tal caso, hay una oportunidad que el flujo de entrada/salida espere espacio libre debido a que se excede `--relay-log-space-limit`, pero el flujo SQL no tiene log retardado para purgar y es incapaz de satisfacer el flujo de entrada/salida. Esto fuerza al flujo de entrada/salida a que ignore temporalmente `--relay-log-space-limit`.

- `--replicate-do-db=`db_name``

  Le dice al esclavo que restrinja replicación a comandos donde la base de datos por defecto (esto es, la seleccionada por `USE`) es `db_name`. Para especificar más de una base de datos, use esta opción múltiples veces, una para cada base de datos. Tenga en cuenta que esto no replica comandos entre bases de datos tales como `UPDATE `some_db.some_table` SET foo='bar'` mientras se haya seleccionado una base de datos distinta o ninguna base de datos. Si necesita actualizaciones entre bases de datos distintas use `--replicate-wild-do-table=`db_name`.%`. Por favor lea las notas que hay a continuación de esta lista de opciones.

  Un ejemplo de lo que no funciona como podría esperar: Si el esclavo arranca con `--replicate-do-db=sales` y realiza el siguiente comando en el maestro, el comando `UPDATE` no se replica:

      USE prices;
      UPDATE sales.january SET amount=amount+1000;

  Si necesita que funcionen actualizaciones entre varias bases de datos, use `--replicate-wild-do-table=`db_name`.%` en su lugar.

  La razón principal para este comportamiento “sólo chequee la base de datos por defecto ” es que es difícil para el comando conocer si debe o no debe ser replicado (por ejemplo, si está usando comandos `DELETE` de múltiples tablas o comandos `UPDATE` de múltiples tablas que actúan entre múltiples bases de datos). También es más rápido chequear sólo la base de datos por defecto en lugar de todas las bases de datos si no hay necesidad.

- `--replicate-do-table=`db_name.tbl_name``

  Le dice al flujo esclavo que restrinja replicación a la tabla especificada. Para especificar más de una tabla, use esta opción múltiples veces, una para cada tabla. Esto funciona para actualizaciones entre bases de datos, en contraste con `--replicate-do-db`. Lea los comentarios a continuación de esta lista de opciones.

- `--replicate-ignore-db=`db_name``

  Le dice al esclavo que no replique ningún comando donde la base de datos por defecto (esto es, la seleccionada por `USE`) es `db_name`. Para especificar más de una base de datos a ignorar, use esta opción múltiples veces, una para cada base de datos. No debe usar esta opción si está usando actualizaciones entre bases de datos y no quiere que estas acutalizaciones se repliquen. Lea las notas después de esta lista de opciones.

  Une ejemplo de lo que no funciona como podría esperar: Si el esclavo arranca con `--replicate-ignore-db=sales` y ejecuta el siguiente comando en el maestro, el comando `UPDATE` se replica not :

      USE prices;
      UPDATE sales.january SET amount=amount+1000;

  Si necesita que funcionen actualizaciones entre bases de datos, use `--replicate-wild-ignore-table=`db_name`.%` en su lugar.

- `--replicate-ignore-table=`db_name.tbl_name``

  Le dice al esclavo que no replique ningún comando que actualice la tabla especificada (incluso si otras tablas se actualizan en el mismo comando). Para especificar más de una tabla a ignorar, use esta opción múltiples veces, una para cada tabla. Esto funciona para actualizaciones entre bases de datos, en contraste con `--replicate-ignore-db`. Lea los comentarios a continuación de esta lista de opciones.

- `--replicate-wild-do-table=`db_name.tbl_name``

  Le dice al esclavo que restrinja la replicación a comandos donde cualquiera de las tablas actualizadas coincida con el patrón de base de datos y tabla. Los patrones pueden contener el comodín '`%`' and '`_`' , que tiene el mismo significado que para el operador `LIKE` . Para especificar más de una tabla, use esta opción múltiples veces, una para cada tabla. Esto funciona para actualizaciones entre bases de datos. Lea los comentarios a continuación de esta lista de opciones.

  Ejemplo: `--replicate-wild-do-table=foo%.bar%` replica sólo actualizaciones que usen una tabla donde el nombre de la base de datos comience con `foo` y el nombre de la tabla comienza con `bar`.

  Si el patrón del nombre de la tabla es `%`, coincide con cualquier nombre de tabla y la opción se aplica a commandos a nivel de base de datos (`CREATE DATABASE`, `DROP DATABASE`, y `ALTER DATABASE`). Por ejemplo, si usa `--replicate-wild-do-table=foo%.%`, comandos a nivel de base de datos se replican si el nombre de la base de datos coinciden con el patrón `foo%`.

  Para incluir carácteres comodín literales en el nombre de la base de datos o de tabla, debe introducir un carácter de antibarra de escape. Por ejemplo, para replicar todas las tablas de una base de datos que se llama `my_own%db`, pero no replicar tablas de la base de datos `my1ownAABCdb` , debe escapar los carácteres '`_`' y '`%`' así: `--replicate-wild-do-table=my\_own\%db`. Si usa la opción en la línea de comandos, puede necesitar doblar las antibarras o poner el valor de la opción entre comillas, dependiendo del intérprete de comandos. Por ejemplo, con el shell bash , tendría que escribir `--replicate-wild-do-table=my\\_own\\%db`.

- `--replicate-wild-ignore-table=`db_name.tbl_name``

  Le dice al esclavo que no replique un comando donde cualquier tabla coincida con el patrón dado. Para especificar más de una tabla a ignorar, use esta opción múltiples veces, una para cada tabla. Esto funciona para actualizaciones entre bases de datos. Lea los comentarios a continuación de esta lista de opciones.

  Ejemplo: `--replicate-wild-ignore-table=foo%.bar%` no replica actualizaciones que use una tabla donde el nombre de la base de datos comience con `foo` y el nombre de tabla comience con `bar`.

  Para información acerca de cómo funcionan las coincidencias, consulte la descripción de la opción `--replicate-wild-do-table` . Las reglas para incluir carácteres comodín en la opción son las mismas que para `--replicate-wild-ignore-table` .

- `--replicate-rewrite-db=`from_name`->`to_name``

  Le dice al esclavo que traduzca la base de datos por defecto (esto es, la seleccionada por `USE`) a `to_name` si era `from_name` en el maestro. Sólo los comandos que tengan que ver con tablas están afectados (no comandos tales como `CREATE DATABASE`, `DROP DATABASE`, y `ALTER DATABASE`), si y sólo si `from_name` era la base de datos por defecto en el maestro. Esto no funciona para actualizaciones entre bases de datos. Tenga en cuenta que la traducción del nombre de la base de datos se hace antes que se testeen las reglas de `--replicate-*`.

  Si usa esta opción en la línea de comandos y el carácter '`>`' es especial en su intérprete de comandos, ponga entre comillas el valor de la opción. Por ejemplo:

      shell> mysqld --replicate-rewrite-db="olddb->newdb"

- `--replicate-same-server-id`

  Para usar en esclavos. Usualmente puede usar el valor por defecto de 0, para evitar bucles infinitos en replicación circular. Si se pone a 1, este esclavo no evita eventos que tengan su propio id de servidor; normalmente esto es útil sólo en configuraciones raras. No puede ponerse a 1 si se usa `--log-slave-updates` . Tenga en cuenta que por defecto el flujo de entrada/salida del esclavo no escribe eventos en el log binario si tiene el id del esclavo (esta optimización ayuda a ahorrar espacio de disco). Así que si quiere usar `--replicate-same-server-id`, asegúrese de arrancar el esclavo con esta opción antes de hacer que el esclavo lea sus propios eventos que quiera que ejecute el flujo SQL del esclavo.

- `--report-host=`slave_name``

  El nombre de máquina o número IP del esclavo que debe reportar al maestro durante el registro del esclavo. Este valor aparece en la salida de `SHOW SLAVE HOSTS` en el maestro. No ponga ningún valor si no quiere que el esclavo se registre él mismo en el maestro. Tenga en cuenta que no es suficiente para el maestro leer el número IP del esclavo en el socket TCP/IP una vez que el esclavo conecte. Debido a `NAT` y otros elementos de enrutamiento, esa IP puede no ser válida para conectar del esclavo al maestro y otros equipos.

- `--report-port=`slave_port``

  El número de puerto TCP/IP para conectar al esclavo, a ser reportado al maestro durante el registro del esclavo. Asigne un valor sólo si el esclavo está escuchando en un puerto no estándar o si tiene un túnel especial desde el maestro u otros clientes al esclavo. Si no está seguro, deje esta opción sin asignar ningún valor.

- `--skip-slave-start`

  Le dice a un esclavo que no arranque el flujo del esclavo cuando el servidor arranque. Para arrancar el flujo posteriormente, use `START SLAVE` .

- `--slave_compressed_protocol={0|1}`

  Si se pone esta opción a 1, use compresión para el protocolo esclavo/maestro si ambos lo soportan.

- `--slave-load-tmpdir=`file_name``

  Nombre del directorio en el que el esclavo crea ficheros temporales. Esta opción por defecto es el valor de la variable de sistema `tmpdir` . Cuando el flujo SQL del esclavo replica un comando `LOAD DATA INFILE`, extrae el fichero a ser cargado del log retardado en ficheros temporales, luego los carga en la tabla .Si el fichero cargado en el maestro es muy grande, los ficheros temporales en el esclavo también lo son. Por lo tanto, es una buena idea usar esta opción para decirle al esclavo que ponga los ficheros temporales en un sistema de ficheros con mucho espacio disponible. En tal caso, puede usar la opción `--relay-log` en ese sistema de ficheros, debido a que los logs retardados también son muy grandes. `--slave-load-tmpdir` debe apuntar un sistema de ficheros en disco, no en memoria. El esclavo necesita los ficheros temporales usados para replicar `LOAD DATA INFILE` para sobrevivir a un reinicio de la máquina. El directorio no debe ser uno que limpie el sistema operativo durante el arranque.

- `--slave-net-timeout=`seconds``

  El número de segundos a esperar para más datos del maestro antes de abortar la lectura, considerando la conexión rota y tratando de reconectar. El primer reintento se hace inmediatamente tras el timeout. El intervalo entre reintentos se controla mediante la opción `--master-connect-retry` .

- `--slave-skip-errors= [`err_code1`,`err_code2`,... | all]`

  Normalmente, la replicación para cuando ocurre un error, lo que le da la oportunidad de resolver la inconsistencia en los datos manualmente. Esta opción le dice al flujo SQL esclavo que continue la replicación cuando un comando retorna cualquiera de los errores listados en la opción.

  No use esta opción a no ser que entienda porqué esta obteniendo opciones. Si no hay bugs en la preparación de la replicación ni en los programas cliente, y no hay bugs en el propio MySQL, nunca ocurre un error que pare la replicación. El uso indiscriminado de esta opción provoca que el esclavo pueda quedar desincronizado con el maestro, sin que usted sepa porqué ha ocurrido.

  Para códigos de error, debe usar los números proporcionados por el mensaje de error en su log de errores del esclavo y en la salida de `SHOW SLAVE STATUS`. Los códigos de error del servidor se listan en Capítulo 26, Manejo de errores en MySQL.

  También puede (pero no debería) usar el valor no recomendable de `all` que ignora todos los mensajes de error y continúa funcionando sin tener en cuenta qué ocurre. No hace falta decir que, si lo usa, no podemos garantizar la integridad de los datos. Por favor no proteste (ni envíe reportes de bug) en este caso si los datos del esclavo no se parecen a lo que hay en el maestro. Le hemos advertido.

  Ejemplos:

      --slave-skip-errors=1062,1053
      --slave-skip-errors=all

Las reglas `--replicate-*` se evalúan como se explica para determinar si un comando se ejecuta por el esclavo o se ignora:

1. ¿Hay algunas reglas `--replicate-do-db` o `--replicate-ignore-db` ?

   - Sí: Puede testearlas como `--binlog-do-db` y `--binlog-ignore-db` (consulte Sección 5.10.3, “El registro binario (Binary Log)”). ¿Cuál es el resultado del test?

     - Ignora el comando: Lo ignora y sale.

     - Ejecuta el comando: No lo ejecuta inmediatamente; difiere la decisión; continúa con el siguiente paso.

   - No: Continúa con el siguiente paso.

2. ¿Estamos ejecutando ahora una función o procedimiento almacenado?

   - Sí: Ejecuta la consulta y sale.

   - No: Continúa con el siguiente paso.

3. ¿Hay alguna regla `--replicate-*-table` ?

   - No: Continúa con el siguiente paso.

   - Sí: Continúa con el siguiente paso. Sólo las tablas que van a ser actualizadas se comparan con las reglas (`INSERT INTO sales SELECT * FROM prices`: sólo `sales` se compara con las reglas). Si varias tablas van a actualizarse (comando de múltiples tablas), la primera tabla coincidente (coincidencia “do” o “ignore”) gana. Esto es, la primera tabla se compara con las reglas. A continuación, si no se puede tomar ninguna decisión, la segunda tabla se compara con las reglas, y así.

4. ¿Hay algunas tablas `--replicate-do-table` ?

   - Sí: ¿Coincide la tabla con alguna de ellas?

     - Sí: Ejecuta la consulta y sale.

     - No: Sigue con el siguiente paso.

   - No: Sigue con el siguiente paso.

5. ¿Hay alguna regla `--replicate-ignore-table`?

   - Sí: ¿Coincide la tabla con alguna de ellas?

     - Sí: Ignora la consulta y sale.

     - No: Continúa con el siguiente paso.

   - No: Continúa con el siguiente paso.

6. ¿Hay alguna regla `--replicate-wild-do-table`?

   - Sí: ¿Coincide la tabla con alguna de ellas?

     - Sí: Ejecuta la consulta y sale.

     - No: Continúa con el siguiente paso.

   - No: Continúa con el siguiente paso.

7. ¿Hay alguna regla `--replicate-wild-ignore-table`?

   - Sí: ¿Coincide la tabla con alguna de ellas?

     - Sí: Ignora la consulta y sale.

     - No: Continúa con el siguiente paso.

   - No: Continúa con el siguiente paso.

8. No coincide ninguna regla `--replicate-*-table` . ¿Hay alguna otra tabla para comprobar con las reglas?

   - Sí: Bucle.

   - No: Hemos testeados todas las tablas a actualizar y no podemos encontrar ninguna coincidencia con ninguna regla. ¿Hay alguna regla `--replicate-do-table` o `--replicate-wild-do-table` ?

     - Sí: Ignora la consulta y sale.

     - No: Ejecuta la consulta y sale.

## 6.9. Preguntas y respuestas sobre replicación

P: ¿Cómo configuro el esclavo si el maestro está en ejecución y no quiero pararlo?

R: Hay varias opciones. Si ha hecho una copia de seguridad del maestro en algún punto y ha guardado el nombre del log binario y el desplazamiento ( de la salida de `SHOW MASTER STATUS`) correspondiente a la muestra de datos, use el siguiente procedimiento:

1. Asegúrese que el esclavo tiene asignado un ID de servidor único.

2. Ejecute el siguiente comando en el esclavo, rellenando los valores apropiados en cada opción:

       mysql> CHANGE MASTER TO
           ->     MASTER_HOST='master_host_name',
           ->     MASTER_USER='master_user_name',
           ->     MASTER_PASSWORD='master_pass',
           ->     MASTER_LOG_FILE='recorded_log_file_name',
           ->     MASTER_LOG_POS=recorded_log_position;

3. Ejecute `START SLAVE` en el esclavo.

Si no tiene una copia de seguridad del maestro, aquí hay un procedimiento rápido para crear uno. Todos los pasos deben realizarse en el maestro.

1. Ejecute este comando:

       mysql> FLUSH TABLES WITH READ LOCK;

2. Con el bloqueo todavía activo, ejecute este comando (o una variación de él):

       shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql

3. Ejecute este comando y asegúrese de guardar la salida, que necesitará posteriormente:

       mysql> SHOW MASTER STATUS;

4. Libere el bloqueo:

       mysql> UNLOCK TABLES;

Una alternativa es hacer un volcado SQL del maestro en lugar de una copia binaria como en el procedimiento precedente. Para hacerlo, puede usar mysqldump --master-data en su maestro y cargar el volcado SQL posteriormetne en su esclavo. Sin embargo, esto es más lento que hacer una copia binaria.

No importa cuál de los dos métodos use, luego siga las instrucciones para el caso en que tenga una muestra de los datos y haya guardado el nombre del log y el desplazamiento. Puede usar la misma muestra de datos para preparar varios esclavos. Una vez que tenga la muesta de datos del maestro, puede esperar a preparar un esclavo mientras los logs binarios en el maestro queden intactos. Hay dos limitaciones prácticas en la cantidad de tiempo que puede esperar que son la cantidad de espacio disponible para guardar los logs binarios y el tiempo que tarda el esclavo en leerlos.

También puede usar `LOAD DATA FROM MASTER`. Este es un comando apropiado que transfiere una muestra de los datos al esclavo y ajusta el nombre del log y el desplazamiento a la vez. En un futuro `LOAD DATA FROM MASTER` será el método recomendado para preparar un esclavo. Tenga en cuenta, sin embargo, que sólo funciona para tablas `MyISAM` y que puede mantener un bloqueo de lectura durante un largo periodo de tiempo. Todavía no está implementado tan eficientemente como querríamos. Si tiene tablas muy grandes, el mejor método por ahora es tomar una muesta de datos binaria en el maestro tras ejecutar `FLUSH TABLES WITH READ LOCK`.

P: ¿Necesita el esclavo estar conectado todo el tiempo al maestro?

R: No, no hace falta. El esclavo puede caer o quedar desconectado durante horas o días, luego reconectar y leer las actualizaciones. Por ejemplo, puede preparar una relación maestro/servidor mediante un enlace telefónico que sólo esté disponible esporádicamente y durante cortos periodos de tiempo. La implicación de esto es, que en un momento dado, el esclavo no garantiza estar sincronizado con el maestro a no ser que tome medidas especiales. En el futuro, tendremos la opción de bloquear el maestro hasta que al menos un esclavo esté sincronizado.

P: ¿Cómo se qué retardo tiene esclavo comparado con el maestro? En otras palabras, ¿cómo se la fecha de la última consulta replicada por el esclavo?

R: Para un esclavo MySQL 5.0, puede leer la columna `Seconds_Behind_Master` en `SHOW SLAVE STATUS`. Consulte Sección 6.3, “Detalles de la implementación de la replicación”.

Cuando un flujo SQL esclavo ejecuta un evento leído del maestro, modifica su propia hora a la hora del evento (esto es el porqué `TIMESTAMP` se replica bien). En la columna `Time` en la salida de `SHOW PROCESSLIST`, el número de segundos mostrados por el flujo SQL del esclavo es el número de segundos entre la hora del último evento replicado y la hora real de la máquina esclava. Puede usar esto para determinar la fecha del último evento replicado. Tenga en cuenta que si su esclavo se ha desconectado del maestro durante una hora, y luego reconecta, puede ver de forma inmediata valores `Time` como 3600 para el flujo SQL esclavo en `SHOW PROCESSLIST`. Esto ocurriría debido a que el esclavo está ejecutando comandos que tienen una hora.

P: ¿Cómo fuerzo al maestro a bloquear actualizaciones hasta que el esclavo las lee?

R: Use el siguiente procedimiento:

1. En el maestro, ejecute estos 2 comandos:

       mysql> FLUSH TABLES WITH READ LOCK;
       mysql> SHOW MASTER STATUS;

   Registra el nombre y desplazamiento del log de la salida del comando `SHOW` . Estas són las coordinaciones de replicación.

2. En el esclavo, ejecute el siguiente comando, donde el argumento de la función `MASTER_POS_WAIT()` son las coordenadas de replicación obtenidos en el prévio paso:

       mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);

   El comando `SELECT` bloquea hasta que el esclavo alcanza el fichero y desplazamiento de log especificado. En este punto, el esclavo está sincronizado con el maestro y el comando retorna.

3. En el maestro, ejectue el siguiente comando para permitir al maestro comenzar a ejecutar actualizaciones otra vez:

       mysql> UNLOCK TABLES;

P: ¿Qué cuestiones debo considerar al preparar una replicación bidireccional?

R: La replicación MySQL actualmente no sopota ningún protocolo de bloqueo entre maestro y servidor para garantizar la atomicidad de una actualización distribuida (entre servidores). En otras palabras, es posible para el cliente A hacer una actualización del co-maestro 1, y mientras tanto, antes de propagar al co-maestro 2, el cliente B puede hacer una actualización en el co-maesto 2 que haga que la actualización del cliente A funcione de forma distinta que haría en el co-maestro 1. Por lo tanto, cuando la actualización del cliente A se hace en el co-maestro 2, produce tablas que son distintas que las que tiene en el co-maestro 1, incluso tras todas las actualizaciones del co-maestro 2 se hayan propagado. Esto significa que no debe encadenar dos servidores en una relación de replicación bidireccional a no ser que esté seguro que sus actualizaciones pueden hacerse en cualquier orden, o a no ser que se encarge de actualizaciones desordenadas de algún modo en el código del cliente.

Debe tener en cuenta que replicación bidireccional no mejora mucho el rendimiento (o nada), en lo que se refiere a actualizaciones. Ambos servidores tienen que hacer el mismo número de actualizaciones, lo mismo que haría un servidor. La única diferencia es que hay un poco menos de bloqueos, ya que las actualizaciones originadas en otro servidor se serializan en un flojo esclavo. Incluso este beneficio puede verse penalizado por retardos de red.

P: ¿Cómo puedo usar replicación para mejorar rendimiento en mi sistema?

R: Debe preparar un servidor como maestro y dirigir todas las escrituras al mismo. Luego configure tantos esclavos como quiera, y distribuya las lecturas entre los esclavos y maestro. También puede arrancar esclavos con las opciones `--skip-innodb`, `--skip-bdb`, `--low-priority-updates`, y `--delay-key-write=ALL` para mejorar la velocidad en el esclavo. En este caso, el esclavo usa tablas no transaccionales `MyISAM` en lugar de `InnoDB` y `BDB` para obtener más velocidad.

P: ¿Qué debo hacer para preparar código cliente en mis propias aplicaciones para usar replicación que mejore el rendimiento?

R: Si la parte de su código que es responsable de acceso a bases de datos se ha modularizado correctamente, convertiéndola para correr con un entorno de replicación debe ser algo sencillo. Cambie la implementación de su acceso a base de datos para enviar todas las escrituras al maestro, y enviar lecturas al maestro o al esclavo. Si su código no tiene este nivel de abstacción, preparar un sistema de replicación le da la oportunidad de limpiarlo. Debe comenzar creando una biblioteca o módulo con las siguientes funciones:

- `safe_writer_connect()`

- `safe_reader_connect()`

- `safe_reader_statement()`

- `safe_writer_statement()`

`safe_` en cada nombre de función significa que la función se encarga de tratar todas las condiciones de error. Puede usar distintos nombres para las funciones. Lo importante es tener una interfaz unificada para conectar para lecturas, conectar para escrituras, hacer una lectura y hacer una escritura.

Luego debe convertir su código de cliente para usar la biblioteca. Este es un proceso largo y complicado en principio, pero vale la pena a la larga. Todas las aplicaciones que usen la aproximación descrita son capaces de aprovechar al configuración maestro/esclavo, incluso uno en el que intervengan varios esclavos. El código es mucho más fácil de mantener, y añadiendo opciones para tratar problemas es trivial. Necesita modificar una o dos funciones sólo; por ejemplo, para loguear cuánto tarda cada comando, o qué comando provoca un error.

Si ha escrito mucho código, puede querer automatizar la tarea de conversión usando la utilidad replace que viene con la distribución estándar MySQL, o escribir su propio script de conversión. Idealmente, su código usa convenciones de estilo. Si no, probablemente es mejor reescribirlo, o al menos regularizarlo manualmente para usar un estilo consistente.

P: ¿Cuándo y cómo puede mejorar la replicación MySQL el rendimiento de mi sistema?

R: La replicación MySQL es más benéfica para sistemas con lecturas frecuentes y escrituras infrecuentes. En teoría, usando una inicialización un maestro/múltiples esclavos, puede escalar el sistema añadiendo más esclavos hasta que se queda sin ancho de banda, o la carga de actualización crece hasta el punto que el maestro no puede tratarla.

Para determinar cuántos esclavos puede tener antes que los beneficios empiecen a notarse, necesita conocer el patrón de consultas, y determinar empíricamente con pruebas la relación entre las lecturas (lecturas por segundo , o `max_reads`) y las escrituras (`max_writes`) en un típico maestro y típico esclavo. El ejemplo muestra un cálculo simplificado de qué puede obtener con replicación para un sistema hipotético.

Digamos que la carga del sistema consiste en 10% de escrituras y 90% de lecturas, y hemos determinado con pruebas que `max_reads` es 1200 - 2 * `max_writes`. En otras palabras, el sistema puede hacer 1,200 lecturas por segundo sin escrituras, la escritura media es el doble de lenta que la lectura media, y la relación es linear. Supongamos que el maestro y cada esclavo tienen la misma capacidad, y que tienen un maestro y `N` esclavos. Tenemos para cada servidor (maestro o esclavo):

`lecturas = 1200 - 2 * escrituras`

`lecturas = 9 * escrituras / (`N` + 1)` (las lecturas se dividen, pero las escrituras van a todos los servidores)

`9 * escrituras / (`N` + 1) + 2 * escrituras = 1200`

`escrituras = 1200 / (2 + 9/(`N`+1))`

La última ecuación indica que el número máximo de escrituras para `N` esclavos, dado el ratio máximo de lecturas de 1,200 por minuto y un rato de nueve lecturas por escritura.

Este análisis lleva a las siguientes conclusiones:

- Si `N` = 0 (que significa que no tenemos replicación), nuestro sistema puede tratar unas 1200/11 = 109 escrituras por segundo.

- Si `N` = 1, tenemos 184 escrituras por segundo.

- Si `N` = 8,tenemos 400 escrituras por segundo.

- Si `N` = 17, tenemos 480 escrituras por segundo.

- Eventualmente, mientras `N` se aproxima al infinito ( y el presupuesto a infinito negativo ), podemos llegar carca de 600 escrituras por segundo, incrementando el rendimiento del sistema 5.5 veces. Sin embargo, con sólo ocho servidores, lo incrementamos cerca de cuatro veces.

Tenga en cuenta que estos cálculos asumen ancho de banda infinito y no tiene en cuenta muchos otros factores que pueden ser significativos en el sistema. En muchos casos, puede no ser capaz de realizar una computación similar al mostrado que prediga que ocurre en su sistema si añade `N` esclavos de replicación. Sin embargo, responder las siguientes cuestiones deben ayudarle a decidir si y cuánto la replicación mejorará el rendimiento de su sistema:

- ¿Cuál es el ratio de lectura/escritura en su sistema?

- ¿Cúanta carga de escritura puede tratar un servidor si reduce las lecturas?

- ¿Para cuántos esclavos tiene ancho de banda disponible?

P: ¿Cómo puedo usar replicación para proporcionar redundancia/alta disponibilidad?

R: Con las características actuales, puede preparar un maestro y un esclavo (o varios esclavos), y escribir un scrip que monitorice el maestro para ver si está en marcha. Luego enseñe a su aplicación y a los esclavos a cambiar el maestro en caso de fallo. Algunas sugerencias:

- Para decir al esclavo que cambie el maestro, use el comando `CHANGE MASTER TO` .

- Una buena forma de mantener a las aplicaciones informadas de la localización del maestro es con una entrada de DNS dinámica para el maestro. Con `bind` puede usar `nsupdate` para actualizar dinámicamente el DNS.

- Debe ejecutar los esclavos con la opción `--log-bin` y sin `--log-slave-updates`. De este modo, el esclavo está preparado para ser un maestro en cuanto ejecute `STOP SLAVE`; `RESET MASTER`, y `CHANGE MASTER TO` en los otros esclavos. Por ejemplo, asuma que tiene la siguiente configuración:

             WC
              \
               v
       WC----> M
             / | \
            /  |  \
           v   v   v
          S1   S2  S3

  M es el maestro, S los esclavos, WC los clientes realizando escrituras y lecturas; los clientes que ejecutan sólo lecturas de bases de datos no se representan , ya que no necesitan cambiar. S1, S2, y S3 son esclavos ejecutándose con `--log-bin` y sin `--log-slave-updates`. Como las actualizaciones recibidas por un esclavo del maestro no se loguean en el log binario a no ser que se especifique `--log-slave-updates`, el log binario en cada esclavo está vacío. Si por alguna razón M no está disponible puede hacer que uno de los esclavos sea el nuevo maestro. Por ejemplo, si elige S1, todos los WC deben redirigirse a S1, y S2 y S3 deben replicar de S1.

  Asegúrese que todos los esclavos han procesado cualquier comando en su log retardado. En cada esclavo, ejecute `STOP SLAVE IO_THREAD`, luego chequee la salida de `SHOW PROCESSLIST` hasta que vea `Has read all relay log`. Mientras que esto es cierto para todos los esclavos, pueden reconfigurarse para una nueva configuración. En el esclavo S1 se promociona a ser el maestro, ejecute `STOP SLAVE` y `RESET MASTER`.

  En los otros esclavos S2 y S3, use `STOP SLAVE` y `CHANGE MASTER TO MASTER_HOST='S1'` (donde `'S1'` representa el nombre de equipo de S1). Para `CHANGE MASTER`, añada toda la información acerca de cómo conectar a S1 desde S2 o S3 (`user`, `password`, `port`). En `CHANGE MASTER`, no es necesario especificar el nombre del log binario de S1 o la posición del log desde la que hay que leer: Sabemos que es el primer log binario y la posición 4, que son los defectos para `CHANGE MASTER`. Finalmente, use `START SLAVE` en S2 y S3.

  Luego enseñe a todos los WC a dirigir sus comandos a S1. Desde ese punto, todos los comandos de actualización enviados de WC a S1 se escriben en el log binario de S1, que contiene cada comando de actualización enviado S1 desde que M murió.

  El resultado es esta configuración:

             WC
            /
            |
       WC   |  M(unavailable)
        \   |
         \  |
          v v
           S1<--S2  S3
            ^       |
            +-------+

  Cuando M está activo otra vez, debe ejecutar en la misma máquina `CHANGE MASTER` como el ejecutado en S2 y S3, así que M llega a ser un esclavo de S1 y recoge todos las escrituras de WC que se ha perdido mientras no estaba activo. Para hacer que M sea un maestro de nuevo (debido a que es la máquina más rápida, por ejemplo), use el anterior protocolo como si S1 no estuviera disponible y M fuera a ser el nuevo maestro. Durante este procedimiento, no olvide ejecutar `RESET MASTER` en M antes de hacer S1, S2, y S3 esclavos de M. De otro modo, ellos podrían recober antiguas escrituras de WC desde el punto en que M dejó de estar disponible.

Estamos trabajando en integrar un sistema de elección de maestro automático en MySQL, pero hasta que esté preparado, debe crear sus propias herramientas de monitoreo.

## 6.10. Resolución de problemas de replicación

Si ha seguido las instrucciones, y su configuración de replicación no funciona, chequee lo siguiente:

- Chequee el log de errores en busca de mensajes. Muchos usuarios han perdido tiempo por no hacer esto lo primero tras encontrar problemas.

- ¿Está logueando el maestro en el log binario? Chequee con `SHOW MASTER STATUS`. Si lo está, `Position` no es cero. Si no, verifique que está ejecutando el maestro con las opciones `log-bin` y `server-id` .

- ¿Está corriendo el esclavo? Use `SHOW SLAVE STATUS` para chequear si los valores `Slave_IO_Running` y `Slave_SQL_Running` son `Yes`. Si no , verfique las opciones que se usaron para arrancar el esclavo.

- Si el esclavo está corriendo, ¿estableció una conexión con el maestro? Use `SHOW PROCESSLIST`, encuentre los flujos de entrada/salida y SQL y chequee su columna `State` para ver qué muestran .Consulte Sección 6.3, “Detalles de la implementación de la replicación”. Si el estado flujo de entrada/salida dice `Connecting to master`, verifique los permisos para los usuarios de replicación en el maestro, nombre de equeipo, la configuración del DNS, si el maestro está corriendo y si se puede acceder desde el esclavo.

- Si el esclavo estaba corriendo préviamente pero ha parado, la razón habitual es que algunos comandos que se han ejectuado en el maestro han fallado en el esclavo. Esto nunca debe ocurrir si ha tomado muestras de datos apropiadas del maestro, y no ha modificado los datos en el esclavo fuera del flujo del esclavo. Si lo ha hecho, es un bug o ha encontrado una de las limitaciones de replicación descritas en Sección 6.7, “Características de la replicación y problemas conocidos”. Si es un bug, consulte Sección 6.11, “Reportar bugs de replicación” para instrucciones de cómo reportarlo.

- Si un comando que ha tenido exito en el maestro no se ejecuta en el esclavo, y no es posible resincronizar la base de datos completa (esto es, borrar la base de datos del esclavo y copiar una nueva muestra del maestro), pruebe lo siguiente:

  1. Determine si la tabla del esclavo es distinta a la del maestro. Trate de entender cómo ha ocurrido. Luego haga que la tabla del esclavo sea idéntica a la del maestro y ejecute `START SLAVE`.

  2. Si el paso precedente no funciona o no se aplica, trate de entender si sería seguro hacer una actualización manual (si es necesario) y luego ignorar el siguiente comando del maestro.

  3. Si decide que puede evitar el siguiente comando del maestro, ejecute los siguientes comandos:

         mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
         mysql> START SLAVE;

     El valor de `n` debe ser 1 si el siguiente comando del maestro no usa `AUTO_INCREMENT` o `LAST_INSERT_ID()`. De otro modo, el valor debe ser 2. La razón para usar un valor de 2 para comandos que usen `AUTO_INCREMENT` or¡ `LAST_INSERT_ID()` es que toman dos eventos en el log binario del maestro.

  4. Si está seguro que el esclavo arrancó perfectamente sincronizado con el maestro, y que nadie ha actualizado las tablas involucradas fuera del flujo esclavo, entonces presumiblemente la discrepancia es producto de un bug. Si está ejecutando la versión más reciente, reporte el problema. Si está ejecutando una versión antigua de MySQL, trate de actualizar a la última versión.

## 6.11. Reportar bugs de replicación

Cuando determine que no hay un error de usuario involucrado, y la replicación todavía no funciona o es inestable, es el momento de enviarnos un reporte de bug. Necesitamos obtener toda la infomación posible que nos pueda proporcionar. Por favor dedique algo de tiempo y esfuerzo para preparar un buen reporte de bug.

Si tiene un caso de test repetible que demuestra el bug, por favor introdúzcalo en nuestra base de datos de bugs en http://bugs.mysql.com/. Si tiene un problema “fantasma” (uno que no pueda duplicar a voluntad), use el siguiente procedimiento:

1. Verifique que no hay ningún error de usuario involucrado. Por ejemplo, si actualiza el esclavo fuera de un flujo esclavo, los datos se desincronizan, y puede tener violaciones de claves únicas en las actualizaciones. En este caso, el flujo esclavo para y espera a que limpie las tablas manualmente para sincronizar. Este no es un problema de replicación. Es un problema de interferencias externas que provocan problemas de replicación.

2. Ejecute el esclavo con las opciones `--log-slave-updates` y `--log-bin` . Estas opciones provocan que el esclavo loguee las actualizaciones que recibe del maestro en sus propios logs binarios.

3. Guarde toda evidencia antes de resetear el estado de replicación. Si no tenemos información o sólo parcial, es difícil o imposible para nosotros encontrar el problema. la evidencia que debe recolectar es:

   - Todos los logs binarios del maestro

   - Todos los logs binarios del esclavo

   - La salida de `SHOW MASTER STATUS` del maestro cuando descubrió el problema

   - La salida de `SHOW SLAVE STATUS` del maestro cuando descubrió el problema

   - Logs de error del maestro y esclavo

4. Use mysqlbinlog para examinar los logs binarios. Lo siguiente debería ser útil para encontrar la consulta problemática, por ejemplo:

       shell> mysqlbinlog -j pos_from_slave_status \
                  /path/to/log_from_slave_status | head

Una vez que ha recolectado la evidencia del problema, trate de isolarlo como un caso de test separado. Luego introduzca el problema en nuestra base de datos de bugs en http://bugs.mysql.com/ que es tanta información como sea posible.

Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.

Anterior |  | Siguiente
Capítulo 5. Administración de bases de datos | Inicio | Capítulo 7. Optimización de MySQL