Quais são as causas e soluções para alterar erros de tabela?

12

Entendo que os erros de tabela de mutação são causados ​​por uma falha de design ou consulta problemática.

Uma consulta antiga foi colocada recentemente em produção, gerando um erro de tabela mutante. Nosso DBA resolveu o problema, mas não sabemos como.

O que exatamente causa erros de tabela mutantes e como nosso DBA teria resolvido o problema?

Parmanand
fonte

Respostas:

17

A causa mais provável de um erro de tabela mutante é o uso indevido de gatilhos. Aqui está um exemplo típico:

  1. você insere uma linha na tabela A
  2. um gatilho na tabela A (para cada linha) executa uma consulta na tabela A, por exemplo, para calcular uma coluna de resumo
  3. O Oracle lança um ORA-04091: a tabela A está em mutação, o gatilho / função pode não vê-lo

Esse é um comportamento esperado e normal. A Oracle deseja protegê-lo de si mesmo, pois a Oracle garante:

  • (i) que cada afirmação é atômica (ou seja, falhará ou terá êxito completo)
  • (ii) que cada declaração tenha uma visão consistente dos dados

Provavelmente, ao escrever esse tipo de gatilho, você esperaria que a consulta (2) visse a linha inserida em (1). Isso estaria em contradição com os dois pontos acima, já que a atualização ainda não foi concluída (pode haver mais linhas a serem inseridas).

A Oracle poderia retornar o resultado consistente com um ponto no tempo imediatamente antes do início da declaração, mas, na maioria dos exemplos que já vi que tentam implementar essa lógica, as pessoas veem uma declaração com várias linhas como uma série de etapas sucessivas e esperam o declaração [2] para ver as alterações feitas nas etapas anteriores. O Oracle não pode retornar o resultado esperado e, portanto, gera o erro.

Para leitura adicional: "tabela mutante" em Ask Tom .

Se, como suspeito, a causa do erro da tabela de mutação for um gatilho, uma maneira de evitar o erro é mover a lógica do gatilho para os procedimentos.

Vincent Malgrat
fonte
9

Uma tabela de mutação ocorre quando uma instrução faz com que um gatilho seja acionado e esse gatilho faz referência à tabela que causou o gatilho. A melhor maneira de evitar esses problemas é não usar gatilhos, mas eu suspeito que o DBA não teve tempo para fazer isso. Ele poderia ter feito um dos seguintes:

Leigh Riffel
fonte
1
Pelo menos para mim, a alteração para ser um disparador posterior falha em 11.2.0.4.0
Outfast Source
Também para mim; versão 12.1.0.2.0 e AFTER não funciona.
eidylon