본문 바로가기

IT관련

v$datafile 에서 unrecoverable_time 컬럼 - Nologging 작업으로인한 복구 불가 문제

v$datafile 딕셔너리 뷰를 조회하다보면, 아래와 같이 unrecoverable_time, unrecoverable_change# 라는 컬럼에 값이 나오는 경우가 있습니다.

복구를 할 수가 없다는 말인데... 쫌 살벌한 말이네요~~

 

 

이런 현상이 생기는 이유는 nologging 작업이 수행되었기 때문입니다.

 

nologging 작업이란 대량의 DML SQL 작업을 할때 Redo Log (Archive Log) 양을 줄이고 속도를 빠르게 하기위해서 Log를 쌓지않도록 하는 것을 말합니다.

 

Log를 쌓지 않고 작업하기 때문에 작업 자체를 빨리 끝낼 수 있지만, 복구할때 문제가 됩니다.

 

복구하는 과정을 보면, 먼저 RMAN 백업이나 Hot Backup 받은 파일에서 데이터파일을 복구하고 Archive Log 파일을 적용하여 최신상태로 복구가 되는 과정을 거칩니다.

그런데, nologging 작업을 한 경우에는 해당 테이블의 최신변경정보가 Redo Log(Archive Log)에 존재하지 않기 때문에 복구가 불가능한 상황이 벌어지는 것이죠~

 

그래서, nologging 작업을 한 이후에는 반드시 DB Full Backup 을 하라고 권고하고 있습니다.

 

nologging 작업을 하는 방법은 아래와 같이 여러가지 방법이 있습니다.

 


/* Unrecover Time 을 만드는 작업들 */

-- unrecoverable CTAS 작업
create table TEST1 unrecoverable as select * from emp;

-- nologging CTAS 작업
create table TEST2 nologging as select * from all_users;

-- nologging 변경후 append Insert
create table TEST1 as select * from EMP;
alter table TEST1 nologging;
insert /*+ append */ into TEST1 select * from TEST1;

-- nologging 변경후 parallel DML Insert
create table TEST1 as select * from EMP;
alter table TEST1 nologging;
insert /*+ enable_parallel_dml parallel(3) */ into TEST1 select * from TEST1;

-- nologging 옵션을 사용한 SQL*Loader 작업


 

Alter Table 구문으로 테이블을 nologging 모드로 변경한 후, Append Insert 작업이나 Parallel DML Insert 작업을 하는 방법이 있고, 또는 테이블을 처음부터 CTAS 등으로 생성할 때부터 nologging 옵션을 주거나 unrecoverable 옵션을 주어서 생성하면 됩니다.

 

위와 같은 작업들이 nologging 작업들에 해당되며, 이 작업들의 여파로 v$datafile 딕셔너리뷰의 unrecoverable_time 이 세팅되게 됩니다.

 

 

위와 같이 TEST1 테이블에 대해 nologging 작업을 한 경우, 아래의 스크립트들을 통해서 확인이 가능합니다.

 


/*
   1) 데이터파일 정보 확인 (@nologging_ts.sql)
*/
set linesize 200
col tablespace_name for a20
col file_name for a70

select df.tablespace_name,
       df.file_name,
       to_char(v.unrecoverable_time,'YYYY/MM/DD HH24:MI:SS') as Unrecoverable_Time,
       v.unrecoverable_change#,
       to_char(b.time,'YYYY/MM/DD HH24:MI:SS') as Backup_Time
from dba_data_files df, v$datafile v, v$backup b
 where v.file# = df.file_id
   and v.file# = b.file#
   and (b.time is null or b.change# < v.unrecoverable_change#)
order by tablespace_name, file_name
/


/*
   2) Nologging 작업을 한 테이블 확인 (@nologging_tab.sql)
*/
set linesize 200
col owner for a20
col object_name for a30
col TAB_LOG for a10
col TS_LOG for a10

select distinct dbo.owner, dbo.object_name, dbo.object_type, dfs.tablespace_name,
       dbt.logging as TAB_LOG, ts.logging as TS_LOG
from v$segstat ss, dba_tablespaces ts, dba_objects dbo, dba_tables dbt,
     v$datafile df, dba_data_files dfs, v$tablespace vts
where ss.statistic_name ='physical writes direct'
  and dbo.object_id = ss.obj#
  and vts.ts# = ss.ts#
  and ts.tablespace_name = vts.name
  and ss.value != 0
  and df.unrecoverable_change# != 0
  and dfs.file_name = df.name
  and ts.tablespace_name = dfs.tablespace_name
  and dbt.owner = dbo.owner
  and dbt.table_name = dbo.object_name
/

 

위 스크립트로 TEST1 테이블이 Unrecoverable 상태인 것을 확인할 수 있고, USERS 테이블스페이스에 Unrecoverable_Time 값이 있는 것을 확인할 수 있습니다.

 

Unrecover_Time 시간이 마지막 Backup_Time 보다 더 최근으로 백업이후에 Nologging 작업이 이루어졌기 때문에 백업본에서 제대로 복구가 안될 것이라는 것을 경고하고 있는 것입니다.

 

 

이 문제를 해결하는 방법은 DB Full Backup 을 다시 하면 됩니다.

 

그런데, 백업을 받아도 위 v$datafile 에서 값이 Clear 되지는 않습니다. 이 값을 Clear 하고자 하는 경우에는 해당 테이블스페이스에 대해 begin backup, end backup 을 한번 해주면 됩니다.

 


alter tablespace USERS begin backup;
alter tablespace USERS end backup;