segunda-feira, 1 de agosto de 2011

Corrigindo segmentos de UNDO corrompidos

Já a algum tempo os segmentos de rollback foram substituídos pelos segmentos de UNDO esse novo dispositivo tornou-se automaticamente dimensionado e gerenciado. No entanto, o que acontece quando um UNDO se corrompe? 

No "ALERT.LOG" poderão ser encontradas mensagens de erros semelhantes a essa:

Errors in file /oracle/admin/test/bdump/test2_smon_21466.trc:
ORA-00600: internal error code, arguments: [6006], [1], [], [], [], [], [], []
SMON: mark undo segment 29 as needs recovery


ORACLE Instance test2 (pid = 11) - Error 600 encountered while recovering 
transaction (29, 42) on object 36.

Mas, o que você pode fazer sobre isso?

Ao tentar alterar o segmento de UNDO utilizando o comando "ALTER ROLLBACK SEGMENT" o comando irá apresentar mensagens de erros, indicando que esse dispositivo não pode ser alterado.

Abaixo, segue um procedimento para a correção deste problema:

1.  Primeiro deve-se criar uma nova tablespace de UNDO, deve-se usar:

    CONNECT / AS SYSDBA
    CREATE UNDO TABLESPACE UNDOTBS2 DATAFILE '/u02/oracle/oradata/test/undotbs2.dbf' SIZE 500M;

2.  Verificar o problema que está ocorrendo no segmento de UNDO.

    SELECT SEGMENT_NAME, STATUS
      FROM DBA_ROLLBACK_SEGS;

    NOTA: O segmento de UNDO que apresentar o valor "Needs Recovery", na coluna "STATUS",
               é o segmento de UNDO com problema.

3.  Aponte o banco de dados para a nova tablespace de UNDO (criado no item 1), usar:

    ALTER SYSTEM SET UNDO_TABLESPACE=UNDOTBS2 SCOPE=BOTH;  

    IMPORTANTE:  Se não estiver utilizando o "spfile", pode-se omitir o comando "SCOPE". Se estiver
                            utilizando o "spfile" deverá criar um novo pfile, seguindo os passos abaixo:

    CONNECT / AS SYSDBA
    CREATE PFILE='/u01/oracle/admin/test/pfile/inittest.ora' FROM SPFILE;

4.  Editar o arquivo "init.ora" (pfile) e adicionar as entradas abaixo:
 
    *._offline_rollback_segments="_SYSSMU29$"
    *._corrupted_rollback_segments="_SYSSMU29$"

    IMPORTANTE: O segmento de UNDO (_SYSSMU29$) é apresentado como um exemplo neste artigo,
                           deve-se utilizar o nome do segmento de UNDO que está apresentando problemas na
                           base de dados.

5.  Realizar um "restart" na base de dados "shutdown e startup". Preferencialmente usa a opção
     (SHUTDOWN IMMEDIATE, evite usar a opção ABORT).
   
6.  "Startar" o banco utilizando o "init.ora" usar o comando abaixo:

    STARTUP PFILE='/u01/oacle/admin/test/pfile=inittest.ora';

7.  Verificar novamente o problema que está ocorrendo no segmento de UNDO, usar:

    SELECT SEGMENT_NAME, STATUS
      FROM DBA_ROLLBACK_SEGS;

8.  Alterar a tablespace de UNDO antiga para OFFLINE, usar:

    ALTER TABLESPACE UNDOTBS1 OFFLINE;

9.  Remover a tablespace de UNDO antiga, usar:

    DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES;

10. Baixar o banco de dados,, usar:

    SHUTDOWN IMMEDIATE;

11. Editar o "init.ora", eliminar os parâmetros utilizados para a correção do UNDO que apresentavam
      problemas (parâmetros "_offline_rollback_segments=" e "_corrupted_rollback_segments=").

12. Restartar o banco de dados usando o "init.ora"

13. Criar um "spfile" a partir do "init.ora", usar:

    CREATE SPFILE FROM PFILE='/u01/oracle/admin/test/pfile/inittest.ora';

Uma vez que o passo 13 for executado os segmentos de UNDO deverão ser recriados automaticamente e não apresentarão mais erros. No entanto, é aconselhável fazer um backup completo e depois reconstruir os segmentos de UNDO, usando uma exportação e importação. Uma vez que um segmento de UNDO foi removido, poderiam existir algumas transações ativas, durante a corrupção, podendo deixar o banco de dados inconsistente, pois alguma transação pode não ter sido totalmente aplicada no banco.

Para informações adicionais sobre o corrupção de segmentos de UNDO, consute a Nota: 1.088.018.1 - Handling Oracle Database Corruption Issues, no Oracle Metalink. E veja também como corrigir a corrupção de LOGs no UNDO (ORA-00375), com a opção "_undo_log_corruption".



Rubens Oliveira
DBA Oracle Consultor
olivert.dba@consultant.com