10 FLASHBACK

  1. 장애
    1. 물리적 장애 : 디스크장애나 서버 장애 등으로 인한 파일 손상을 의미
    2. 논리적 장애 : 사용자의 실수나 오류로 발생한 장애를 의미
  2. FLASHBACK 기능
    1. 사용자의 실수로 발생한 테이블 삭제나 DML 오류등의 논리적인 장애만 복구
    2. 물리적인 장애는 복구 할수 없다

10.1 FLASHBACK 종류

  1. Row Level Flashback
  2. Table Level Falshback
  3. Database Level Falshback

!flashback 버전.png!

  • Flashback Query : 특정 시점의 변경 내역만 알 수 있는 쿼리
  • Flashback Version Query : 해당 데이터의 과거 변경이력을 전부 찾아주는 쿼리
  • Flashback Transaction Query : 변경 사항을 취소시켜 이전 값으로 돌려 주는 쿼리

1) Row Level Flashback

  1. 정의
    1. 특정 테이블의 특정 Row만 Flashback해주는 기능
    2. Undo data의 정보를 이용하여 복구
    3. Undo segment가 재사용된 경우 ORA-01555 snapshot too old 에러 발생

실습1. Row Level Flashback을 사용하여 특정 행 복구하기


SQL> select supplemental_log_data_min from v$database
  2  /

SUPPLEMENTAL_LOG
----------------
NO

SQL>alter database add supplemental log data;
Database altered

SQL> select supplemental_log_data_min from v$database
  2  /
SUPPLEMENTAL_LOG
----------------
YES

SQL> create table fmem
  2  (name varchar2(10)
  3  ,addr varchar2(10)
  4  ,tel  varchar2(10)
  5  );

Table created

SQL>insert into fmem values('박동주','부천','111');
1 row created

SQL>insert into fmem values('서진수','강남','222');
1 row created

SQL>insert into fmem values('채미','전남','333');
1 row created

SQL>commit;
Commit complete.

SQL> select * from fmem;

NAME                 ADDR                 TEL
-------------------- -------------------- --------------------
박동주               부천                 111
서진수               강남                 222
채미                 전남                 333


SQL> update fmem set name = '안지혜' where tel = '111';

1 row updated.

SQL> commit;

Commit complete.

SQL> update fmem set name = '김세실' where tel = '333';

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from fmem;

NAME                 ADDR                 TEL
-------------------- -------------------- --------------------
안지혜               부천                 111
서진수               강남                 222
김세실               전남                 333

** 변경 이력을 찾는 Flashback Version Query 수행
SQL> select versions_startscn st_scn, versions_endscn endscn,
  2  versions_xid txid, versions_operation opt, name
  3  from fmem versions between scn minvalue and maxvalue
  4* where tel = '111';


SQL> ST_SCN     ENDSCN TXID             OP NAME
---------- ---------- ---------------- -- --------------------
   3566236            0500100032030000 U  안지혜
   3566164    3566236 01000200C7020000 I  박동주


** scn_to_timestamp을 이용한 발생시간 Query
SQL> select scn_to_timestamp(3566236) from dual;

SCN_TO_TIMESTAMP(3566236)
------------------------------------------------------------
15/12/07 20:16:36.000000000

SQL> update fmem set name = '박동주' where tel = '111';

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from fmem;

NAME                 ADDR                 TEL
-------------------- -------------------- --------------------
박동주               부천                 111
서진수               강남                 222
김세실               전남                 333

2) Table Level Flashback

  1. DML 에러가 발생했을떄 특정 테이블 전체 내용을 장애 발생 전 상태로 flashback하는 방법
  2. 복구 방법
    1. DML 에러에 대한 복구
    2. 특정 테이블이 Drop되었을때 사용하는 방법

실습2. SCN을 조회하여 DML 에러 복구하기 - undo data를 사용


SQL>create table fruits
(no number
,name varchar2(10)
,price number);


SQL> insert into fruits values(1,'apple',1000);

1 row created.


SQL> insert into fruits values(2,'grape',1500);

1 row created.

SQL> insert into fruits values(3,'orange',800);

1 row created.

SQL> commit;

Commit complete.


SQL> select * from fruits;

        NO NAME                      PRICE
---------- -------------------- ----------
         1 apple                      1000
         2 grape                      1500
         3 orange                      800

SQL> select current_scn from v$database;

CURRENT_SCN
-----------
    3567107

SQL> update fruits
  2 set price = 2000
  3 where no = 2
SQL> /

1 row updated.

SQL>
SQL>
SQL>
SQL> commit;

Commit complete.

SQL> select * from fruits
  2  /

        NO NAME                      PRICE
