DATABASE(oracleDB 11g)/DBA

[Oracle DBA]Flashback 기술01

SEUNGSAMI 2019. 5. 3. 09:43
Flashback 기술01







Flashback Query
  • 지정된 시점(timestamp, scn) 의 데이터를 조회(아래와 같은말)
  • 과거 특정 시점의 COMMIT 된 데이터를 검색
  • SELECT 문의 AS OF 절을 사용하여 과저 시점을 지정
  • 데이터 불일치 분석에 유용
SYS@orcl2> select systimestamp, localtimestamp from dual;

SYSTIMESTAMP                             LOCALTIMESTAMP
---------------------------------------- ----------------------------------------
25-APR-19 11.45.59.479952 AM +09:00      25-APR-19 11.45.59.479956 AM
-- systimestamp : timestamp with timezone
-- localtimestamp : timestamp

SYS@orcl2> select current_scn, scn_to_timestamp(current_scn) current_time, localtimestamp
           from v$database; 

CURRENT_SCN CURRENT_TIME                        LOCALTIMESTAMP
----------- ----------------------------------- -----------------------------------
    1505087 25-APR-19 11.52.30.000000000 AM     25-APR-19 11.52.31.191420 AM
-- scn을 시간으로 변환
-- scn이 가장 정확한 값이다.


SYS@orcl2> select localtimestamp, timestamp_to_scn(localtimestamp) from dual;

LOCALTIMESTAMP                      TIMESTAMP_TO_SCN(LOCALTIMESTAMP)
----------------------------------- --------------------------------
25-APR-19 11.54.29.619326 AM                                 1505187
-- 시간을 scn으로 변환


SYS@orcl2> select systimestamp, timestamp_to_scn(systimestamp) from dual;

SYSTIMESTAMP                             TIMESTAMP_TO_SCN(SYSTIMESTAMP)
---------------------------------------- ------------------------------
25-APR-19 11.59.07.927113 AM +09:00                             1505650


SYS@orcl2> save time
Created file time.sql


SYS@orcl2> select employee_id, salary from hr.employees
           where employee_id=176;

EMPLOYEE_ID     SALARY
----------- ----------
        176       8600


SYS@orcl2> update hr.employees
           set salary=salary+100
           where employee_id=176;

1 row updated.


SYS@orcl2> commit;
Commit complete.


SYS@orcl2> select employee_id, salary from hr.employees
           where employee_id=176;

EMPLOYEE_ID     SALARY
----------- ----------
        176       8700


SYS@orcl2> select employee_id, salary
from hr.employees as of timestamp to_timestamp('25-APR-19 11.59.07', 'DD-MON-RR HH24.MI.SS')
           where employee_id=176; 

EMPLOYEE_ID     SALARY
----------- ----------
        176       8600
-- 이 시점의 데이터를 확인 할 수 있다.


SYS@orcl2> select employee_id, salary
           from hr.employees as of scn 1505650
           where employee_id=176;

EMPLOYEE_ID     SALARY
----------- ----------
        176       8600
-- scn 으로 확인


SYS@orcl2> select employee_id, salary
           from hr.employees
           as of timestamp localtimestamp - interval '5' minute
           where employee_id=176;

EMPLOYEE_ID     SALARY
----------- ----------
        176       8700
-- 5분 전의 데이터를 확인


SYS@orcl2> update hr.employees
           set salary=(select salary
                       from hr.employees as of timestamp to_timestamp('19/04/25 11:58:27', 'RR/MM/DD HH24:MI:SS')
                       where employee_id=176)
           where employee_id=176;

1 row updated.
-- 과거 특정시점의 데이터를 읽어서(flashback query) 현재 데이터를 update


SYS@orcl2> select salary from hr.employees where employee_id=176;

    SALARY
----------
      8600


SYS@orcl2> commit;
Commit complete.



Flashback Versions Query
  • 특정 기간(시간, scn) 동안 데이터의 변경 정보(version)을 조회할 수 있다. 아래와 같은 의미
  • VERSIONS 절을 사용하여 과거 두 Point-in-time 또는 두 SCN 사이에 존재하는 행의 모든 버전을 검색할 수 있다.
  • VERSIONS PSEUDO-COLUMNS
      • VERSIONS_STARTTIME (start timestamp of version)
      • VERSIONS_STARTSCN (start SCN of version)
      • VERSIONS_ENDTIME (end timestamp of version)
      • VERSIONS_ENDSCN (end SCN of version)
      • VERSIONS_XID (transaction ID of version)
      • VERSIONS_OPERATION (DML operation of version)
