Flashback Database
Flashback Database와 보장 복원 지점의 조건, 읽기 전용 검증 및 RESETLOGS로 DB 열기
#핵심 요약
Flashback Database는 플래시백 로그로 데이터 블록의 과거 버전을 가져와 데이터베이스 전체를 과거 시점으로 되감음
백업을 복원하지 않음
미리 플래시백 로그를 켜 두었거나(ALTER DATABASE FLASHBACK ON), 보장 복원 지점을 만들어 두어야 함
미디어 장애 복구용이 아님
데이터 파일이 손상되거나 삭제된 경우, 컨트롤 파일을 복원하거나 다시 만든 시점 이전으로 가는 경우에는 쓸 수 없음
되감은 뒤 OPEN READ ONLY로 내용을 확인하고, 만족하면 OPEN RESETLOGS로 엶
끝나면 새 전체 백업을 받음
#개념과 동작 원리
쓸 수 없는 경우:
- 현재 데이터 파일이 손상되거나 없어진 경우
Flashback Database는 Oracle이 데이터 파일에 한 변경만 되돌림 - 데이터 파일 삭제, 데이터 파일 축소, 데이터베이스 이름 변경을 되돌리려는 경우
- 컨트롤 파일을 복원하거나 다시 만든 시점 이전으로 가려는 경우
그때 쌓인 플래시백 로그 정보가 모두 버려짐 - 호환성(COMPATIBLE) 변경을 되돌리려는 경우
대상 SCN이 플래시백 창 밖이면 ORA-38729로 실패하고 데이터베이스는 바뀌지 않음
FRA 공간 부족으로 플래시백 로그가 지워졌으면 도달하지 못할 수 있음
되감기가 끝나면 데이터베이스는 MOUNT 상태로 남음
RESETLOGS로 열면 대상 SCN 이후의 변경은 버려짐
대신 손상된 객체만 Data Pump로 내보낸 뒤 RECOVER DATABASE로 현재 시점까지 다시 감을 수도 있음
너무 멀리 되감았으면 RECOVER DATABASE UNTIL SCN으로 앞으로 감고, 아예 취소하려면 UNTIL 없는 RECOVER DATABASE로 완전 복구함
CDB 전체나 개별 PDB에 할 수 있지만 루트만 따로 할 수는 없음
#필수 명령어 또는 SQL
#사전 설정과 복원 지점
SELECT flashback_on FROM v$database;SHUTDOWN IMMEDIATE
STARTUP MOUNT
ALTER DATABASE FLASHBACK ON;CREATE RESTORE POINT before_drop GUARANTEE FLASHBACK DATABASE;결과 해석:
실습에서는 중요한 작업 전에 보장 복원 지점을 만들어 두라고 적었음
실습에서는 이 명령을 RMAN 단계로 표시했음
SELECT oldest_flashback_scn, oldest_flashback_time FROM v$flashback_database_log;
SELECT current_scn FROM v$database;
SELECT name, scn, time, database_incarnation#, guarantee_flashback_database
FROM v$restore_point WHERE guarantee_flashback_database = 'YES';결과 해석:
위 조회는 되감을 수 있는 가장 이른 시점과 보장 복원 지점을 확인하는 공식 문서 예시임
#실수 시각 찾기
SELECT first_load_time, last_active_time, parsing_schema_name, sql_text
FROM v$sql
WHERE UPPER(sql_text) LIKE 'DROP USER%'
ORDER BY last_active_time DESC;결과 해석:
실습에서는 패턴을 'DROP USER$'로 적어 와일드카드가 없었음
공유 풀에서 이미 밀려났으면 찾을 수 없음
SET SERVEROUTPUT ON
DECLARE
v_cnt NUMBER;
BEGIN
FOR i IN 1..180 LOOP
EXECUTE IMMEDIATE
'SELECT COUNT(*) FROM dba_users AS OF TIMESTAMP SYSDATE - ' || i ||
'/1440 WHERE username = ''<USERNAME>'''
INTO v_cnt;
IF v_cnt > 0 THEN
DBMS_OUTPUT.PUT_LINE(i || ' 분 전에는 존재 → 그 직후에 DROP');
EXIT;
END IF;
END LOOP;
END;
/결과 해석:
실습 기록: "8 분 전에는 존재"가 나왔음
1분 단위로 거슬러 올라가며 Flashback Query로 사용자가 있었는지 확인하는 방식임
바꿀 입력값: <USERNAME>
#되감기와 확인, 열기
SHUTDOWN IMMEDIATE
STARTUP MOUNTFLASHBACK DATABASE TO TIMESTAMP TO_TIMESTAMP('<YYYY/MM/DD:HH24:MI:SS>', 'RRRR/MM/DD:HH24:MI:SS');
ALTER DATABASE OPEN READ ONLY;
SELECT COUNT(*) FROM dba_users WHERE username = '<USERNAME>';SHUTDOWN IMMEDIATE
STARTUP MOUNT
ALTER DATABASE OPEN RESETLOGS;DROP RESTORE POINT before_drop;BACKUP DATABASE;결과 해석:
공식 문서의 RMAN 형식은 FLASHBACK DATABASE TO SCN <SCN>, FLASHBACK DATABASE TO RESTORE POINT <이름>임
보장 복원 지점은 쓰지 않으면 지움
지우지 않으면 FRA에 플래시백 로그가 계속 쌓이는 것으로 보이나 설명은 기재 없음
#RAC에서 PDB 하나만 되감기
잘못된 배포 뒤 CDB와 다른 PDB는 계속 열어 둔 채 한 PDB만 배포 직전으로 되돌리는 실습
PDB PITR은 백업 데이터 파일을 복원한 뒤 리두를 적용하지만, PDB Flashback은 FRA의 flashback 로그로 현재 파일을 과거로 되돌려 큰 파일을 다시 복원하는 시간을 줄일 수 있음
SHOW PARAMETER db_recovery_file_dest
SELECT log_mode, flashback_on FROM v$database;
SELECT property_value FROM database_properties WHERE property_name = 'LOCAL_UNDO_ENABLED';CREATE RESTORE POINT rp_pdb1 FOR PLUGGABLE DATABASE <PDB_NAME> GUARANTEE FLASHBACK DATABASE;
SELECT con_id, name, guarantee_flashback_database, pdb_restore_point FROM v$restore_point;
-- (실수 재현 뒤)
ALTER PLUGGABLE DATABASE <PDB_NAME> CLOSE IMMEDIATE INSTANCES = ALL;
SELECT inst_id, name, open_mode FROM gv$pdbs WHERE name = '<PDB_NAME>';
FLASHBACK PLUGGABLE DATABASE <PDB_NAME> TO RESTORE POINT rp_pdb1;
ALTER PLUGGABLE DATABASE <PDB_NAME> OPEN RESETLOGS;
ALTER PLUGGABLE DATABASE <PDB_NAME> OPEN INSTANCES = ('<INSTANCE2>');
DROP RESTORE POINT rp_pdb1 FOR PLUGGABLE DATABASE <PDB_NAME>;결과 해석:
전제: CDB ARCHIVELOG, FRA 설정(실습은 +FRA), FLASHBACK_ON = YES(NO면 루트에서 ALTER DATABASE FLASHBACK ON), 로컬 UNDO TRUE
실습 기록: 복원 지점은 CON_ID 3, GUARANTEE_FLASHBACK_DATABASE = YES, PDB_RESTORE_POINT = YES인 PDB 전용으로 만들어졌고, 2번 노드에서 t_bk 1,000건을 TRUNCATE한 뒤 1번 노드에서 되감자 2번 노드에서 다시 1,000건이 보였음
공유 데이터 파일이라 실수를 한 노드와 되감는 노드가 달라도 됨
PDB가 한 노드라도 열려 있으면 ORA-65025로 거부되므로 CLOSE ... INSTANCES = ALL로 모든 노드에서 MOUNTED로 만든 뒤 되감음
CLOSE 때 그 PDB 세션은 끊겨 다시 접속해야 함
OPEN RESETLOGS 뒤 PDB의 새 incarnation은 V$PDB_INCARNATION에서 봄
보장 복원 지점은 쓴 뒤 남겨 두면 flashback 로그가 FRA에 계속 쌓여 아카이브 로그와 백업 공간을 압박하므로 확인 뒤 지움
#복원 지점 없이 시각으로 PDB 되감기 (RAC 2번 노드만 사용)
수업 확인문제: 2번 노드에서 운영 계정을 DROP USER ... CASCADE로 지워 주문 테이블까지 사라졌고 미리 만든 복원 지점은 없음
1번 노드는 다른 업무 중이라 2번 노드에서만 작업함
SELECT event_timestamp, dbusername, action_name, object_name
FROM unified_audit_trail
WHERE action_name = 'DROP USER'
ORDER BY event_timestamp;
ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER SESSION SET nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
SELECT oldest_flashback_time, retention_target FROM v$flashback_database_log;
SELECT inst_id, name, open_mode FROM gv$pdbs WHERE name = '<PDB_NAME>';ALTER PLUGGABLE DATABASE <PDB_NAME> CLOSE IMMEDIATE INSTANCES = ALL;
FLASHBACK PLUGGABLE DATABASE <PDB_NAME>
TO TIMESTAMP TO_TIMESTAMP('<사고 직전 시각>', 'YYYY-MM-DD HH24:MI:SS');
ALTER PLUGGABLE DATABASE <PDB_NAME> OPEN RESETLOGS;
ALTER PLUGGABLE DATABASE <PDB_NAME> OPEN INSTANCES = ALL;
SELECT inst_id, name, open_mode FROM gv$pdbs WHERE name = '<PDB_NAME>';결과 해석:
DROP USER ... CASCADE로 지운 객체는 휴지통에 들어가지 않아 FLASHBACK TABLE ... TO BEFORE DROP으로 살릴 수 없음
사고 시각은 UNIFIED_AUDIT_TRAIL에서 찾고, 기본 감사 정책(ORA_SECURECONFIG)이 꺼져 결과가 없으면 미리 기록해 둔 시각을 씀
되감을 시각은 V$FLASHBACK_DATABASE_LOG.OLDEST_FLASHBACK_TIME보다 뒤여야 함
시각과 SCN의 대응에는 몇 초 오차가 있어 사고 시각보다 조금 앞으로 잡아야 DROP이 다시 포함되지 않음TO SCN으로도 되감을 수 있음
보장 복원 지점과 달리 시각 기준 되감기는 db_flashback_retention_target 안에서 flashback 로그가 남아 있어야만 되며, 범위를 벗어나면 백업 기반 PDB PITR로 감
되감은 시각 이후 그 PDB의 정상 변경도 함께 사라지므로 작업 전에 손실 범위를 먼저 합의함
실행 결과는 확인 불가
예상값: 두 노드 모두 READ WRITE, 계정 복구, 주문 1,000건이 DROP 직전 상태
#사용 조건과 주의사항
RESETLOGS로 열면 되감은 시점 이후의 모든 변경을 잃음
한 테이블만 되돌리면 되는 경우 Flashback 조회와 테이블 복구를 먼저 검토함