[firebase-br] Chave Primária Duplicada

Carlos H. Cantu listas em warmboot.com.br
Segunda Setembro 12 16:37:07 -03 2022


O trigger em questão iria falhar se o índice estivesse corrompido, pois o exists 
não encontraria o registro mesmo ele existindo.

[]s
Carlos H. Cantu
eBook Guia de Migração para o FB 4 - www.firebase.com.br/guiafb4.php
www.FireBase.com.br - www.firebirdnews.org - blog.firebase.com.br

JSvl> Boa Tarde,

JSvl> Já tivemos esse mesmo problema (registro duplicado com a mesma pk). 

JSvl> O problema nunca mais ocorreu quando migramos para Firebird 2.5.9 (ou 3.0),
JSvl> pois esse problema identificamos em servidores que utilizavam Firebird 2.5.5
JSvl> e 2.5.7.

JSvl> Antes da migração, chegamos a colocar trigger BEFORE INSERT na tabela em
JSvl> questão, com a condição semelhante a essa:

JSvl> if exists (select 1 from tabela where PK = new.PK) then 
JSvl>         Begin
JSvl>          -- aqui vc pode tratar, buscando um novo valor para a PK ou dar um
JSvl> exception para o usuário te chamar, e poder melhor analisar o ambiente no
JSvl> momento em que o erro se manifesta
JSvl>         end



JSvl> -----Mensagem original-----
JSvl> De: lista <lista-bounces em firebase.com.br> Em nome de
JSvl> lista-request em firebase.com.br
JSvl> Enviada em: segunda-feira, 12 de setembro de 2022 12:00
JSvl> Para: lista em firebase.com.br
JSvl> Assunto: Digest lista, volume 5052, assunto 1

JSvl> Enviar submissões para a lista de discussão lista para 
JSvl>         lista em firebase.com.br

JSvl> Para se cadastrar ou descadastrar via WWW, visite o endereço
JSvl>         http://firebase.com.br/mailman/listinfo/lista_firebase.com.br
JSvl> ou, via email, envie uma mensagem com a palavra 'help' no assunto ou corpo
JSvl> da mensagem para 
JSvl>         lista-request em firebase.com.br

JSvl> Você poderá entrar em contato com a pessoa que gerencia a lista pelo
JSvl> endereço
JSvl>         lista-owner em firebase.com.br

JSvl> Quando responder, por favor edite sua linha Assunto assim ela será mais
JSvl> específica que "Re: Contents of lista digest..."


JSvl> Resumos das últimas mensagens enviadas para a lista da FireBase.


JSvl> Tópicos de Hoje:

JSvl>    1. Chave Primária Duplicada (Valdir Dill)
JSvl>    2. Re: Chave Primária Duplicada (Mário Reis)
JSvl>    3. Re: Chave Primária Duplicada (Carlos H. Cantu)


JSvl> ----------------------------------------------------------------------

JSvl> Message: 1
JSvl> Date: Mon, 12 Sep 2022 06:58:42 -0300
JSvl> From: Valdir Dill <valdiralbertod em gmail.com>
JSvl> To: Lista Firebase <lista em firebase.com.br>
JSvl> Subject: [firebase-br] Chave Primária Duplicada
JSvl> Message-ID: <ee66de86-6346-3091-bafb-fbb42ec75c5a em gmail.com>
JSvl> Content-Type: text/plain; charset=UTF-8; format=flowed

JSvl> Boa tarde,

JSvl> Temos uma tabela (VENDAS). Ocorre também em outras tabelas, mas, aqui vamos
JSvl> nos ater apenas à VENDAS.
JSvl> Entre outros campos, a VENdAS tem o NUMERO e FILIAL. Estes 2 compõem o
JSvl> índice primário.

JSvl> Se tentarmos gravar a venda 100, com FILIAL 1, uma segunda vez, obviamente
JSvl> que o Firebird vai "berrar", porque se está tentando duplicar o índice
JSvl> primário.
JSvl> É claro que antes do Firebird gerar erro, é aplicação que deve controlar
JSvl> isso e não permitir que chegue a esse ponto. Mas...

JSvl> O problema que ocorre, muito eventualmente, mas ocorreu já mais de uma vez
JSvl> com usuários nossos é: o banco de dados está lá, tudo certo, com a venda 100
JSvl> registrada apenas 1 vez, o índice primário ativo, tudo certo.
JSvl> Aí faz-se um backup e o restore com gbak.exe. Nesse restore vem duas vendas
JSvl> 100, com filial 1 registradas, o que obviamente vai dar conflito no banco
JSvl> pelo fato do índice primário estar duplicado.
JSvl> Ao mesmo tempo, o índice primário é desativado automaticamente. Acredito que
JSvl> o Firebird faça isso (desativar o índice), justamente para poder restaurar
JSvl> esse segundo registro da venda 100.
JSvl> Obs.: não é a mesma venda 100, pois outros campos não têm o mesmo valor. 
JSvl> São duas vendas 100 diferentes.

