OS환경 : Oracle Linux6.8(64bit)
DB 환경 : Oracle Database 11.2.0.4 ~ 12cR1
방법 : 로그마이너 log miner 사용법
사전 준비
로그마이너가 있는지 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
SQL> desc dbms_logmnr
PROCEDURE ADD_LOGFILE
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
LOGFILENAME VARCHAR2 IN
OPTIONS BINARY_INTEGER IN DEFAULT
FUNCTION COLUMN_PRESENT RETURNS BINARY_INTEGER
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
SQL_REDO_UNDO NUMBER IN DEFAULT
COLUMN_NAME VARCHAR2 IN DEFAULT
PROCEDURE END_LOGMNR
FUNCTION MINE_VALUE RETURNS VARCHAR2
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
SQL_REDO_UNDO NUMBER IN DEFAULT
COLUMN_NAME VARCHAR2 IN DEFAULT
PROCEDURE REMOVE_LOGFILE
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
LOGFILENAME VARCHAR2 IN
PROCEDURE START_LOGMNR
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
STARTSCN NUMBER IN DEFAULT
ENDSCN NUMBER IN DEFAULT
STARTTIME DATE IN DEFAULT
ENDTIME DATE IN DEFAULT
DICTFILENAME VARCHAR2 IN DEFAULT
OPTIONS BINARY_INTEGER IN DEFAULT
|
default로 설치가 되어 있지 않다면 sysdba 유저로 설치
1
|
SQL> @?/rdbms/admin/dbmslm.sql
|
supplemental logging 기능 상태 확인
1
2
3
4
5
|
SQL> select supplemental_log_data_min from v$database;
SUPPLEMENTAL_LOG
----------------
NO
|
supplemental logging 기능 활성화
1
2
3
|
SQL> alter database add supplemental log data;
Database altered.
|
supplemental logging 기능 상태 재확인
1
2
3
4
5
|
SQL> select supplemental_log_data_min from v$database;
SUPPLEMENTAL_LOG
----------------
YES
|
장애상황
scott계정에서 emp2 테이블의 모든 empno를 1000으로 변경
update 구문 실행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
SQL> conn scott/tiger
update emp2 set empno=1000;
commit;
select * from emp2;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
1000 KING PRESIDENT (null) 17-NOV-81 5000 (null) 10
1000 BLAKE MANAGER 7839 01-MAY-81 2850 (null) 30
1000 CLARK MANAGER 7839 09-JUN-81 2450 (null) 10
1000 JONES MANAGER 7839 02-APR-81 2975 (null) 20
1000 SCOTT ANALYST 7566 19-APR-87 3000 (null) 20
1000 FORD ANALYST 7566 03-DEC-81 3000 (null) 20
1000 SMITH CLERK 7902 17-DEC-80 800 (null) 20
1000 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
1000 WARD SALESMAN 7698 22-FEB-81 1250 500 30
1000 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
1000 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
1000 ADAMS CLERK 7788 23-MAY-87 1100 (null) 20
1000 JAMES CLERK 7698 03-DEC-81 950 (null) 30
1000 MILLER CLERK 7782 23-JAN-82 1300 (null) 10
|
모든 empno가 1000으로 변경됨
해결방법
경로 생성
1
|
$ mkdir -p /home/oracle/logmnr
|
파라미터 파일에 utl_file_dir 파라미터 추가
1
2
3
4
5
6
7
8
|
$ vi initORCL.ora
.
.
*.open_cursors=300
*.processes=150
*.remote_listener='prsjedb-scan:1521'
*.remote_login_passwordfile='exclusive'
utl_file_dir='/home/oracle/logmnr'
|
제일 아래에 utl_file_dir='/home/oracle/logmnr' 입력
db 재기동
1
2
3
4
5
6
7
8
9
10
11
12
|
SQL> shutdown immediate
SQL> startup pfile=$ORACLE_HOME/dbs/initORCL.ora
ORACLE instance started.
Total System Global Area 830930944 bytes
Fixed Size 2257800 bytes
Variable Size 557845624 bytes
Database Buffers 268435456 bytes
Redo Buffers 2392064 bytes
Database mounted.
Database opened.
|
utl_file_dir 파라미터 확인
1
2
3
4
5
|
SQL> show parameter utl_file_dir
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
utl_file_dir string /home/oracle/logmnr
|
리두로그 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SQL>
col member for a30
select a.sequence#, a.group#, a.status, a.members, b.status, b.type, b.member
from v$log a , v$logfile b
where a.group#=b.group#
order by a.group# asc, a.sequence# asc;
SEQUENCE# GROUP# STATUS MEMBERS STATUS TYPE MEMBER
---------- ---------- ---------------- ---------- ------- ------- ------------------------------
289 1 INACTIVE 1 (null) ONLINE /dev/raw/raw12
290 2 INACTIVE 1 (null) ONLINE /dev/raw/raw13
291 3 CURRENT 1 (null) ONLINE /dev/raw/raw14
229 4 INACTIVE 1 (null) ONLINE /dev/raw/raw15
230 5 CURRENT 1 (null) ONLINE /dev/raw/raw16
228 6 INACTIVE 1 (null) ONLINE /dev/raw/raw17
|
딕셔너리 파일을 생성
1
|
SQL> exec dbms_logmnr_d.build ('logmnrdict.ora','/home/oracle/logmnr');
|
분석 할 로그 파일을 등록(update 실행 시간을 모른다면 모든 redo, 아카이브 확인)
1
2
3
4
5
6
7
|
SQL>
exec dbms_logmnr.add_logfile('/dev/raw/raw12',1);
exec dbms_logmnr.add_logfile('/dev/raw/raw13',3);
exec dbms_logmnr.add_logfile('/dev/raw/raw14',3);
exec dbms_logmnr.add_logfile('/dev/raw/raw15',3);
exec dbms_logmnr.add_logfile('/dev/raw/raw16',3);
exec dbms_logmnr.add_logfile('/dev/raw/raw17',3);
|
숫자 의미 : 1: 신규등록, 2: 파일 삭제, 3: 추가등록
(아카이브 로그파일을 넣어도됨)
등록한 log 파일을 분석
1
|
SQL> exec dbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/logmnr/logmnrdict.ora');
|
※ 분석 범위 설정 옵션
startscn (기본값 : 0)
endscn (기본값 : 0)
starttime (기본값 : 01-JAN-1988)
endtime (기본값 : 01-JAN-2988)
dictfilename (기본값 : null)
Options (기본값 : 0)
조회(한번에 여러개 파일을 확인하면 속도가 느림)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
SQL>
set line 200
col timestamp for a20
col seg_owner for a10
col username for a10
col sql_redo for a120
col sql_undo for a120
select to_char(timestamp,'YYYY-MM-DD:HH24:MI:SS'), seg_owner, username, sql_redo, sql_undo
from v$logmnr_contents
where sql_redo like '%update%'
and seg_owner='SCOTT';
TO_CHAR(TIMESTAMP,' SEG_OWNER USERNAME SQL_REDO SQL_UNDO
------------------- ---------- ---------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7839' and ROWID = 'AAADtqAAGAAAJkzAAA'; update "SCOTT"."EMP2" set "EMPNO" = '7839' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAA';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7698' and ROWID = 'AAADtqAAGAAAJkzAAB'; update "SCOTT"."EMP2" set "EMPNO" = '7698' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAB';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7782' and ROWID = 'AAADtqAAGAAAJkzAAC'; update "SCOTT"."EMP2" set "EMPNO" = '7782' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAC';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7566' and ROWID = 'AAADtqAAGAAAJkzAAD'; update "SCOTT"."EMP2" set "EMPNO" = '7566' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAD';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7788' and ROWID = 'AAADtqAAGAAAJkzAAE'; update "SCOTT"."EMP2" set "EMPNO" = '7788' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAE';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7902' and ROWID = 'AAADtqAAGAAAJkzAAF'; update "SCOTT"."EMP2" set "EMPNO" = '7902' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAF';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7369' and ROWID = 'AAADtqAAGAAAJkzAAG'; update "SCOTT"."EMP2" set "EMPNO" = '7369' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAG';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7499' and ROWID = 'AAADtqAAGAAAJkzAAH'; update "SCOTT"."EMP2" set "EMPNO" = '7499' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAH';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7521' and ROWID = 'AAADtqAAGAAAJkzAAI'; update "SCOTT"."EMP2" set "EMPNO" = '7521' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAI';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7654' and ROWID = 'AAADtqAAGAAAJkzAAJ'; update "SCOTT"."EMP2" set "EMPNO" = '7654' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAJ';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7844' and ROWID = 'AAADtqAAGAAAJkzAAK'; update "SCOTT"."EMP2" set "EMPNO" = '7844' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAK';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7876' and ROWID = 'AAADtqAAGAAAJkzAAL'; update "SCOTT"."EMP2" set "EMPNO" = '7876' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAL';
2019-01-15:14:27:27 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7934' and ROWID = 'AAADtqAAGAAAJkzAAN'; update "SCOTT"."EMP2" set "EMPNO" = '7934' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAN';
|
실수로 update 한 구문(SQL_REDO)과 되돌릴수 있는 구문(SQL_UNDO)이 나옴
바로 안나온다면 분석할 로그파일을 바꿔가며 확인
해당 SQL_UNDO를 복사 후 붙여넣기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SQL>
update "SCOTT"."EMP2" set "EMPNO" = '7839' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAA';
update "SCOTT"."EMP2" set "EMPNO" = '7698' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAB';
update "SCOTT"."EMP2" set "EMPNO" = '7782' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAC';
update "SCOTT"."EMP2" set "EMPNO" = '7566' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAD';
update "SCOTT"."EMP2" set "EMPNO" = '7788' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAE';
update "SCOTT"."EMP2" set "EMPNO" = '7902' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAF';
update "SCOTT"."EMP2" set "EMPNO" = '7369' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAG';
update "SCOTT"."EMP2" set "EMPNO" = '7499' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAH';
update "SCOTT"."EMP2" set "EMPNO" = '7521' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAI';
update "SCOTT"."EMP2" set "EMPNO" = '7654' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAJ';
update "SCOTT"."EMP2" set "EMPNO" = '7844' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAK';
update "SCOTT"."EMP2" set "EMPNO" = '7876' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAL';
update "SCOTT"."EMP2" set "EMPNO" = '7934' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAN';
|
확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
SQL> select * from scott.emp2;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7839 KING PRESIDENT (null) 17-NOV-81 5000 (null) 10
7698 BLAKE MANAGER 7839 01-MAY-81 2850 (null) 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 (null) 10
7566 JONES MANAGER 7839 02-APR-81 2975 (null) 20
7788 SCOTT ANALYST 7566 19-APR-87 3000 (null) 20
7902 FORD ANALYST 7566 03-DEC-81 3000 (null) 20
7369 SMITH CLERK 7902 17-DEC-80 800 (null) 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 (null) 20
1000 JAMES CLERK 7698 03-DEC-81 950 (null) 30
7934 MILLER CLERK 7782 23-JAN-82 1300 (null) 10
|
기존 상태대로 변경됨
제대로 적용 됬다면 커밋
1
|
SQL> commit;
|
로그 마이너 중지
1
|
SQL> exec dbms_logmnr.end_logmnr();
|
복구완료
sqlplus 에서 작업해서 조금 복잡한데 오렌지나 유료 프로그램을 사용하면 편리하게 로그마이너를 사용할 수 있음
리두로그 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SQL>
col member for a30
select a.sequence#, a.group#, a.status, a.members, b.status, b.type, b.member
from v$log a , v$logfile b
where a.group#=b.group#
order by a.group# asc, a.sequence# asc;
SEQUENCE# GROUP# STATUS MEMBERS STATUS TYPE MEMBER
---------- ---------- ---------------- ---------- ------- ------- ------------------------------
289 1 INACTIVE 1 (null) ONLINE /dev/raw/raw12
290 2 INACTIVE 1 (null) ONLINE /dev/raw/raw13
291 3 CURRENT 1 (null) ONLINE /dev/raw/raw14
229 4 INACTIVE 1 (null) ONLINE /dev/raw/raw15
230 5 CURRENT 1 (null) ONLINE /dev/raw/raw16
228 6 INACTIVE 1 (null) ONLINE /dev/raw/raw17
|
분석 할 로그 파일을 등록(update 실행 시간을 모른다면 모든 redo, 아카이브 확인)
1
2
3
4
5
6
7
|
SQL>
exec dbms_logmnr.add_logfile('/dev/raw/raw12',1);
exec dbms_logmnr.add_logfile('/dev/raw/raw13',3);
exec dbms_logmnr.add_logfile('/dev/raw/raw14',3);
exec dbms_logmnr.add_logfile('/dev/raw/raw15',3);
exec dbms_logmnr.add_logfile('/dev/raw/raw16',3);
exec dbms_logmnr.add_logfile('/dev/raw/raw17',3);
|
숫자 의미 : 1: 신규등록, 2: 파일 삭제, 3: 추가등록
(아카이브 로그파일을 넣어도됨)
등록한 log 파일을 분석
1
|
SQL> exec dbms_logmnr.start_logmnr(options => dbms_logmnr.dict_from_online_catalog);
|
현재 운영중인 데이터베이스의 dictionary를 참조하게 할 수 있음
하지만 redo log file이 생성될 시점과 현재의 dictionary는 서로 다를 수 있다는 점을 고려해야함
또한 이 모드로는 'DDL tracking'을 사용할 수 없음
이 모드를 사용할 때는 DBMS_LOGMNR_D.BUILD의 과정이 필요없음
조회(한번에 여러개 파일을 확인하면 속도가 느림)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
SQL>
set line 200
col timestamp for a20
col seg_owner for a10
col username for a10
col sql_redo for a120
col sql_undo for a120
select to_char(timestamp,'YYYY-MM-DD:HH24:MI:SS'), seg_owner, username, sql_redo, sql_undo
from v$logmnr_contents
where sql_redo like '%update%'
and seg_owner='SCOTT';
TO_CHAR(TIMESTAMP,' SEG_OWNER USERNAME SQL_REDO SQL_UNDO
------------------- ---------- ---------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7839' and ROWID = 'AAADtqAAGAAAJkzAAA'; update "SCOTT"."EMP2" set "EMPNO" = '7839' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAA';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7698' and ROWID = 'AAADtqAAGAAAJkzAAB'; update "SCOTT"."EMP2" set "EMPNO" = '7698' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAB';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7782' and ROWID = 'AAADtqAAGAAAJkzAAC'; update "SCOTT"."EMP2" set "EMPNO" = '7782' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAC';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7566' and ROWID = 'AAADtqAAGAAAJkzAAD'; update "SCOTT"."EMP2" set "EMPNO" = '7566' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAD';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7788' and ROWID = 'AAADtqAAGAAAJkzAAE'; update "SCOTT"."EMP2" set "EMPNO" = '7788' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAE';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7902' and ROWID = 'AAADtqAAGAAAJkzAAF'; update "SCOTT"."EMP2" set "EMPNO" = '7902' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAF';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7369' and ROWID = 'AAADtqAAGAAAJkzAAG'; update "SCOTT"."EMP2" set "EMPNO" = '7369' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAG';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7499' and ROWID = 'AAADtqAAGAAAJkzAAH'; update "SCOTT"."EMP2" set "EMPNO" = '7499' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAH';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7521' and ROWID = 'AAADtqAAGAAAJkzAAI'; update "SCOTT"."EMP2" set "EMPNO" = '7521' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAI';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7654' and ROWID = 'AAADtqAAGAAAJkzAAJ'; update "SCOTT"."EMP2" set "EMPNO" = '7654' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAJ';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7844' and ROWID = 'AAADtqAAGAAAJkzAAK'; update "SCOTT"."EMP2" set "EMPNO" = '7844' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAK';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7876' and ROWID = 'AAADtqAAGAAAJkzAAL'; update "SCOTT"."EMP2" set "EMPNO" = '7876' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAL';
2019-01-17:13:38:37 SCOTT UNKNOWN update "SCOTT"."EMP2" set "EMPNO" = '1000' where "EMPNO" = '7934' and ROWID = 'AAADtqAAGAAAJkzAAN'; update "SCOTT"."EMP2" set "EMPNO" = '7934' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAN';
|
실수로 update 한 구문(SQL_REDO)과 되돌릴수 있는 구문(SQL_UNDO)이 나옴
바로 안나온다면 분석할 로그파일을 바꿔가며 확인
해당 SQL_UNDO를 복사 후 붙여넣기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SQL>
update "SCOTT"."EMP2" set "EMPNO" = '7839' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAA';
update "SCOTT"."EMP2" set "EMPNO" = '7698' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAB';
update "SCOTT"."EMP2" set "EMPNO" = '7782' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAC';
update "SCOTT"."EMP2" set "EMPNO" = '7566' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAD';
update "SCOTT"."EMP2" set "EMPNO" = '7788' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAE';
update "SCOTT"."EMP2" set "EMPNO" = '7902' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAF';
update "SCOTT"."EMP2" set "EMPNO" = '7369' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAG';
update "SCOTT"."EMP2" set "EMPNO" = '7499' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAH';
update "SCOTT"."EMP2" set "EMPNO" = '7521' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAI';
update "SCOTT"."EMP2" set "EMPNO" = '7654' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAJ';
update "SCOTT"."EMP2" set "EMPNO" = '7844' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAK';
update "SCOTT"."EMP2" set "EMPNO" = '7876' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAL';
update "SCOTT"."EMP2" set "EMPNO" = '7934' where "EMPNO" = '1000' and ROWID = 'AAADtqAAGAAAJkzAAN';
|
확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
SQL> select * from scott.emp2;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7839 KING PRESIDENT (null) 17-NOV-81 5000 (null) 10
7698 BLAKE MANAGER 7839 01-MAY-81 2850 (null) 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 (null) 10
7566 JONES MANAGER 7839 02-APR-81 2975 (null) 20
7788 SCOTT ANALYST 7566 19-APR-87 3000 (null) 20
7902 FORD ANALYST 7566 03-DEC-81 3000 (null) 20
7369 SMITH CLERK 7902 17-DEC-80 800 (null) 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 (null) 20
1000 JAMES CLERK 7698 03-DEC-81 950 (null) 30
7934 MILLER CLERK 7782 23-JAN-82 1300 (null) 10
|
기존 상태대로 변경됨
제대로 적용 됬다면 커밋
1
|
SQL> commit;
|
로그 마이너 중지
1
|
SQL> exec dbms_logmnr.end_logmnr();
|
복구완료
sqlplus 에서 작업해서 조금 복잡한데 오렌지나 유료 프로그램을 사용하면 편리하게 로그마이너를 사용할 수 있음
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
SQL>
col name for a40
select name,sequence#,to_char(FIRST_TIME,'YYYY/MM/DD HH24:MI:SS') FIRST_TIME, to_char(NEXT_TIME,'YYYY/MM/DD HH24:MI:SS') NEXT_TIME
from v$archived_log
order by 2;
NAME SEQUENCE# FIRST_TIME NEXT_TIME
------------------------------ ---------- ------------------- -------------------
/arch/arc1/1_299_991691191.dbf 299 2019/01/28 00:02:50 2019/01/28 17:36:32
/arch/arc1/1_300_991691191.dbf 300 2019/01/28 17:36:32 2019/01/28 17:36:35
/arch/arc1/1_301_991691191.dbf 301 2019/01/28 17:36:35 2019/01/31 04:07:41
/arch/arc1/1_302_991691191.dbf 302 2019/01/31 04:07:41 2019/01/31 14:24:22
/arch/arc2/1_303_991691191.dbf 303 2019/01/31 14:24:22 2019/01/31 14:37:24
/arch/arc2/1_304_991691191.dbf 304 2019/01/31 14:37:24 2019/01/31 14:37:24
/arch/arc1/1_305_991691191.dbf 305 2019/01/31 14:41:17 2019/02/01 16:19:17
/arch/arc1/1_306_991691191.dbf 306 2019/02/01 16:19:17 2019/02/03 06:00:01
/arch/arc1/1_307_991691191.dbf 307 2019/02/03 06:00:01 2019/02/05 00:19:34
/arch/arc1/1_308_991691191.dbf 308 2019/02/05 00:19:34 2019/02/07 22:00:25
/arch/arc1/1_309_991691191.dbf 309 2019/02/07 22:00:25 2019/02/10 01:00:20
|
+supplemental logging 관련
일반 테이블의 경우 Chained/Migrated Rows 가 있을 경우 log miner 가 불가능함
로그마이너가 안되는 것에 대해서 V$LOGMNR_CONTENTS 뷰의 SQL_UNDO, SQL_REDO 를 확인 시 'Unsupported' 라고 표기됨
Chained/Migrated Rows 에 대해서는 supplemental 걸어야 지원됨
참조 : https://positivemh.tistory.com/424
http://haisins.epac.to/wordpress/?p=2494
https://dinggur.tistory.com/159
https://positivemh.tistory.com/415
https://cafe.naver.com/prodba/47206
https://docs.oracle.com/cd/E11882_01/server.112/e22490/logminer.htm#SUTIL1583
'ORACLE > Admin' 카테고리의 다른 글
ALTER SYSTEM ARCHIVE LOG CURRENT 관련 (0) | 2017.10.18 |
---|---|
OS와 DB간 디스크 관련 팁 (0) | 2017.07.12 |
oracle glogin.sql 설정 (0) | 2017.01.11 |
Oracle ASM (0) | 2016.12.29 |
12c R2 샤딩 (Sharding) 관련 링크 (0) | 2016.11.25 |