---------- -------------------- ----------
         1 apple                      1000
         2 grape                      2000
         3 orange                      800

SQL> select current_scn from v$database;

CURRENT_SCN
-----------
    3567136         <= grape 가격이 2000원으로 변경된 scn

SQL> update fruits
  2  set price = 1000
  3  where no = 3
  4  /

1 row updated.

SQL>
SQL>
SQL> select * from fruits
  2  /

        NO NAME                      PRICE
---------- -------------------- ----------
         1 apple                      1000
         2 grape                      2000
         3 orange                     1000

SQL> commit;

Commit complete.

SQL> select current_scn from v$database;

CURRENT_SCN
-----------
    3567168    <= orange 가격을 800 -> 1000원으로 업데이트한 scn

* orange 가격이 800원인 때로 Flashback
SQL>flashback table fruits to scn '3567107'
flashback table fruits to scn '3567107'

ERROR at line 1:
ORA-08189 : cannot flashback the table bacause row movement is not enabled

SQL> alter table fruits enable row movement;
Table altered

SQL>flashback table fruits to scn '3567107'
Flashback complete

SQL> select * from fruits
  2  /

        NO NAME                      PRICE
---------- -------------------- ----------
         1 apple                      1000
         2 grape                      2000
         3 orange                      800

  1. 해당 Tabledp Flashback Version Query를 수행해서 각 데이터별로 SCN을 모두 찾은 후 Flashback 수행
  2. Undo Segment가 재사용된 후라면 복구 불가

실습3. 시간으로 DML 에러 복구하기 - undo data를 사용


SQL> select * from fruits;

        NO NAME                      PRICE
---------- -------------------- ----------
         1 apple                      1000
         2 grape                      1500
         3 orange                      800

SQL> update fruits
  2  set price = 3000;
3 rows updated

SQL> commit;

Commit complete.

SQL> select * from fruits;

        NO NAME                      PRICE
---------- -------------------- ----------
         1 apple                      3000
         2 grape                      3000
         3 orange                     3000

SQL>delete from fruits;
3 rows deleted

SQL>select * from fruits;
no rows selected

SQL>commit;

Commit complete.

SQL>flashback table fruits
2 to timestamp(systimestamp - interval '2' minute);

Flashback complete

SQL>select * from fruits;
no rows selected


SQL>flashback table fruits
2 to timestamp(systimestamp - interval '5' minute);

SQL> select * from fruits;

        NO NAME                      PRICE
---------- -------------------- ----------
         1 apple                      1000
         2 grape                      1500
         3 orange                      800

* 시간을 너무 이전 시점으로 설정할 경우 에러 발생
SQL>flashback table fruits
2 to timestamp(systimestamp - interval '90' minute);
flashback table fruits
             *
ERROR at line 1:
ORA-01466:unable to read data - table definition has changed

  1. Undo Segment가 재사용된 후라면 복구 불가
  2. 분 단위의 시간뿐아니라 초 단위도 가능

실습4. Table의 컬럼이 삭제된 후 undo segment 내역을 못찾는 경우


SQL> select * from fruits;

        NO NAME                      PRICE
---------- -------------------- ----------
         1 apple                      1000
         2 grape                      1500
         3 orange                     1000

SQL>update fruits set price = 3000;
3 rows updated

SQL>commit;
Commit complete.

SQL>alter table fruits add (qty number default 0);
Table altered

SQL> select * from fruits;

        NO NAME                      PRICE    QTY
---------- -------------------- ---------- ---------
         1 apple                      3000     0
         2 grape                      3000     0
         3 orange                     3000     0

SQL>flashback table fruits 
2 to timestampe(systimestamp - interval '6' minute);
Flashback complete          <= 컬럼을 추가하고 한 후 flashback을 수행합니다

SQL> select * from fruits;

        NO NAME                      PRICE    QTY
---------- -------------------- ---------- ---------
         1 apple                      1000     
         2 grape                      2000     
         3 orange                     1000     

SQL>alter table fruits drop column qty;
Table altered             <= 컬럼을 삭제

SQL> select * from fruits;

        NO NAME                      PRICE   
---------- -------------------- ---------- 
         1 apple                      1000     
         2 grape                      2000     
         3 orange                     1000   

SQL>flashback table fruits
2 to timestampe(systimestamp - interval '8' minute);
flashback table fruits
             *
ERROR at line 1:
ORA-01466:unable to read data - table definition has changed

SQL>flashback table fruits
2 to timestampe(systimestamp - interval '6' minute);
flashback table fruits
             *
ERROR at line 1:
ORA-01466:unable to read data - table definition has changed


  • column이 drop될 경우 flashback table 명령으로 복구 불가