erro do mysql 1062 'entrada duplicada' ao restaurar o backup

4

Desculpe, vi tópicos semelhantes, mas ainda não consegui encontrá-lo abordando meu problema. Além disso, precisei de mais algumas informações sobre isso.

Requisito: Para criar uma réplica exata 'db4' de um DB 'db3' existente.

Procedimento seguido:

  • mysqldump -uuser -ppass db3 > db3.sql (tamanho é 6G)
  • mysql -uuser -ppass db4 < db3.sql (db4 era um banco de dados em branco recém-criado)

O segundo passo gera o erro:

ERROR 1062 (23000) at line 5524: Duplicate entry '600806' for key 1"

Corri o segundo passo novamente com --force. A restauração foi concluída, mas com dois erros semelhantes adicionais:

ERROR 1062 (23000) at line 6309: Duplicate entry '187694' for key 1    
ERROR 1062 (23000) at line 6572: Duplicate entry '1567400' for key 1

Na conclusão, quando consultei algumas tabelas do banco de dados db4, consegui ver os registros ausentes.

Pergunta:

  1. Isso indica um banco de dados db3 corrompido / problemático?

  2. Como proceder para criar uma réplica 'consistente / funcional' (db4) do db3?

Obrigado,

    
por user492160 03.01.2013 / 18:05

3 respostas

2

Existem várias razões pelas quais tais "duplicatas" podem ocorrer:

  • seus dados são torrados.
  • um aplicativo INSERIDO usando o incremento automático, mas depois executou um UPDATE para Modifique manualmente a identidade para um valor diferente, provavelmente existente. este às vezes ocorre com desenvolvedores de aplicativos que estão classificando "por ID" e querem para "corrigir a classificação" (quebrando a consistência).
  • uma variação da segunda edição acontece por pessoas que mais tarde adicionam uma restrição "única", depois que registros não exclusivos foram inseridos.

As mensagens de erro referem-se à primeira chave, que na maioria dos esquemas do banco de dados é o primeiro valor. Dê uma olhada na saída de despejo bruto, particularmente as instruções INSERT e verifique por