SYS@orcl2> select salary from hr.employees where employee_id=176;

    SALARY
----------
      8600

SYS@orcl2> save sel
Created file sel.sql


SYS@orcl2> select current_scn, localtimestamp
           from v$database;

CURRENT_SCN LOCALTIMESTAMP
----------- -----------------------------------
    1510160 25-APR-19 01.43.42.054668 PM


SYS@orcl2> update hr.employees
           set salary=salary + 1000
           where employee_id=176;
1 row updated.


SYS@orcl2> commit;     
Commit complete.


SYS@orcl2> update hr.employees
           set salary=salary + 1000
           where employee_id=176;
1 row updated.


SYS@orcl2> commit;     
Commit complete.


SYS@orcl2> update hr.employees
           set salary=salary + 1000
           where employee_id=176;
1 row updated.


SYS@orcl2> commit;     
Commit complete.


SYS@orcl2> @sel

    SALARY
----------
     11600
-- 현재 버전


SYS@orcl2> select employee_id, salary
           from hr.employees versions between scn minvalue and maxvalue
           where employee_id=176;

EMPLOYEE_ID     SALARY
----------- ----------
        176      11600
        176      10600
        176       9600
        176       8600
        176       8700
-- undo에 있는 최소값과 최대값



SYS@orcl2> select employee_id, salary, versions_starttime stime, versions_endtime etime
           from hr.employees versions between scn minvalue and maxvalue
           where employee_id=176;

EMPLOYEE_ID     SALARY STIME                     ETIME
----------- ---------- ------------------------- -------------------------
        176      11600 25-APR-19 01.47.54 PM
        176      10600 25-APR-19 01.47.54 PM     25-APR-19 01.47.54 PM
        176       9600 25-APR-19 01.47.42 PM     25-APR-19 01.47.54 PM
        176       8600 25-APR-19 01.40.49 PM     25-APR-19 01.47.42 PM
        176       8700                           25-APR-19 01.40.49 PM


SYS@orcl2> save ver_time
Created file ver_time.sql


SYS@orcl2> select employee_id, salary, versions_startscn sscn, versions_endscn escn
           from hr.employees versions between scn minvalue and maxvalue
           where employee_id=176;

EMPLOYEE_ID     SALARY       SSCN       ESCN
----------- ---------- ---------- ----------
        176      11600    1510314
        176      10600    1510312    1510314
        176       9600    1510307    1510312
        176       8600    1510076    1510307
        176       8700               1510076
-- scn을 기준으로 확인

SYS@orcl2> save ver_scn
Created file ver_scn.sql



SYS@orcl2> select employee_id, salary, versions_xid, versions_starttime stime,
           versions_endtime etime
           from hr.employees versions between scn minvalue and maxvalue
           where employee_id=176; 

EMPLOYEE_ID     SALARY VERSIONS_XID     STIME                     ETIME
----------- ---------- ---------------- ------------------------- -------------------------
        176      11600 0A00070060020000 25-APR-19 01.47.54 PM
        176      10600 08001000FA030000 25-APR-19 01.47.54 PM     25-APR-19 01.47.54 PM
        176       9600 0900210014030000 25-APR-19 01.47.42 PM     25-APR-19 01.47.54 PM
        176       8600 07001F0069020000 25-APR-19 01.40.49 PM     25-APR-19 01.47.42 PM
        176       8700                                            25-APR-19 01.40.49 PM
-- 트랜잭션을 확인할 수 있다.(versions_xid)




