데이터베이스 연구실.log

데이터베이스 전체 이행

FULL 이행과 SQLFILE, 파일 매핑, 기존 테이블 처리 조건이며 파일, 건수 대조와 최종 재수행 결과는 확인 불가

FULL=YSQLFILEREMAP_DATAFILETABLE_EXISTS_ACTIONORA-39151FULL

#핵심 요약

FULL=Y는 Data Pump가 지원하는 전체 범위의 논리적 이행이며 OS 설정과 Oracle 관리 스키마 전체를 복제하는 방식은 아님

SQLFILE로 적용 예정 DDL을 먼저 검토하고 실제 Import 후 오류, 건너뛴 테이블, 객체 상태, 데이터를 확인함

이행 뒤 Import 로그의 ORA 오류, 사용자 설정, 권한, INVALID 객체, 테이블별 실제 행 수를 차례로 확인함

#개념과 동작 원리

순서 실습의 확인 내용
접속, 환경 소스, 타깃의 ORACLE_HOME, SID, PATH, DB 버전, non-CDB 여부, 열림 상태, 문자셋, 타임존 파일, 구성 요소
범위, 공간 사용자, 테이블스페이스, 데이터 파일, 세그먼트 용량, 소스 덤프 공간과 타깃 덤프, 데이터, TEMP 공간
계정, DIRECTORY 양쪽 OS 경로, DIRECTORY, 파일 권한, 일반 전용 계정의 접속, 작업 테이블, Quota와 Export/Import 전체 역할
Export FULL, ESTIMATE_ONLY, FLASHBACK_TIME=SYSTIMESTAMP, LOGTIME, METRICS 사용과 로그 확인
전송 파일 크기, SHA-256 비교, 실제 비교값은 확인 불가
사전 DDL SQLFILE로 테이블스페이스, 파일 경로, DIRECTORY, 사용자 기본 저장 위치 검토
경로 매핑 REMAP_DATAFILE로 실제 원래 파일과 타깃 파일 경로를 대응하고 SQLFILE 재생성 후 검토
Import 후 ORA 오류, 기존 테이블 건너뜀, 사용자 설정, 권한, INVALID, 실제 행수 비교

SQLFILE은 예정 DDL을 파일로 출력하며 DDL 실행과 데이터 적재를 하지 않는다고 수업 자료에 설명되어 있음
FLASHBACK_TIME에 필요한 과거 데이터가 UNDO에 남아 있지 않으면 Export가 실패할 수 있다는 메모도 있음

#주요 용어와 구성 요소

구문 의미
FULL 이행 논리적 데이터, 메타데이터를 대상으로 하며 Oracle 관리 스키마 중 Export 제외 대상이 있음
DIRECTORY와 PARFILE 덤프, 로그, SQLFILE은 DB 서버의 경로, PARFILE은 impdp 클라이언트가 읽는 파일임

#필수 명령어 또는 SQL

항목 실행 조건
작업 대상 소스, 타깃 환경 조회, FULL 덤프, 전송, DDL 미리보기, 실제 Import와 재컴파일
필요 권한 FULL Export, Import 역할, DIRECTORY READ, WRITE, 서버 OS 경로 권한, 관리 조회, 재컴파일 권한을 단계별로 구분함
바꿀 입력값 덤프, 로그, SQL, parfile 경로, <SOURCE_DATA_DIR>, <TARGET_DATA_DIR>, <SCHEMA1>, <SCHEMA2>, 객체 이름
결과 해석 기존 오류, 뷰 재컴파일 기록만 유지하며 파일 동일성, 최종 데이터 건수와 전체 성공 결과는 확인 불가

#환경과 대상 확인 (양쪽)

SQL*Plus (SYSDBA, 소스·타깃)조회만 함
SELECT banner FROM v$version;
SELECT name, cdb, open_mode FROM v$database;
SELECT parameter, value FROM nls_database_parameters
 WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
SELECT filename, version FROM v$timezone_file;
SELECT comp_id, version, status FROM dba_registry ORDER BY comp_id;

SELECT username, default_tablespace, account_status
  FROM dba_users WHERE oracle_maintained = 'N' ORDER BY username;
SELECT owner, ROUND(SUM(bytes)/1024/1024) AS segment_mb
  FROM dba_segments
 WHERE owner IN (SELECT username FROM dba_users WHERE oracle_maintained = 'N')
 GROUP BY owner ORDER BY owner;

결과 해석: CDB = NO, READ WRITE, 양쪽 문자셋이 같은지 보고, 타임존 파일은 일반 Data Pump에서 소스 버전이 타깃보다 높으면 ORA-39405가 남
세그먼트 용량으로 소스 덤프 공간과 타깃 덤프, 데이터 파일, TEMP 공간을 잡음
Full Import는 사용자와 테이블스페이스 생성 DDL도 처리하므로 이행 대상 사용자를 모두 손으로 만들 필요는 없음