JSvl> A única coisa que posso imaginar é que por algum erro, em algum momento, o
JSvl> sistema tentou registrar duas vezes com o mesmo número (100 e FILIAL
JSvl> 1) e o Firebird não permitiu. Entretanto esses dados não gravados  (da
JSvl> segunda venda) ficaram em "um limbo" e, ao fazer o restore, eles foram
JSvl> ressuscitados.
JSvl> Tentamos de todas formas reproduzir o problema em labortório, mas não
JSvl> ocorre. Sempre que se tenta gravar uma segunda vez registro com os mesmos
JSvl> dados nos campos índice, o Firebird impede e descarta tudo (corretamente).
JSvl> Quado o usuário nos envia o banco, o problema já está instalado.

JSvl> Alguém poderia me dar uma luz sobre isso. Pode ser de fato isso que esteja
JSvl> ocorrendo? Como é que o Firebird permitiu um segundo registro com a mesma
JSvl> chave primária? E como não permitir que o Firebird gere essa situação?

JSvl> Usamos Firebird 2.5

JSvl> Qualquer sugestão é bem vinda!

JSvl> Obrigado!


JSvl> ------------------------------------------------------------------------
JSvl> /Cordialmente
JSvl> Valdir Dill
JSvl> /


JSvl> ------------------------------

JSvl> Message: 2
JSvl> Date: Mon, 12 Sep 2022 11:01:26 +0000
JSvl> From: Mário Reis <mariodosreyx em gmail.com>
JSvl> To: FireBase <lista em firebase.com.br>
JSvl> Cc: Valdir Dill <valdiralbertod em gmail.com>
JSvl> Subject: Re: [firebase-br] Chave Primária Duplicada
JSvl> Message-ID:
JSvl>         <CAF_dzr=Yhvnaz8XRfb6y9YUEPMaq+bNrLmOvrJENETucEd4MCg em mail.gmail.com>
JSvl> Content-Type: text/plain; charset="UTF-8"

JSvl> Bom dia,
JSvl> Não sei se percebi bem! Está a dizer que FB2.5, no "Restore" lhe traz mais
JSvl> um registo venda 100 + Filial 10!
JSvl> Ou seja,  "Restore" a duplicar o registo! É isso que nos está a dizer?
JSvl> Desculpará, mas isso cheira a "martelada da grossa" e não acredito que
JSvl> consiga nunca mais reconstruir a PK sem eliminar essa redundância, primeiro,
JSvl> ou então, é um problema de corrupção da base só por aí compreendo uma tal
JSvl> situação! Também acontece, ou ainda, tem que rever o parâmetros do
JSvl> backup/restore(Obs.: não é a mesma venda 100, pois outros campos não têm o
JSvl> mesmo valor. São duas vendas 100 diferentes)!?.
JSvl> Bem, há bastante  tempo que deixamos de ter Primary Key compostas e que não
JSvl> sejam sequenciais únicos e absolutos, que nas "dependências, amarram toda a
JSvl> aplicação" todos as outras chaves como o seu "Venda+Filial" são Unique Keys
JSvl> e em regra não servem para mais do que isso. Depois nos acessos com essas
JSvl> chaves, quando necessário, usamos views sobre esses campos. Nos inputs de
JSvl> pesquisa podem até ser pedidos "N.Venda + N.º da Filial", mas lá por de
JSvl> trás, posiciona no registo lê a PK toda e qualquer relação dai em diante se
JSvl> processa via PK!
JSvl> Quanto ao controle, é feito pelo próprio FB, sim, qual a admiração. Todo o
JSvl> resto é degradação de tempo em acessos Fazer à lá "Clipper/Fox" com DBFs "if
JSvl> found then trava com erro Else deixa criar" caiu.
JSvl> Acabou na mesma hora em que a opção/decisão foi pelo RDBMS com "Integridade
JSvl> Referencial" primeiro pelo PG depois pelo Firebird por ser muito mais leve
JSvl> ainda que, à data, com bastante menos potencialidades!
JSvl> E, bendita hora; mudar tudo custou um pouco, mas nem que nos pagassem para
JSvl> voltar para trás! Está fora de questão!
JSvl> Na hora o compromisso foi FB1.5, creio (hoje FB3), mas também mudamos o
JSvl> paradigma de programação.
JSvl> É o "data engine" quem trava a repetição de uma chave e quando ele retorna
JSvl> em erro, interceptamos e  tratamos o erro.
JSvl> E,  é assim há quase 20 anos sem problemas uma falha de energia com uma UPS
JSvl> problemática, mas reposumemos o backup , limpinho e tudo voltou ao normal.
JSvl> Com os meus melhores cumprimentos
JSvl> Mário Agostinho Reis
JSvl> 919262146

