I have to use statement based replication for reasons that are immutable for the purposes of this question.
Eu assumo, para o propósito desta questão, que de fato podem existir razões convincentes para o uso de logging baseado em declarações¹, mas geralmente não é recomendado, porque o log baseado em instruções é relativamente frágil. Em qualquer sistema em que você tenha a flexibilidade não para usar o registro baseado em instruções, não o use - use MIXED
ou ROW
.²
O MySQL Server (e sistemas compatíveis, como Percona Server, MariaDB e Aurora for MySQL) automaticamente "traduzem" de um formato para outro, com base na configuração de cada servidor individual.
“Each MySQL Server can set its own and only its own binary logging format (true whether
binlog_format
is set with global or session scope). This means that changing the logging format on a replication master does not cause a slave to change its logging format to match.”— https://dev.mysql.com/doc/refman/5.6/en/binary-log-setting.html
Para reafirmar isso com algumas implicações adicionais, o que você quer fazer "simplesmente funciona", porque a configuração de binlog_format
no escravo não especifica o que o escravo espera. Ele só define o que o escravo irá gerar .
Configure o escravo com binlog_format=ROW
e ative log_slave_updates
em my.cnf
on o escravo (que faz com que os eventos recebidos sejam reescritos no log binário do escravo).
... e pronto.
O escravo registrará todos os seus DML como eventos baseados em linha, apesar do formato de log binário do mestre. Você realmente não precisa fazer mais nada para fazer um escravo também ser um mestre, já que todo servidor MySQL com o log binário ativado é, essencialmente, já um mestre - pode acontecer de ele ser um mestre sem escravos reais. / p>
Qualquer combinação de mestre e escravo binlog_format
é válida exceto para um mestre configurado como ROW
e um escravo configurado como STATEMENT
(o oposto do que você está fazendo aqui), porque enquanto as declarações podem ser traduzidas em eventos de linha (eles afetam as linhas no escravo, afinal de contas), o inverso não é verdadeiro - você não pode necessariamente determinar a declaração específica que mudou as linhas, se seu único conhecimento é o real alterado dados. Mas para o aplicativo que você está perguntando, o acima deve fazer exatamente o que você pretende.
Eu também discuti as interações das possíveis combinações de formato de registro de log mestre e escravo aqui, em dba.stackexchange.com em alguns detalhes adicionais.
¹ logging é usado aqui em vez de "replicação" porque é uma descrição mais precisa do que está sendo realmente configurado, embora sem dúvida o significado não seja alterado.
² STATEMENT
registra as consultas reais que fizeram a alteração; ROW
registra "imagens de linha" das linhas inseridas / atualizadas / excluídas pela consulta. Para atualizações, os valores antigos e novos são registrados. O modo MIXED
permite que o servidor escolha o formato para cada consulta, sempre usando ROW
quando há algo sobre a consulta que faz com que seu impacto no banco de dados seja potencialmente inseguro para replicação baseada em instrução, porque a réplica poderia interpretá-lo uma maneira que faria com que os dados da réplica divergissem do mestre, porque a consulta não é determinista. Os exemplos podem incluir um UPDATE ... LIMIT
não ordenado, em que a réplica pode atualizar um conjunto diferente de linhas, dependendo de sua seleção de índice, e instruções usando funções não determinísticas, como UUID()
. Outras funções aparentemente não determinísticas como NOW()
e RAND()
são compatíveis com replicação baseada em instrução, porque há dicas escritas no log da instrução para indicar a hora do sistema do mestre e a semente aleatória do mestre, no momento em que a consulta foi executado.