SQL*Plus (SYSDBA, 소스·타깃)객체 또는 설정을 변경함
CREATE DIRECTORY dpump_db AS '/home/oracle/dpump_db';
GRANT READ, WRITE ON DIRECTORY dpump_db TO system;

결과 해석: 개별 실행 출력은 기재 없음

#Export와 전송

oracle 계정 셸 (소스)조회만 함
expdp system FULL=Y DIRECTORY=DPUMP_DB ESTIMATE_ONLY=Y LOGFILE=db_full_estimate.log
oracle 계정 셸 (소스)객체 또는 설정을 변경함
expdp system FULL=Y \
  DIRECTORY=DPUMP_DB \
  DUMPFILE=db_full_12c.dmp \
  LOGFILE=db_full_12c_exp.log \
  FLASHBACK_TIME=SYSTIMESTAMP \
  LOGTIME=ALL METRICS=Y
tail -n 40 /home/oracle/dpump_db/db_full_12c_exp.log
sha256sum /home/oracle/dpump_db/db_full_12c.dmp
scp /home/oracle/dpump_db/db_full_12c.dmp oracle@<TARGET_HOST>:/home/oracle/dpump_db/

결과 해석:

옵션 뜻
FULL=Y DB 전체 Export
ESTIMATE_ONLY=Y 파일을 만들지 않고 크기만 추정
FLASHBACK_TIME=SYSTIMESTAMP Export 시작 시점 기준으로 일관되게 추출
LOGTIME=ALL 로그에 시각 표시
METRICS=Y 객체 수와 소요 시간 표시

이행 시간대에 테이블 변경 배포, DROP, TRUNCATE, 파티션 변경이 겹치지 않게 조율함

타깃에서도 sha256sum을 돌려 해시가 같은지 봄

#타깃 사전 검토와 Import

oracle 계정 셸 (타깃)조회만 함
impdp system FULL=Y DIRECTORY=DPUMP_DB DUMPFILE=db_full_12c.dmp \
  SQLFILE=db_full_preview.sql LOGFILE=db_full_preview.log
grep -nE 'CREATE.*TABLESPACE|\.dbf' /home/oracle/dpump_db/db_full_preview.sql
파일 (타깃 /home/oracle/dpump_db/db_full_imp.par)객체 또는 설정을 변경함
FULL=Y
DIRECTORY=DPUMP_DB
DUMPFILE=db_full_12c.dmp
LOGFILE=db_full_19c_imp.log
LOGTIME=ALL
METRICS=Y
REMAP_DATAFILE="'<SOURCE_DATA_DIR>/<FILE>.dbf':'<TARGET_DATA_DIR>/<FILE>.dbf'"
oracle 계정 셸 (타깃)객체 또는 설정을 변경함
impdp system PARFILE=/home/oracle/dpump_db/db_full_imp.par SQLFILE=db_full_preview_final.sql
impdp system PARFILE=/home/oracle/dpump_db/db_full_imp.par
grep -n 'ORA-' /home/oracle/dpump_db/db_full_19c_imp.log

결과 해석:

SQLFILE에서 CREATE TABLESPACE의 데이터 파일, 임시 파일 경로가 타깃에 맞는지, 그 디렉터리와 쓰기 권한, 공간이 있는지, CREATE DIRECTORY 경로가 맞는지 봄
타깃에 없는 업무 테이블스페이스는 Import 중 소스 경로로 만들려 하므로 파일마다 REMAP_DATAFILE로 경로를 바꾸고 SQLFILE을 다시 만들어 반영됐는지 확인함
이미 있는 UNDO, TEMP, USERS는 고치지 않아도 됨

실습 기록: 최종 Import 로그에는 이미 있는 테이블스페이스, 사용자, DIRECTORY의 ORA-31684, SYS 사용자의 ORA-31685(권한 부족), 없는 내부 계정 때문의 ORA-39083, ORA-01918, 내부 객체 ORA-39342, 이미 있는 BANK, SCOTT 테이블의 ORA-39151(TABLE_EXISTS_ACTION=SKIP으로 데이터와 종속 메타데이터를 건너뜀)이 남았음

#오류 조치와 검증

oracle 계정 셸 (타깃)데이터 또는 파일을 삭제함, 되돌릴 수 없음
impdp system DIRECTORY=DPUMP_DB DUMPFILE=db_full_12c.dmp \
  SCHEMAS=<SCHEMA1>,<SCHEMA2> TABLE_EXISTS_ACTION=REPLACE \
  LOGFILE=db_schema_replace.log LOGTIME=ALL METRICS=Y
