Temos algumas tabelas enormes em nosso banco de dados MySQL 5.6 que têm latin-1 como conjunto de caracteres e queremos convertê-las todas para UTF-8 (junto com a conversão do conjunto de caracteres global do banco de dados). As ALTER TABLE
declarações necessárias levam, entre elas, cerca de uma hora para serem executadas. Gostaríamos de minimizar nosso tempo de inatividade.
Nosso plano é configurar a replicação, fazer as alterações de codificação no banco de dados escravo, permitir que os bancos de dados sejam sincronizados e, em seguida, desativar brevemente nosso servidor da web e apontá-lo para o banco de dados escravo.
Isso funcionará ou há risco de causar corrupção de dados no escravo?
Minha preocupação sobre isso decorre de haver duas abordagens possíveis óbvias de como os valores de string (que estão sendo INSERT
ed ou UPDATE
ed) podem ser armazenados no binlog do MySQL e enviados para o escravo. Qualquer...
Os valores são armazenados como sequências de caracteres unicode (ou seja, o log binário sabe em qual codificação eles estão codificados e envia essas informações ao escravo para que ele possa converter os valores para corresponder ao conjunto de caracteres da coluna de destino no escravo).
ou...
- Os valores codificados são armazenados apenas como sequências de bytes, sem registro de qual era o conjunto de caracteres.
A documentação não esclarece qual dos modelos acima o MySQL usa.
Se o nº 1 for verdadeiro, nosso plano funcionará bem.
No entanto, se o nº 2 for verdadeiro, tentar replicar consultas do mestre para o escravo dará errado de alguma forma se uma das colunas envolvidas tiver um conjunto de caracteres diferente. Por exemplo, uma vez que convertemos nossas tabelas de latin-1 para UTF-8 no slave, o slave pode tentar armazenar strings codificadas em latin-1 transmitidas pelo master em uma coluna codificada em UTF-8, resultando em o texto armazenado não está sendo codificado de forma válida em UTF-8 ou representa os caracteres errados.
Os documentos do MySQL sobre replicação e conjuntos de caracteres lançam pouca luz sobre o problema; eles discutem possíveis problemas resultantes de diferenças no conjunto de caracteres globais de cada servidor, mas não abordam problemas potenciais causados por diferenças em conjuntos de caracteres de tabela ou coluna.
Nosso plano é sólido ou corremos o risco de acabar com dados corrompidos no escravo?
https://dev.mysql.com/doc/refman/5.7/en/replication-features-differing-tables.html descreve as variações suportadas nas definições de tabela.
Por um lado, parece que isso é compatível com a replicação baseada em instrução :
Com a replicação baseada em linha, apenas certas conversões de tipo são suportadas, que são afetadas pela
slave_type_conversions
variável. As principais citações de acordo com a minha leitura são:No entanto: