Replicação do MySQL: 'Entrada duplicada para chave PRIMARY'


9

Você poderia me ajudar a entender por que estou recebendo 'Entrada duplicada para chave PRIMARY' em um servidor escravo após uma ressincronização completa.

Basicamente, o 'mysqldump' estava rodando quase a noite toda e, em seguida, o processo de restauração levou algumas horas; então, quando iniciei o escravo, estava ~ 63874 segundos atrás do master.

O servidor escravo é somente leitura (somente leitura) e não houve gravações durante o processo de ressincronização, portanto não entendo por que existem chaves duplicadas.

O formato do log binário é definido como MIXED no master.

Comando usado para fazer backup do banco de dados:

mysqldump --opt --single-transaction -Q --master-data=2 db | bzip2 -cz > db.sql.bz2

O escravo está replicando apenas um banco de dados do mestre (db -> db_backup) com as seguintes opções:

replicate-wild-do-table = db_backup.%
replicate-rewrite-db = db->db_backup

Respostas:


11

ASPECTO Nº 1: Replicação

Eu não acho isso

replicate-wild-do-table = db_backup.%
replicate-rewrite-db = db->db_backup

pertencem um ao outro.

Outras pessoas se perguntaram sobre isso também

O problema decorre das regras de replicação de pedidos que são processadas. De acordo com a documentação do MySQL sobre regras de replicação :

Se alguma opção --replicate-rewrite-db for especificada, elas serão aplicadas antes que as regras de filtragem --replicate- * sejam testadas.

Até a documentação do MySQL em replicate-rewrite-db diz:

A tradução do nome do banco de dados é feita antes das regras --replicate- * serem testadas.

O replicate-wild-do-tableé aplicado após a reescrita. Não seria surpreendente se essa ordem de alguma forma impusesse um INSERT em uma tabela que já possui dados.

Você provavelmente está perguntando como os dados chegaram lá?

ASPECTO # 2: mysqldump

Fazer mysqldump --single-transactionparece ser a melhor maneira de apontar despejos de dados no tempo. Infelizmente, mysqldump --single-transactiontem um calcanhar de Aquiles: ALTER TABLE. Se uma tabela estiver sujeita a qualquer ALTER TABLEcomando, como a DROP TABLEe CREATE TABLE, que possa quebrar a integridade da transação, o mysqldump estava tentando executar o despejo. também ser tão perturbador.

Você pode encontrar mais informações sobre isso no MySQLDump Secret mais bem guardado do MySQL Performance Blog . Na verdade, eu abordei esse ponto em uma pergunta anterior descrevendo 12 comandos que podem quebrar a integridade da transação de um mysqldump: Backup do MySQL InnoDB

EMBARGO

EPÍLOGO

Um ou ambos os aspectos podem ter contribuído para permitir a entrada de uma linha durante o mysqldump que não deveria existir devido às regras de reescrita ou ao isolamento do mysqldump sendo substituído.

SUGESTÕES

Eu faria um despejo mysqlbinlog de todos os logs de retransmissão desde o início do mysqldump para ver todos os INSERTs que o escravo processará e ver se essas linhas já existem no escravo. Se o fizerem, você provavelmente poderia fazer duas coisas:

1: ignore todos os erros de chave duplicada

Basta adicionar isso ao my.cnf no Slave

[mysqld]
slave-skip-errors=1062
skip-slave-start

e reinicie o mysql. Então corraSTART SLAVE;

todos os erros de chave duplicada serão ignorados. Quando Seconds_Behind_Masterchegar a 0, remova essas linhas e reinicie o mysql.

2: Faça o download das ferramentas percona

As ferramentas que você precisa são

Use-os para encontrar as diferenças no Escravo e corrija-as


0

Verifique a consulta de inserção no código que insere diretamente no escravo. Só podemos ler de escravos. As consultas de gravação devem ser direcionadas ao mestre.


Olhe para a pergunta. O escravo é somente leitura e não há gravações durante a ressincronização.
RolandoMySQLDBA
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.