Flashback Table
  • 테이블을 특정 시점으로 Recovery
  • DB는 Online 상태를 유지
  • 특정 테이블에 대하여 FLASHBACK ANY TABLE 또는 FLASHBACK 권한 필요
  • FLASHBACK 될 테이블에 대해 SELECT, INSERT, DELETE, ALTER 권한이 필요
  • 고려 사항
      • FLASHBACK TABLE 명령은 단일 트랜잭션으로 실행되며 배타적 DML lock을 획득합니다.
      • 통계는 flashback되지 않습니다.
      • 현재 인덱스와 종속 객체는 유지됩니다.
      • Data Dictionary Table 수행할수 없다.
      • 테이블의 DDL 작업 수행했거나, 테이블의 재구성을 했을경우에는 그이전시간으로 flashback 할수 없다.
      • 언두 및 리두 데이터를 생성합니다.
SYS@orcl2> select current_scn, scn_to_timestamp(current_scn) current_time
           from v$database;

CURRENT_SCN CURRENT_TIME
----------- -----------------------------------
    1635395 29-APR-19 10.56.32.000000000 AM


SYS@orcl2> create table hr.emp_flash
           as select employee_id, last_name, salary
           from hr.employees
           where department_id=30;
Table created.


SYS@orcl2> select current_scn, scn_to_timestamp(current_scn) current_time
           from v$database;

CURRENT_SCN CURRENT_TIME
----------- -----------------------------------
    1635429 29-APR-19 10.56.43.000000000 AM


SYS@orcl2> select * from hr.emp_flash;

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        114 Raphaely                       11000
        115 Khoo                            3100
        116 Baida                           2900
        117 Tobias                          2800
        118 Himuro                          2600
        119 Colmenares                      2500

6 rows selected.


SYS@orcl2> update hr.emp_flash
           set salary=1000;
6 rows updated.


SYS@orcl2> commit;
Commit complete.


SYS@orcl2> select current_scn, scn_to_timestamp(current_scn) current_time
           from v$database;

CURRENT_SCN CURRENT_TIME
----------- -----------------------------------
    1635453 29-APR-19 10.57.20.000000000 AM


SYS@orcl2> select * from hr.emp_flash;

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        114 Raphaely                        1000
        115 Khoo                            1000
        116 Baida                           1000
        117 Tobias                          1000
        118 Himuro                          1000
        119 Colmenares                      1000

6 rows selected.


SYS@orcl2> alter table hr.emp_flash enable row movement;
Table altered.


SYS@orcl2> select * from hr.emp_flash;

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        114 Raphaely                       11000
        115 Khoo                            3100
        116 Baida                           2900
        117 Tobias                          2800
        118 Himuro                          2600
        119 Colmenares                      2500

6 rows selected.





SYS@orcl2> select row_movement
           from dba_tables
           where table_name='EMP_FLASH';
           
ROW_MOVE
--------
ENABLED


SYS@orcl2> alter table hr.emp_flash disable row movement;
Table altered.


SYS@orcl2> select row_movement
           from dba_tables
           where table_name='EMP_FLASH';
           
ROW_MOVE
--------
DISABLED


SYS@orcl2> drop table hr.emp_flash purge;
Table dropped.

SYS@orcl2> create table hr.dept
           as
           select *
           from hr.departments
           where department_id in (10,20);


Table created.


SYS@orcl2> create table hr.emp
           as
           select employee_id, last_name, department_id
           from hr.employees
           where department_id in (10,20);
           
Table created.


SYS@orcl2> alter table hr.dept
           add constraint dept_pk primary key(department_id);
Table altered.


SYS@orcl2> alter table hr.emp
           add constraint emp_fk foreign key(department_id)
           references hr.dept;
Table altered.


SYS@orcl2> select * from hr.dept;

DEPARTMENT_ID DEPARTMENT_NAME                MANAGER_ID LOCATION_ID
------------- ------------------------------ ---------- -----------
           10 Administration                        200        1700
           20 Marketing                             201        1800


SYS@orcl2> select * from hr.emp;

EMPLOYEE_ID LAST_NAME                 DEPARTMENT_ID
----------- ------------------------- -------------
        200 Whalen                               10
        201 Hartstein                            20
        202 Fay                                  20


SYS@orcl2> @current

CURRENT_SCN CURRENT_TIME
----------- -----------------------------------
    1636132 29-APR-19 11.06.59.000000000 AM


SYS@orcl2> insert into hr.dept
           values(30,'Sales',202,1700);
1 row created.


SYS@orcl2> commit;
Commit complete.


SYS@orcl2> @current

CURRENT_SCN CURRENT_TIME
----------- -----------------------------------
    1636199 29-APR-19 11.08.48.000000000 AM


SYS@orcl2> insert into hr.emp
           values(203,'CHO',30);
           
1 row created.


SYS@orcl2> commit;
Commit complete.


SYS@orcl2> @current

CURRENT_SCN CURRENT_TIME
----------- -----------------------------------
    1636279 29-APR-19 11.09.49.000000000 AM


SYS@orcl2> alter table hr.dept enable row movement;
Table altered.


SYS@orcl2> alter table hr.emp enable row movement;
Table altered.


SYS@orcl2> flashback table hr.dept to scn 1636132;
flashback table hr.dept to scn 1636132
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02292: integrity constraint (HR.EMP_FK) violated - child record found


SYS@orcl2> flashback table hr.dept, hr.emp to scn 1636132;
Flashback complete.


SYS@orcl2> select * from hr.dept;

DEPARTMENT_ID DEPARTMENT_NAME                MANAGER_ID LOCATION_ID
------------- ------------------------------ ---------- -----------
           10 Administration                        200        1700
           20 Marketing                             201        1800


SYS@orcl2> select * from hr.emp;

EMPLOYEE_ID LAST_NAME                 DEPARTMENT_ID
----------- ------------------------- -------------
        200 Whalen                               10
        201 Hartstein                            20
        202 Fay                                  20


SYS@orcl2> drop table hr.emp purge;
Table dropped.


SYS@orcl2> drop table hr.dept purge;
Table dropped.



SYS@orcl2> select empno, sal from scott.emp
           where empno=7788;


     EMPNO        SAL
---------- ----------
      7788       3000


SYS@orcl2> update scott.emp
           set sal=sal+1000
           where empno = 7788;
           
1 row updated.


SYS@orcl2> commit;
Commit complete.


SYS@orcl2> select current_scn from v$database;

CURRENT_SCN
-----------
    1512593


SYS@orcl2> update scott.emp
           set sal=sal+1000
           where empno = 7788;
           
1 row updated.


SYS@orcl2> commit;
Commit complete.


SYS@orcl2> select current_scn from v$database;

CURRENT_SCN
-----------
    1512604


SYS@orcl2> select empno, sal, versions_startscn, versions_endscn, versions_operation
           from scott.emp versions between scn minvalue and maxvalue
           where empno = 7788;
    
     EMPNO        SAL VERSIONS_STARTSCN VERSIONS_ENDSCN V
---------- ---------- ----------------- --------------- -
      7788       5000           1512602                 U
      7788       4000           1512586         1512602 U
      7788       3000                           1512586
-- U는 udpate
-- I는 insert


SYS@orcl2> flashback table scott.emp to scn 1512586;
-- undo 정보를 이용해서 과거로 슝슝

flashback table scott.emp to scn 1512586
                       *
ERROR at line 1:
ORA-08189: cannot flashback the table because row movement is not enabled
-- row movement를 해야 실행 가능


SYS@orcl2> alter table scott.emp enable row movement;
Table altered.


SYS@orcl2> flashback table scott.emp to scn 1512586;
Flashback complete.


SYS@orcl2> select empno, sal from scott.emp
           where empno=7788;

     EMPNO        SAL
---------- ----------
      7788       4000
-- 4000으로 돌아갔다.



Flashcback Transaction Query
  •    수행되었던 Transaction의 Operation들을 검색
  •    FLASHBACK_TRANSACTION_QUERY 테이블을 검색
      • SELECT ANY TRANSACTION 권한 필요
  • undo sql을 찾아서 취소하는 효과가 있다.
  • 단 추가적인 log data가 필요
SYS@orcl2> select supplemental_log_data_min, supplemental_log_data_pk from v$database;

SUPPLEME SUP
-------- ---
YES      NO

-- flashback의 데이터를 저장하는 별도의 보조적인 로그가 필요하다.
-- 하나의 칼럼이 변경되더라도 전체 row의 정보를 모두 redo log에 저장


SYS@orcl2> alter database add supplemental log data;
Database altered.


SYS@orcl2> alter database add supplemental log data (primary key) columns;
Database altered.

============================
해제
SYS@orcl2> alter database drop supplemental log data;


SYS@orcl2>  alter database drop supplemental log data (primary key) columns;
============================


SYS@orcl2> create table hr.emp_60
           as select employee_id, last_name, salary
              from hr.employees
              where department_id = 60;
           
Table created.


SYS@orcl2> select * from hr.emp_60;

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        103 Hunold                          9000
        104 Ernst                           6000
        105 Austin                          4800
        106 Pataballa                       4800
        107 Lorentz                         4200

SYS@orcl2> create table hr.emp_90
           as select employee_id, last_name, salary
              from hr.employees
              where department_id = 90;

Table created.


SYS@orcl2> select * from hr.emp_90;

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        100 King                           24000
        101 Kochhar                        17000
        102 De Haan                        17000


1. update 전
SYS@orcl2> select current_scn, systimestamp from v$database;

CURRENT_SCN SYSTIMESTAMP
----------- ----------------------------------------
    1518799 25-APR-19 04.19.38.689134 PM +09:00


2.emp_60 변경한 다음( 103 :U 9000 -> 90)
SYS@orcl2> update hr.emp_60
           set salary=90
           where employee_id=103;

1 rows updated.


SYS@orcl2> commit;
Commit complete.


SYS@orcl2> select current_scn, systimestamp from v$database;

CURRENT_SCN SYSTIMESTAMP
----------- ----------------------------------------
    1518808 25-APR-19 04.19.54.016389 PM +09:00


2.emp_90 변경한 다음( 100 :U 24000 -> 24)
SYS@orcl2> update hr.emp_90
           set salary=24
           where employee_id=100;

1 rows updated.


SYS@orcl2> commit;
Commit complete.


SYS@orcl2> select current_scn, systimestamp from v$database;

CURRENT_SCN SYSTIMESTAMP
----------- ----------------------------------------
    1518815 25-APR-19 04.20.08.209719 PM +09:00



3. flashback 확인
SYS@orcl2> select versions_xid, versions_startscn sscn, versions_endscn escn, employee_id, salary
           from hr.emp_60 versions between scn minvalue and maxvalue
           where employee_id = 103;
           
VERSIONS_XID           SSCN       ESCN EMPLOYEE_ID     SALARY
---------------- ---------- ---------- ----------- ----------
0300000038030000    1518806                    103         90
                               1518806         103       9000


SYS@orcl2> select versions_xid, versions_startscn sscn, versions_endscn escn, employee_id, salary
           from hr.emp_90 versions between scn minvalue and maxvalue
           where employee_id = 100;
           
VERSIONS_XID           SSCN       ESCN EMPLOYEE_ID     SALARY
---------------- ---------- ---------- ----------- ----------
09001B0018030000    1518813                    100         24
                               1518813         100      24000


SYS@orcl2> select table_name, operation, undo_sql
           from flashback_transaction_query
           where xid='0300000038030000';

TABLE_NAME OPERATION  UNDO_SQL
---------- ---------- ------------------------------------------------------------
EMP_60     UPDATE     update "HR"."EMP_60" set "SALARY" = '9000' where ROWID = 'AA
                      ASQVAAEAAAAKLAAA';


SYS@orcl2> select table_name, operation, undo_sql
           from flashback_transaction_query
           where xid='09001B0018030000';

TABLE_NAME OPERATION  UNDO_SQL
---------- ---------- ------------------------------------------------------------
EMP_90     UPDATE     update "HR"."EMP_90" set "SALARY" = '24000' where ROWID = 'A
                      AASQWAAEAAAAKTAAA';


SYS@orcl2> DROP TABLE HR.EMP_60 PURGE;
Table dropped.


SYS@orcl2> DROP TABLE HR.EMP_90 PURGE;
Table dropped.







<<<<복습>>>>
1. 현재 DB의 SCN번호, SCN의 날짜 정보를 확인 하세요.
  
SYS@orcl2> select current_scn, scn_to_timestamp(current_scn) current_time from v$database;

CURRENT_SCN CURRENT_TIME
----------- ----------------------------------------
    1546398 26-APR-19 09.51.35.000000000 AM



2. hr.employees 테이블에 있는 데이터 중에  최고 commission 값을 가지고 있는 사원 정보를 조회하세요.
select *
from (select *
      from hr.employees
      order by commission_pct desc nulls last)