INSERT INTO ... values (0,...

Analise os números de linha do mysql dump dados nas mensagens de erro.

Exemplo de qual tipo de mysqldump estou esperando:

INSERT INTO foo (id,bar,baz) values (1,2,3);
INSERT INTO foo (id,bar,baz) values (0,4,5);
INSERT INTO foo (id,bar,baz) values (2,6,7);

Em uma instrução INSERT "normal" em um campo de incremento automático, o valor "0" especifica o incremento automático do campo e, portanto, não deve ser exibido em um dump SQL do banco de dados em que um campo de incremento automático está sendo usava. Ao recarregar o banco de dados por meio de um dump SQL, seu dump solicita que o servidor SQL incremente o valor do campo atual em um e insira esse ID. Se alguém tiver atualizado manualmente a identidade para zero depois de INSERIR o registro, seu MySQL Dump também incluirá esse id estranho.

Se você estiver repetindo esse despejo em uma tabela vazia, isso tentará criar os seguintes registros:

1,2,3
2,4,5
2,6,7

Como o campo "id" foi definido como incremento automático exclusivo, o segundo INSERT criará um registro "errado" (esperado: 0,4,5; real: 2,4,5) que entra em conflito com o registro a seguir ( id = 2) e como resultado dá a mensagem de erro.

Em uma variação disso, alguém "manualmente" atualizou a identidade para um valor já existente e depois alterou o registro para "exclusivo". Alterar um tipo de registro para exclusivo não faz a nova validação do MySQL se os dados atuais corresponderem ao requisito, portanto, o erro atrasado. Essa variação pode criar um dump assim:

INSERT INTO foo (id,bar,baz) values (1,2,3);
INSERT INTO foo (id,bar,baz) values (1,4,5);
INSERT INTO foo (id,bar,baz) values (2,6,7);

Tentar inserir a segunda linha falhará devido à restrição exclusiva.

Em ambos os casos, usar "--force" apenas ignora a linha "conflitante" e continua a importação. As linhas "conflitantes" estarão faltando, mas provavelmente as linhas que levam a este conflito estarão lá (mas com um registro de id errado).

Por favor, verifique o seu despejo de banco de dados se a minha ideia corresponder ao seu problema. Se for esse o caso, aqui estão duas soluções alternativas para "fazer funcionar":

  • importe dados em duas etapas, primeiro apenas o esquema, depois os dados. Remova as restrições exclusivas do seu esquema antes de importar os dados, mais tarde, adicione as restrições exclusivas ("ALTER TABLE ... add unique ...").

  • force-import schema e todos os dados, resultando em problemas de restrição "diferentes". Verificar manualmente quais registros estão corretos e reatribuir os errados para seu valor original.

Exemplo para o último problema:

mysql -uuser -ppass --execute "SET UNIQUE_CHECKS=0; source db3.sql" db4

Isso força a importação de todos os registros conflitantes, violando até mesmo restrições reais. Após a importação, você terá várias entradas para esses três registros (600806, 187694 e 1567400), e você terá que classificar manualmente quais são os corretos, verificando o seu despejo, quais dessas "duplicatas" resultaram na Conflito e atualizar manualmente os registros errados "back" para zero (ou qualquer que seja a linha conflitante no despejo disse).

Nos dois cenários, seus dados ainda violam o esquema fornecido: seu esquema diz que os dados são exclusivos, mas não são. No longo prazo, os dados precisam ser corrigidos no nível do aplicativo.

    
por 22.07.2013 / 18:25
1

Primeiro, verifique se as linhas em questão existem nesse estado no banco de dados original.

Provavelmente, o que aconteceu é um dos seguintes:

  • A coluna / campo em questão não era único em determinado momento, mas foi alterado mais tarde.
  • Este é um banco de dados escravo que você está descarregando, e houve alguns replays do log binário em algum momento, e possíveis chaves duplicadas foram inseridas
  • Uma declaração incorreta de SQL ou a importação de comandos resultaram em entradas duplicadas.

Se houver apenas 3 linhas mostrando o problema, corrija o campo-chave para elas, se possível, execute um dump e importe-a e veja se o erro não se apresenta novamente. Eu acho que deveria ir embora.

    
por 09.04.2013 / 23:21
1

Prefácio

Então me deparei com esse problema depois que um de nossos servidores de replicação entrou em um estado inconsistente. Não foi possível recuperá-lo on-line com uma correção rápida e decidimos reinicializar a replicação com um novo backup.

A pergunta acima não é o mesmo problema, mas retorna o mesmo erro, portanto, decidi adicionar essa resposta caso outras pessoas a estejam procurando.

É também uma cópia exata desta questão em DBA Stack Exchange mas porque esta questão tem uma classificação mais alta em (meu ) Resultados do Google Eu também estou postando aqui.

O que fizemos

Nós deletamos todas as nossas bases de dados na instância com o MySQL Workbench, eu reiniciei a instância e verifiquei duas vezes que não havia bancos de dados na instância. No servidor mestre, já começamos a criar um novo backup com o script que sempre usamos.

Depois que o backup estava no servidor com falha, iniciamos a importação e, depois de algumas horas, ele importou a maioria dos dados e falhou com esses tipos de erros:

ERROR 1062 (23000) at line XXX: Duplicate entry 'dbName-tblName' for key 'PRIMARY'
Operation failed with exitcode 1

Nós pensamos que sim, talvez algo deu errado ao criar o backup, eu verifiquei os dados no backup, mas não consegui encontrar nada de errado. Nós repetimos todos os passos novamente para ter certeza de que não perdemos nada, mas infelizmente não havia nenhum charuto ..

O problema real

O erro exibido não é a inserção real dos dados, mas a criação de um índice. É por isso que os dados foram inseridos sem problemas (verificamos), mas ainda geraram um erro. Aparentemente a exclusão de todas as tabelas não é suficiente, os dados de índice ainda existem no servidor (isso pode ser devido a uma mudança no MySQL 5.6, pois nunca tivemos esse problema antes). E como a importação desse índice está em algum lugar no meio do arquivo de importação, o restante dos dados não foi importado.

A correção

Nós excluímos o arquivo ibdata1 e todos os arquivos innodb_index_stats e innodb_table_stats na pasta do banco de dados mysql e, em seguida, iniciamos a instância. O MySQL então lhe dirá que algumas tabelas do sistema estão faltando você pode encontrar mais informações sobre isso aqui

Isso resolveu nosso problema e nosso servidor agora está replicando como esperado.

Espero que isso economize algumas horas para alguém em algum lugar :)

    
por 23.09.2015 / 13:29