segunda-feira, 17 de setembro de 2012

Correção de corrupção de bloco no banco de dados Oracle


Neste artigo vamos apresentar a correção on-line de blocos corrompidos.

Esse procedimento pode salvar horas de recuperação como um banco de dados, não necessitando restaurar completamente o banco de dados.

A seguir vamos apresentar um exemplo.
1.     No exemplo relatado o erro é de uma corrupção do bloco na tabela TABLE_TEST.

ORA-01578: ORACLE data block corrupted (file # 48, block # 142713)
ORA-01110: data file 48: '/u01/app/oracle/data/TS_DATA.dbf'
ORA-02063: preceding 2 lines from TABLE_TEST
File name: /u01/app/oracle/data/TS_DATA.dbf

2.  Verifique se o há apenas um (ou mais) blocos corrompido(s) ou a se a maioria dos blocos está corrompido. Para essa atividade devemos utilizar o utilitário DBV (Data Base Verify).

dbsrv:/u01/app/oracle/admin/bdump> dbv \ file=/u01/app/oracle/data/TS_DATA.dbf BLOCKSIZE=8192 LOGFILE=test.log

DBVERIFY: Release 10.2.0.3.0 - Production on Wed Sep 4 14:28:37 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.

DBV-00200: Block, dba 201469305, already marked corrupted

Depois deve-se verificar o conteúdo do arquivo gerado a fim de identificar uma corrupção no banco de dados.

dbsrv:/u01/app/oracle/admin/bdump> vi test.log

DBVERIFY: Release 10.2.0.1.0 - Production on Wed Sep 4 14:28:37 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.

DBVERIFY - Verification starting : FILE = /u01/app/oracle/data/TS_DATA.dbf
DBVERIFY - Verification complete

Total Pages Examined         : 262144
Total Pages Processed (Data) : 218615
Total Pages Failing (Data)   : 0
Total Pages Processed (Index): 0
Total Pages Failing (Index)  : 0
Total Pages Processed (Other): 22422
Total Pages Processed (Seg)  : 0
Total Pages Failing (Seg)    : 0
Total Pages Empty            : 21107
Total Pages Marked Corrupt   : 1
Total Pages Influx           : 0
Highest block SCN            : 2550111754 (1040.2550111754)

No arquivo de “log” gerado (test.log) deve-se verificar o valor na linha “Total Pages Marked Corrupt” que apresenta o valor 1 (um), que aponta para o número de bloco corrompido.

Para obter a lista de blocos corrompidos, deve-se verificar a visão V$DATABASE_BLOCK_CORRUPTION.


SQL> select * from v$database_block_corruption;

Acessando essa visão você irá verificar o número do bloco corrompido, para esse exemplo o bloco 142713.

Com a identificação do bloco (142713), iremos utilizar o RMAN para recuperar o bloco corrompido.

  3.Executando o RMAN.

dbsrv:/u01/app/oracle> rman target / catalog rman/rman@rman

Recovery Manager: Release 10.2.0.1.0 - Production on Wed Sep 4 14:33:26 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.

connected to target database: ORCL (DBID=1125202344)
connected to recovery catalog database

RMAN> blockrecover datafile 48 block 142713;

Starting blockrecover at 04-SEP-12
allocated channel: ORA_SBT_TAPE_1
channel ORA_SBT_TAPE_1: sid=119 devtype=SBT_TAPE
channel ORA_SBT_TAPE_1: Tivoli Data Protection for Oracle: version 5.2.0.0
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=131 devtype=DISK
channel ORA_SBT_TAPE_1: restoring block(s)
channel ORA_SBT_TAPE_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00048
channel ORA_SBT_TAPE_1: reading from backup piece
ORCL.20121004.7379.1.1.602899473
channel ORA_SBT_TAPE_1: restored block(s) from backup piece 1
piece handle=ORCL.20121004.7379.1.1.602899473 tag=TAG20121003T222108
channel ORA_SBT_TAPE_1: reading from backup piece
ORCL.20121004.7379.2.1.602899473channel ORA_SBT_TAPE_1: restored block(s) from backup piece 2
piece handle=ORCL.20121004.7379.2.1.602899473 tag=TAG20121003T222108
channel ORA_SBT_TAPE_1: block restore complete, elapsed time: 00:04:01
starting media recovery
media recovery complete, elapsed time: 00:00:46

Finished blockrecover at 04-SEP-12

A corrupção do bloco foi corrigida online, durante o funcionamento do banco de dados.

NOTAS:
V$DATABASE_BLOCK_CORRUPTION é uma visão para verificar a lista de blocos corrompidos.
Caso existam múltiplos blocos corrompidos, pode-se utilizar a recuperação de uma lista, apresentada abaixo.

RMAN> BLOCKRECOVER corruption list;

  


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

domingo, 2 de setembro de 2012

Alteração da tablespace de UNDO no banco de dados Oracle


Este artigo apresentará os passos para a alteração na tablespace de UNDO no banco de dados Oracle.

Como alterar o banco de dados para uma nova tablespace UNDO e descartar a tablespace antiga.

Primeiro vamos verificar os parâmetros ativos no banco de dados:

$ sqlplus / as sysdba

SQL> show parameter undo NAME                      TYPE        VALUE
------------------------- ----------- ------------------------------
UNDO_MANAGEMENT           string      AUTO
UNDO_RETENTION            integer     600
UNDO_TABLESPACE           string      UNDOTBS1

A tablespace de UNDO atual como sugerido pela inicialização parâmetro UNDO_TABLESPACE é UNDOTBS1, que é a tablespace que armazena os segmentos de UNDO, o gerenciamento está configurado como automático (UNDO_MANAGEMENT) e possui uma retenção de 600 segundos (UNDO_RETENTION). Para realizarmos um teste vamos abriremos outra sessão (SCOTT) para simularmos uma transação no banco de dados.

$ sqlplus scott/tiger

SQL> update emp set sal = sal + 1500 where empno=7839;

1 row updated.

Quando realizamos um “update” na tabela EMP, iniciamos uma transação, os dados são escritos inicialmente em um segmento de UNDO, na tablespace UNDOTBS1, para depois serem gravados na tabela EMP.

Essa sessão ficará propositalmente aberta, sem a finalização da transação (COMMIT ou ROLLBACK).

Iremos criar uma nova tablespace de UNDO, chamada de UNDOTBS2.
 
SQL> CREATE UNDO TABLESPACE undotbs2
DATAFILE '/apps/oradata/dbf/undotbs02.dbf'
         SIZE 50M AUTOEXTEND OFF NEXT 5M;
 
Tablespace created.
 
Vamos alterar o banco de dados para a nova tablespace de UNDO (UNDOTBS2).
 
SQL> ALTER SYSTEM SET UNDO_TABLESPACE=UNDOTBS2 SCOPE=BOTH;
 
System altered.
 
Vamos tentar remover a tablespace de UNDO antiga  (UNDOTBS1).
 
SQL> DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES;
DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES
*
ERROR at line 1:
ORA-30013: undo tablespace 'UNDOTBS1' is currently in use
 
Com a nova tablespace de UNDO criada (UNDOTBS2), a tablespace UNDO já foi alterada no banco de dados. A partir do momento da criação da nova tablespace de UNDO todas as novas transações passarão a utilizar os segmentos de UNDO que estão criados na nova tablespace, ou seja, UNDOTBS2.
 
Porém os dados de transações pendentes em nosso exemplo pela conexão do usuário (SCOTT) ainda estão apontando para o segmento de UNDO antigo e possuem o “status” pendente OFFLINE.  

Abaixo segue o resultado de uma consulta nos segmentos de UNDO.
 
column username format a6
 
SELECT a.name,b.status , d.username , d.sid , d.serial#
FROM   v$rollname a,v$rollstat b, v$transaction c , v$session d
WHERE  a.usn = b.usn
AND    a.usn = c.xidusn
AND    c.ses_addr = d.saddr
AND    a.name IN (
              SELECT segment_name
              FROM dba_segments
              WHERE tablespace_name = 'UNDOTBS1'
             );
 
NAME       STATUS          USERNA        SID    SERIAL#
---------- --------------- ------ ---------- ----------
_SYSSMU8$  PENDING OFFLINE SCOTT         151          2
 
A sessão que está com a operação pendente é a conexão realizada no inicio da demonstração, com o usuário SCOTT (SID = 151 e SERIAL# = 2). Neste exemplo vamos eliminar a sessão no banco de dados, porém, poderíamos realizar um (COMMIT ou ROLLBACK) para finalizarmos a transação normalmente.
 
O objetivo de eliminarmos a sessão é para verificarmos o tempo de retenção do segmento de UNDO, que está configurado no banco de dados em 600 segundos.
 
SQL> alter system kill session '151, 2' immediate;
 
System altered.
 
 
Depois da sessão eliminada, foi realizada uma nova consulta para verificar o “status” do segmento de UNDO.
 
SQL> SELECT a.name,b.status , d.username , d.sid , d.serial#
FROM   v$rollname a,v$rollstat b, v$transaction c , v$session d
WHERE  a.usn = b.usn
AND    a.usn = c.xidusn
AND    c.ses_addr = d.saddr
AND    a.name IN (
              WHERE tablespace_name = 'UNDOTBS1'
             );
 
no rows selected

Como podemos verificar depois que a sessão foi eliminada e não vemos mais os segmentos ocupados na tablespace UNDOTBS1. Iremos remover a tablespace UNDOTBS1, pois todos os segmentos de UNDO ativos encontram-se na nova tablespace UNDOTBS2.

SQL> DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES;
DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES
*
ERROR at line 1:
ORA-30013: undo tablespace 'UNDOTBS1' is currently in use

Ao executar o comando acima, a mensagem de erro foi apresentada (ORA-30013). Essa mensagem é referente ao tempo de retenção estabelecido pelo banco de dados (parâmetro UNDO_RETENTION), que está configurado em 600 segundos. Parâmetro deve sempre ser configurado em segundos, neste exemplo, 600 segundos, ou seja, 10 minutos.

Após 10 minutos o comando foi re-executado, permitindo a remoção da tablespace UNDOTBS1.

SQL> DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES;

Tablespace dropped.






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