JSvl> Esta mensagem contém informação de natureza confidencial e é exclusivamente
JSvl> dirigida ao(s) destinatário(s) indicado(s). Se, por engano, receber este
JSvl> email agradecemos que não o copie nem o reenvie e que nos notifique do
JSvl> ocorrido através do email de resposta.


JSvl> Valdir Dill via lista <lista em firebase.com.br> escreveu no dia segunda,
JSvl> 12/09/2022 à(s) 09:59:

>> Boa tarde,
>>
>> Temos uma tabela (VENDAS). Ocorre também em outras tabelas, mas, aqui 
>> vamos nos ater apenas à VENDAS.
>> Entre outros campos, a VENdAS tem o NUMERO e FILIAL. Estes 2 compõem o 
>> índice primário.
>>
>> Se tentarmos gravar a venda 100, com FILIAL 1, uma segunda vez, 
>> obviamente que o Firebird vai "berrar", porque se está tentando 
>> duplicar o índice primário.
>> É claro que antes do Firebird gerar erro, é aplicação que deve 
>> controlar isso e não permitir que chegue a esse ponto. Mas...
>>
>> O problema que ocorre, muito eventualmente, mas ocorreu já mais de uma 
>> vez com usuários nossos é: o banco de dados está lá, tudo certo, com a 
>> venda 100 registrada apenas 1 vez, o índice primário ativo, tudo certo.
>> Aí faz-se um backup e o restore com gbak.exe. Nesse restore vem duas 
>> vendas 100, com filial 1 registradas, o que obviamente vai dar 
>> conflito no banco pelo fato do índice primário estar duplicado.
>> Ao mesmo tempo, o índice primário é desativado automaticamente. 
>> Acredito que o Firebird faça isso (desativar o índice), justamente 
>> para poder restaurar esse segundo registro da venda 100.
>> Obs.: não é a mesma venda 100, pois outros campos não têm o mesmo valor.
>> São duas vendas 100 diferentes.
>>
>> A única coisa que posso imaginar é que por algum erro, em algum 
>> momento, o sistema tentou registrar duas vezes com o mesmo número (100 
>> e FILIAL
>> 1) e o Firebird não permitiu. Entretanto esses dados não gravados  (da 
>> segunda venda) ficaram em "um limbo" e, ao fazer o restore, eles foram 
>> ressuscitados.
>> Tentamos de todas formas reproduzir o problema em labortório, mas não 
>> ocorre. Sempre que se tenta gravar uma segunda vez registro com os 
>> mesmos dados nos campos índice, o Firebird impede e descarta tudo 
>> (corretamente). Quado o usuário nos envia o banco, o problema já está 
>> instalado.
>>
>> Alguém poderia me dar uma luz sobre isso. Pode ser de fato isso que 
>> esteja ocorrendo? Como é que o Firebird permitiu um segundo registro 
>> com a mesma chave primária? E como não permitir que o Firebird gere 
>> essa situação?
>>
>> Usamos Firebird 2.5
>>
>> Qualquer sugestão é bem vinda!
>>
>> Obrigado!
>>
>>
>> ----------------------------------------------------------------------
>> --
>> /Cordialmente
>> Valdir Dill
>> /
>> ______________________________________________
>> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br 
>> Para saber como gerenciar/excluir seu cadastro na lista, use:
>> http://www.firebase.com.br/fb/artigo.php?id=1107
>> Para consultar mensagens antigas:
>> http://www.firebase.com.br/pesquisa_lista.html
>>


JSvl> ------------------------------

JSvl> Message: 3
JSvl> Date: Mon, 12 Sep 2022 09:05:20 -0300
JSvl> From: "Carlos H. Cantu" <listas em warmboot.com.br>
JSvl> To: FireBase <lista em firebase.com.br>
JSvl> Subject: Re: [firebase-br] Chave Primária Duplicada
JSvl> Message-ID: <828013511.20220912090520 em warmboot.com.br>
JSvl> Content-Type: text/plain; charset=iso-8859-1

