Eu estava no caminho certo aqui com as grandes transações de consultas de ontem.
Depois de migrar os dados, executei uma instrução DELETE na tabela original para me livrar das linhas que eu havia migrado.
Essas tabelas são repletas de dados de rastreamento e, portanto, não possuem chaves primárias ou exclusivas.
Devido a como funciona a replicação baseada em ROW, o escravo, em vez de executar a instrução DELETE idêntica que foi executada no master, executa uma instrução DELETE para cada linha, que acaba parecendo assim:
DELETE FROM table WHERE colA=foo AND colB=bar AND colC=baz....etc
E, como não há um índice que corresponda a essa consulta, o encadeamento SQL de replicação encadeada única executou 40 milhões + instruções de exclusão (ou ... estava tentando), o que levou muito tempo para ser executado devido a toda a varredura tinha que ser feito para identificar cada linha (a tabela tinha cerca de 80 milhões de linhas de tamanho na época).
No final, lidei com isso interrompendo o encadeamento escravo ( STOP SLAVE
) ignorando uma única transação escrava ( SET GLOBAL sql_slave_skip_counter = 1;
) e reiniciando o encadeamento secundário ( START SLAVE
).
Isso resultou em meu Master e Slave estarem fora de sincronia na tabela em questão aqui - mas consegui aproveitar a natureza da replicação baseada em linha para trazê-la de volta em sincronia, executando o seguinte no Master:
mysql> CREATE TABLE table_tmp; -- with the same schema as 'table' (SHOW CREATE TABLE table;)
mysql> RENAME TABLE table TO table_bak, table_tmp TO table;
mysql> INSERT INTO table ( SELECT * FROM table_bak );
mysql> DROP TABLE table_bak;
Como o DELETE foi executado no Master, o INSERT aqui só inseriu os registros que eu queria manter (os excluídos foram eliminados). E, como a replicação baseada em linha insere cada linha individualmente, em vez de executar a mesma instrução INSERT INTO ... SELECT, a tabela Slave foi preenchida apenas com os dados desejados. Em seguida, a instrução DROP TABLE subseqüente elimina a tabela no escravo sem precisar endereçar cada linha individualmente.
A ressalva aqui é que, porque a versão Master da tabela ainda estava entre 30 e 40 milhões de linhas ... o INSERT e a replicação consequente acabam bloqueando seu escravo por um tempo (duplicando o problema acima), mas é um muito mais curto (acabou sendo cerca de 20 minutos) devido ao mysql não ter que varrer o banco de dados para as linhas a serem deletadas.
Espero que isso possa ajudar alguém no futuro. Desculpem-se, espero que tenha sido informativo e útil.