O que causa o erro do MySQL 1062 - entrada duplicada ao iniciar o slave?

11
  • Versão do MySQL Master: 5.5.16-1
  • Versão do MySQL Slave: 5.5.18-1

O instantâneo do mestre é criado por:

mysql> FLUSH TABLES WITH READ LOCK;
shell> mysqldump --all-databases --master-data > dbname_`date +%F`.sql

Este arquivo de despejo é importado no escravo (que é iniciado com a --skip-slave-startopção) sem erro:

shell> pv dbname_`date +%F`.sql | mysql -u root -p

Mas recebi o seguinte erro ao executar o mysql> start slave;:

    Last_SQL_Errno: 1062
    Last_SQL_Error: Error 'Duplicate entry '115846' for key
'PRIMARY'' on query. Default database: 'db'. Query: 'INSERT INTO
request_posted (id, user_id, channel, message, link, picture, name, ...

Existe apenas um registro com o ID 115846 no mestre:

mysql> select count(*) from request_posted where id=115846;
Current database: db

+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.01 sec)

Tente pular algumas consultas com:

mysql> STOP SLAVE; 
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; 
mysql> START SLAVE;

não ajudou. Não quero ignorar esses erros adicionando:

slave-skip-errors = 1062

de my.cnfarquivo porque ele pode trazer inconsistente escravo.

Qual pode ser o motivo desse erro?


ATUALIZAR

Não é assim que eu costumo configurar a replicação mySQL

Quais etapas você acha que não sigo o documento?

Gostaria de saber se você encontrará o mesmo problema se tiver que definir a configuração inteira em vez de passar o comando mysqldump.

Não, funciona normalmente se eu também mudar o mestre para as coordenadas correspondentes.

Eu tentaria soltar o banco de dados no escravo, garantir que os binlogs estejam limpos e começar novamente. Verifique também a tabela em questão no mestre para garantir que os índices não apresentem erros.

Excluir (mover) todo o datadir é suficiente? Eu fiz isso e obtive o mesmo resultado.


Responder para @Dmytro Leonenko

'show slave status \ G' no slave para garantir que ele esteja configurado corretamente, MASTER_LOG_POS é 0

Somente 'show slave statug \ G' após a importação, mas antes de 'start slave;' pode nos dar a resposta

Fiz backup do datadir, excluo tudo e execute mysql_install_db, importe o arquivo de despejo, execute change master toe eis os resultados:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: x.x.x.x
                  Master_User: xx
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: 
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysqld-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: 
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 0
              Relay_Log_Space: 106
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
1 row in set (0.00 sec)

Gostaria de saber por que Master_Log_Pos é 4?

quanta
fonte
1
Só pode haver um registro com esse ID; portanto, o erro nunca será gravado. Quando você emite SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1A consulta que está causando o erro muda no mínimo? A posição do binlog escravo foi configurada corretamente?
Thin11
Sempre que pulo o contador, ele muda para outro ID. A --master-dataopção já está gravando as coordenadas do log binário no arquivo de despejo. Eu só preciso alterar master para master_host, master_user, master_password.
quanta
Não é assim que geralmente configuro a replicação mySQL (geralmente configuro a replicação por URL aqui: dev.mysql.com/doc/refman/5.0/en/replication-howto.html ) No entanto, lendo as opções do mysqldump, não há motivo por que não deveria funcionar. Eu me pergunto se você encontrará o mesmo problema se tiver que definir a configuração inteira em vez de passar o comando mysqldump.
Rilindo
Você quer dizer que não devo usar a --master-dataopção ao criar um instantâneo de dados? Se isso ainda acontece quando eu uso a --lock-all-tablesopção e change master to master_log_file='', master_log_pos='', ..., quais podem ser as causas?
Quanta
Não, não é isso que estou dizendo. Como mencionei, o que você fez deve funcionar como pretendido - até onde posso ver, não existe nenhum bug com essa opção. No entanto, isso não significa que não exista; portanto, como uma etapa de isolamento, eu seguiria a convenção fornecida pelo mySQL primeiro através desse URL. t. Se isso funcionar, pelo menos você tem a orientação para iniciar a solução de problemas. Se isso não acontecer, bem, temos um problema diferente. :)
Rilindo

Respostas:

7