where rownum = 1;

EMPLOYEE_ID FIRST_NAME           LAST_NAME                 EMAIL
----------- -------------------- ------------------------- -------------------------
PHONE_NUMBER         HIRE_DATE JOB_ID         SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
-------------------- --------- ---------- ---------- -------------- ---------- -------------
        145 John                 Russell                   JRUSSEL
011.44.1344.429268   01-OCT-04 SA_MAN          14000             .4        100            80




3. hr.employees 테이블에 있는 데이터 중에 최고 commission 값을 가지고 있는 사원의 급여를 1000로 수정한 후 영구히 저장하세요.
SYS@orcl2>  update hr.employees
            set salary = 1000
            where commission_pct = (select employee_id
                                    from (select *
                                          from hr.employees
                                          order by commission_pct desc nulls last)
                                    where rownum = 1);
1 row updated.

SYS@orcl2> commit;


SYS@orcl2> select * from hr.employees where employee_id = 145;

EMPLOYEE_ID FIRST_NAME           LAST_NAME                 EMAIL
----------- -------------------- ------------------------- -------------------------
PHONE_NUMBER         HIRE_DATE JOB_ID         SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
-------------------- --------- ---------- ---------- -------------- ---------- -------------
        145 John                 Russell                   JRUSSEL
011.44.1344.429268   01-OCT-04 SA_MAN           1000             .4        100            80




4. hr.employees 테이블에 있는 데이터 중에  최저 commission 값을 가지고 있는 사원 정보들 중에 관리자 148 부하 직원들에 대해서 조회하세요.
SYS@orcl2> select *
           from hr.employees
           where commission_pct=(select min(commission_pct)
                                 from hr.employees)
           and manager_id = 148 ;


EMPLOYEE_ID FIRST_NAME           LAST_NAME                 EMAIL
----------- -------------------- ------------------------- -------------------------
PHONE_NUMBER         HIRE_DATE JOB_ID         SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
-------------------- --------- ---------- ---------- -------------- ---------- -------------
        173 Sundita              Kumar                     SKUMAR
011.44.1343.329268   21-APR-08 SA_REP           6100             .1        148            80


5. 3번 수정을 잘못 했습니다. 이전값을 확인해 주세요. flashback query을 이용해서 확인 해주세요.
SYS@orcl2> select employee_id, last_name, salary
           from hr.employees as of timestamp to_timestamp('26-APR-19 09.51.35', 'DD-MON-RR HH24.MI.SS')
           where employee_id=145;

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        145 Russell                        14000
-- 이 시점의 데이터를 확인 할 수 있다.


SYS@orcl2> select employee_id, last_name, salary
           from hr.employees as of scn 1546398
           where employee_id=145;

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        145 Russell                        14000
-- scn 으로 확인


SYS@orcl2> select employee_id, last_name, salary
           from hr.employees
           as of timestamp localtimestamp - interval '15' minute
           where employee_id=145;
           
EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        145 Russell                        14000


6. 3번 수정을 잘못 했습니다. 이전값과 현재값을 확인해 주세요.flashback version을 이용해서 확인 해주세요.
SYS@orcl2> select employee_id, salary, versions_xid, versions_starttime stime,
           versions_endtime etime
           from hr.employees versions between scn minvalue and maxvalue
           where employee_id=145;
           
EMPLOYEE_ID     SALARY VERSIONS_XID     STIME                     ETIME
----------- ---------- ---------------- ------------------------- ------------------------
        145       1000 01000D0035020000 26-APR-19 10.00.27 AM
        145      14000                                            26-APR-19 10.00.27 AM


7. flashback table을 이용하여 이전 값으로 바꿔주세요.
SYS@orcl2> flashback table hr.employees to scn 1546398;
flashback table hr.employees to scn 1546398
                   *
ERROR at line 1:
ORA-08189: cannot flashback the table because row movement is not enabled


SYS@orcl2> alter table hr.employees enable row movement;
Table altered.


SYS@orcl2> flashback table hr.employees to scn 1546398;
Flashback complete.


SYS@orcl2> select employee_id, last_name, salary from hr.employees where employee_id = 145;

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        145 Russell                        14000