PDB 이동 전후 백업과 복구
PDB 이동 전 preplugin 백업을 이용한 복구와 relocate 절차, 이동 후 새 백업이 필요한 이유
#핵심 요약
PDB를 다른 CDB로 옮기면 이전 CDB에서 받은 백업은 새 CDB의 일반 백업으로 보이지 않음
새 CDB에서 RESTORE PLUGGABLE DATABASE만 하면 쓸 백업이 없음
이전 백업은 preplugin 백업으로 씀SET PREPLUGIN CONTAINER, CATALOG PREPLUGIN ARCHIVELOG로 이전 CDB의 백업과 아카이브 로그를 등록한 뒤 RESTORE/RECOVER ... FROM PREPLUGIN, 이어서 일반 RECOVER PLUGGABLE DATABASE를 함
relocate는 대상 CDB 루트에서 DB 링크로 소스 PDB를 복사하고, 대상에서 여는 순간 남은 변경을 맞춘 뒤 소스 PDB를 없앰
중단은 여는 순간뿐이고 GUID가 그대로임
DUPLICATE PLUGGABLE DATABASE는 소스 PDB를 열어 둔 채 다른 CDB에 사본을 하나 더 만듦(18c부터)
옮기는 것이 아니라 개발, 테스트용 사본이나 장애 재현 환경을 만들 때 씀
어느 방법이든 옮긴 뒤에는 새 CDB에서 바로 백업함
그래야 이후 복구가 단순함
#개념과 동작 원리
| 방법 | 중단 | 결과 PDB | 이동 전 백업 |
|---|---|---|---|
| unplug/plug | 언플러그부터 플러그까지 | 같은 PDB | 새 CDB에서 preplugin 백업으로 사용 |
| relocate | 대상에서 여는 순간 | 같은 PDB, GUID 그대로 | 새 CDB 컨트롤 파일이 인식하지 못함 |
| duplicate | 없음(소스 PDB는 열린 채 복제) | 이름이 다른 사본, GUID, DBID 다름 | 관계없음(소스는 그대로 남음) |
세 방법을 쉽게 기억하면 unplug/plug는 문 닫고 이사, duplicate는 가게 하나 더 복제, relocate는 영업하면서 이사임
relocate는 시간이 오래 걸리는 데이터 복사를 서비스 중에 미리 해 두고 마지막 전환 구간에만 중단이 생김
복사 과정을 쓰지만 사본을 하나 더 만드는 것이 아니라 소스 PDB를 다른 CDB로 옮기는 것임(12.2부터)
| relocate 준비물 | 이유 |
|---|---|
| 소스, 대상 CDB 모두 ARCHIVELOG 모드, 로컬 UNDO | 소스를 연 채 복사하므로 복사 중 변경을 리두로 맞춰야 함 |
소스 CDB의 공통 사용자(CREATE PLUGGABLE DATABASE, SYSOPER) |
DB 링크가 접속할 계정 relocate는 소스 PDB를 닫고 지워야 해서 SYSOPER가 필요함 |
| 대상 CDB 루트의 DB 링크 | 대상이 소스에 접속해 데이터 파일과 리두를 끌어오는 통로 |
| 같은 버전, 패치, 같은 문자 집합 | 다르면 옮긴 PDB가 열리지 않음 |
백업 기록은 백업을 받은 CDB의 컨트롤 파일에 남으므로, 옮긴 뒤 새 CDB에서 평소처럼 RESTORE PLUGGABLE DATABASE를 하면 백업이 없다고 나옴
언플러그할 때 백업 메타데이터는 PDB 안에 자동으로 내보내지지만, 백업 파일과 아카이브 로그 파일은 대상 서버에서 같은 경로로 읽을 수 있어야 함(실습은 같은 서버의 두 CDB라 자연히 만족함)
| preplugin 단계 | 명령(대상 CDB 루트) |
|---|---|
| 대상 PDB 지정 | SET PREPLUGIN CONTAINER = <PDB_NAME>; |
| 옮기기 전 아카이브 등록 | CATALOG PREPLUGIN ARCHIVELOG '<ARCHIVELOG_FILE>'; |
| 확인 | LIST PREPLUGIN BACKUP;, LIST PREPLUGIN ARCHIVELOG ALL; |
| 옮기기 전 백업으로 복원 | RESTORE PLUGGABLE DATABASE <PDB_NAME> FROM PREPLUGIN; |
| 옮기기 전 구간 복구 | RECOVER PLUGGABLE DATABASE <PDB_NAME> FROM PREPLUGIN; |
| 옮긴 뒤 구간 복구 | RECOVER PLUGGABLE DATABASE <PDB_NAME>; |
실습 환경의 빈 대상 CDB는 같은 Oracle Home에서 dbca -silent -createDatabase에 -createAsContainerDatabase true -numberOfPDBs 0 -enableArchive true를 주어 만들었음(명령 전체는 DBCA 무인 생성 참고)
설명: preplugin 복구는 두 구간의 리두를 차례로 적용함
백업 뒤부터 언플러그 직전까지는 이전 CDB의 아카이브 로그로(FROM PREPLUGIN), 플러그 뒤부터는 현재 CDB의 리두와 아카이브 로그로(일반 RECOVER) 복구함
이전 CDB: PDB 백업 → 변경(A) → 언플러그(ARCHIVE LOG CURRENT)
현재 CDB: 플러그 → 변경(B) → 데이터 파일 장애
복구: RESTORE FROM PREPLUGIN → RECOVER FROM PREPLUGIN(A까지) → RECOVER(B까지) → OPEN#필수 명령어 또는 SQL
#preplugin 백업으로 복구
이전 CDB에서 PDB를 백업하고, 백업 뒤 변경을 만듦
BACKUP PLUGGABLE DATABASE <PDB_NAME> PLUS ARCHIVELOG;결과 해석:
설명: 백업 뒤 넣은 행은 백업에 없으므로 복구 때 아카이브 로그를 적용해야 들어옴
실습의 확인용 INSERT는 열 두 개짜리 실습 테이블 기준이어서, 일반 SCOTT.EMP 구조에는 그대로 실행할 수 없음
언플러그하고 마지막 변경을 아카이브 로그로 남김
ALTER PLUGGABLE DATABASE <PDB_NAME> CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE <PDB_NAME> UNPLUG INTO '<XML_FILE>';
DROP PLUGGABLE DATABASE <PDB_NAME> KEEP DATAFILES;
ALTER SYSTEM ARCHIVE LOG CURRENT;SELECT sequence#, name FROM v$archived_log
WHERE first_time > SYSDATE - 1/24 ORDER BY sequence#;결과 해석:
설명: KEEP DATAFILES라 데이터 파일은 남음ARCHIVE LOG CURRENT로 언플러그 직전까지의 변경을 아카이브 로그로 남겨야 나중에 preplugin 복구에 쓸 수 있음
백업 뒤부터 이 시점까지의 아카이브 로그 경로를 기록해 둠
대상 CDB에 플러그함
SET SERVEROUTPUT ON
DECLARE
ok BOOLEAN;
BEGIN
ok := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(
pdb_descr_file => '<XML_FILE>',
pdb_name => '<PDB_NAME>');
DBMS_OUTPUT.PUT_LINE(CASE WHEN ok THEN 'YES' ELSE 'NO' END);
END;
/
SELECT message FROM pdb_plug_in_violations WHERE status <> 'RESOLVED';결과 해석:
설명: 정상이면 YES임
NO면 PDB_PLUG_IN_VIOLATIONS에서 원인을 봄
CREATE PLUGGABLE DATABASE <PDB_NAME> USING '<XML_FILE>' NOCOPY TEMPFILE REUSE;
ALTER PLUGGABLE DATABASE <PDB_NAME> OPEN;
ALTER PLUGGABLE DATABASE <PDB_NAME> SAVE STATE;결과 해석:
설명: NOCOPY라 데이터 파일을 복사하지 않고 원래 위치의 파일을 그대로 씀
실습에서는 이어서 플러그 뒤 변경을 하나 더 만들고 로그 스위치를 했음
장애가 나면 일반 복원은 쓸 백업이 없음
LIST BACKUP OF PLUGGABLE DATABASE <PDB_NAME>;결과 해석:
실습 기록: 데이터 파일을 지운 뒤 PDB 열기는 ORA-01157로 실패했고, 현재 CDB에는 그 PDB의 백업이 없었음
설명: 백업이 없는 것이 아니라 이전 CDB에서 만든 백업이어서 preplugin 백업으로 접근해야 함
SET PREPLUGIN CONTAINER = <PDB_NAME>;
LIST PREPLUGIN BACKUP;
CATALOG PREPLUGIN ARCHIVELOG '<ARCHIVELOG_FILE>';
LIST PREPLUGIN ARCHIVELOG ALL;결과 해석:
실습에서는 백업 뒤부터 언플러그 때 ARCHIVE LOG CURRENT까지의 아카이브 로그 네 개를 하나씩 등록했음
실습의 파일 경로 일부는 줄이 끊겨 있어 그대로 실행되지 않음
RESTORE PLUGGABLE DATABASE <PDB_NAME> FROM PREPLUGIN;
RECOVER PLUGGABLE DATABASE <PDB_NAME> FROM PREPLUGIN;
RECOVER PLUGGABLE DATABASE <PDB_NAME>;
ALTER PLUGGABLE DATABASE <PDB_NAME> OPEN;
BACKUP PLUGGABLE DATABASE <PDB_NAME> PLUS ARCHIVELOG;결과 해석:
설명: 첫 RECOVER로 이전 CDB에서 생긴 변경이, 두 번째 RECOVER로 플러그 뒤 현재 CDB에서 생긴 변경이 들어옴
두 변경이 모두 보이면 복구 성공임
조회 출력은 기재 없음
끝나면 현재 CDB 기준으로 새로 백업함
실습에서는 마지막에 PDB를 다시 원래 CDB로 언플러그와 플러그로 되돌리고 BACKUP DATABASE PLUS ARCHIVELOG로 백업했음
CDB 삭제 시 SYS 비밀번호를 명령줄에 쓰면 노출될 수 있음
#relocate로 옮기기
ARCHIVE LOG LIST
SELECT property_value FROM database_properties WHERE property_name = 'LOCAL_UNDO_ENABLED';결과 해석:
설명: 두 CDB 모두 ARCHIVELOG 모드이고 local undo가 TRUE여야 함
19c DBCA로 만들면 기본값이 TRUE이고, FALSE면 relocate를 할 수 없음
CREATE USER c##<USERNAME> IDENTIFIED BY <PASSWORD> CONTAINER = ALL;
GRANT CREATE SESSION, CREATE PLUGGABLE DATABASE, SYSOPER TO c##<USERNAME> CONTAINER = ALL;
SELECT username, sysoper, con_id FROM v$pwfile_users;결과 해석:
설명: SYSOPER는 비밀번호 파일에 기록되므로 V$PWFILE_USERS에서 확인함
양쪽에 다 만드는 것은 나중에 반대 방향으로 되돌리기 위해서임
CREATE DATABASE LINK <LINK_NAME>
CONNECT TO c##<USERNAME> IDENTIFIED BY <PASSWORD> USING '<SOURCE_TNS_ALIAS>';
SELECT * FROM dual@<LINK_NAME>;
CREATE PLUGGABLE DATABASE <PDB_NAME> FROM <PDB_NAME>@<LINK_NAME> RELOCATE
FILE_NAME_CONVERT = ('<SOURCE_DATAFILE_DIR>', '<TARGET_DATAFILE_DIR>');
SHOW PDBS결과 해석:
설명: 이 시점의 대상 PDB는 MOUNTED이고 데이터 파일 복사만 끝난 상태임
소스 PDB는 계속 READ WRITE로 서비스함
실습에서는 이 사이에 소스 PDB에 행을 하나 더 넣었음
ALTER PLUGGABLE DATABASE <PDB_NAME> OPEN;결과 해석:
설명: 여는 순간 복사 뒤 실습의 변경을 리두로 가져와 맞추고, 소스 PDB는 닫히고 삭제됨
이 짧은 순간이 유일한 중단임
SELECT file#, name FROM v$datafile;
SELECT name, guid FROM v$pdbs;결과 해석:
실습 기록: 소스 CDB의 SHOW PDBS에서 PDB가 사라졌고, 대상에서 확인용 행 두 건이 모두 있었으며, 데이터 파일은 대상 경로, GUID는 옮기기 전과 같았음
설명: TNS 별칭이 서비스 이름으로 접속하면, 같은 리스너에 서비스가 다시 등록되어 같은 별칭으로 대상 CDB에 접속됨
BACKUP PLUGGABLE DATABASE <PDB_NAME>;결과 해석:
설명: 옮기기 전 백업 기록은 새 CDB의 컨트롤 파일이 인식하지 못하므로 이관 뒤 바로 백업함
실습에서는 반대 방향 DB 링크로 같은 relocate를 한 번 더 해 원래 CDB로 되돌리고 백업했음
확인용 테이블과 DB 링크는 정리함
#duplicate로 PDB 사본 만들기
| 준비물 | 이유 |
|---|---|
| 소스, 대상 CDB 모두 OPEN, ARCHIVELOG 모드 | 소스를 연 채 복사하므로 복사 중 변경분을 아카이브 로그로 맞춰야 함 |
| 두 CDB의 TNS 별칭 | RMAN이 소스(target)와 대상(auxiliary)에 동시에 원격 SYSDBA로 접속 |
| 같은 SYS 비밀번호(패스워드 파일) | 원격 SYSDBA 접속 |
대상 CDB의 REMOTE_RECOVERY_FILE_DEST |
소스에서 가져온 아카이브 로그를 대상 쪽에 잠시 둘 위치 없으면 duplicate가 시작하자마자 실패함 |
| 같은 버전, 패치, 같은 문자 집합 | 다르면 사본 PDB가 열리지 않음 |
tnsping <SOURCE_CDB>
tnsping <TARGET_CDB>
sqlplus sys@<SOURCE_CDB> as sysdba
sqlplus sys@<TARGET_CDB> as sysdba결과 해석:
접속이 안 되면 lsnrctl status에 대상 CDB 서비스가 있는지 보고, 없으면 대상 CDB에서 ALTER SYSTEM REGISTER를 실행함
그래도 안 되면 LOCAL_LISTENER를 (ADDRESS=(PROTOCOL=TCP)(HOST=<HOST>)(PORT=<PORT>))로 정적으로 지정함
ALTER SYSTEM SET remote_recovery_file_dest = '<REMOTE_ARCH_DIR>' SCOPE = BOTH;
SHOW PARAMETER remote_recovery_file_destrman target sys@<SOURCE_CDB> auxiliary sys@<TARGET_CDB>DUPLICATE PLUGGABLE DATABASE <PDB_NAME> AS <NEW_PDB_NAME> TO <TARGET_CDB>
FROM ACTIVE DATABASE
DB_FILE_NAME_CONVERT = ('<SOURCE_PDB_DIR>/', '<TARGET_PDB_DIR>/');결과 해석:
진행 순서: 소스 데이터 파일 복사, 아카이브 로그 적용, 새 PDB 생성, 열기 순서로 출력이 길게 나옴
그동안 소스 PDB는 계속 서비스됨
결과 확인: 대상 CDB에서 SHOW PDBS로 새 PDB가 READ WRITE인지, SELECT file#, name FROM v$datafile로 대상 경로인지 확인함
SELECT name, dbid, guid FROM v$pdbs;결과 해석: 사본은 GUID와 DBID가 소스와 달라 연결이 끊긴 별개의 PDB임
실습 기록에서 복제 뒤 소스에 넣은 행은 사본에 나타나지 않았음
사본에서 무엇을 해도 운영 PDB에는 영향이 없음
ALTER PLUGGABLE DATABASE <NEW_PDB_NAME> CLOSE IMMEDIATE;
DROP PLUGGABLE DATABASE <NEW_PDB_NAME> INCLUDING DATAFILES;결과 해석:
실습 사본을 정리할 때만 씀INCLUDING DATAFILES는 사본의 데이터 파일까지 지움
#사용 조건과 주의사항
preplugin 복구에는 이전 CDB에서 백업 뒤부터 언플러그 직전까지의 아카이브 로그가 모두 있어야 함
실습에서는 DB 링크 계정과 샘플 계정의 비밀번호를 명령에 적었음
일부 절차의 백업 단계와 확인 단계 번호가 맞지 않아 실제 실행 순서는 확인 불가