JSvl> Imagino a seguinte situação:

JSvl> 1) Houve uma corrupção na base de dados, mais especificamente no índice da
JSvl> PK da tabela de vendas, que é usado pelo Firebird para saber se já existe um
JSvl> registro e impedir duplicidade. Com a corrupção, o FB não encontrou a venda
JSvl> no índice e deixou gravar uma segunda venda com os mesmos IDs, pois para
JSvl> ele, ainda não existia.

JSvl> 2) Em algum momento, você fez um backup/restore. Durante o restore, os
JSvl> índices são recriados e com isso a "duplicidade" apareceu, fazendo com que o
JSvl> a PK ficasse desativada no banco restaurado. Se vc não se atentou nisso (o
JSvl> gbak reporta o problema), pode ter usado o banco com a PK desativada,
JSvl> possibilitando o surgimento de novas duplicidades, já que a PK não estava
JSvl> ativa para assegurar que isso não acontecesse.

JSvl> PS: Corrupção não é normal. Sugiro que verifique o ambiente do servidor,
JSvl> especialmente HDDs e memória RAM, e lembre-se de deixar o forced writes
JSvl> ligado.

JSvl> []s
JSvl> Carlos H. Cantu
JSvl> eBook Guia de Migração para o FB 4 - www.firebase.com.br/guiafb4.php
JSvl> www.FireBase.com.br - www.firebirdnews.org - blog.firebase.com.br

VDvl>> Boa tarde,

VDvl>> Temos uma tabela (VENDAS). Ocorre também em outras tabelas, mas, aqui
JSvl> vamos nos ater apenas à VENDAS.
VDvl>> Entre outros campos, a VENdAS tem o NUMERO e FILIAL. Estes 2 compõem o
JSvl> índice primário.

VDvl>> Se tentarmos gravar a venda 100, com FILIAL 1, uma segunda vez, 
VDvl>> obviamente que o Firebird vai "berrar", porque se está tentando
JSvl> duplicar o índice primário.
VDvl>> É claro que antes do Firebird gerar erro, é aplicação que deve 
VDvl>> controlar isso e não permitir que chegue a esse ponto. Mas...

VDvl>> O problema que ocorre, muito eventualmente, mas ocorreu já mais de 
VDvl>> uma vez com usuários nossos é: o banco de dados está lá, tudo 
VDvl>> certo, com a venda 100 registrada apenas 1 vez, o índice primário
JSvl> ativo, tudo certo.
VDvl>> Aí faz-se um backup e o restore com gbak.exe. Nesse restore vem 
VDvl>> duas vendas 100, com filial 1 registradas, o que obviamente vai 
VDvl>> dar conflito no banco pelo fato do índice primário estar duplicado.
VDvl>> Ao mesmo tempo, o índice primário é desativado automaticamente. 
VDvl>> Acredito que o Firebird faça isso (desativar o índice), justamente 
VDvl>> para poder restaurar esse segundo registro da venda 100.
VDvl>> Obs.: não é a mesma venda 100, pois outros campos não têm o mesmo
JSvl> valor. São duas vendas 100 diferentes.

VDvl>> A única coisa que posso imaginar é que por algum erro, em algum 
VDvl>> momento, o sistema tentou registrar duas vezes com o mesmo número 
VDvl>> (100 e FILIAL 1) e o Firebird não permitiu. Entretanto esses dados 
VDvl>> não gravados  (da segunda venda) ficaram em "um limbo" e, ao fazer o
JSvl> restore, eles foram ressuscitados.
VDvl>> Tentamos de todas formas reproduzir o problema em labortório, mas 
VDvl>> não ocorre. Sempre que se tenta gravar uma segunda vez registro 
VDvl>> com os mesmos dados nos campos índice, o Firebird impede e descarta
JSvl> tudo (corretamente).
VDvl>> Quado o usuário nos envia o banco, o problema já está instalado.

VDvl>> Alguém poderia me dar uma luz sobre isso. Pode ser de fato isso 
VDvl>> que esteja ocorrendo? Como é que o Firebird permitiu um segundo 
VDvl>> registro com a mesma chave primária? E como não permitir que o
JSvl> Firebird gere essa situação?

VDvl>> Usamos Firebird 2.5

VDvl>> Qualquer sugestão é bem vinda!

VDvl>> Obrigado!


VDvl>> ------------------------------------------------------------------
VDvl>> ------
VDvl>> /Cordialmente
VDvl>> Valdir Dill




Mais detalhes sobre a lista de discussão lista