SQL*Plus (SYSDBA, 소스·타깃)조회만 함
SELECT grantee, privilege, admin_option FROM dba_sys_privs WHERE grantee IN ('<SCHEMA1>', '<SCHEMA2>');
SELECT grantee, owner, table_name, privilege FROM dba_tab_privs WHERE grantee IN ('<SCHEMA1>', '<SCHEMA2>');
SELECT grantee, granted_role, default_role FROM dba_role_privs WHERE grantee IN ('<SCHEMA1>', '<SCHEMA2>');

SELECT owner, object_type, status, COUNT(*) AS cnt
  FROM dba_objects
 WHERE owner IN (SELECT username FROM dba_users WHERE oracle_maintained = 'N')
 GROUP BY owner, object_type, status ORDER BY owner, object_type, status;

SELECT owner, object_name, object_type FROM dba_objects
 WHERE status = 'INVALID'
   AND owner IN (SELECT username FROM dba_users WHERE oracle_maintained = 'N');

SELECT COUNT(*) FROM <OWNER>.<TABLE_NAME>;
타깃 SQL*Plus (SYSDBA)객체 또는 설정을 변경함
ALTER VIEW <OWNER>.<VIEW_NAME> COMPILE;
SHOW ERRORS VIEW <OWNER>.<VIEW_NAME>
@?/rdbms/admin/utlrp.sql

결과 해석:

실습은 ORA-39151을 기존 테이블을 지워도 되는 실습 스키마 두 개로 한정해 TABLE_EXISTS_ACTION=REPLACE로 다시 넣었음

ORA-31684(사용자 이미 있음)는 사용자 생성만 건너뛴 것이라, 기본, 임시 테이블스페이스, Quota, 시스템, 객체 권한, 역할을 소스와 비교함
실습은 비교 뒤 권한을 따로 고치지 않았음

실습에서는 외부 테이블을 쓰는 뷰 하나가 INVALID로 나와 ALTER VIEW ... COMPILE 뒤 VALID가 됐고, 여러 개면 utlrp.sql로 한꺼번에 재컴파일함

버전마다 기본 계정이 달라 전체 계정 수가 같은지만으로 판정하지 않고, 이행 대상 사용자와 객체 종류, 상태별 개수, 테이블별 COUNT(*)로 비교함

#구문과 옵션 설명

구문 의미
SQLFILE 예정 DDL을 기록하며 DB에 실행하거나 데이터를 적재하지 않음
REMAP_DATAFILE DDL의 소스 파일 참조를 타깃 이름으로 바꾸며 DATAPUMP_IMP_FULL_DATABASE가 필요함
TABLE_EXISTS_ACTION 일반 기본값은 SKIP, CONTENT=DATA_ONLY의 기본값은 APPEND임
TRUNCATE와 REPLACE 기존 행 삭제와 테이블 삭제, 재생성의 차이를 구분함

#사용 조건과 주의사항

오류, 상황 실습의 확인 방법
completed with errors 완료 문구만으로 성공 판단하지 않음
ORA-31684 이미 있는 객체 종류, 이름과 업무 대상 충돌 구분
ORA-39083 뒤따르는 실제 오류와 실패 DDL 확인
ORA-39151 기존 테이블 때문에 데이터, 종속 메타데이터가 SKIP되었는지 확인
ORA-01119, ORA-27040 파일 경로, OS 권한, 공간 확인
ORA-39087, ORA-31640 DIRECTORY, DB 권한, 덤프 위치, OS 권한 확인
ORA-00959 테이블스페이스 부재와 앞선 생성 실패 확인
ORA-01555 지정 시점에 필요한 UNDO 확인
ORA-39405 타임존 파일 버전과 해당 19c RU 지원 조건 확인

타임존 버전과 함께 RU별 지원 조건을 확인해야 함

일반 FULL 이행과 TTS의 READ ONLY 설정, 소스 데이터 파일 복사는 별도 절차임

REPLACE로 사용자 권한까지 소스와 동일해지는 것은 아니라는 수업 자료 메모가 있음
사용자 기본, 임시 테이블스페이스, Quota, 역할, 시스템 및 객체 권한을 별도 비교함

수업 자료에는 내부 객체 오류도 남아 있으며 특정 뷰의 최초 INVALID 원인과 최종 재수행 결과는 확인 불가

DIRECTORY의 DB 권한과 서버 OS 파일 권한은 별개임
SQLFILE 생성과 실제 Import의 매개변수가 같아야 사전 검토한 범위와 실제 적용 범위를 비교할 수 있음
REPLACE 대상 범위, 기존 데이터 손실과 최종 로그를 확인하지 못한 상태를 성공으로 판정하지 않음

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기