O que tentar resolver o seu problema:

  1. Você deve remover o master.info no slave primeiro e reiniciar o mysql
  2. emitir ALTERAR MASTER PARA MASTER_HOST = 'XX.XX.XX.XX', MASTER_USER = 'repl', MASTER_PASSWORD = 'slavepass';
  3. do mysqldump com a opção '--flush-logs' no master
  4. 'mysql -u user -p <dump.sql' no escravo
  5. 'show slave status \ G' no slave para garantir que ele esteja configurado corretamente, MASTER_LOG_POS é 0
  6. 'iniciar escravo;' escravo.

O que verificar também:

  • Formato de binlog: MIXED
  • server_ids são diferentes no master e slave
Dmytro Leonenko
fonte
A emissão de toda a cadeia mestre de alterações (incluindo o nome do log e o número da posição) realmente a corrige, mas, neste momento, acho que a questão principal é por que o Quanta deve inserir novamente o nome do log e o número da posição quando já está no diretório despejar arquivo.
Rilindo
Somente 'show slave statug \ G' após a importação, mas antes de 'start slave;' pode nos dar a resposta
Dmytro Leonenko
anexou as informações solicitadas na minha postagem original.
quanta
Como você terminou com "Master_Host: xxxx Master_User: xx" sem emitir "CHANGE MASTER ...". Ou você simplesmente não mencionou isso em resposta? Você verificou o formato do binlog e qual era a linha de comando do mysqldump?
Dmytro Leonenko 12/12
Eu já mencionei que no meu post " importe o arquivo de despejo, executechange master to ". Estou usando o log baseado em MIXED. Eu testei com o MySQL 5.0.77 (baseado em instruções), mas também causa esse erro. O mysqldump completo émysqldump -u root -p --all-databases --master-data --flush-logs > alldb_$(date +%F).sql
quanta
2

O problema é causado pela configuração do mestre em um servidor de produção em execução ANTES de fazer o dump (tanto quanto eu sei). Portanto, existem consultas escritas no master_log que já foram executadas nos dados que residem no escravo. Na verdade, nunca vi uma solução no site mysql ou na lista de discussão. Então, eu vim com a seguinte solução que resolveu meu problema.

no escravo:

mysql> STOP SLAVE;
mysql> FLUSH PRIVILEGES;  # dump likly included users too

no mestre:

mysql> RESET MASTER;

no escravo:

mysql> RESET SLAVE;
mysql> START SLAVE;

a propósito, eu executei meu despejo com o seguinte no escravo:

mysqldump -uROOTUSER -pROOTPASSWORD -hMYSQLMASTER.EXAMPLE.COM --all-databases --delete-master-logs | mysql -uROOTUSER -pROOTPASSWORD

Espero que isto ajude alguém.

http://dev.mysql.com/doc/refman/5.0/en/reset-master.html

http://dev.mysql.com/doc/refman/5.0/en/reset-slave.html

BroknDodge
fonte
editado para incluir privilégios de descarga; Após outro erro, percebi que, mesmo que meus usuários tivessem sido importados com o dump, seus privilégios ainda não estavam ativos.
precisa saber é o seguinte
O RESET MASTER deve ser executado no escravo, não no mestre, consulte percona.com/blog/2013/02/08/…
Jon
1

Se você não deseja que o REDO seja o procedimento completo, uma boa solução seria usar

STOP SLAVE;    
SET GLOBAL sql_slave_skip_counter=1;
START SLAVE;

Se houver muitos desses erros, uma boa idéia seria automatizá-lo usando um script bash.

Ref: Corrigindo erro de entrada duplicada

Ut xD
fonte
1

Eu tive o problema exato e o link do Ut xd ajudou. mas o comando nesse link teve erro de sintaxe e aqui está a versão que funcionou para mim:

while [ 1 ]; do if [ `mysql -uroot -ppassword -e"show slave status \G;" | grep "Duplicate entry" | wc -l` -eq 2 ] ; then mysql -uroot -ppassword -e"stop slave; set global sql_slave_skip_counter=1; start slave;"; fi; sleep 1; mysql -uroot -ppassword -e"show slave status\G"; done

Ele basicamente verifica se há um erro de entrada duplicada e pula esse evento do mestre. e faça isso em um loop.

perlwle
fonte
1
Essa seria uma resposta muito melhor se você explicasse o que esse código faz e formate o código para ser mais legível.
kasperd
0

No meu caso, o problema foi resolvido pelos seguintes comandos

pelas seguintes etapas

STOP SLAVE;
RESET SLAVE;
START SLAVE;
Karthik
fonte