¿Cuál es la forma más segura de cambiar el formato binlog en tiempo de ejecución?

25

Debido a la siguiente advertencia en mysqld.log:

[Advertencia] Declaración insegura escrita en el registro binario usando el formato de declaración desde BINLOG_FORMAT = STATEMENT. La declaración no es segura porque usa una cláusula LIMIT. Esto no es seguro porque el conjunto de filas incluidas no se puede predecir.

Quiero cambiar el formato de replicación a MIXED.

Pero de acuerdo con el documento MySQL:

No se recomienda cambiar el formato de replicación en tiempo de ejecución cuando existen tablas temporales, porque las tablas temporales se registran solo cuando se usa la replicación basada en instrucciones, mientras que con la replicación basada en filas no se registran.

Entonces, la pregunta es ¿cómo puedo identificar si existen tablas temporales para cambiar el formato de registro binario de manera segura?

quanta
fuente
1
Advertencia rápida Tenga cuidado con esto cuando vaya de RBR-> SBR y use read-commit: bugs.mysql.com/bug.php?id=62493
Morgan Tocker

Respuestas:

35

Dado que un binlog tendrá un formato específico en el momento en que lo haga, puede decidir no jugar con los dos formatos juntos, aunque MySQL (eh Oracle [todavía no puede salir de mi lengua]) construyó esta característica.

Para jugar de forma totalmente segura sin reiniciar mysql, intente lo siguiente:

FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
SET GLOBAL binlog_format = 'MIXED';
FLUSH LOGS;
UNLOCK TABLES;

Esto dejará el último binlog en el formato 'MIXTO'. El binlog penultimiate (penúltimo) existe simplemente cierra el último binlog que estaba en el formato anterior.

Todas las sesiones existentes antes de la primera FLUSH LOGS;comenzarán a escribirse en el último binlog una vez que UNLOCK TABLES;se ejecute.

Darle una oportunidad !!!

ADVERTENCIA

Dando crédito donde se debe, mi respuesta es realmente aprovecharse de la respuesta de @ Jonathan . Simplemente cierro y abro binlogs encima de eso. Obtiene un +1 por sacar esto primero.

ACTUALIZACIÓN 2011-10-12 13:58 EDT

Si le hace esto a un maestro activo y hay uno o más esclavos que se replican desde ese maestro, también debe preocuparse de que los registros de retransmisión estén en el nuevo formato. Esto es lo que puedes hacer:

En el esclavo, corre STOP SLAVE;

En el Master ejecuta estos:

FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
SET GLOBAL binlog_format = 'MIXED';
FLUSH LOGS;
UNLOCK TABLES;

En el esclavo, corre START SLAVE;

Al ejecutar STOP SLAVE;y START SLAVE;rotar los registros de retransmisión, las nuevas entradas se replican en cualquier formato. Es posible que también desee aplicar el cambio binlog_format en el esclavo.

RolandoMySQLDBA
fuente
3
Una cosa a tener en cuenta es que la configuración de replicación de mysql en realidad se establece por sesión de cliente. Establecer el binlog_format global simplemente cambia el valor para NUEVAS sesiones. Por lo tanto, si lo está ejecutando en un sistema con clientes conectados permanentemente, los cambios que realice en la configuración no serán aplicables de inmediato, incluso si realiza el enjuague y el bloqueo como se especifica aquí; no tendrán efecto hasta que los clientes volver a conectar (o establecer el valor en su propia sesión, pero en mi experiencia, lo primero es más probable).
Austin Mills
Para aquellos curiosos, también puede poner este "binlog_format = 'MIXED';" en tu my.cnf.
Christian
2
FYI, esta respuesta no está de acuerdo con una respuesta aquí: dba.stackexchange.com/questions/58539/…
HTTP500
El manual dice : Esto significa que cambiar el formato de registro en un maestro de replicación no hace que un esclavo cambie su formato de registro para que coincida. (..snip ..) Cambiar el formato de registro binario en el maestro mientras la replicación está en curso, o sin cambiarlo también en el esclavo, puede causar resultados inesperados o incluso fallar por completo la replicación.
Halfgaar
@Halfgaar La semana pasada, cambié un esclavo de MIXED a STATEMENT tres veces sin efectos negativos. Estaba haciendo eso porque la replicación se estaba rompiendo debido a una condición de carrera. La tabla se volvió inexistente en un esclavo antes de la ejecución de la consulta. Entonces, cambié a DECLARACIÓN a estable como esa situación. Por supuesto, todas las escrituras se detuvieron mientras hacía esto. Por cierto, también hice al maestro.
RolandoMySQLDBA
6

Para cambiar binlog_format en tiempo de ejecución puede hacer:

set global binlog_format = 'MIXED';

Esto configurará todas las NUEVAS sesiones en un formato binlog mixto. Todas las sesiones existentes serán las que se hayan configurado previamente hasta que finalicen.

También puede hacerlo set session binlog_format = 'MIXED';manualmente para resolver cualquier problema con la sesión específicamente.

Jonathan
fuente
No pregunto el camino, pregunto el camino más seguro y cómo puedo verificar si existen tablas temporales.
quanta
3
Establecer la variable global primero y esperar a que finalicen las sesiones restantes es la forma más segura.
Jonathan