Restore de datafile excluído no Linux
Olá pessoal, como meu primeiro artigo resolvi abordar um dos assuntos que eu mais gosto, backup & restore. Esse procedimento eu aprendi no curso do Ricardo Portilho, trata-se da recuperação de um datafile excluído no Linux por um usuário ou até mesmo um DBA que acordou com o pé esquerdo.
Primeiramente vou explicar o cenário:
Criarei um usuário chamado T e uma tabela chamada T1, irei popular a mesma com algumas linhas para simular uma aplicação. Em seguida irei exlcluir o datafile para simular o erro humano no Linux e mostrar como é feito a recuperação.
Vamos lá:
21:48:21 ORCL.ORACLE02.SYS>create user t identified by t;
User created.
21:48:32 ORCL.ORACLE02.SYS>grant resource, dba, connect to t;
Grant succeeded.
21:48:34 ORCL.ORACLE02.SYS>conn t/t
Connected.
21:48:39 ORCL.ORACLE02.SYS>create table t1 as select * from all_objects;
Table created.
21:48:52 ORCL.ORACLE02.SYS>insert into t1 select * from all_objects;
88955 rows created.
21:49:03 ORCL.ORACLE02.SYS>commit;
Commit complete.
A tablespace do meu usuário é:
21:52:11 ORCL.ORACLE02.SYS>select username, default_tablespace from dba_users where username='T';
USERNAME DEFAULT_TABLESP
--------------- ---------------
T USERS
Nesse caso o meu datafile name e o meu datafile id serão:
21:53:51 ORCL.ORACLE02.SYS>select file_name, file_id, tablespace_name from dba_data_files where tablespace_name='USERS';
FILE_NAME FILE_ID TABLESPACE_NAME
-------------------------------------------------- ---------- --------------------------------------------------
/u01/app/oracle/oradata/ORCL/users01.dbf 6 USERS
Vamos supor que um analista de Unix esteja procurando arquivos para liberar espaço em disco e não goste muito do user01.dbf consumindo 28M no seu filesystem.
[oracle02][oracle][SID=ORCL]/u01/app/oracle/oradata/ORCL> ls -ltrh
total 2.1G
-rw-r-----. 1 oracle oinstall 101M Jul 24 21:39 redo02.log
-rw-r-----. 1 oracle oinstall 101M Jul 24 21:40 redo03.log
-rw-r-----. 1 oracle oinstall 88M Jul 24 21:49 temp01.dbf
-rw-r-----. 1 oracle oinstall 781M Jul 24 21:53 system01.dbf
-rw-r-----. 1 oracle oinstall 731M Jul 24 21:54 sysaux01.dbf
-rw-r-----. 1 oracle oinstall 141M Jul 24 21:54 undotbs01.dbf
-rw-r-----. 1 oracle oinstall 28M Jul 24 21:54 users01.dbf
-rw-r-----. 1 oracle oinstall 101M Jul 24 21:54 redo01.log
-rw-r-----. 1 oracle oinstall 9.6M Jul 24 21:54 control01.ctl
Ele simplesmente vai lá e exclui o arquivo, o espaço é liberado e ele fica feliz. Pelo menos até o cliente abrir uma crise dizendo que a aplicação está dando erro.
[oracle02][oracle][SID=ORCL]/u01/app/oracle/oradata/ORCL> rm -rf users01.dbf
21:55:43 ORCL.ORACLE02.SYS>insert into t1 select * from all_objects;
insert into t1 select * from all_objects
*
ERROR at line 1:
ORA-01565: error in identifying file '/u01/app/oracle/oradata/ORCL/users01.dbf'
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
Se nós tentarmos fazer um check logical datafile 6 o mesmo retornará erro:
[oracle02][oracle][SID=ORCL]/u01/app/oracle/product/12.1.0/dbhome_1/dbs> rman
Recovery Manager: Release 12.1.0.1.0 - Production on Fri Jul 24 21:56:37 2015
Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved.
connected to target database: ORCL (DBID=1413717262)
RMAN> BACKUP VALIDATE CHECK LOGICAL DATAFILE 6;
Starting backup at 24-JUL-15
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
RMAN-06169: could not read file header for datafile 6 error reason 5
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of backup command at 07/24/2015 21:56:58
RMAN-06056: could not access datafile 6
Depois de muitas desculpas esfarrapadas a equipe de backup admite que não tem backup do datafile 6. E agora? O analista de Unix já começar a arrumar as coisas dele e se dirigir até o RH. Mas você diz para ele esperar um pouco e que vai tentar um último procedimento para verificar uma possível recuperação do datafile.
Como usuário root procure pelo processo dbwr e pegue o número do PID dele:
[root@oracle02 ~]# ps -ef | grep dbw
oracle 3488 1 0 21:37 ? 00:00:00 ora_dbw0_ORCL
root 3947 3921 0 21:57 pts/2 00:00:00 grep dbw
Vá até o diretório /proc/PID/fd:
[root@oracle02 ~]# cd /proc/3488/fd
Verifique qual o file descriptor do datafile que foi excluído:
[root@oracle02 fd]# ls -ltr
total 0
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 9 -> /dev/urandom
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 8 -> /dev/zero
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 7 -> /proc/3488/fd
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 6 -> /u01/app/oracle/product/12.1.0/dbhome_1/rdbms/mesg/oraus.msb
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 5 -> /dev/null
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 4 -> /dev/null
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 3 -> /dev/null
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 29 -> /dev/urandom
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 28 -> /dev/urandom
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 262 -> /u01/app/oracle/oradata/ORCL/temp01.dbf
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 261 -> /u01/app/oracle/oradata/ORCL/users01.dbf (deleted)
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 260 -> /u01/app/oracle/oradata/ORCL/undotbs01.dbf
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 259 -> /u01/app/oracle/oradata/ORCL/sysaux01.dbf
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 258 -> /u01/app/oracle/oradata/ORCL/system01.dbf
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 257 -> /u01/app/oracle/fast_recovery_area/ORCL/control02.ctl
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 256 -> /u01/app/oracle/oradata/ORCL/control01.ctl
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 23 -> /dev/urandom
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 22 -> /dev/urandom
l-wx------. 1 oracle oinstall 64 Jul 24 21:58 2 -> /dev/null
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 17 -> /u01/app/oracle/product/12.1.0/dbhome_1/rdbms/mesg/oraus.msb
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 16 -> anon_inode:[eventpoll]
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 15 -> /u01/app/oracle/product/12.1.0/dbhome_1/dbs/lkORCL
l-wx------. 1 oracle oinstall 64 Jul 24 21:58 14 -> /home/oracle/logs/spool/spool_2015-07-24-21-36-25_ORCL.lst
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 11 -> /dev/urandom
lrwx------. 1 oracle oinstall 64 Jul 24 21:58 10 -> /u01/app/oracle/product/12.1.0/dbhome_1/dbs/hc_ORCL.dat
l-wx------. 1 oracle oinstall 64 Jul 24 21:58 1 -> /dev/null
lr-x------. 1 oracle oinstall 64 Jul 24 21:58 0 -> /dev/null
Copie o file descriptor em cima do local do datafile e dê permissão ao user oracle:
[root@oracle02 fd]# cat 261 > /u01/app/oracle/oradata/ORCL/users01.dbf
[root@oracle02 fd]# chown oracle:oinstall /u01/app/oracle/oradata/ORCL/users01.dbf
Verifique se o datafile está integro:
RMAN> BACKUP VALIDATE CHECK LOGICAL DATAFILE 6;
Starting backup at 24-JUL-15
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00006 name=/u01/app/oracle/oradata/ORCL/users01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
6 OK 0 209 3522 1850939
File Name: /u01/app/oracle/oradata/ORCL/users01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 3046
Index 0 5
Other 0 260
Finished backup at 24-JUL-15
Peça para o cliente validar a aplicação, no meu caso eu mesmo irei similar o cliente validando:
22:00:41 ORCL.ORACLE02.SYS>conn t/t
Connected.
22:00:45 ORCL.ORACLE02.SYS>insert into t1 select * from all_objects;
88958 rows created.
22:00:52 ORCL.ORACLE02.SYS>commit;
Commit complete.
Por que isso é possível? No Linux quando você exclui um arquivo que está em uso com o f (force) ele na verdade marca o arquivo como excluído, libera espaço dos blocos usados por aquele arquivo, mas na verdade não o exclui, pois existe outro processo alocando aquele arquivo. No nosso caso esse processo é o dbwr, ele tem lock preferencial nos datafiles, isso faz com que enquanto a instancia estiver no ar (open) ele sempre estará “segurando” o datafile.
Mas fique atento, se a instancia for desligada, (shutdown) o dbwr será finalizado e o lock do datafile será liberado, nisso o Linux irá realmente apagar o arquivo e ai, bye bye datafile.
Ah, o último passo, mas não menos mais importante: Diga ao analista de Unix que ele lhe deve um almoço!
Referências
- https://docs.oracle.com/cd/B19306_01/server.102/b14220/process.htm#i7259
- http://nervinformatica.com.br/obr.php