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

domingo, 4 de agosto de 2013

Melhorias na administração da tablespace TEMP


A partir da versão do Oracle 11g foram implementadas melhorias na administração da tablespace temporária TEMP. Foi criada a visão chamada “DBA_TEMP_FREE_SPACE”, que apresenta as informações sobre a utilização da tablespace temporária TEMP, abaixo segue as colunas da visão.

SQL> desc dba_temp_free_space

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 TABLESPACE_NAME                           NOT NULL VARCHAR2(30)
 TABLESPACE_SIZE                                    NUMBER
 ALLOCATED_SPACE                                    NUMBER
 FREE_SPACE                                         NUMBER

SQL> SELECT * FROM dba_temp_free_space;

TABLESPACE_NAME                TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE
------------------------------ --------------- --------------- ----------
TEMP                                1.7180E+10      8801746944 1.2778E+10

Com as informações contidas na visão DBA_TEMP_FREE_SPACE, pode realizar um “shrink” na tablespace TEMP para liberar o espaço que não está em uso, conforme apresentado abaixo:

SQL> ALTER TABLESPACE temp SHRINK SPACE KEEP 540M;

Tablespace altered.

Após o ajuste da tablespace temporária pode-se verificar que o tamanho que era de  8 GB baixou para 540 MB.

TAMANHO ANTES DA EXECUÇÃO DO COMANDO “ALTER TABLESPACE”:

                                     ALOC        HWM     EM USO      LIVRE     %
TABLESPACE                           (MB)       (MB)       (MB)       (MB) LIVRE
------------------------------ ---------- ---------- ---------- ---------- -----
TEMP                                 8192       2097          0       8192   100


TAMANHO DEPOIS DA EXECUÇÃO DO COMANDO “ALTER TABLESPACE”:

                                     ALOC        HWM     EM USO      LIVRE     %
TABLESPACE                           (MB)       (MB)       (MB)       (MB) LIVRE
------------------------------ ---------- ---------- ---------- ---------- -----
TEMP                                  541       2097          0        541   100

O “shrink” também pode executado diretamente no arquivo físico “tempfile”, deve-se utilizar a cláusula abaixo:

SQL> ALTER TABLESPACE temp
     SHRINK TEMPFILE '+DATADG/dbteste/tempfile/temp01.dbf' KEEP 540M;

Tablespace altered.



                                ALOC        HWM     EM USO      LIVRE     %
TABLESPACE                      (MB)       (MB)       (MB)       (MB) LIVRE
------------------------- ---------- ---------- ---------- ---------- -----
TEMP                             541       2097          0        541   100


A cláusula “keep” especifica o tamanho mínimo da tablespace TEMP ou do “tempfile”. Se este parâmetro for omitido, o banco de dados diminuirá o espaço da tablespace TEMP ou do “tempfile” para o menor tamanho possível, abaixo um exemplo do comando sem a cláusula “keep”.

SQL> ALTER TABLESPACE temp SHRINK SPACE;

Tablespace altered.

                                ALOC        HWM     EM USO      LIVRE     %
TABLESPACE                      (MB)       (MB)       (MB)       (MB) LIVRE
------------------------- ---------- ---------- ---------- ---------- -----
TEMP                               2       2097          0          2   100

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




MSc. Rubens Oliveira
DBA Oracle Consultor