segunda-feira, 19 de agosto de 2013

Resolvendo o erro ORA-01555


A mensagem de erro ORA-01555 (snapshot too old) pode ocorrer em diferentes situações.


Por exemplo, durante uma exportação de dados:

EXP-00008: ORACLE error 1555 encountered
ORA-01555: snapshot too old: rollback segment number 10 with name "_SYSSMU10$" too small
EXP-00000: Export terminated unsuccessfully

E também pode ocorrer o durante uma transação de “flashback”

ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number with name "" too small
ORA-06512: at "SYS.DBMS_FLASHBACK", line 37
ORA-06512: at "SYS.DBMS_FLASHBACK", line 70

Mas porque o erro ocorre?

O erro ocorre quando o banco de dados desfaz uma transação, porém os dados estão sendo utilizados por outra transação. O erro é um resultado direto da consistência de leitura do banco de dados. Também ocorre durante a execução de uma consulta de longa duração e o banco de dados tenta ler a imagem anterior dos dados “before image” das linhas envolvidas na consulta que ficam armazenadas no segmento de UNDO.


Por exemplo, se uma consulta de longa duração começa à 1 hora e vai até as 6 horas possivelmente o banco de dados irá alterar os dados que fazem parte desta consulta durante o período em que a consulta é executada.E quando o banco de dados tenta ler os dados, os dados que estavam no inicio da execução (a 1 hora), foram atualizados e não estão mais presentes nos segmentos de UNDO, gerando o erro.


Se o banco de dados está executando uma série de atualizações, o Oracle não será capaz de buscar as linhas alteradas, pois as alterações que são armazenadas nos segmentos de UNDO já terão os valores substituídos. As transações que mudaram as linhas já terão sido gravadas no banco de dados (commit) e os segmentos de UNDO não terão os registros anteriores porque o banco de dados substituiu os valores dos segmentos de UNDO relevantes.


Uma vez que o banco de dados não consiga retornar dados consistentes para a consulta atual, ele emite a mensagem de erroORA-01555”. Isto porque a consulta que está atualmente em execução precisa da imagem anterior para garantir uma leitura consistente.


O erro ORA-01555 pode ser o resultado de um ou mais procedimentos: Muitas atualizações no banco de dados ou uma tablespace de UNDO pequena.


Como solucionar ?


Para contornar o problema pode-se aumentar o tamanho da tablespace de UNDO, mas isso não garante que o erro não irá ocorrer novamente.

Uma das soluções a serem adotadas seria a definir um valor elevado para o parâmetro UNDO_RETENTION, isso poderá minimizar a possibilidade de receber a mensagem de erro "snapshot too old". Porém somente essa ação não garante que o banco de dados não irá substituir os dados mais velhos do segmento de UNDO por outra transação em execução.

Outra solução seria mover a janela de execução dos “batchs”, que normalmente possuem um tempo de execução mais longo para os períodos em que outros programas não estejam em execução no banco de dados.

Mas se configurarmos a área de retenção “undo retention” no banco de dados, nenhuma transação poderá falhar por causa do erro "snapshot too old". Com essa cláusula ativa, o banco de dados manterá as novas instruções DML.

Para implementar o “undo retention” é simples. Supohamos que iremos garantir que o banco manterá a retenção por uma hora (equivalente a 3.600 segundos). Deve-se primeiro definir o limite de retenção com o comandoalter system” apresentado abaixo e em seguida, configurar “retention garantee”, para isso deve-se especificar a cláusula de “retention garantee”.


SQL> alter system set undo_retention = 3600;


System altered.



SQL
alter tablespace undotbs1 retention guarantee;


System altered.

Para desabilitar o “retention guarantee” deve-se executar o comando ALTER TABLESPACE com
a cláusula “retention noguarantee”.


SQL> alter tablespace undotbs1 retention noguarantee;


System altered.

 



Referências: Oracle® Database Reference 11gR2 (11.2)
                    Oracle® Database Administrator´s Guide 11gR2 (11.2)




MSc. Rubens Oliveira
DBA Oracle Consultor