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 caracteres 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 caracteres:
Debe siempre usar las
mismas colaciones y conjuntos de caracteres
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 caracteres del
maestro puede no ser único en el conjunto de caracteres
del esclavo.
Si el maestro es anterior a MySQL 4.1.3, el conjunto de
caracteres 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 caracteres 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
caracteres (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
caracteres idénticos.
Si tiene bases de datos en el maestro con distintos
conjuntos de caracteres al valor global de
collation_server
, debe diseñar su
comando CREATE TABLE
que no se base
en el conjunto de caracteres por defecto de la base de
datos, ya que actualmente hay un bug (Bug#2326); una
solución es poner el conjunto de caracteres 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=
del script timezone_name
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
@
) 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.
var_name
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:
Ejecute un comando STOP SLAVE
.
Use SHOW STATUS
para chequear el valor
de la variable Slave_open_temp_tables
.
Si el valor es 0, ejecute un comando mysqladmin shutdown para parar el esclavo.
Si el valor no es 0, reinicie los flujos esclavos con
START SLAVE
.
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.
É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.