'02.Oracle'에 해당되는 글 248건

  1. 2008.11.24 [oracle] 백업 & 복구
  2. 2008.11.24 [oracle] 오라클 기초
  3. 2008.11.24 [oracle] Oracle Backup & Restore
  4. 2008.11.24 [oracle] Recovery Manager 사용 및 RMAN Backup 2
  5. 2008.11.24 Oracle Database 10g: DBA를 위한 20가지 주요 기능
  6. 2008.11.24 [oracle] cold backup & hot backup
  7. 2008.11.21 oracle start, stop, 오라클 시작과 종료
  8. 2008.11.17 [oralce] error code
  9. 2008.11.17 [oralce] ora-00257
  10. 2008.11.10 ORACLE Creating Database Links v1.0
  11. 2008.10.23 아카이브 로그 모드란?
  12. 2008.10.23 os별 오라클 설치 가이드 라인 1
  13. 2008.10.23 데이터베이스 관리 (추천)
  14. 2008.10.23 그리드 컴퓨팅 데이터베이스의 약진 Oracle Database 10g Release 2
  15. 2008.10.23 Oracle Database 11g: DBA와 개발자가 알고 있어야 하는 새로운 기능
  16. 2008.10.23 Windows에서 Oracle 10gR2 EM의 인증서 설정 방법 1
  17. 2008.10.23 오라클이 권장하는 백업방법
  18. 2008.10.23 [오라클 백업툴] Oracle Secure Backup
  19. 2008.10.23 [oracle 백업툴]Oracle용 SnapManager
  20. 2008.10.23 [오라클 온라인 백업툴]오라클 온라인 APM™ 1
  21. 2008.10.22 [오라클] ORA-12560 에러 대처법 && sqlplus 사용안될때(댓글참조) 2
  22. 2008.10.22 Oralce sqlplus 접속안될때
  23. 2008.10.22 오라클 테이블스페이스 만들기
  24. 2008.10.20 오라클 유용한 함수
  25. 2008.09.25 [oracle] 기초
  26. 2008.09.25 [Oracle] SQL Developer
  27. 2008.09.25 테이블조인
  28. 2008.09.01 oracle JDBC Driver Downloads
  29. 2008.08.07 [oracle] 모든테이블의 정보보기
  30. 2008.08.06 [oracle] 자동 startup, 리스너 스타트 1
02.Oracle/DataBase2008. 11. 24. 18:04
반응형

*프로세스 간단설명
DBWR:데이터 버퍼 캐쉬에 존재하는 더티 블럭들을 체크포인트가 발생하는 동시에 데이터 파일로 내려쓰는 기능
   체크포인트 발생하는경우
  1,새로운 데이터 블럭을 데이터 버퍼 캐쉬로 불러들이고자 할때 여유공간이 없는경우
  2,타임아웃이 발생하는 경우 (LOG_CHECKPOINT_TIMEOUT파라미터 설정)
  3,온라인 리두 로그 파일에 기록된 데이터 블럭(operating system block)의 수가 임의의 개수에 도달하는 경우(LOG_CHECKPOINT_INTERVAL 파라미터 설정)
  4.데잍너 베이이스를 종료(closing)할 경우
  5,더티 버퍼의 수가 어느정도의 threshold 값에 도달하는 경우
  6,테이블스페이스가 오프라인이 되는 경우 또는 온라인 백업이 실행되는 경우
  7,alter system checkpoint 명령을 사용하였을경우

LGWR: 사용자가 임의의 트랙잰션(transaction)에 대하여 커밋(commint)을 수행하고 나면 LGWR가 그시점에서의 리두 로그 버퍼에 저장되어있는 모든 리두로그 기록들을 리두 로그 파일로 내려쓰게 된다.(리두로그파일은 어느시점에서 데이터 파일이 손상이 되거나 손실된 경우 문제가 발생한 그 시점까지의 모든 데이터 변경에 관한 정보를 가지고 있으므로 데이터를 복구하는 경우 사용되는 파일)

PMON:오라클을 운용중에 임의의 오라클 프로세스에 문제가 생겨 실패하는 경우 임의의 오라클 프로세스가 사용하고 있던 리소스(resource)를 해제시킴으로 다른 사용자들이 그 리소스를 사용할수 있도록 해주는 기능을 가진다.

SMON:오라클 인스턴스에 문제가 생겨 어느 누구도 오라클 DB 접속할수 없는 상황이 되는 경우 데이터 베이스 버퍼 캐쉬에 아직 데이터 파일로 저장되지 못한 더티 버버(dorty buffer)들에 대해 리두 로그를 사용함으로써 복구가 이루어져야 한다. 인스턴스가 SMON에 의하여 다시 구동되어질때 인스턴스를 복구하는일을 담당.

CKPT: 로그 스위치가 일어나는 동시에 디비라이터는 데이터 버퍼 캐쉬에 존재하는 더티 버퍼들을 이제야 데이터베이스 파일로 내려쓰게 되는데 ,이것을 체크포인트라고 한다. 이때 CKPT는 DBWR로하여금 데이터 파일 헤더 부분에 현재의 상태를 CURRENT라고 기록하고 컨트롤 파일 내부와 데이터 파일 헤더부분에 현재 진행중인 체크포인트에 관한 체크포인트 시퀀스 넘버(sequence number)를 길록한다. 체크포인트 시콘스 넘버는 리두로그 파일,컨트롤파일,그리고 데이터 파일들이 모두 통합되어 있는 상태라는 것을 말해준다. 실제로 이파일들에 저장되어 있는 체크 포인트 시퀀스 넘버들이 어느하나라도 다른경우 데이터 베이이슬 시작할수없구,복구가 요구됨.

ARCH: 아카이버 프로세스는 이미 데이터베이스의 리두 기록들을 저장하고 이쓴ㄴ 리두로그 파일들을 임의의 안전한 외부 기억장치로 저장해주는 역할
>alter database archivelog  <-아카이브 모드로 운용중일때..이역할 수행

데이터 파일: 일반 적으로 binary 파일

리두로그 파일: 임의의 데이터에 대한 변경 이전과 이후의 데이터의 이미지와 그에 관계된 정보를 저장하는 파일로 LGWR에 의해 리두로그 버퍼로부터 내려써지게 된다._.이후 아카이브 백그라운드 프로세스에 의해 아카이브로 보관된다.

컨트롤 파일: 기본적인 오라클 데이터베이스의 물리적인 구조와 상태에 관한 정보를 저장되는 파일,거의 모든 데이터베이스 내부적인 변경사항들이 이곳에 저장되므로 이후에 데이터베이스를 복구하는경우 사용 (컨트롤 파일에 체크포인트와 로그 시퀀스정보가 저장되어있는데 이것은 리두로그파일 컨트롤파일 그로그 데이터 파일)의 통합성 또는 일관성을 보관하는 척도)

아카이브 리두로그 파일
온라인 리두 로그 파일의 복사본으로 아카이브 백그라운드 포그세스(ARCH)에 의해 생성

* 백업으로부터 데이터베이스 파일과 아카이브 리두로그 파일의 복원
#sqlplus '/as sysdba'
>startup mount     <---mount 후 recovery를 실시하게 된다.
>alter database recover   <-init.ora파라미터파일의 log_archive_dest값의 위치로 복원
or >alter database recover database from '/arch';   <-직접경로지정 예
or >recover from '/arch/ database;

*ARCHIVE 모드
>alter system archivelog; <- 아카이브 모드로의 변경
>alter system archivelog stop;  <-archive 프로세스 멈춤
>alter system noarchivelog; <-컨트롤 파일에 현재 데이터베이스의 아카이브 설정을 변경해 줌.

*자동 아카이브설정
>archive log list < -현재 상태 보기 automatic archiveal :disable이면 자동아카이브해제상태
init.ora 에 LOG_ARCHIvE_START=TRUE 후 데이터베이스 재시작
>alter system archive log start to '/opt/oracle/tmp'; <-자동 아카이브 모드설정 명령
>archive log list;  <-확인해 본다.

>select sequence# from v$log; < -현재 설정되어있는 리두로그파일들의 로그 시퀀스넘버확인

*Alter system archive log [옵션들..]
thread: 아카이브되어질 리두 로그 그룹이 해당되는 thread 를 지정하는 경우
sequence :아카이브되어질 리두로그그룹이 가지는 로그 시퀀스 넘버를 지정하는 경우
chance:아카이브되어질 리두로그르룹이 가지는 SCN을 지정하는경우
group:아카이브되어질 리두로그 글부을 지정하는 경우
current:현재 current한 리두 로그 그룹을 아카이브하는 경우
logfile :아카이브할 리두 로그그룹의 파일 이름을 지정하는경우
next:아직 아카이브되어 있지 않았던 가장 오래된 리두 로그 그룹을 아카이브하는 경우
all:모든 아카이브 파일을 아카이브하는 경우
start:자동 아카이브옵션을 실행하는 경우
to:아카이브되는 파일이 정장되는 위치 설정
stop:자동아카이브 옵션을 종료시키는 경우

*v$ARHIVED_LOG
NAME:아카이브 리두로그파일의 위치와이름
SEQUENCE# :각각의 리두로그 파일에 설정된 시퀀스 넘버
ARCHIVED:아카이브 여부
COMPLETION_TIME: 아카이브 시점
>select name,sequence#,archived,completion_time from v$archived_log;
#ls -lrt /arch <--아카이브파일들 확인해라..


[Close 백업과 Open 백업]
*Close 백업 혹은 Cold백업은 DB가 내려가 있는 상태에서 실시
datafile,controlfile,redolog파일들의 위치를 파악후 백업
>select name from v$datafile;
or >select file_name from dba_data_files;
>select name from v$controlfile;
>select member from v$logfile;

*Open 백업 혹은 Hot백업은 DB가 기동되어있는 상태에서 백업
tablespace위치와 datafile위치확인후 백업
>select * from v$tablespace;  
>select name from v$datafile;
>alter tablespace users begin backup;  <-table space를 백업모드로
<-tablespace가 백업모드로 변경되면 그 테이블스페이스 내에 존재하는 데이터 파일의 헤더에 저장되어 있는 로그 시퀀스 넘버는 더이상 변경되지 않는다.그래서 데이터베이스 복구해야하는 경우 이 시점 이후에 발생하게 되는 새로운 트랙잭션들은 로그파일에 의해 복구가능해지는 것임.

백업후
>alter tablespace users end backup;
>alter system switch logfile; <-로그 스위치실행하여 모든데이터 파일 헤더에 저장되어있는 체크포인턴 넘버를 통합시켜준다.

확인방법
>select file#,status,tablespace_name,checkpoint_change#,name from v$datafile_header; <-check point 넘버확인
그리고 >alter tablespace users begin backup; 후 다시한번 checkpoint 넘버확인
<-users라는 테이블스페이스가 백업모드로 전환되면서 작동적으로 로그스위치
그리고 >alter tablespace users end backup; 후
>alter system switch logfile;하고 다시
checkpoint 넘버 확인해보면 모두 일치하는게 확인될것임


* 컨트롤 파일 백업
>alter database backup controlfile to '/arch/backup_controlfile.bkp;
     <-다음과 같은 명령어로 백업실시 binary 파일이다
>alter database backup controlfile to trace;  
    <-init.ora의 user_dump_dest 파라미터값에 위해 udump로 저장된다 ascii 형태로


(*)완전 데이터베이스 복구
**사용자가 임의의 데이터 파일을 삭제해 버린경우 복구방법(데이터베이스 오픈상태에서 복구)
>select filed_id,file_name,talbespace_name,status from dba_data_files;
     <-삭제되어진 데이터 파일이 어느 테이블스페이스인지 확인한다.
>alter database datafile '/database/COM/data/user.dbf' offline  <-offline 상태 만들기
>select file#,status,name from v$datafile;  <-user.dbf 가 status가 recover상태를 확인
>cp /backup/COM/user.dbf /database/COM/data   <-손상된 db파일 복원
>recover datafile '/database/COM/data/user.dbf' <- 복원된 데이타 파일 복구
또는 >recover tablsespace users;   <-user.dbf의 tablespace이름이 users라면..
>alter database datafile'/database/COM/data/user.dbf' online <-다시 online
>select file#,status,tablespace_name,checkpoint_change#,name from v$datafile_header;
<-check point 가 같을 경우 모든 데이터 파일들이 현재 통합되어 있다고 볼수있다.

**사용자가 임의의 데이터 파일을 삭제해 버린경우 복구방법(데이터베이스 오프상태에서 복구)
>cp /backup/COM/system.dbf /database/COM/data <-손상된 시스템 백업본 복사
>sqlplus /nolog
>connect /as sysdba
>startup mount    <--mount 까지만 진행
>recover datafile '/database/COM/data/system.dbf'; <-복구
>alter database open;   <-db open
>select file#,status,tablespace_name,checkpoing_change#,name from v$datafile_header;
    <-check point 확인 같은지

**임의의 디스크가 송상되어 그안의 저장된 데이터 파일을 사용못하는상황(DB오픈상태복구)
>sqlplus /nolog
>connect /as sysdba
>startup mount
>select file#,status,error,tablespae_name from v$datafile_header;  <-테이블스페이스users가 손실 되었을경우  ->tablasespace_name file not found 로 나옴
>alter database datafie '/database/COM/data/user.dbf' offline;
>select file#,status,error,tablespae_name from v$datafile_header;  <-offline 되어있는지확인
그다음 백업으로 user.dbf 파일을 restore한다 디스크 손상가정이므로 다른디스크에 복원
예)/tmp/COM 여긴 다른 디스크라 가정하자..
>alter database rename file '/database/COM/data/user.dbf' to /tmp/COM/user.dbf;
  <-기존 user.dbf 파일의 이름을 복원된 datafile로 이름을 바꿔준다.
>select file#,status,error,tablespae_name from v$datafile_header; <-다시 보면 tabable space확인 가능
>recover datafile '/tmp/COM/user.dbf';   <-복구한다.

>alter database datafie '/tmp/COM/user.dbf' online  <-online후
>select file#,status,error,tablespae_name from v$datafile_header;   <- 상태확인

(*)두개의 리두로그파일 존재시 파일 복구방법
** 손상된 리두 로그파일을 제거하여 재사용하는 방법
>select * from v$logfile; <- 현상태 확인  status <- status 라고 안나오면 비정ㅇ상
#cp /database/COM/redo/log_02.dbf /dtabase/COM/redo/log_01.dbf  <2에서1번으로 카피
>alter database clear unarchived logfile 'database/COM/redo/log_01.dbf';

**리두로그파일 단지 2개일경우 무작정거한후 다시 추가할수 없다. 이때는 다시 리두로그그룹을 추가시켜 해결가능(리두로그파일은 최소한 2개존재해야함)
>select * from v$logfile; <-log_01.dfb 파일 손상확인
>alter database add logfile group3 '/database/COM/redo/log_03.dbf'; <-임시 리두로그추가
>alter database drop logfile group 1; <-로그그룹1번 삭제
>alter database add logfile group1 '/database/COM/redo/log_01.dbf' SIZE 1M;
   <-다시 리두로그 그룹 1을 데이터베이스에 다시 추가
>alter database drop logfile group 3; <-리두로그그룹 3번삭제
>alter database open;  <- db open

(*) 불완전한 데이터베이스 복구
.아카이브리두 로그파일손상
.컨트롤 파일이 손실된경우
.리두 로그 파일이 손실된경우
* 아카이브로그  파일 적용 복구 "cancell' 복구방법
>shutdown
#cp /backup/data/* /database/COM/data  <-db파일 restore
>sqlplus /nolog
>connect /as sysdba
>startup mount
>recover database until cancel;
적용될 아카이브를 하나씩 보여주고
마지막에 적용되지 못할 아카이브파일을 보여주면
cancel 이라 입력하면 그이전까지 복구된다.
>alter database open resetlog; <-db를 resetlogs옵션으로 오픈

*  과거임의의 특정시점까지 데이터 베이스 복구 상황
>shutdown
#cp /backup/data/* /database/COM/data < -db 복구
#sysdba
>startup mount
>recover database until time '2004-02-17:06:42:00';  <-특정시점까지 복구
>alter database open resetlog;

* 임의의 시스템 체인지 넘버 (SCN)시점까지 DB복구
>shutdown
#cp /backup/data/* /database/COM/data < -db 복구
#sysdba
>startup mount
>recover database until scn 16673;
>alter database open resetlog;

* 예전 백업해두웠던 컨트롤파일을 이용복구
>shutdown
#cp /backup/data/* /database/COM/data < -db 복구
#sysdba
>startup mount
>recover dtabase using backup controlfile;
>alter database open resetlogs;

**Export 와 Import
Export:데이터베이스 오브젝트(Table 또는 인덱스)에 대한 논리적백업
Import:export 파일에 저장되어 있는 데이터들을 데이터베이스 내부로 읽어들여 저장할 수 있도록해주는 기능


-대화형 export
#exp
username:com
passwd:****
buffersize: > 4096
file name:> expdat.dmp
user,table:> 2
export grants y/n  >yes
export talbe data y/n > yes
compress extents y/n > yes

-명령어를 제공하는 export
#exp com/*** tables=COM_MSG rows=y file=COM_test_exp.dump

-conventional path =>데이터를 데이터파일로부터 데이터 버퍼캐쉬로 불러들인 후에 그 데이터를 사용자 프로세스로 보내고 결국 마지막으로 파일에 저장되는 방법

-direct path => 데이터 버퍼캐쉬를 통하지 않고 바로 데이터 파일로 부터 데이터를 읽어 들인 후에 바로 사용자 프로세스로 보내어 데이터를 처리(빠르다)

* Export 유틸리티에 사용되는 모드
- Full database mode : sys 스키마 내에 포함되어 있는 오브젝트를 제외한 모든 데이터베이스 오브젝트를 export
   =comleate export:full백업
   =incremental export:증가분 백업
   =cumulative export:마지막으로 실행된 compelte export이후의 증가분 백업)
-tablespace mode
-table mode :임의의 사용자 스키마에 존재하는 임의의 테이블 exort하는경우
-user mode :임의의 사용자 스키마에 존재하는 테이블을 포함하는 모든 오브젝트 export

*Export 유틸리티 실행에서 사용되는 파라미터
.userid:사용자의 오라클 아이디
#exp com/**** tables=COM_MSG

.buffer: Export 과정에서 row를 fetch 하는 경우 요구되는 buffer 크기 설정
#exp com/**** tables=COM_MSG buffer=4096

.file: export된 정보를 저장하게 될 dump 파일
#exp com/**** tables=COM_MSG file= COM_test_exp.dmp

.compress: fragment 된 세그먼트들을 하나의 extent로 compress
#exp com/**** tables=COM_MSG compress=yes file= COM_test_exp.dmp

.rows:데이터 베이스 오브젝트 내에 존재하는 모든 row를 export할때
  #exp com/**** tables=COM_MSG rows=y file= COM_test_exp.dmp

.full: db전체를 export (dba처럼 EXP_FULL_DATABASE)를 가져와야함
#exp dba/**** tables=COM_MSG full=y rows=y file= COM_test_exp.dmp

.owner:사용자모드로 DB를 export하는 경우
#exp com/**** tables=COM_MSG owner=com rows=y file= COM_test_exp.dmp

.tables :테이블 모드로 데이터 베이스를 export하는 경우 사용자 스키마에 포함되는 임의의 테이블 이름 설정
#exp com/**** tables=COM_MSG tables=tb_COM_data,tb_COM_names rows=y file= COM_test_exp.dmp

.indexs :index도 같이 export
.parfile :파일에 있는 파라미터 값으로 실행하는 방법
#vi par_test.par
userid=com/***
tables=TB_COM_SERVICE
rows=y
file=COM_test_exp.dmp
#exp parfile=par_test.par

.help : 설명 (기본은 n)
#exp com/**** tables=COM_MSG rows=y file= COM_test_exp.dmp help=y

.log:로그파일 저장
#exp com/**** tables=COM_MSG rows=y log=exp.log file= COM_test_exp.dmp

.statistics :export 되는 데이터 베이스 오브젝트에 대하여 ANALYZE명령을 사용할 것인지설정
  (estimate,compute,none :기본은 estimate)
#exp com/****  tables=COM_MSG rows=y statistics=compute  file= COM_test_exp.dmp

  .consistent :export되는 동안 서로 연관이 있는 테이블들의 데이터들이 수정되는 경우  충분한 롤백세그멘트 공간이 요구된다.
#exp com/**** tables=COM_MSG  rows=y consistent=y file= COM_test_exp.dmp

.feedback=1000 <- 1000건 받을때 마다 ..  " . " 점 찍히는지 확인하려구

.tablespaces :export되게 될 테이블스페이스 리스트 설정
*exprot 시 주의 사항 :
- LONG칼럼에 대한 데이터가 포함된 하나의 row를 처리할수 있는 메모리
- full,table,owner 파아미터들은 동시사용할수 없다.(mutually exclusive)
- consistent 파라미터는 가급적 데이터 분량이 큰 오브젝트는 피한다.
- direct path는 명령어 사용하는 export에서만 실행가능
- direct path설정하여 export하는 경우 buffer 파라미터 사용못함. buffer파라미터는 conventional path사용하는 경우에만 사용

**Import
- 대화형식
>imp
user:com_owner
passwd:***
import file>COM_analysis.dmp
enter insert buffer size>30720
list contents of import file only>no
ignore create error>no
import grants>yes
import table data>yes
import entire export file>no
username:com_owner
*Import 유틸리티 실행에서 사용되는 파라미터
.userid :import유틸리티 실행하고 이쓴 사용자의 오라클 사용자 아이디

.file: import되어질 정보를 저장하고 있는 export파일

.rows :임의의 데이터베이스 오브젝트 내에 존재하는 모든 로우(row)를 import시 포함하는 것을 설정
      defautl Y ,만약 N라면 데이터베이스 오프젝트에 대한 DDL정보만 import

.ignore:DDL create명령을 실행할때 import유틸리티는 발생하는 에러를 무시하고 넘어가게 된다는 의미를 가진다.import시 이미존재하는 object를 import하는 경우 필요
  >imp dba/dat_pw full=y rows=y file=COM_test_exp.dump

.tables:import 되어질 테이블명

.indexs:임의의 테이블에 관계된 index를 함께 import할 것인지를 설정한다.기본값 Y

.parfile :import를 실행할때 사용되게 될 파라미터 파일의 이름 설정
>imp parfile=Par_test.par

.help :import실행할때 화면에 간단한 파라미터 설명 보여주는 기능 ,default=N

.log :import 실행시 과정을 로그 파일로 저장하기 원하는 경우 설정
  >imp com/com_pw tables=COM_MSG rows=y log=COM_test_exp.log file=COM_test_exp.dump

.stattistics
export되는 데이터베이스 오브젝트에 대하여 analyze 명령을 사용할 것인지를 설정한다. 이때 설정 할수 있는 옵션은 esimate,compute,그리고 none이 존재한다.
>imp com/com_pw tables=COM_MSG rows=y statistics=compu file=COM_test_exp.dump

.destory: full export dump 파일에 create tablesspace라는 명령이 존재할 경우 destory =Y라고 설정하게 되면 import유틸리에 의해 임의의 테이블스페이스 생성하게 될때 기존에 존재하고 있던 데이터를 overwrite 하게 된다는 조건을 부여 default =N

.fromuser :export파일이 존재할경우 그가운데 임의의 사용자에게 해당오브젝트들을 읽어들일지에 대한 사용자의 이름지정,full export의경우 사용 못함

.touser export된 dump 파일로부터 읽어들인 임의의 데이터 베이스 오브젝트를 어느 사용자의 스키마로 import할 것인지 설정

.direct :export 처리할때 사용하게 될 ,path 에 대한 설정,Y:direct path ,N:conventional path

.analyze :export된 dump파일 내부에 존재하는 analyze 명령을 import시 실행할 것인지에 대한 설정

.tablespaces :export된 dump파일 내부에 저장되어있는 테이블스페이스 가운데 실제로 import하게될 테이블 리스트설정

*테이블을 import하는 경우
1)import 유틸리트 실행
2)create table 명령
3)rows=Y    row date가 새롭게 생성된 테이블로 import
4)인덱스 생성 (import유틸리티가 성공적종료후 index생성하는게 좋다)
5)데이터 베이스 트리거가 import된다.
6)integrity constraint가 새롭게 생성된 테이블에 생성된다.
7)비트맵 인덱스 구조가 생성된다.

*import 유틸리티에 사용되는 모드
.full database mode :export파일에 저장되어있는 오브젝트중 SYS스키마에 포함되어 있는 오브젝트를 제외한 모든 데이터베이스 오브젝트들을 import할수 있는 모드,(imp_fll_database role을가진사용자에서만 가능

.talbe mode: export 에 저장되어있는 임의의 사용자 스키마에 존재하는 임의의 테이블들을 impor할경우 사용되는 모드

.user mode

*데이터 백업/복구에 과한 데이터 딕셔너리 정보
>select intance_name,status,archiver,startup_time from V$INSTANCE;
:현재 status ,arhive프로세스가 존재하는지 보여줌

>sleect name,resetlog_time,log_mode,checkpoint_change#,controlfile_sequence# from V$DATABASES;

>select file#,creation_time,status,bytes,blocks,name from v$datafile;
<-현상태 확인 online인지 오프라인인지
>alter database  archivelog < -아카이브 모드설정안되어있슴 전환시켜준다.
>alter tablespace users begin backup;
>select file#,creation_time,status,bytes,blocks,name from v$datafile;
  <-user  데이타파일만 status가 RECOVER이고 나머지는 ONLINE임이 확인될것이다.
reocver상태가 되면 아무도 user.dbf 파일에 액세스 할수 없다.
>select group#,sequence#,bytes,archived,status from v$log;
<-현재 리둘로그파일의 시퀀스넘버와 현재 아카이브상태를 확인하는데 사용
>select * from v$tablsespace; <-데이터베이스 백업시 임의의 테이블 스페이를 오프라인으로 만들어줄때 테이블 스페이스 이름 참조시 사용
>select * from v$recover_file; : 데이타파일의 온라인 여부 확인
>select * from v$backup;  :현재 백업모든인지확인

select file#,status,tablespace_name,checkpoinrt_change#,fuzzy,name from v$datafie_header;
<fuzz칼럼이 yes연경우 백업모드로 전환된 상태라는것을 의미

출처 : http://ioneit.co.kr/ver1/bbs/board.php?bo_table=tiptech1_3&wr_id=1
Posted by 1010
02.Oracle/DataBase2008. 11. 24. 18:02
반응형


// 네임스페이스 만들기
create tablespace Oracletable
datafile 'e:\OracleDB\Oracletable.dbf' size 10m
autoextend on next 100m maxsize 1000m online;


//아이디 생성 및 네임스페이스 연결
create user oldb identified by oldb
default tablespace Oracletable;


//권한부여
grant connect, resource to oldb;


//테이블생성 및 필드값 추가
create Table Dept (Deptno  Number(3) Primary Key,
                   Dname  Varchar2(10) UNIQUE,
                   Loc  Varchar2(10)) ;

Insert Into Dept Values(10, '총무부','서울');
Insert Into Dept Values(20, '영업부','대전');
Insert Into Dept Values(30, ‘전산부’,’부산’);
Insert Into Dept Values(40, '관리부', ‘광주’);

 

// 수정
alter table imsi add (tel number(5));  - > 추가
alter table samp modify (tel varchar2(10)); -> 데이타 타입 변경
alter table samp modify (tel varchar2(30)); -> 칼럼의 폭 변경
insert into samp values(‘kim’,20,’123-3456’) ; -> 데이타 추가
alter table samp modify (tel varchar2(14)); -> 칼럼의 폭 축소는 불가
alter table samp add constraint samp_name_uq unique(name); -> 유일성 부여


//삭제
DROP TABLE 테이블명


// 필드삭제....
alter table imsi drop column temp02;


// 필드값 업데이트
update imsi a set id='변경아이디' where id='아이디';


//조건 삭제
delete from imsi where no='2';

------------------------------------


/* dbf 데이터 파일 경로 및 개수 확인 */
select file_name from dba_data_files;


/* 모든 사용자 이름 조회 */
select * from all_users;

select * from tablespace;

/* 모든 테이블 스페이스 확인 */
select a.tablespace_name, a.bytes/1024/1024 || 'M' total, substr(a.file_name,1,50), b.free || 'M' from DBA_DATA_FILES a,

(select tablespace_name, sum(bytes)/1024/1024 free from DBA_FREE_SPACE group by tablespace_name) b

where a.tablespace_name = b.tablespace_name
/* 모든 테이블 스페이스 확인 */
SELECT USERNAME, DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE FROM DBA_USERS;

SELECT TABLE_NAME, TABLESPACE_NAME FROM USER_TABLES;

 

 


 

Posted by 1010
02.Oracle/DataBase2008. 11. 24. 17:58
반응형

  1. 백업과 복구의 종류
        백업방법
        - 물리적 방법  ( Physical Mode ) : OS에서 제공하고 있는 복사 명령어
        - 논리적 방법 ( Logical Mode ) : 오라클 사에서 제공하는 Export 유틸리티를 통한  파일 복사 방법

        복구방법
        - 노-아카이브 모드 ( no-Archive Mode )
            : 로그버퍼 영역과 redo 로그 파일에 저장된 내용을 복구 하는 방법 ( 오라클 설치 후 기본 설정 값 )
           
        - 아카이브 모드 ( Archive Mode )
            * 완전 복구 ( Complete Recovery )
                : DB의 문제가 발생한 시점까지의 복구 방법

            * 불완전 복구 ( In-Complete Recovery )
                :  DB의 문제가 발생한 시점까지 복구가 안되고 정적인 백업자료를 복구


    2. Hang-up 상태인 경우 오라클 서버 재부팅 하도록 함

DB Backup

  1. 물리적 방법 백업
        사전 준비 단계 
        - 이 방법으로 백업을 하기 위해서는 반드시 Oracle 을 Shutdown 시켜야 한다.
        - SQL>shutdown [ 옵션 ]
        - 옵션 : Normal, Transactional, immediate 

        파일 복사
        - 아래의 저장된 데이터베이스 파일을 별도의 백업 폴더로 복사 한다.
    datafiles.jpg
  2.  
  3. Export 유틸리티 사용 
        사전 준비 단계  ( 백업 위치가 클라이언트 인 경우 )
        - 오라클 클라이언트 버전 10g R2 (설치 옵션 - 관리자) 버전으로 설치 하여야 함 

        전체 백업방법 ( 자세한 사항은 오라클 유틸리티 매뉴얼을 참조 ) 
                - exp userid=계정명/패스워드@TNS명 file=백업된파일 저장위치 log=백업과정의 로그 정보 저장 위치 
        : indexes=yes(no)
        : grants=yes(no)
        : contraints=yes(no)

                - 예) exp userid=erprail/erprail@RAIL file=C:\erprail_mon.dmp log=D:\erprail_mon.log

        일부 백업방법
                - exp 계정명/패스워드@TNS명 file=백업된파일 저장위치 log=백업과정의 로그 정보 저장 위치 tables=백업할 테이블명

                - 예) exp userid=erprail/erprail@RAIL file=C:\erprail_mon.dmp log=D:\erprail_mon.log  tables=p1_master,p0_dept


    2. Export 퀵 사용법  -  exp 계정명/패스워드
        1) 인출버퍼 사이즈 조정
        2) Export 될 파일명 지정
        3) 전체, 사용자, 테이블 선택 라인
        4) 완료

    3. HELP 보는 방법
       C:> EXP HELP=Y

 

DB Restore

  1. No-Archive Mode ( 노 – 아카이브 모드 )
       : 사용자 들의 Insert/Update/Delete 작업을 수행 할 때 마다 모든 변경 전 데이터와 변경 후 데이터를 Redo Log 버퍼에 저장 함

        설정확인 방법 ( SQL  PLUS )
        - SQL> ARCHIVE   LOG   LIST
        - SQL> SELECT GROUP#, SEQUENCE#, ARCHIVED, STATUS FROM V$LOG;
    restore1.jpg

 

  1. 오프라인 복구 방법  
        백업 1 에서 한 물리적 파일을 전부 재 설치

         참고 Page 43 ~ 46 ( 백업 복구 가이드 )
    restore2.jpg
  2. 아카이브 모드 환경 설정
        initSID.ora 변수 설정 
        - LOG_ARCHIVE_START : ARCH 백그라운드 프로세스에 의해 아카이브 모드 전황 및 자동 실행 처리 설정
        - LOG_ARCHIVE_DEPT : Redo 로그 파일에 대한 아카이브  파일이 생성될 기본 위치
        - LOG_ARCHIVE_DEPT_n : 아카이브 경로를 여러군데로 지정할 때 사용
        - LOG_ARCHIVE_FORMAT : 아카이브 파일의 포멧을 결정

       설정확인 방법 ( SQL  PLUS )
                 - SQL> ARCHIVE   LOG   LIST
                 - SQL> SELECT GROUP#, SEQUENCE#, ARCHIVED, STATUS FROM V$LOG;

      복구 방법
                - 전체 완전 복구  : MOUNT 단계의 복구 작업    (   백업 및 복구 가이드 매뉴얼 52 ~ 55 Page 참조 )
                - 테이블스페이스 완전 복구 : OPEN 단계의 복구 작업 ( 백업 및 복구 가이드 매뉴얼 56 ~ 58 Page 참조 )
                - 데이터 완전 복구 : OPEN 단계의 복구 작업 ( 백업 및 복구 가이드 매뉴얼 59 ~ 63 Page 참조 )

 

1. Import 유틸리티 사용 
     Export 를 사용하여 백업을 받은 경우 처리 할 수 있는 방법 
     Import 방법 ( 자세한 사항은 오라클 유틸리티 매뉴얼을 참조 ) 
            - imp 오라클사용자명/암호@TNS명 file=덤프파일명 fromuser=ExportID touser=ImportID ignore=yes

            - 예) imp userid=erprail/erprail@RAIL file=C:\erprail_mon.dmp fromuser=erprail touser=erprail ignore=yes

    일반적 경고
            - 1) Export 사용자와 Import 사용자의 ID가 틀린 경우
            - 2) Export 객체들의 테이블 스페이스와 Import 테이블 스페이스 이름이 다른 경우
            - 3) Export 테이블스페이스 스토리지 옵션과 덤프할 데이터가 맞지 않은 경우 ( Initial 사이즈가 너무 크거나 작다거나 등 )


    일반적 경고 해결 방법
            - 2) 덤프 파일에서 테이블 생성 스크립트 추출하기 : imp 명령의 indexfile 옵션을 이용한다
                  : imp 사용자명/암호@TNS명 file=덤프파일이름 fromuser=Export사용자ID touser=ImportID indexfile=ScriptFile

    - 3) Spool / TAB View 를 활용 하여 처리 함
                  : spool drop.sql ( 파일 명 임  ) select 'drop table '||table_name||';' from tabs; spool off     ( 실행방법 @파일명 임 )
                  : 실행도중 Referencial Integrity Error 발생시 수동 Drop 을 시켜 주면서 복구




출처 : http://gtko.springnote.com/pages/723356

Posted by 1010
02.Oracle/DataBase2008. 11. 24. 17:52
반응형

1. BACKUP 명령 옵션

- 물리적 블록 손상을 검사한다.
- 논리적 손상 및 물리적 손상을 스캔 한다.
- 중지 전에 허용된 손상 감지 수에 대한 임계값을 설정한다.
- 백업 작업을 수행하기 전에 대상 입력 파일을 검증한다.
- 백업 셋을 이중화한다.
- 기존 백업 셋 또는 Image Copy를 겹쳐 사용한다.
- 저장 장치와 디스크의 데이터 파일 간 데이터 전송에 대한 제어를 Media management층에 전달한다.
- 백업 파일을 암호화(encryption)한다. (10g 10.2c R2 부터 가능)



2. 아카이브된 리두 로그 백업

- 온라인 리두 로그 파일 스위치는 자동으로 발생한다.
- 아카이브된 로그 failover가 수행된다.
- 백업할 아카이브된 리두 로그의 범위를 지정할 수 있다.
- 아카이브된 리두 로그 파일의 백업 셋은 다른 유형의 파일을 포함할 수 없다.
  ( 데이터파일, 컨트롤파일, 아카이브 리두 로그 파일을 백업 했을때 데이터파일과 컨트롤파일은 같은 백업 셋에 들어갈 수 있지만 아카이브 리두 로그 파일은 별도의 백업 셋에 저장되어야 한다. )

예)
RMAN> BACKUP
       2>    FORMAT '/disk1/backup/ar_%t_%s_%p'
       3>    ARCHIVELOG FROM SEQUENCE=234
       4>    DELETE INPUT;

 - 슬라이드에 표시된 예제는 Sequence Number가 234 이상인 아카이브된 리두 로그를 모두 백업 셋에 백업한다.
 - 아카이브된 로그는 복사된 후 디스크에서 삭제되며 V$ARCHIVED_LOG뷰에도 삭제된 것으로 표시된다.




3. Whole 데이터베이스 백업



Whole : 전체라는 뜻

RMAN> BACKUP DATABASE PLUS ARCHIVELOG <- 데이터베이스와 아카이브 로그까지 같이 백업 받겠다는 명령 ( CONTROLFILE AUTOBACKUP ON 설정이 되어 있다면 SPFILE도 같이 백업을 받는다. )

- Whole 데이터베이스 백업은 모든 데이터 파일 및 콘트롤 파일의 복사본이다.
- 선택적으로 SPFILE 및 아카이브된 로그 파일을 포함시킬 수 있다.
- Recovery Manager를 사용하여 모든 데이터베이스 파일의 Image Copy를 만들려면 데이터베이스를 마운트( 컨트롤 파일이 열려있는 상태 )하고 RMAN을 시작한 다음 슬라이드에 표시된 BACKUP 명령을 입력하기만 하면된다.
- 이 작업은 다음 CONFIGURE 명령을 이미 실행한 경우에만 가능하다.

CONFIGURE DEFAUlT DEVICE TYPE TO disk;
CONFIGURE DEVICE TYPE DISK BACKUP TYPE TO COPY;
CONFIGURE CONTROLFILE AUTOBACKUP ON;


- 다음 명령을 사용하여 데이터베이스의 모든 데이터 파일과 컨트롤 파일의 이전 Image Copy의 백업(백업 셋 또는 Image Copy)를 생성할 수도 있습니다. 
 (백업 파일을 백업하는것 )

RMAN> BACKUP COPY OF DATABASE;



4. RMAN백업 유형

- Full 백업은 사용된 모든 데이터 파일 블록을 포함한다.
- 레벨 0 Incremental 백업은 레벨 0으로 표시된 Full백업과 동일하다.
- Cumulative 레벨 1 Incremental 백업은 마지막 레벨 0 Incremental 백업 이후 수정한 블록만 포함한다.
- Differential 레벨 1 Incremental 백업은 마지막 incrementail 백업 이후 수정한 블록만 포함한다.


1) Incremental 백업

RMAN은 다음과 같이 다중 레벨 Incremental 백업을 생성할 수 있다.

- Differential : 레벨 1 또는 레벨 0에서 최근 Incremental 백업 이후에 변경된 모든 블럭을 백업하는 Incremental 백업의 기본 유형

- Cumulative : 레벨 0 에서 최근 백업 이후 변경된 모든 블럭을 백업한다.

예)
레벨 0에서 Incremental 백업을 수행하려면 다음 명령을 사용
RMAN> BACKUP INCREMENTAL LEVEL 0 DATABASE;

Differential incremental 백업을 수행하려면 다음 명령을 사용
RMAN> BACKUP INCREMENTAL LEVEL 1 DATABASE;

Cumulative incremental 백업을 수행하려면 다음 명령을 사용
RMAN> BACKUP INCREMENTAL LEVEL 1 CUMULATIVE DATABASE;


2) Differential 백업과 Cumulative 백업 비교

- Differential 백업 : 마지막 Incremental 백업 이후 변경된 모든 블록을 백업

- Cumulative 백업 : 마지막 레벨 0 Incremental 백업 이후 변경된 모든 블록을 백업



※ 위의 그림에서 <- 은 Cumulative 백업, <- Differentail 백업

- 일요일 마다 레벨 0 Incremental 백업을 수행
- 일주일에 두번, 수요일과 금요일에 Cumulative 백업을 수행하여 데이터베이스 Recovery 시간을 줄인다.
- 그외의 요일에는 Differential 백업을 수행하여 백업 시간과 저장 영역 요구 사항을 줄인다.


3) Incremental 백업 및 Cumulative 백업 비교

- Differential 백업 : 빠르고 더 적은 수의 블록을 기록하여 보다 작은 백업 파일을 생성한다.
                           결과적으로 백업 프로세스는 빨라지지만 Recovery중에 RMAN이 각 Incremental 백업을 검색하여 적용해야 한다.

- Cumulative 백업 : 시간이 오래 걸리고 많은 블록을 작성하며 보다 큰 백업 파일을 생성한다.
                             Recovery시 적은 수의 백업이 적용되므로 Recovery 속도가 빠르다.


4) 블럭 변경 사항 추적

※ 블럭 변경 사항 추적(Block Change Tracking)을 활성화하면 백업 프로세스를 효율화할 수 있다.

- 변경 사항 추적 파일에서 변경된 블록 기록
- 활성화된 경우 RMAN에 의해 자동으로 사용됨
- 백업 중에 전체 데이터 파일을 스캔하지 않도록 Incremental 백업 최적화




5) 블럭 변경 사항 추적 활성화

SQL> ALTER DATABASE ENABLE
    2> BLOCK CHANGE TRACKING
    3> USING FILE '/mydir/rman_change_track.f'
    4> REUSE;





6) Incremental 갱신 백업

Incrementally Updated Backup 기능을 사용하면 RMAN에서 Incremental 백업을 데이터 파일 Image Copy에 적용할 수 있다.





5. LIST 명령

- 백업 셋 및 데이터 파일의 복사본 나열
RMAN> LIST BACKUP OF DATABASE;
RMAN> LIST BACKUP OF DATABASE
       2>    "/db01/ORADATA/u03/users01.dbf";


- 지정된 테이블 스페이스에 대한 백업 셋 및 데이터 파일의 복사본 나열
RMAN> LIST COPY OF TABLESPACE "SYSTEM";

- 지정된 범위의 아카이브 로그를 포함하느 백업 셋 및 복사본 나열
RMAN> LIST COPY OF DATABASE ARCHIVELOG
       2> FROM TIME='SYSDATE-7'

※ RMAN LIST 명령을 사용하여 responsitory에 기록된 백업 셋, proxy 복사본 및 Image Copy에 대한 정보를 표시한다.
이 명령을 사용하여 다음을 나열한다.

- RMAN repository에 AVAILAVLE 상태가 없는 백업 및 복사본
- 복원 작업에 사용할 수 있는 가용 백업 및 데이터 파일의 복사본
- 지정된 데이터 파일 리스트 또는 지정된 테이블스페이스의 백업을 포함하는 백업 셋 및 복사본
- 지정된 이름 또는 범위를 갖는 아카이브된 로그의 백업을 포함하는 백업 셋 및 복사본
- 태그, 완료시간, recovery 가능성 또는 장치로 제한된 백업 셋 및 복사본
- 지정된 데이터베이스 또는 respository에 알려진 모든 데이터베이스의 Incarmation
- Recovery Catalog의 내장 스크립트



6. REPORT 명령

1) 보고서 생성

repository에 대한 자세한 분석을 생성한다.
다음 경우에 보고서를 생성한다.

- 데이터베이스의 데이터 파일을 알고자 하는 경우
RMAN> REPORT SCHEMA;

- 백업이 필요한 파일을 알고자 하는 경우
RMAN> REPORT NEED BACKUP;

- 삭제할 수 있는 백업을 알고자 하는 경우
RMAN> REPORT OBSOLETE;

- recovery할 수 없는 파일을 알고자 하는 경우
RMAN> REPORT UNRECOVERABLE....;


2) REPORT NEED BACKUP 명령

- 백업이 필요한 모든 데이터 파알을 나열한다.
- 복원 중 가장 최근 백업을 사용한다고 가정한다.
- 다음 네가지 옵션을 제공한다.
   * Incremental
      Recovery 중에 복원해야 할 최대 Incremental 백업 수를 지정하는 정수
      예) Recovery를 위해 세개 이상의 Incremental 백업이 필요한 파일을 보고하는 경우
     RMAN> REPORT NEED BACKUP incremental 3 database;

   * Days
      파일의 마지막 Full 또는 Incremental 백업 이후의 최대 날짜 수를 지정하는 정수
      ) 3일동안 백업되지 않은 시스템 파일을 보고하는 경우

   * Redundancy
      필요하다고 생각되는 최소 중복성 레벨을 주정하는 정수
      예) 중복성 레벨을 2로 지정한 경우 두개 이상의 백업이 없으면 백업이 필요하다.

   * Recovery Window
      RMAN이 데이터베이스를 Recovery해야 하는 기간

- 옵션을 지정하지 않은 경우 현재 retention 정책 구성을 사용한다.


3) REPORT NEED BACKUP 예제

- Recovery를 위해 세개를 초과하는 Incremental 백업이 필요한 파일
RMAN> REPORT NEED BACKUP incremental 3;

- 3일 동안 백업되지 않은 파일
RMAN> REPORT NEED BACKUP days 3;

- 아직 두개 이상의 백업이 없을 경우 필요한 백업
RMAN> REPORT NEED BACKUP redundancy 2;

- 3일 전으로 Recovery하기 위해 필요한 백업
RMAN> REPORT NEED BACKUP
      2>   recovery window of 3 days;



4) REPORT OBSOLETE 및 DELETE OBSOLETE

- 현재 retention 정책 설정에 따라 불필요한 모든 recovery 파일 찾기
RMAN> REPORT OBSOLETE;

- 두 개 이하의 백업 복사본이 필요한 경우 불필요한 recovery 파일 나열
RMAN> REPORT OBSOLETE REDUNDANCY 2;

- 백업 셋 키가 4인 백업 셋 삭제
RMAN> DELETE BACKUPSET 4;

- recovery 파일에 백업이 두 개를 초과하므로 불필요한 것으로 간주되는 파일 삭제
RMAN> DELETE OBSOLETE REDUNDANCY 2;



7. EM을 사용하여 백업 관리

Database Home 페이지 > Maintenance > Manage Current Backups



※ Enterprise Manager에 제공된 백업 유지 관리 기능은 다음과 같다.

- RMAN repository에 기록된 백업(백업 셋 및 Image Copy) 리스트 보기

- repository 상호 확인:
  * repository에 나열된 백업이 존재하고 이 백업에 액세스할 수 있는지 확인
  * 상호 확인 작업 시 백업에 액세스할 수 없으면 만료된 것으로 표시

- RMAN repository에서 만료된 백업의 레코드 삭제

- repository 및 디스크에서 불필요한 백업 삭제



8. RMAN 동작 뷰

※ 다음 뷰를 사용하여 컨트롤 파일에 저장된 RMAN 정보를 얻을 수 있다.

- V$ARCHIVED_LOG는 어떤 아카이브가 데이터베이스에서 생성되고 백업되고 지워졌는지 보여준다.

- V$BACKUP_CORRUPTION은 백업 셋을 백업하는 중에 발견한 손상 블록을 보여준다.

- V$BACKUP_DATAFILE은 각 데이터 파일의 블록 수를 확인하여 동일한 크기의 백업 셋을 생성하는 데 유용하다.
  또한 데이터 파일의 손상된 블록 수도 알 수 있다.
 
- V$BACKUP_DEVICE는 지원되는 백업 장치에 대한 정보를 표시한다.
  특수 장치 유형 DISK는 항상 사용할 수 있기 때문에 이 뷰에 의해 반환되지 않는다.

- V$BACKUP_FILES는 모든 RMAN 백업(Image Copy 및 백업 셋 모두) 및 아카이브된 로그에 대한 정보를 표시한다.
  이 뷰는 LIST BACKUP 및 LIST COPY RMAN 명령을 시뮬레이트한다.

- V$BACKUP_PIECE는 백업 셋에 생성된 백업 피스를 보여준다.

- V$BACKUP_REDOLOG는 백업 셋에 저장된 아카이브된 로그를 보여준다.

- V$BACKUP_SET은 생성된 백업 셋을 보여준다.

- V$BACKUP_SPFILE은 백업 셋의 서버 파라미터 파일에 대한 정보를 표시한다.

- V$COPY_CORRUPTION은 Image Copy 중에 발견한 손상 블록을 보여준다.



9. RMAN 백업 모니터

- SET COMMAND ID 명령을 사용하여 서버 세션과 채널을 상호 연관짓는다.

- V$PROCESS 및 V$SESSION을 query하여 어떤 세션이 어떤 RMAN 채널에 대응되는지 확인한다.

- V$SESSION_LONGOPS를 query하여 백업 및 복사본의 진행 상태를 모니터한다.

- 운영 체제 유틸리티를 사용하여 프로세스 또는 스레드를 모니터한다.

Posted by 1010
02.Oracle/DataBase2008. 11. 24. 17:40
반응형

Oracle Database 10g: DBA를 위한 20가지 주요 기능  

원문 : http://www.oracle.com/technology/global/kr/pub/articles/10gdba/index.html
 
1주 — 플래시백 버전 질의
2주 — 롤백 모니터링
3주 — 테이블스페이스 관리
4주 — Oracle Data Pump
5주 — Flashback Table
6주 — Automatic Workload Repository
7주 — SQL*Plus의 향상된 기능
8주 — Automatic Storage Management
9주 — RMAN
10주 — 감사기능의 확장
11주 — Wait 인터페이스
12주 — Materialized Views
13주 — Enterprise Manager 10g
14주 — Virtual Private Database
15주 — 세그먼트의 관리
16주 — Transportable Tablespace
17주 — Automatic Shared Memory Management
18주 — ADDM과 SQL Tuning Advisor
19주 — Scheduler
20주 — 그 밖의 주요 기능


 
첫번째.
사진이 아닌 동영상으로: Flashback 버전 질의
전혀 아무런 설정 없이도 행의 모든 변경 내용을 즉시 식별 가능
Oracle9i Database에는 Flashback 질의 형태의 소위 “타임 머신” 기능이 이미 도입된 바 있습니다. DBA는 이 기능을 통해 실행 취소 세그먼트에 블록의 이전 이미지 복사본이 있으면 열의 값을 특정 시간으로 확인할 수 있습니다. 하지만 Flashback 질의는 두 시점 간의 변경된 데이타를 표시하는 대신 데이타의 고정된 스냅샷을 시간으로 나타내는 데 그칩니다. 외환 관리 등과 관련된 일부 애플리케이션에서는 값 데이타의 변경 내용을 두 시점에서가 아닌 일정 기간으로 확인해야 합니다. Oracle Database 10g에는 Flashback 버전 질의 기능이 있어 이러한 작업을 쉽고 편리하게 수행할 수 있습니다.
테이블 변경 내용 질의
이 예에서는 은행의 외환 관리 애플리케이션을 사용했습니다. 데이타베이스에는 특정 시간의 환율을 기록하는 RATES라는 테이블이 있습니다.
SQL> desc rates
 Name              Null?    Type
 ----------------- -------- ------------
 CURRENCY                   VARCHAR2(4)
 RATE                       NUMBER(15,10)

이 테이블에는 CURRENCY 열에 표시된 기타 여러 통화에 대한 US 달러의 환율이 표시됩니다. 재무 서비스 업계에서는 환율을 단순히 변경될 때마다 업데이트하는 대신 지속적인 기록으로 관리합니다. 이 접근방법은 은행 거래가 “이미 지난 시간”에 이루어져 송금으로 인한 시간상의 손실을 수용할 수 있기 때문에 채택되는 것입니다. 예를 들어, 오전 10:12에 이뤄지지만 오전 9:12에 발효된 거래는 현재 시간이 아닌 오전 9:12의 환율이 적용됩니다.
지금까지는 환율 기록 테이블을 생성해 환율 변경 내용을 저장한 후 해당 테이블에 기록이 있는지 질의할 수 밖에 없었습니다. 이 밖에도 RATES 테이블 자체에 특정 환율이 적용되는 시작 시간과 종료 시간을 기록하는 방법이 있었습니다. 변경 내용이 발생하면 기존 행의 END_TIME 열이 SYSDATE로 업데이트되며 END_TIME이 NULL인 새 환율과 함께 행이 새로 삽입되는 것입니다.
하지만 Oracle Database 10g에는 Flashback 버전 질의 기능이 있어 기록 테이블을 유지하거나 시작 및 종료 시간을 저장할 필요가 없습니다. 대신 이 기능을 사용하면 추가로 설정하지 않고도 과거의 특정 시간에 해당하는 행의 값을 가져올 수 있습니다.
예를 들어, 일상 업무를 수행하는 DBA가 환율을 여러 번 업데이트하거나, 때로는 행을 삭제하고 다시 삽입하기도 한다고 가정합니다.
insert into rates values ('EURO',1.1012);
commit;
update rates set rate = 1.1014;
commit;
update rates set rate = 1.1013;
commit;
delete rates;
commit;
insert into rates values ('EURO',1.1016);
commit;
update rates set rate = 1.1011;
commit;

이러한 일련의 작업이 끝나면 DBA는 다음과 같은 RATE 열의 현재 커밋된 값을 얻게 됩니다.
SQL> select * from rates;

CURR       RATE
---- ----------
EURO     1.1011

이 결과에는 행을 처음 생성했을 때부터 발생한 모든 변경 내용이 아닌 RATE의 현재 값이 표시됩니다. 따라서 Flashback 질의를 사용하면 해당 시점의 값을 검색할 수 있지만, 여기서 보다 핵심적인 의도는 단순히 특정 시점에 얻은 일련의 스냅샷이 아니라 캠코더를 통해 변경 내용을 기록하는 것 같이 변경 내용의 감사추적(Audit Trail)을 구축하려는 것입니다.
다음 질의에는 테이블의 변경 내용이 나와 있습니다.
select versions_starttime, versions_endtime, versions_xid,
versions_operation, rate
from rates versions between timestamp minvalue and maxvalue
order by VERSIONS_STARTTIME
/

VERSIONS_STARTTIME     VERSIONS_ENDTIME       VERSIONS_XID     V       RATE
---------------------- ---------------------- ---------------- - ----------
01-DEC-03 03.57.12 PM  01-DEC-03 03.57.30 PM  0002002800000C61 I     1.1012
01-DEC-03 03.57.30 PM  01-DEC-03 03.57.39 PM  000A000A00000029 U     1.1014
01-DEC-03 03.57.39 PM  01-DEC-03 03.57.55 PM  000A000B00000029 U     1.1013
01-DEC-03 03.57.55 PM                         000A000C00000029 D     1.1013
01-DEC-03 03.58.07 PM  01-DEC-03 03.58.17 PM  000A000D00000029 I     1.1016
01-DEC-03 03.58.17 PM                         000A000E00000029 U     1.1011

행을 삭제하고 다시 삽입했더라도 여기에 행의 모든 변경 내용이 표시됩니다. VERSION_OPERATION 열에는 행에서 수행한 작업(삽입/업데이트/삭제)이 나타나며, 이를 위한 모든 과정이 기록 테이블이나 추가 열 없이 이뤄집니다.
위의 질의에서 versions_starttime, versions_endtime, versions_xid, versions_operation 열은 ROWNUM, LEVEL 같이 친숙한 열과 유사한 의사(Pseduo) 열입니다. VERSIONS_STARTSCN 및 VERSIONS_ENDSCN 같은 다른 의사 열에는 해당 시간의 시스템 변경 번호(SCN)가 표시됩니다. 또한 versions_xid 열에는 행을 변경한 트랜잭션 식별자가 표시됩니다. 트랜잭션의 상세 내역은 FLASHBACK_TRANSACTION_QUERY 뷰에 나와 있으며, 여기서 XID 열에는 트랜잭션 ID가 표시됩니다. 예를 들어, 위에서 VERSIONS_XID 값인 000A000D00000029를 사용하면 UNDO_SQL 값에 실제 문이 표시됩니다.
SELECT UNDO_SQL
FROM FLASHBACK_TRANSACTION_QUERY
WHERE XID = '000A000D00000029';

UNDO_SQL
----------------------------------------------------------------------------
insert into "ANANDA"."RATES"("CURRENCY","RATE") values ('EURO','1.1013');

이 뷰에는 실제 문 외에도 커밋의 타임 스탬프와 SCN을 비롯해 질의 시작 시의 SCN과 타임 스탬프가 표시됩니다.
기간 내 변경 내용 확인
이제 이러한 정보를 효과적으로 사용하는 방법에 대해 알아보도록 하겠습니다. 오후 3:57:54의 RATE 열 값을 확인해야 한다고 가정하면 다음과 같이 실행할 수 있습니다.
select rate, versions_starttime, versions_endtime
from rates versions
between timestamp
to_date('12/1/2003 15:57:54','mm/dd/yyyy hh24:mi:ss')
and to_date('12/1/2003 16:57:55','mm/dd/yyyy hh24:mi:ss')
/

      RATE VERSIONS_STARTTIME     VERSIONS_ENDTIME
---------- ---------------------- ----------------------
    1.1011

이 질의는 Flashback 질의와 유사합니다. 위의 예에서 시작 및 종료 시간은 NULL로 해당 시간 간격 동안 환율이 변하지 않았으며 시간 간격을 포함하고 있음을 나타냅니다. 또한 SCN을 사용하면 이전 버전 값을 확인할 수 있으며, SCN 번호는 의사 열인 VERSIONS_STARTSCN 및 VERSIONS_ENDSCN에서 가져옵니다. 다음은 이에 대한 예입니다.
select rate, versions_starttime, versions_endtime
from rates versions
between scn 1000 and 1001
/

키워드 MINVALUE 및 MAXVALUE를 사용하면 실행 취소 세그먼트의 모든 변경 내용이 표시됩니다. 특정 날짜 또는 SCN 값을 범위의 끝점 중 하나로 지정하고 다른 끝점을 리터럴 MAXVALUE 또는 MINVALUE로 지정할 수도 있습니다. 예를 들어, 다음은 전체 범위가 아닌 오후 3:57:52부터의 변경 내용을 알려주는 질의입니다.
select versions_starttime, versions_endtime, versions_xid,
versions_operation, rate
from rates versions between timestamp
to_date('12/11/2003 15:57:52', 'mm/dd/yyyy hh24:mi:ss')
and maxvalue
order by VERSIONS_STARTTIME
/

VERSIONS_STARTTIME     VERSIONS_ENDTIME       VERSIONS_XID     V       RATE
---------------------- ---------------------- ---------------- - ----------
01-DEC-03 03.57.55 PM                         000A000C00000029 D     1.1013
01-DEC-03 03.58.07 PM  01-DEC-03 03.58.17 PM  000A000D00000029 I     1.1016
01-DEC-03 03.58.17 PM                         000A000E00000029 U     1.1011

최종 분석
Flashback 버전 질의는 틀을 벗어나 테이블 변경 내용의 짧은 휘발성 값(value) 감사(Audit)를 복제합니다. 이러한 이점을 통해 DBA는 과거의 특정 값이 아니라 일정 기간의 모든 변경 내용을 가져오므로 실행 취소 세그먼트(Undo Segment)의 데이타를 최대한 활용할 수 있습니다. 따라서 최대한으로 사용할 수 있는 버전은 UNDO_RETENTION 매개변수에 달려있다고 하겠습니다.
Flashback 버전 질의에 대한 자세한 내용은 Oracle Database Concepts 10g Release 1 (10.1) 설명서의 관련 섹션을 참조하십시오.
 
 
두번째.
얼마나 더 걸리나요?: 롤백 모니터링
롤백 작업 시간의 정확한 예측
아직 멀었나요? 얼마나 더 걸리죠?
귀에 익은 말들입니까? 이런 질문은 아이들이 좋아하는 테마 공원에 가는 도중 갈수록 횟수를 더하며 끊임없이 뒷좌석에서 들려올 수 있습니다. 이럴 때, 앞으로 정확히 얼마나 더 걸릴지 말해주거나 적어도 그 답을 혼자만이라도 알고 있다면 낫지 않겠습니까?
긴 실행 트랜잭션을 롤백했을 때도 이와 마찬가지로 여러 사용자들이 바짝 따라다니며 같은 질문을 하는 경우가 많습니다. 롤백이 진행되면서 트랜잭션에 잠금이 발생하고 일반적인 처리 성능이 저하되므로 이러한 질문을 하는 것은 당연합니다. Oracle 9i Database 이전 버전에서는 다음 질의를 실행하면,
SELECT USED_UREC
FROM V$TRANSACTION;

현재 트랜잭션에서 사용하는 실행 취소 레코드 수를 반환하며, 반복해서 실행하면 롤백 프로세스가 진행되면서 실행 취소 레코드가 해제되므로 계속해서 줄어든 값이 표시됩니다. 그런 다음 일정 간격의 스냅샷을 얻어 비율을 계산한 후 결과를 추정하여 종료 시간을 예측할 수 있습니다.
V$TRANSACTION 뷰에 START_TIME이라는 열이 있지만, 이 열에는 전체 트랜잭션의 시작 시간만 표시됩니다(즉, 롤백 실행 전). 따라서 실제로 롤백을 실행한 시간을 알 수 있는 방법은 추정뿐입니다.
트랜잭션 롤백을 위한 통계 확장
Oracle Database 10g에서는 이 과제를 간단히 수행할 수 있습니다. 트랜잭션을 롤백하면 이벤트가 V$SESSION_LONGOPS 뷰에 기록되어 긴 실행 트랜잭션을 표시합니다. 롤백을 위한 프로세스가 6초 이상 걸리는 경우 레코드가 뷰에 나타납니다. 롤백의 실행이 끝나면 모니터 스크린을 가리고도 다음 질의를 실행할 수 있을 것입니다.
select time_remaining
from v$session_longops
where sid = <sid of the session doing the rollback>;

이제 이 V$SESSION_LONGOPS 뷰가 얼마나 중요한지 알았으니 이 뷰의 다른 기능들에 대해 살펴보도록 하겠습니다. Oracle Database 10g 이전 버전에도 이 뷰가 있지만 롤백 트랜잭션 정보는 캡처되지 않았습니다. 모든 열을 읽기 쉬운 방식으로 표시하기 위해 Tom Kyte가 AskTom.com에 설명한 PRINT_TABLE 함수를 사용하겠습니다. 이 프로시저는 열을 일반적인 행이 아닌 테이블로만 표시합니다.
SQL> set serveroutput on size 999999
SQL> exec print_table('select * from v$session_longops where sid = 9')
SID                           : 9
SERIAL#                       : 68
OPNAME                        : Transaction Rollback
TARGET                        :
TARGET_DESC                   : xid:0x000e.01c.00000067
SOFAR                         : 10234
TOTALWORK                     : 20554
UNITS                         : Blocks
START_TIME                    : 07-dec-2003 21:20:07
LAST_UPDATE_TIME              : 07-dec-2003 21:21:24
TIME_REMAINING                : 77
ELAPSED_SECONDS               : 77
CONTEXT                       : 0
MESSAGE                       : Transaction Rollback: xid:0x000e.01c.00000067 :
                                 10234 out of 20554 Blocks done
USERNAME                      : SYS
SQL_ADDRESS                   : 00000003B719ED08
SQL_HASH_VALUE                : 1430203031
SQL_ID                        : 306w9c5amyanr
QCSID                         : 0

이제 이 열들을 하나하나 자세히 살펴보도록 하겠습니다. 뷰에는 이전 세션의 모든 긴 실행 작업 기록이 포함되어 있으므로 세션에는 긴 실행 작업이 하나 이상일 수 있습니다. OPNAME 열에는 이 레코드가 “트랜잭션 롤백”용이라고 명시되어 있어 올바른 작업 방향으로 이끌어줍니다. TIME_REMAINING 열은 이전에 기술한 예측 잔여 시간을 초 단위로 표시하며, ELAPSED_SECONDS 열에는 현재까지 사용된 시간이 표시됩니다.
그렇다면 이 테이블에 어떻게 예측 잔여 시간을 나타낼까요? 단서는 총 수행 작업량을 나타내는 TOTALWORK 열과 현재까지 수행한 작업량을 나타내는 SOFAR 열에 있습니다. 작업 단위는 UNITS 열에 나와 있습니다. 여기서는 블록에 들어 있으므로 현재까지 20,554개의 블록 중 총 10,234개를 롤백한 것입니다. 또한 현재까지의 작업 소요 시간은 77초이므로 잔여 블록의 롤백 시간은 다음과 같이 구합니다.
77 * ( 10234 / (20554-10234) ) ≈ 77 seconds
반드시 이러한 경로를 통해서만 수치를 얻어야 하는 것은 아니지만 가장 명확한 방법입니다. 마지막으로 LAST_UPDATE_TIME 열에는 뷰 내용이 통용되는 시간이 표시되어 결과를 보다 쉽게 해석할 수 있도록 해줍니다.
SQL 문
또 하나의 중요하면서도 새로운 정보는 롤백 중인 SQL 문의 식별자입니다. 이전에는 롤백 중인 SQL 문을 가져오기 위해 SQL_ADDRESS 및 SQL_HASH_VALUE를 사용했습니다. 새로운 열인 SQL_ID는 아래에서처럼 V$SQL 뷰의 SQL_ID에 해당됩니다.
SELECT SQL_TEXT
FROM V$SQL
WHERE SQL_ID = <value of SQL_ID from V$SESSION_LONGOPS>;

이 질의를 실행하면 롤백된 문을 반환하므로 SQL 문의 주소 및 해시 값과 함께 추가 검사를 제공합니다.
병렬 인스턴스 복구
DML 작업이 병렬이었으면 QCSID 열에 병렬 질의 서버 세션의 SID가 표시됩니다. 인스턴스 복구 및 실패한 트랜잭션의 후속 복구 과정 같은 병렬 롤백을 실행하는 경우 대개 이 정보를 유용하게 사용할 수 있습니다.
예를 들어, 대규모 업데이트를 수행하는 도중 인스턴스가 비정상적으로 종료되었다고 가정합시다. 인스턴스가 나타나면 실패한 트랜잭션이 롤백됩니다. 병렬 복구를 위한 초기화 매개변수 값을 사용할 수 있는 경우 롤백이 정규 트랜잭션 롤백에서 발생하므로 직렬이 아닌 병렬로 이뤄집니다. 그런 다음 롤백 프로세스의 완료 시간을 예측합니다.
V$FAST_START_TRANSACTIONS 뷰에는 실패한 트랜잭션을 롤백하기 위해 발생한 트랜잭션이 표시됩니다. 이와 유사한 뷰인 V$FAST_START_SERVERS에는 롤백에 실행되는 병렬 질의 서버의 수가 나와 있습니다. 이전 버전에서는 이러한 두 개의 뷰가 있지만, 트랜잭션 식별자를 나타내는 새로운 XID 열이 추가되어 조인이 더 수월해졌습니다. Oracle9i Database 이전에서는 세 개 열(USN – 실행 취소 번호, SLT – 실행 취소 세그먼트 내의 슬롯 번호 및 SEQ – 시퀀스 번호)의 뷰에 조인해야 했습니다. 또한 상위 집합은 PARENTUSN, PARENTSLT 및 PARENTSEQ에 표시되었습니다. 하지만 Oracle Database 10g에서는 XID 열의 뷰에만 조인하면 되고 상위 XID는 알기 쉽게 PXID로 표시됩니다.
가장 유용한 정보는 V$FAST_START_TRANSACTIONS 뷰의 RCVSERVERS 열에 나와 있습니다. 병렬 롤백을 진행하면 이 열에 병렬 질의 서버의 수가 나타나며, 이를 통해 다음과 같이 시작된 병렬 질의 프로세스의 수를 확인할 수 있습니다.
select rcvservers from v$fast_start_transactions;

출력에 1로만 나타나면 트랜잭션이 가장 비효율적인 방식인 SMON 프로세스를 통해 직렬로 롤백되고 있는 것입니다. 이 경우 초기화 매개변수 RECOVERY_PARALLELISM을 0과 1을 제외한 값으로 수정한 다음 병렬 롤백 인스턴스를 다시 시작할 수 있습니다. 그런 다음, ALTER SYSTEM SET FAST_START_PARALLEL_ROLLBACK = HIGH를 실행하면 CPU 수의 네 배나 되는 병렬 서버를 생성할 수 있습니다.
위의 질의 출력이 1을 제외한 임의의 값이 표시되면 병렬 롤백이 이뤄지는 것입니다. 이 경우 동일한 뷰(V$FAST_START_TRANSACTIONS)를 질의하여 상위 및 하위 트랜잭션(상위 트랜잭션 ID – PXID 및 하위 트랜잭션 ID – XID)을 가져올 수 있습니다. 또한 XID는 이 뷰와 V$FAST_START_SERVERS를 조인하는 데 사용하여 상세 내역을 추가로 가져올 수 있습니다.
결론
요컨대 Oracle Database 10g에서 긴 실행 트랜잭션을 롤백할 때는 병렬 인스턴스 복구 세션이나 사용자 실행 롤백 문으로 표시한 다음, V$SESSION_LONGOPS 뷰를 살펴보고 향후 소요 시간의 결과를 예측하기만 하면 됩니다. 이제 테마 공원에 도착하는 시간만 예측할 수 있으면 되겠군요!
 
 
 
세번째.
손쉬운 이름 변경: 향상된 테이블스페이스 관리
Sparser인 SYSTEM, 사용자 기본 테이블스페이스 정의 지원, 새로운 SYSAUX 및 이름 바꾸기 등으로 수월해진 테이블스페이스 관리
누구나 SYSTEM 테이블스페이스에 SYS 및 SYSTEM을 제외한 세그먼트를 생성하면서 좌절감에 머리를 쥐어 뜯으며 고민한 경험이 있을 것입니다.
Oracle9i Database 이전 버전에서는 사용자를 생성할 때 DEFAULT TABLESPACE를 명시하지 않으면 기본값이 SYSTEM 테이블스페이스로 설정되었습니다. 사용자가 세그먼트를 생성하는 동안 테이블스페이스를 명시적으로 지정하지 않는 경우, 명시적으로 부여 받은 것이든 시스템 권한 UNLIMITED TABLESPACE를 통한 것이든 사용자가 테이블스페이스 할당량을 갖고 있으면 SYSTEM에 생성되었습니다. Oracle9i에서는 DBA가 명시적인 임시 테이블스페이스 절 없이 생성된 모든 사용자에 대해 기본 임시 테이블스페이스를 지정하도록 하여 이 문제를 어느 정도 해결했습니다.
Oracle Database 10g에서도 이와 유사하게 사용자에게 기본 테이블스페이스를 지정할 수 있습니다. 우선, 데이타베이스를 생성하는 과정에 CREATE DATABASE 명령은 DEFAULT TABLESPACE 절을 포함할 수 있습니다. 데이타베이스의 생성이 끝나면 다음을 실행하여 기본 테이블스페이스를 만들 수 있습니다.
ALTER DATABASE DEFAULT TABLESPACE <tsname>;

DEFAULT TABLESPACE 절 없이 생성된 모든 사용자는 기본값으로 <tsname>을 갖게 됩니다. 기본 테이블스페이스는 이 ALTER 명령을 사용해 언제든 변경하여 다른 위치의 기본값으로 다른 테이블스페이스를 지정할 수 있습니다.
여기서 중요한 점은 일부 사용자에 대해 다른 어떤 항목이 명시적으로 지정되어 있어도 이전 테이블스페이스와 함께 모든 사용자의 기본 테이블스페이스가 <tsname>으로 변경된다는 것입니다. 예를 들어, 사용자 생성 도중 사용자 USER1 및 USER2의 기본 테이블스페이스를 각각 TS1 및 TS2로 명시적으로 지정했다고 가정합니다. 데이타베이스의 현재 기본 테이블스페이스는 TS2지만, 나중에는 데이타베이스의 기본 테이블스페이스가 TS1으로 변경됩니다. USER2의 기본 테이블스페이스를 TS2로 명시적으로 지정했다 하더라도 TS1으로 바뀌게 되므로 이러한 부작용을 염두에 둬야 합니다!
데이타베이스 생성 과정에 기본 테이블스페이스를 지정하지 않으면 기본값이 SYSTEM으로 설정됩니다. 하지만 기존 데이타베이스의 기본 테이블스페이스는 어떻게 알 수 있을까요? 우선, 다음 질의를 실행합니다.
SELECT PROPERTY_VALUE
FROM DATABASE_PROPERTIES
WHERE PROPERTY_NAME = 'DEFAULT_PERMANENT_TABLESPACE';

DATABASE_PROPERTIES 뷰에는 기본 테이블스페이스 외에도 기본 임시 테이블스페이스, 전역 데이타베이스 이름, 시간대 등과 같은 몇 가지 매우 중요한 정보가 표시됩니다.
중요하지 않은 스키마의 기본 테이블스페이스
인텔리전트 에이전트 사용자 DBSNMP 및 데이타 마이닝 사용자 ODM 같은 여러 스키마는 사용자 작업과 직접적인 관련이 없지만 데이타베이스 무결성을 위해 나름대로 중요한 역할을 합니다. 이러한 스키마의 일부는 기본 테이블스페이스가 SYSTEM인데, 이는 해당 특수 테이블스페이스 내에서 객체가 확산되는 또 다른 이유이기도 합니다.
Oracle Database 10g에는 이러한 스키마의 객체를 보유하는 SYSAUX라는 새로운 테이블스페이스가 도입되었습니다. 이 테이블스페이스는 데이타베이스 생성 도중 자동으로 생성되며 지역적으로 관리됩니다. 또한 데이타 파일 이름만 유일하게 변경할 수 있습니다.
이 접근방법은 SYSTEM이 손상되어 전체 데이타베이스를 복구해야 할 때 복구를 지원합니다. 데이타베이스는 계속 실행하면서 SYSAUX의 객체를 일반 사용자 객체로 복구할 수 있습니다.
하지만 SYSAUX에 있는 이들 스키마의 일부를 다른 테이블스페이스로 옮겨야 한다면 어떻게 할까요? 크기가 늘어나 결국에는 테이블스페이스를 꽉 채우는 일이 빈번한 LogMiner에 사용되는 객체를 예로 들어봅시다. 관리 효율을 높이기 위해 이를 저마다의 테이블스페이스로 옮기는 방법을 고려할 수도 있을 것입니다. 하지만 이것이 최선의 방법일까요?
DBA라면 이러한 특수 객체를 옮기기 위한 올바른 프로시저를 알고 있어야 합니다. 다행히도 Oracle Database 10g에는 이러한 추측 작업을 수행하는 새로운 뷰가 있습니다. 이 V$SYSAUX_OCCUPANTS 뷰에는 SYSAUX 테이블스페이스에 있는 스키마의 이름, 설명, 현재 사용 공간 그리고 이동 방법이 나와 있습니다 (See 표 1 참조).
여기서 LogMiner가 어떻게 분명히 7,488KB를 차지하고 있는 것으로 표시되는지에 주목합니다. LogMiner는 SYSTEM 스키마에 속해 있으며 객체를 이동하려면 패키지 프로시저 SYS.DBMS_LOGMNR_D.SET_TABLESPACE를 실행합니다. 하지만 STATSPACK 객체의 경우 뷰에 엑스포트/임포트 접근방법을 사용하는 것이 좋으며 Streams에는 이동 프로시저가 없으므로 SYSAUX 테이블스페이스에서 이를 쉽게 옮길 수 없습니다. MOVE_PROCEDURE 열에는 SYSAUX에 기본적으로 상주하는 거의 모든 툴에 대한 올바른 이동 프로시저가 표시됩니다. 이동 프로시저는 역방향으로도 사용하여 객체를 다시 SYSAUX 테이블스페이스로 가져올 수 있습니다.
테이블스페이스 이름 바꾸기
데이타 웨어하우스 환경에서는 일반적으로 데이타 마트 아키텍처가 데이타베이스 사이에서 테이블스페이스를 이동합니다. 하지만 원본 및 대상 데이타베이스는 테이블스페이스 이름이 서로 달라야 합니다. 이름이 같은 테이블스페이스가 두 개이면 대상 테이블스페이스의 세그먼트를 다른 테이블스페이스로 옮기고 테이블스페이스를 다시 생성해야 하는데 말처럼 쉽지가 않습니다.
Oracle Database 10g에는 편리한 솔루션이 있어 영구 또는 임시 여부에 관계 없이 기존 테이블스페이스(SYSTEM 및 SYSAUX 제외)의 이름을 다음 명령을 사용해 간단히 변경할 수 있습니다.
ALTER TABLESPACE <oldname> RENAME TO <newname>;

이 기능은 아카이브 프로세스에도 유용하게 사용할 수 있습니다. 매출 기록을 관리하기 위해 범위로 분할된 테이블이 있으며, 매월의 파티션은 해당 월의 이름을 따 명명된 테이블스페이스에 있습니다. 예를 들어, 1월의 파티션에는 JAN이라는 이름이 지정되며 JAN으로 명명된 테이블스페이스에 상주합니다. 보존 정책 기간은 12개월입니다. 따라서 2004년 1월에 2003년 1월의 데이타를 아카이브할 수 있게 되는 것입니다. 대략적인 작업 과정은 다음과 유사한 형태가 됩니다.
ALTER TABLE EXCHANGE PARTITION을 사용해 파티션 JAN에서 독립형 테이블 JAN03을 생성합니다.
테이블스페이스 이름을 JAN03으로 변경합니다.
테이블스페이스 JAN03에 설정된 이동 가능한 테이블스페이스를 생성합니다.
테이블스페이스 JAN03의 이름을 다시 JAN으로 변경합니다.
비어 있는 파티션을 다시 테이블로 교환합니다.
1, 2, 4 및 5단계는 순조롭게 진행되며 리두 및 실행 취소 공간 같은 리소스를 과도하게 소모하지 않습니다. 3단계는 단순히 파일을 복사하고 JAN03의 데이타 딕셔너리만 엑스포트하면 되므로 마찬가지로 매우 간단한 프로세스입니다. 이전에 아카이브한 파티션을 다시 유효화해야 하는 경우, 프로시저는 동일한 프로세스를 반대로 수행하는 것만큼 간단합니다.
Oracle Database 10g는 이러한 이름 바꾸기를 처리하는 방식에 있어 상당히 지능적입니다. UNDO로 사용되는 테이블스페이스 또는 기본 임시 테이블스페이스의 이름을 변경하는 경우 혼동이 발생할 수 있습니다. 하지만 데이타베이스가 필요한 레코드를 자동으로 조정하여 변경 내용을 반영합니다. 예를 들어, 기본 테이블스페이스 이름을 USERS에서 USER_DATA로 변경하면 DATABASE_PROPERTIES가 자동으로 변경됩니다. 변경에 앞서 다음 질의가
select property_value from database_properties
where property_name = 'DEFAULT_PERMANENT_TABLESPACE';

USERS를 반환합니다. 다음 문을 실행하고 나면
alter tablespace users rename to user_data;

USER_DATA에 대한 모든 참조가 USER_DATA로 변경되었므로 위의 질의가 USER_DATA를 반환합니다.
기본 임시 테이블스페이스를 변경하는 방법도 이와 동일합니다. UNDO 테이블스페이스 이름을 변경하더라도 다음과 같이 SPFILE에 변경을 트리거합니다.
SQL> select value from v$spparameter where name = 'undo_tablespace';

VALUE
--------
UNDOTBS1

SQL> alter tablespace undotbs1 rename to undotbs;

Tablespace altered.

SQL> select value from v$spparameter where name = 'undo_tablespace';

VALUE
--------
UNDOTBS
결론
객체 처리 기능은 최근의 여러 Oracle 버전을 거치면서 꾸준히 향상되었습니다. Oracle8i에는 한 테이블스페이스에서 다른 테이블스페이스로의 테이블 이동이 도입되었으며, Oracle 9i Database R2는 열 이름 변경 기능을 갖추게 되었습니다. 그리고 지금은 테이블스페이스 자체의 이름을 변경할 수 있는 수준에 이르고 있습니다. 또한 이처럼 기능이 향상되면서 데이타 웨어하우스 또는 마트 환경 등에서 DBA의 작업 부담을 크게 덜어주고 있습니다.
 
 
 
네번째.
한층 강화된 엑스포트/임포트: Oracle Data Pump
Oracle Database 10g 유틸리티로 크게 향상된 데이타 이동 기능
지금까지 엑스포트/임포트 툴세트는 열악한 속도에 대한 불만에도 불구하고 최소한의 노력으로 여러 플랫폼에 데이타를 전송하기 위해 사용해 온 유틸리티였습니다. 임포트는 단순히 엑스포트 덤프 파일에서 각 레코드를 읽고 이를 일반적인 INSERT INTO 명령을 사용해 대상 테이블에 삽입하기만 하므로 임포트 프로세스가 느린 것은 그리 놀랄만한 일이 아닙니다.
이제 프로세스 속도가 월등히 향상된 Oracle Database 10g의 보다 새롭고 빠른 엑스포트/임포트 툴킷인 Oracle Data Pump, the newer and faster sibling of the export/import toolkit in Oracle Database 10g를 사용해 보십시오.
Data Pump는 엑스포트/임포트 프로세스의 전체 구성을 나타냅니다. 일반적인 SQL 문을 사용하는 대신 독점 API로 데이타를 현저하게 빠른 속도로 로드 및 언로드합니다. 제가 테스트해본 결과, 직접 모드의 엑스포트보다 성능이 10-15배 향상되었으며, 임포트 프로세스 성능도 5배 이상 증가했습니다. 또한 엑스포트 유틸리티와 달리 프로시저 같은 특정 유형의 객체만 추출할 수 있습니다.
Data Pump Export
이 새로운 유틸리티는 원래의 엑스포트인 exp와 구분하기 위해 expdp라고 합니다. 이 예에서는 Data Pump를 사용해 약 3GB 크기의 대형 테이블인 CASES를 엑스포트합니다. Data Pump는 서버 측에서 파일 조작을 사용하여 파일을 생성하고 읽으므로 디렉토리를 위치로 사용합니다. 여기서는 filesystem /u02/dpdata1을 사용해 덤프 파일을 유지할 예정입니다.
create directory dpdata1 as '/u02/dpdata1';
grant read, write on directory dpdata1 to ananda;

그리고 다음과 같이 데이타를 엑스포트합니다.
expdp ananda/abc123 tables=CASES directory=DPDATA1
  dumpfile=expCASES.dmp job_name=CASES_EXPORT

이제 이 명령의 각 부분을 분석해 보겠습니다. 사용자 ID/암호 조합, 테이블 및 덤프 파일 매개변수는 말 그대로이므로 설명이 필요 없습니다. 원래의 엑스포트와 달리 파일이 클라이언트가 아닌 서버에 생성됩니다. 위치는 디렉토리 매개변수 값 DPDATA1로 지정되며, 이는 이전에 생성된 /u02/dpdata1을 가리킵니다. 또한 프로세스를 실행하면 서버의 디렉토리 매개변수로 지정된 위치에 로그 파일이 생성됩니다. 이 프로세스에는 기본적으로 DPUMP_DIR로 명명된 디렉토리가 사용되므로 DPDATA1 대신 생성할 수 있습니다.
위의 job_name 매개변수를 보면 원래의 엑스포트에 없는 특별한 항목이 하나 있습니다. 모든 Data Pump 작업은 작업(job)을 통해 이뤄집니다. Data Pump 작업은 DBMS 작업과 달리 주 프로세스를 대신해 데이타를 처리하는 단순한 서버 프로세스입니다. 마스터 제어 프로세스라고 하는 이 주 프로세스는 Advanced Queuing을 통해 이러한 작업 노력을 조정하는데, 이는 마스터 테이블이라고 하는 런타임 시 생성된 특수 테이블을 통해 이뤄집니다. 제시한 예에서 expdp를 실행하면서 사용자 ANANDA의 스키마를 검사하면 job_name 매개변수에 해당되는 CASES_EXPORT 테이블이 있음을 알 수 있습니다. expdp가 종료되면 이 테이블은 삭제됩니다.
엑스포트 모니터링
DPE(Data Pump Export)를 실행하면서 Control-C를 누르면 화면상에 메시지 표시를 중지하지만 프로세스 자체를 엑스포트하지는 않습니다. 대신 다음과 같이 DPE 프롬프트를 표시합니다. 이제 프로세스는 소위 “대화식” 모드에 들어갑니다.
Export>

이 접근방법에서는 DPE 작업에 여러 명령을 입력할 수 있습니다. 요약을 확인하려면 다음과 같이 프롬프트에 STATUS 명령을 사용합니다.
Export> status
Job: CASES_EXPORT
  Operation: EXPORT                        
  Mode: TABLE                         
  State: EXECUTING                     
  Degree: 1
  Job Error Count: 0
  Dump file:  /u02/dpdata1/expCASES.dmp
      bytes written =  2048

Worker 1 Status:
  State: EXECUTING                     
  Object Schema: DWOWNER
  Object Name: CASES
  Object Type: TABLE_EXPORT/TBL_TABLE_DATA/TABLE/TABLE_DATA
  Completed Objects: 1
  Total Objects: 1
  Completed Rows: 4687818

하지만 이것은 상태 표시일 뿐이며 엑스포트는 백그라운드에서 실행되고 있습니다. 화면의 메시지를 계속 확인하려면 Export> 프롬프트에서 CONTINUE_CLIENT 명령을 사용합니다.
병렬 작업
PARALLEL 매개변수를 통해 엑스포트시 하나 이상의 스레드를 사용하면 작업 속도를 크게 개선할 수 있습니다. 스레드마다 개별 덤프 파일을 생성하므로 매개변수 dumpfile은 병렬화 만큼 많은 여러 항목을 갖게 됩니다. 또한 하나씩 명시적으로 입력하는 대신 다음과 같이 대체 문자를 파일 이름으로 지정할 수 있습니다.
expdp ananda/abc123 tables=CASES directory=DPDATA1
  dumpfile=expCASES_%U.dmp parallel=4 job_name=Cases_Export

여기서 dumpfile 매개변수에 어떻게 대체 문자 %U가 생기는지 주목합니다. 이 대체 문자는 파일이 필요에 따라 생성되고 형식은 expCASES_nn.dmp이 됨을 나타내는데, 여기서 nn은 01에서 시작하며 필요에 따라 증가하게 됩니다.
병렬 모드에서는 상태 화면에 네 개의 작업자 프로세스가 표시됩니다. (기본 모드에서는 프로세스가 한 개만 표시됩니다.) 모든 작업자 프로세스가 데이타를 동시에 추출하며 진행률을 상태 화면에 표시합니다.
데이타베이스 파일 및 덤프 파일 디렉토리 파일 시스템에 액세스하려면 I/O 채널을 반드시 구분해야 합니다. 그렇지 않으면 Data Pump 작업의 유지와 관련된 오버헤드가 병렬 스레드의 이점을 뛰어넘어 성능을 저하시킬 수 있습니다. 병렬화는 테이블 수가 병렬 값보다 크고 테이블이 대규모인 경우에만 적용됩니다.
데이타베이스 모니터링
데이타베이스 뷰에서 실행되는 Data Pump 작업에 관해서도 자세한 정보를 확인할 수 있습니다. 작업을 모니터링하는 기본 뷰는 DBA_DATAPUMP_JOBS로 작업에서 실행되는 작업자 프로세스(DEGREE 열)의 수를 알려줍니다. 그 밖의 중요한 뷰에는 DBA_DATAPUMP_SESSIONS가 있는데, 이전 뷰 및 V$SESSION과 조인하면 주 포그라운드(Foreground) 프로세스 세션의 SID를 확인할 수 있습니다.
select sid, serial#
from v$session s, dba_datapump_sessions d
where s.saddr = d.saddr;

이 명령에는 포그라운드 프로세스의 세션이 표시됩니다. 경고 로그에서는 보다 유용한 정보를 얻을 수 있습니다. 프로세스가 시작되면 MCP 및 작업자 프로세스가 다음과 같이 경고 로그에 나타납니다.
kupprdp: master process DM00 started with pid=23, OS id=20530 to execute -
  SYS.KUPM$MCP.MAIN('CASES_EXPORT', 'ANANDA');

kupprdp: worker process DW01 started with worker id=1, pid=24, OS id=20532 to execute -
  SYS.KUPW$WORKER.MAIN('CASES_EXPORT', 'ANANDA');

kupprdp: worker process DW03 started with worker id=2, pid=25, OS id=20534 to execute -
  SYS.KUPW$WORKER.MAIN('CASES_EXPORT', 'ANANDA');

경고 로그에는 Data Pump 작업을 위해 시작된 세션의 PID가 표시됩니다. 실제 SID는 이 질의를 사용해 확인합니다.
select sid, program from v$session where paddr in
 (select addr from v$process where pid in (23,24,25));

PROGRAM 열에는 경고 로그 파일의 이름에 해당되는 프로세스 DM(마스터 프로세스) 또는 DW(작업자 프로세스)가 표시됩니다. SID 23 같은 작업자 프로세스에서 병렬 질의를 사용하는 경우, V$PX_SESSION 뷰에서 확인할 수 있습니다. 이 뷰에는 SID 23으로 표시된 작업자 프로세스에서 실행되는 모든 병렬 질의 세션이 나타납니다.
select sid from v$px_session where qcsid = 23;

V$SESSION_LONGOPS 뷰에서는 작업 완료에 걸리는 시간을 예측하는 또 다른 유용한 정보를 얻을 수 있습니다.
select sid, serial#, sofar, totalwork
from v$session_longops
where opname = 'CASES_EXPORT'
and sofar != totalwork;

totalwork 열에는 총 작업량이 표시되는데, 이 중 현재까지 sofar 작업량을 완료했으므로 이를 통해 얼마나 더 시간이 걸릴지 예측할 수 있습니다.
Data Pump Import
하지만 Data Pump에서 가장 눈에 잘 띄는 부분은 데이타 임포트 성능입니다. 이전에 엑스포트된 데이타를 임포트하려면 다음을 사용합니다.
impdp ananda/abc123 directory=dpdata1 dumpfile=expCASES.dmp job_name=cases_import

임포트 프로세스의 기본 작업 방식은 테이블 및 연관된 모든 객체를 생성하고 테이블이 있는 상태에서 오류를 만들어 내는 것입니다. 기존 테이블에 데이타를 추가해야 하는 경우 위의 명령행에 TABLE_EXISTS_ACTION=APPEND를 사용할 수 있습니다.
DPE와 마찬가지로 프로세스 도중 Control-C를 누르면 DPI(Date Pump Import)의 대화식 모드를 표시하며 Import>가 프롬프트됩니다.
특정 객체 작업
한 사용자에서 특정 프로시저만 엑스포트하여 다른 데이타베이스나 사용자에 다시 생성해야 했던 경험이 있습니까? 기존의 엑스포트 유틸리티와 달리 Data Pump는 특정 유형의 객체만 엑스포트할 수 있습니다. 예를 들어, 다음 명령을 실행하면 테이블, 뷰 또는 함수 등은 제외하고 오로지 프로시저만 엑스포트할 수 있습니다.
expdp ananda/iclaim directory=DPDATA1 dumpfile=expprocs.dmp include=PROCEDURE

To export only a few specific objects--say, function FUNC1 and procedure PROC1--you could use
expdp ananda/iclaim directory=DPDATA1 dumpfile=expprocs.dmp
  include=PROCEDURE:"='PROC1'",FUNCTION:"='FUNC1'"

이 덤프 파일은 소스의 백업으로 사용됩니다. 때로는 이를 사용해 DDL 스크립트를 생성하여 나중에 사용할 수도 있습니다. DDL 스크립트 파일을 생성하려면 SQLFILE이라고 하는 특수 매개변수를 사용합니다.
impdp ananda/iclaim directory=DPDATA1 dumpfile=expprocs.dmp sqlfile=procs.sql

이 명령은 DPDATA1로 지정된 디렉토리에 procs.sql로 명명된 파일을 생성하며 엑스포트 덤프 파일 내의 객체 스크립트가 들어 있습니다. 이 접근방법을 사용하면 다른 스키마에 원본을 보다 신속하게 생성할 수 있습니다.
INCLUDE 매개변수를 사용하면 객체가 덤프 파일에서 포함 또는 제외되도록 정의할 수 있습니다. 예를 들어, INCLUDE=TABLE:"LIKE 'TAB%'" 절을 사용하면 이름이 TAB로 시작하는 테이블만 엑스포트할 수 있습니다. 마찬가지로 INCLUDE=TABLE:"NOT LIKE 'TAB%'" 구문을 사용하면 TAB으로 시작하는 모든 테이블을 제외시킬 수 있습니다. 아니면 EXCLUDE 매개변수를 사용해 특정 객체를 제외시킬 수 있습니다.
Data Pump를 사용하면 외부 테이블로 테이블스페이스를 이동할 수도 있는데, 이렇게 하면 진행 중인 병렬화를 다시 정의하고 기존 프로세스에 테이블을 추가하는 등의 작업에 매우 효과적입니다(이는 본 문서의 범위를 벗어난 내용이므로 자세한 내용은 Oracle Database Utilities 10g Release 1 10.1을 참조하십시오). 다음 명령을 실행하면 Data Pump 엑스포트 유틸리티에서 사용 가능한 매개변수 목록이 생성됩니다.
expdp help=y

마찬가지로 impdp help=y 명령을 실행하면 DPI의 모든 매개변수가 표시됩니다.
Data Pump 작업을 실행하는 동안 DPE 또는 DPI 프롬프트에 STOP_JOB을 실행하여 작업을 일시 중지한 다음 START_JOB으로 다시 시작할 수 있습니다. 이 기능은 공간이 부족하여 계속하기 전에 정정해야 하는 경우 유용하게 사용할 수 있습니다.
자세한 내용은 Oracle Database Utilities 10g Release 1 10.1 설명서 1부를 참조하십시오.
 
 
 
다섯번째.
Flashback 테이블
실수로 삭제한 테이블을 손쉽게 다시 유효화할 수 있는 Oracle Database 10g의 Flashback 테이블 기능
매우 중요한 테이블을 실수로 삭제하여 즉시 복구해야 하는 상황은 생각보다 자주 일어나는 시나리오입니다. (때로는 이처럼 불운한 사용자가 DBA일 수도 있습니다!)
Oracle9i Database에는 Flashback 질의 옵션 개념이 도입되어 데이타를 과거의 시점에서부터 검색하지만, 테이블 삭제 같은 DDL 작업을 순간적으로 되돌릴 수는 없습니다. 이 경우 유일한 수단은 다른 데이타베이스에서 테이블스페이스 적시 복구를 사용한 다음, 엑스포트/임포트 또는 기타 메서드를 사용해 현재 데이타베이스에 테이블을 다시 생성하는 것입니다. 이 프로시저를 수행하려면 복제를 위해 다른 데이타베이스를 사용하는 것은 물론, DBA의 많은 노력과 귀중한 시간이 요구됩니다.
하지만 Oracle Database 10g의 Flashback 테이블 기능으로 들어가면 몇 개의 문만 실행하여 삭제된 테이블을 간단히 검색할 수 있습니다. 그럼, 지금부터 이 기능의 작동 원리에 대해 알아보도록 하겠습니다.
자유로운 테이블 삭제
먼저, 현재 스키마의 테이블을 확인해 봅시다.
SQL> select * from tab;

TNAME                    TABTYPE  CLUSTERID
------------------------ ------- ----------
RECYCLETEST              TABLE

그런 다음, 아래와 같이 고의로 테이블을 삭제합니다.
SQL> drop table recycletest;

Table dropped.

이제 테이블의 상태를 확인합니다.
SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
BIN$04LhcpndanfgMAAAAAANPw==$0 TABLE

RECYCLETEST 테이블이 사라졌지만 새 테이블인 BIN$04LhcpndanfgMAAAAAANPw==$0이 있다는 점에 주목합니다. 좀 더 자세히 설명하면 삭제된 테이블 RECYCLETEST가 완전히 사라지는 대신 시스템 정의 이름으로 이름이 변경된 것입니다. 이 테이블은 여전히 동일한 테이블스페이스에 있으며 원래 테이블과 구조도 동일합니다. 테이블에 인덱스 또는 트리거가 정의되어 있는 경우, 마찬가지로 테이블과 동일한 명명 규칙을 사용하여 이름이 변경됩니다. 프로시저 같은 종속적인 소스는 무효화되지만, 대신 원래 테이블의 트리거 및 인덱스가 이름이 변경된 테이블인 BIN$04LhcpndanfgMAAAAAANPw==$0에 들어가 삭제된 테이블의 완전한 객체 구조를 보존합니다.
테이블 및 연관된 객체는 PC에 있는 것과 유사한 “휴지통(RecycleBin)”이라고 하는 논리적 컨테이너에 들어갑니다. 하지만 이들 객체가 이전에 있던 테이블스페이스에서 옮겨지는 것은 아니며 계속 해당 테이블스페이스에서 공간을 차지하고 있습니다. 휴지통은 단순히 삭제된 객체의 목록을 만드는 논리적 구조입니다. 휴지통의 컨텐트를 확인하려면 SQL*Plus 프롬프트에서 다음 명령을 사용합니다(SQL*Plus 10.1이 있어야 함).
SQL> show recyclebin

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ ------------------
RECYCLETEST      BIN$04LhcpndanfgMAAAAAANPw==$0 TABLE        2004-02-16:21:13:31

이렇게 하면 테이블의 원래 이름인 RECYCLETEST는 물론, 삭제된 후 생성된 새 테이블 이름과 동일한 휴지통에서의 새 이름이 표시됩니다. (참고: 정확한 이름은 플랫폼별로 다를 수 있습니다.) 테이블을 다시 유효화하기 위해서는 FLASHBACK TABLE 명령만 사용하면 됩니다.
SQL> FLASHBACK TABLE RECYCLETEST TO BEFORE DROP;

FLASHBACK COMPLETE.

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
RECYCLETEST                    TABLE

자, 테이블이 정말 간단히 유효화되지 않습니까? 지금 휴지통을 확인하면 비어 있습니다.
여기서 유의할 점은 테이블을 휴지통에 넣는다고 해도 원래 테이블스페이스의 공간이 제거되는 것은 아니라는 것입니다. 공간을 제거하려면 다음을 사용해 휴지통을 지워야 합니다.
PURGE RECYCLEBIN;

하지만 Flashback 기능을 사용하지 않고 테이블을 완전히 삭제하려면 어떻게 해야 할까요? 이 경우 다음을 사용하면 테이블을 영구적으로 삭제할 수 있습니다.
DROP TABLE RECYCLETEST PURGE;

이 명령을 실행하면 테이블 이름이 휴지통 이름으로 변경되는 것이 아니라, 10g 이전 버전에서처럼 영구적으로 삭제됩니다.
휴지통 관리
이 프로세스에서 테이블을 완전히 삭제하지 않아 테이블스페이스를 해제하지 않은 상태에서 삭제된 객체가 테이블스페이스의 모든 공간을 차지하면 어떤 일이 발생할까요?
답은 간단합니다. 그 같은 상황은 결코 발생하지 않습니다. 데이타 파일에 데이타를 추가할 공간을 확보해야 할 정도로 휴지통 데이타가 테이블스페이스로 꽉 차는 상황이 발생하면 테이블스페이스는 이른바 “공간 압축” 상태에 들어갑니다. 위의 시나리오에서 객체는 선입선출 방식으로 휴지통에서 자동으로 지워지며, 종속된 객체(예: 인덱스)는 테이블보다 먼저 제거됩니다.
마찬가지로 특정 테이블스페이스에 정의된 사용자 할당량에도 공간 압축이 발생할 수 있습니다. 테이블에는 사용 가능한 공간이 충분하지만 사용자는 할당된 공간이 부족할 수 있습니다. 이러한 상황에서 Oracle은 해당 테이블스페이스의 사용자에 속한 객체를 자동으로 지웁니다.
이 외에도 여러 가지 방법으로 휴지통을 수동으로 제어할 수 있습니다. 삭제한 후 휴지통에서 TEST라고 명명된 특정 테이블을 삭제하려면 다음을 실행하거나,
PURGE TABLE TEST;

아래와 같이 해당 휴지통 이름을 사용합니다.
PURGE TABLE "BIN$04LhcpndanfgMAAAAAANPw==$0";

이 명령을 실행하면 휴지통에서 TEST 테이블과 인덱스, 제약 조건 등과 같은 모든 종속 객체가 삭제되어 일정 공간을 확보하게 됩니다. 하지만 휴지통에서 인덱스를 영구적으로 삭제하려면 다음을 사용합니다.
purge index in_test1_01;

이렇게 하면 인덱스만 제거되며 테이블의 복사본은 휴지통에 남아 있습니다.
때로는 상위 레벨에서 지우는 것이 유용할 수도 있습니다. 예를 들어, 테이블스페이스 USERS의 휴지통에 있는 모든 객체를 지워야 한다면 다음을 실행합니다.
PURGE TABLESPACE USERS;

휴지통에서 해당 테이블스페이스의 특정 사용자만 지워야 하는 경우도 있습니다. 이 접근방법은 사용자가 많은 수의 과도 상태 테이블을 생성 및 삭제하는 데이타 웨어하우스 유형의 환경에 유용합니다. 다음과 같이 위의 명령을 수정해 지우기 작업을 특정 사용자만으로 제한할 수 있습니다.
PURGE TABLESPACE USERS USER SCOTT;

사용자 SCOTT는 다음 명령으로 휴지통을 지웁니다.
PURGE RECYCLEBIN;

DBA는 다음을 사용해 테이블스페이스의 모든 객체를 지울 수 있습니다.
PURGE DBA_RECYCLEBIN;

위에서 살펴본 것처럼 휴지통은 사용자의 특정한 요구에 맞는 다양한 방식으로 관리할 수 있습니다.
테이블 버전 및 Flashback
다음과 같이 동일한 테이블을 여러 번 생성 및 삭제해야 하는 경우도 흔히 발생합니다.
CREATE TABLE TEST (COL1 NUMBER);
INSERT INTO TEST VALUES (1);
COMMIT;
DROP TABLE TEST;
CREATE TABLE TEST (COL1 NUMBER);
INSERT INTO TEST VALUES (2);
COMMIT;
DROP TABLE TEST;
CREATE TABLE TEST (COL1 NUMBER);
INSERT INTO TEST VALUES (3);
COMMIT;
DROP TABLE TEST;

여기서 TEST 테이블을 순간적으로 되돌린다면 COL1 열의 값은 어떻게 될까요? 기존의 개념에서 보면 휴지통에서 테이블의 첫 번째 버전이 검색되고 COL1 열의 값은 1이 될 것입니다. 하지만 실제로는 첫 번째가 아닌 테이블의 세 번째 버전이 검색되므로 COL1 열의 값은 1이 아닌 3이 됩니다.
이 때 삭제된 테이블의 다른 버전을 검색할 수도 있습니다. 하지만 TEST 테이블이 존재하는 이러한 작업이 불가능한데, 이 경우 다음 두 가지를 선택할 수 있습니다.
다음과 같이 이름 바꾸기 옵션을 사용합니다.
FLASHBACK TABLE TEST TO BEFORE DROP RENAME TO TEST2;
FLASHBACK TABLE TEST TO BEFORE DROP RENAME TO TEST1;

이렇게 하면 테이블의 첫 번째 버전은 TEST1으로, 두 번째 버전은 TEST2로 다시 유효화됩니다. 또한 TEST1 및 TEST2에서 COL1의 값은 각각 1과 2가 됩니다. 또는
복원할 테이블의 특정 휴지통 이름을 사용합니다. 이를 위해 먼저 테이블의 휴지통 이름을 식별한 후 다음을 실행합니다.
FLASHBACK TABLE "BIN$04LhcpnoanfgMAAAAAANPw==$0" TO BEFORE DROP RENAME TO TEST2;
FLASHBACK TABLE "BIN$04LhcpnqanfgMAAAAAANPw==$0" TO BEFORE DROP RENAME TO TEST1;

이렇게 하면 삭제된 테이블의 두 가지 버전이 복원됩니다.
주의 사항
삭제 취소 기능을 사용하면 테이블의 이름이 원래대로 돌아가지만 인덱스 및 트리거 같은 연관된 객체는 그렇지 않으며 계속 휴지통 이름으로 남아 있습니다. 또한 뷰 및 프로시저 같이 테이블에 정의된 소스는 재컴파일되지 않으며 무효화된 상태로 남게 됩니다. 이러한 이전 이름들은 수동으로 검색한 다음 순간적으로 되돌린 테이블에 적용해야 합니다.
이 정보는 USER_RECYCLEBIN으로 명명된 뷰에서 관리됩니다. 테이블을 순간적으로 되돌리기 전에 다음 질의를 사용해 이전 이름을 검색합니다.
SELECT OBJECT_NAME, ORIGINAL_NAME, TYPE
FROM USER_RECYCLEBIN
WHERE BASE_OBJECT = (SELECT BASE_OBJECT FROM USER_RECYCLEBIN
WHERE ORIGINAL_NAME = 'RECYCLETEST')
AND ORIGINAL_NAME != 'RECYCLETEST';

OBJECT_NAME                    ORIGINAL_N TYPE
------------------------------ ---------- --------
BIN$04LhcpnianfgMAAAAAANPw==$0 IN_RT_01   INDEX
BIN$04LhcpnganfgMAAAAAANPw==$0 TR_RT      TRIGGER

테이블을 순간적으로 되돌리면 RECYCLETEST 테이블의 인덱스 및 트리거에는 OBJECT_NAME 열에 나타난 이름이 지정됩니다. 위의 질의에서는 원래 이름을 사용해 객체의 이름을 다음과 같이 변경할 수 있습니다.
ALTER INDEX "BIN$04LhcpnianfgMAAAAAANPw==$0" RENAME TO IN_RT_01;
ALTER TRIGGER "BIN$04LhcpnganfgMAAAAAANPw==$0" RENAME TO TR_RT;

한가지 유의해야 할 예외는 비트맵 인덱스입니다. 비트맵 인덱스를 삭제하면 휴지통에 들어가지 않으므로 검색할 수 없습니다. 또한 뷰에서 제약 조건 이름을 검색할 수 없습니다. 따라서 이 인덱스의 이름은 다른 소스에서 변경해야 합니다.
Flashback 테이블의 다른 용도
Flashback Drop Table에는 테이블 삭제 작업을 되돌리는 것 외에도 다른 기능이 있습니다. Flashback 질의와 마찬가지로 이를 사용해 테이블을 다른 시점으로 다시 유효화하여 전체 테이블을 “이전” 버전으로 바꿀 수 있습니다. 예를 들어, 다음 문을 사용하면 테이블을 시스템 변경 번호(SCN) 2202666520으로 다시 유효화합니다.
FLASHBACK TABLE RECYCLETEST TO SCN 2202666520;

이 기능은 Oracle Data Pump 기술로 다른 테이블을 생성하고 Flashback으로 테이블을 해당 SCN의 데이타 버전으로 채운 다음, 원래의 테이블을 새 테이블로 바꿉니다. 테이블을 어느 정도까지 순간적으로 되돌릴 수 있는지 확인하려면 Oracle Database 10g의 버전 관리 기능을 사용합니다. (자세한 내용은 이 시리즈의 1주 부분을 참조하십시오.) 또한 Flashback 절에 SCN 대신 타임 스탬프를 지정할 수도 있습니다.
Flashback 테이블 가능에 대한 자세한 내용은 Oracle Database Administrator's Guide 10g Release 1 (10.1)을 참조하십시오.
 
 
 
 
제 6 주
Automatic Workload Repository
AWR을 이용하여 분석과 튜닝을 위한 데이타베이스 성능 통계정보와 메트릭을 수집하고, 데이타베이스에서 사용한 정확한 시간을 확인하거나 세션 정보를 저장할 수 있습니다.
데이타베이스에 성능에 관련한 문제가 생겼을 때, 귀하가 DBA로서 가장 먼저 취하는 조치는 무엇입니까? 아마도 문제에 일정한 패턴이 존재하는지 확인하는 것이 가장 일반적인 접근방법의 하나일 것입니다. “동일한 문제가 반복되는가?”, “특정한 시간대에만 발생하는가?”, 또는 “두 가지 문제에 연관성이 있는가?” 등의 질문을 먼저 제기해 봄으로써 보다 정확한 진단을 수행할 수 있습니다.
Oracle DBA들은 데이타베이스 운영에 관련한 통계정보를 수집하거나 성능 메트릭(metric)을 추출하기 위해 써드 파티 툴, 또는 직접 개발한 툴을 사용하고 있습니다. 이렇게 수집된 정보는, 문제 발생 이전과 이후의 상태를 비교하는 데 이용됩니다. 과거에 발생했던 이벤트들을 재현해 봄으로써 현재 문제를 다양한 관점에서 분석할 수 있습니다. 이처럼 관련 통계정보들을 지속적으로 수집하는 것은 성능 분석에서 매우 중요한 작업 중의 하나입니다.
오라클은 한동안 이를 위해 Statspack이라는 이름의 빌트-인 툴을 제공하기도 했습니다. Statspack은 상황에 따라 매우 유용하긴 했지만, 성능 관련 트러블슈팅 과정에서 요구되는 안정성이 결여되었다는 문제가 있었습니다. Oracle Database 10g는 성능 통계정보의 수집과 관련하여 그 기능이 비약적으로 향상된 Automatic Workload Repository(AWR)을 제공합니다. AWR은 데이타베이스와 함께 설치되며, 기본적인 통계정보뿐 아니라 통계정보로부터 유추된 메트릭(derived metric)도 함께 수집합니다.
간단하게 테스트해 보기
AWR을 이용한 새로운 기능들은 $ORACLE_HOME/rdbms/admin 디렉토리의 awrrpt.sql 스크립트를 실행하고, 수집된 통계정보와 메트릭 정보를 바탕으로 생성된 리포트를 확인함으로써 가장 쉽게 이해할 수 있습니다. awrrpt.sql 스크립트는 Statspack과 유사한 구조로 되어있습니다. 먼저 현재 저장된 AWR 스냅샷을 모두 표시한 후, 시간 간격 설정을 위한 입력값을 요구합니다. 출력은 두 가지 형태로 제공됩니다. 텍스트 포맷 출력은 Statspack 리포트와 유사하지만, AWR 리포지토리를 기반으로 하며 (디폴트로 제공되는) HTML 포맷을 통해 section/subsection으로 구분된 하이퍼링크를 제공하는 등 사용자 편의성을 강화하였다는 점에서 차이를 갖습니다. 먼저 awrrpt.sql 스크립트를 실행하여 리포트를 확인해 보시고, AWR의 기능에 대한.특성을 이해하시기 바랍니다.
구현 원리
이제 AWR의 설계방식과 구조에 대해 알아보기로 합시다. AWR은 수집된 성능관련 통계정보가 저장되며 이를 바탕으로 성능 메트릭을 제공함으로서 잠재적인 문제의 원인 추적을 가능하게 해주는 근간을 제공해 줍니다. Statspack의 경우와 달리, Oracle10g는 AWR을 활용하여 새로운 MMON 백그라운드 프로세스와, 여러 개의 슬레이브 프로세스를 통해 자동적으로 매시간별 스냅샷 정보를 수집합니다. 공간 절약을 위해, 수집된 데이타는 7일 후 자동으로 삭제됩니다. 스냅샷 빈도와 보관 주기는 사용자에 의해 설정 가능합니다. 현재 설정값을 보기 위해서는 아래와 같이 명령을 수행하면 됩니다:
select snap_interval, retention
from dba_hist_wr_control;

SNAP_INTERVAL       RETENTION
------------------- -------------------
+00000 01:00:00.0   +00007 00:00:00.0

위의 실행결과는 스냅샷이 매 시간대 별로 수집되고 있으며 수집된 통계가 7일 동안 보관되고 있음을 보여주고 있습니다. 스냅샷 주기를 20분으로, 보관 주기를 2일로 변경하기 위해서는 아래와 같이 수행하면 됩니다. (매개변수는 분 단위로 표시됩니다.)
begin
   dbms_workload_repository.modify_snapshot_settings (
      interval => 20,
      retention => 2*24*60
   );
end;

AWR은 수집된 통계를 저장하기 위해 여러 개의 테이블을 사용합니다. 이 테이블들은 모두 SYS 스키마의 SYSAUX 테이블스페이스 내에 저장되어 있으며, WRM$_* 또는 WRH$_*의 네임 포맷을 갖습니다. WRM$_* 테이블은 수집 대상 데이타베이스 및 스냅샷에 관련한 메타데이타 정보를, WRH$_* 테이블은 실제 수집된 통계 정보를 저장하는데 사용됩니다. (예측하시는 바와 같이, H는 “historical”, M은 “metadata”의 약자를 의미합니다.) 이 테이블을 기반으로 DBA_HIST_라는 prefix를 갖는 여러 가지 뷰가 제공되고 있으며, 이 뷰들을 응용하여 자신만의 성능 분석 툴을 만들 수도 있습니다. 뷰의 이름은 테이블 이름과 직접적인 연관성을 갖습니다. 예를 들어 DBA_HIST_SYSMETRIC_SUMMARY 뷰는 WRH$_SYSMETRIC_SUMMARY 테이블을 기반으로 합니다.
AWR 히스토리 테이블은 Statspack에서는 수집되지 않았던 다양한 정보(테이블스페이스 사용 통계, 파일시스템 사용 통계, 운영체제 통계 등)를 제공합니다. 테이블의 전체 리스트는 아래와 같이 데이타 딕셔너리 조회를 통해 확인할 수 있습니다:
select view_name from user_views where view_name like 'DBA_HIST_%' escape '';

DBA_HIST_METRIC_NAME 뷰는 AWR에 수집되는 주요 메트릭과 메트릭이 속한 그룹, 그리고 수집 단위(unit) 등을 정의하고 있습니다. DBA_HIST_METRIC_NAME 뷰의 레코드에 대한 조회 결과의 예가 아래와 같습니다:
DBID                  : 4133493568
GROUP_ID              : 2
GROUP_NAME            : System Metrics Long Duration
METRIC_ID             : 2075
METRIC_NAME           : CPU Usage Per Sec
METRIC_UNIT           : CentiSeconds Per Second

위에서는 "초당 CPU 사용량(CPU Usage Per Sec)" 메트릭이 “100분의 1초(CentiSeconds Per Second)” 단위로 수집되고 있으며, 이 메트릭이 "System Metrics Long Duration” 그룹에 속함을 확인할 수 있습니다. 이 레코드를 DBA_HIST_SYSMETRIC_SUMMARY와 JOIN하여 실제 통계를 확인할 수 있습니다:
select begin_time, intsize, num_interval, minval, maxval, average, standard_deviation sd
from dba_hist_sysmetric_summary where metric_id = 2075;

BEGIN    INTSIZE NUM_INTERVAL   MINVAL  MAXVAL  AVERAGE           SD
----- ---------- ------------   ------- ------- --------  ----------
11:39     179916           30         0      33        3  9.81553548
11:09     180023           30        21      35       28  5.91543912

... 후략 ...

위 조회 결과를 통해 백 분의 1초 단위로 CPU 자원이 어떻게 소비되고 있는지 확인할 수 있습니다. SD(standard deviation, 표준 편차) 값을 참조하면 계산된 평균 값이 실제 부하와 비교하여 얼마나 오차를 갖는지 분석 가능합니다. 첫 번째 레코드의 경우, 초당 백 분의 3초의 CPU 시간이 소모된 것으로 계산되었지만, 표준 편차가 9.81이나 되므로 계산된 3의 평균값이 실제 부하를 정확하게 반영하지 못하는 것으로 볼 수 있습니다. 반면 28의 평균값과 5.9의 표준 편차를 갖는 두 번째 레코드가 실제 수치에 더 가깝다고 볼 수 있습니다. 이러한 트렌드 분석을 통해 성능 메트릭과 환경 변수의 상관 관계를 보다 명확하게 이해할 수 있습니다.
통계의 활용
지금까지 AWR의 수집 대상이 어떻게 정의되는지 알아보았습니다. 이번에는 수집된 데이타를 어떻게 활용할 수 있는지 설명하기로 합니다.
성능 문제는 독립적으로 존재하는 경우가 거의 없으며, 대개 다른 근본적인 문제를 암시하는 징후로서 해석되는 것이 일반적입니다. 전형적인 튜닝 과정의 예를 짚어보기로 합시다: DBA가 시스템 성능이 저하되었음을 발견하고 wait에 대한 진단을 수행합니다. 진단 결과 “buffer busy wait”이 매우 높게 나타나고 있음을 확인합니다. 그렇다면 문제의 원인은 무엇일까요? 여러 가지 가능성이 존재합니다: 인덱스의 크기가 감당할 수 없을 만큼 커지고 있을 수도 있고, 테이블의 조밀도(density)가 너무 높아 하나의 블록을 메모리에 읽어 오는 데 요구되는 시간이 제한된 때문일 수도 있고, 그 밖의 다른 이유가 있을 수 있습니다. 원인이 무엇이든, 문제가 되는 세그먼트를 먼저 확인해 보는 것이 필요합니다. 문제가 인덱스 세그먼트에서 발생했다면, 리빌드 작업을 수행하거나 reverse key index로 변경하거나 또는 Oracle Database 10g에서 새로 제공하는 hash-partitioned index로 변경해 볼 수 있을 것입니다. 문제가 테이블에서 발생했다면, 저장 관련 매개변수를 변경해서 조밀도를 낮추거나, 자동 세그먼트 공간 관리(automatic segment space management)가 설정된 테이블스페이스로 이동할 수 있을 것입니다.
DBA가 실제로 사용하는 접근법은 일반적인 방법론, DBA의 경험 및 지식 등을 그 바탕으로 합니다. 만일 똑같은 일을 별도의 엔진이, 메트릭을 수집하고 사전 정의된 로직을 바탕으로 적용 가능한 방법을 추론하는 엔진이 대신해 준다면 어떨까요? DBA의 작업이 한층 쉬워지지 않을까요?
바로 이러한 엔진이 Oracle Database 10g에 새로 추가된 Automatic Database Diagnostic Monitor (ADDM)입니다. ADDM은 AWR이 수집한 데이타를 사용하여 결론을 추론합니다. 위의 예의 경우, ADDM은 buffer busy wait이 발생하고 있음을 감지하고, 필요한 데이타를 조회하여 wait이 실제로 발생하는 세그먼트를 확인한 후, 그 구조와 분포를 평가함으로써 최종적으로 해결책을 제시합니다. AWR의 스냅샷 수집이 완료될 때마다, ADDM이 자동으로 호출되어 메트릭을 점검하고 권고사항을 제시합니다. 결국 여러분은 데이타 분석 및 권고사항 제시를 담당하는 풀 타임 DBA 로봇을 하나 두고, 보다 전략적인 업무에 집중할 수 있게 된 셈입니다.
Enterprise Manager 10g 콘솔의 “DB Home” 페이지에서 ADDM의 권고사항과 AWR 리포지토리 데이타를 확인할 수 있습니다. AWR 리포트를 보려면, Administration->Workload Repository->Snapshot의 순서로 메뉴를 따라가야 합니다. ADDM의 자세한 기능은 향후 연재에서 소개하도록 하겠습니다.
특정 조건을 기준으로 알림 메시지를 생성하도록 설정하는 것도 가능합니다. 이 기능은 Server Generated Alert라 불리며, Advanced Queue에 푸시(push) 형태로 저장되고 리스닝 중인 모든 클라이언트에 전달되는 형태로 관리됩니다. Enterprise Manager 10g 역시 Server Generated Alert의 클라이언트의 하나로서 관리됩니다.
타임 모델 (Time Model)
성능 문제가 발생했을 때, 응답시간을 줄이기 위한 방법으로 DBA의 머릿속에 가장 먼저 떠오르는 것은 무엇일까요? 말할 필요도 없이, 문제의 근본원인을 찾아내어 제거하는 것이 최우선일 것입니다. 그렇다면 얼마나 많은 시간이 (대기가 아닌) 실제 작업에 사용되었는지 어떻게 확인할 수 있을까요? Oracle Database 10g는 여러 가지 자원에 관련한 실제 사용 시간을 확인하기 위한 타임 모델(time model)을 구현하고 있습니다. 전체 시스템 관련 소요 시간 통계는 V$SYS_TIME_MODEL 뷰에 저장됩니다. V$SYS_TIME_MODEL 뷰에 대한 쿼리 결과의 예가 아래와 같습니다.
STAT_NAME                                     VALUE
-------------------------------------         --------------
DB time                                       58211645
DB CPU                                        54500000
background cpu time                           254490000
sequence load elapsed time                    0
parse time elapsed                            1867816
hard parse elapsed time                       1758922
sql execute elapsed time                      57632352
connection management call elapsed time       288819
failed parse elapsed time                     50794
hard parse (sharing criteria) elapsed time    220345
hard parse (bind mismatch) elapsed time       5040
PL/SQL execution elapsed time                 197792
inbound PL/SQL rpc elapsed time               0
PL/SQL compilation elapsed time               593992
Java execution elapsed time                   0
bind/define call elapsed time                 0

위에서 DB time이라는 통계정보는 인스턴스 시작 이후 데이타베이스가 사용한 시간의 누적치를 의미합니다. 샘플 작업을 실행한 다음 다시 뷰를 조회했을 때 표시되는 DB time의 값과 이전 값의 차이가 바로 해당 작업을 위해 데이타베이스가 사용한 시간이 됩니다. 튜닝을 거친 후 DB time 값의 차이를 다시 분석하면 튜닝을 통해 얻어진 성능 효과를 확인할 수 있습니다.
이와 별도로 V$SYS_TIME_MODEL 뷰를 통해 파싱(parsing) 작업 또는 PL/SQL 컴파일 작업에 소요된 시간 등을 확인할 수 있습니다. 이 뷰를 이용하면 시스템이 사용한 시간을 확인하는 것도 가능합니다. 시스템 / 데이타베이스 레벨이 아닌 세션 레벨의 통계를 원한다면 V$SESS_TIME_MODEL 뷰를 이용할 수 있습니다. V$SESS_TIME_MODEL 뷰는 현재 연결 중인 active/inactive 세션들의 통계를 제공합니다. 세션의 SID 값을 지정해서 개별 세션의 통계를 확인할 수 있습니다.
이전 릴리즈에서는 이러한 통계가 제공되지 않았으며, 사용자들은 여러 정보 소스를 참고해서 근사치를 추측할 수 밖에 없었습니다.
Active Session History
Oracle Database 10g의 V$SESSION에도 개선이 이루어졌습니다. 가장 중요한 변화로 wait 이벤트와 그 지속시간에 대한 통계가 뷰에 추가되어, V$SESSION_WAIT를 별도로 참조할 필요가 없게 되었다는 점을 들 수 있습니다. 하지만 이 뷰가 실시간 정보를 제공하므로, 나중에 다시 조회했을 때에는 중요한 정보가 이미 사라져 버리고 없을 수 있습니다. 예를 들어 wait 상태에 있는 세션이 있음을 확인하고 이를 조회하려 하면, 이미 wait 이벤트가 종료되어 버려 아무런 정보도 얻지 못하는 경우가 있을 수 있습니다.
또 새롭게 추가된 Active Session History(ASH)는 AWR과 마찬가지로 향후 분석 작업을 위해 세션 성능 통계를 버퍼에 저장합니다. AWR과 다른 점은, 테이블 대신 메모리가 저장 매체로 이용되며 V$ACTIVE_SESSION_HISTORY 등을 통해 조회된다는 사실입니다. 데이타는 1초 단위로 수집되며, 액티브 세션만이 수집 대상이 됩니다. 버퍼는 순환적인 형태로 관리되며, 저장 메모리 용량이 가득 차는 경우 오래된 데이타부터 순서대로 삭제됩니다. 이벤트를 위해 대기 중인 세션의 수가 얼마나 되는지 확인하려면 아래와 같이 조회하면 됩니다:
select session_id||','||session_serial# SID, n.name, wait_time, time_waited
from v$active_session_history a, v$event_name n
where n.event# = a.event#

위 쿼리는 이벤트 별로 대기하는 데 얼마나 많은 시간이 사용되었는지를 알려 줍니다. 특정 wait 이벤트에 대한 드릴다운을 수행할 때에도 ASH 뷰를 이용할 수 있습니다. 예를 들어, 세션 중 하나가 buffer busy wait 상태에 있는 경우 정확히 어떤 세그먼트에 wait 이벤트가 발생했는지 확인하는 것이 가능합니다. 이때 ASH 뷰의 CURRENT_OBJ# 컬럼과 DBA_OBJECTS 뷰를 조인하면 문제가 되는 세그먼트를 확인할 수 있습니다.
ASH 뷰는 그 밖에도 병렬 쿼리 서버 세션에 대한 기록을 저장하고 있으므로, 병렬 쿼리의 wait 이벤트를 진단하는 데 유용하게 활용됩니다. 레코드가 병렬 쿼리의 slave process로서 활용되는 경우, coordinator server session의 SID는 QC_SESSION_ID 컬럼으로 확인할 수 있습니다. SQL_ID 컬럼은 wait 이벤트를 발생시킨 SQL 구문의 ID를 의미하며, 이 컬럼과 V$SQL 뷰를 조인하여 문제를 발생시킨 SQL 구문을 찾아낼 수 있습니다. CLIENT_ID 컬럼은 웹 애플리케이션과 같은 공유 사용자 환경에서 클라이언트를 확인하는 데 유용하며, 이 값은 DBMS_SESSION.SET_IDENTFIER를 통해 설정 가능합니다.
ASH 뷰가 제공하는 정보의 유용성을 감안하면, AWR과 마찬가지로 이 정보들을 영구적인 형태의 매체에 저장할 필요가 있을 수도 있습니다. AWR 테이블을 MMON 슬레이브를 통해 디스크로 flush 할 수 있으며, 이 경우 DBA_HIST_ACTIVE_SESS_HISTORY 뷰를 통해 저장된 결과를 확인할 수 있습니다.
수작업으로 스냅샷 생성하기
스냅샷은 자동으로 수집되도록 디폴트 설정되어 있으며, 원하는 경우 온디맨드 형태의 실행이 가능합니다. 모든 AWR 기능은 DBMS_WORKLOAD_REPOSITORY 패키지에 구현되어 있습니다. 스냅샷을 실행하려면 아래와 같은 명령을 사용하면 됩니다:
execute dbms_workload_repository.create_snapshot

위 명령은 스냅샷을 즉각적으로 실행하여 그 결과를 table WRM$_SNAPSHOT 테이블에 저장합니다. 수집되는 메트릭의 수준은 TYPICAL 레벨로 설정됩니다. 더욱 자세한 통계를 원하는 경우 FLUSH_LEVEL 매개변수를 ALL로 설정하면 됩니다. 수집된 통계는 자동으로 삭제되며, 수작업으로 삭제하려는 경우 drop_snapshot_range() 프로시저를 실행하면 됩니다.
베이스라인
성능 튜닝 작업을 수행할 때에는 먼저 일련의 메트릭에 대한 베이스라인(baseline)을 수집하고 튜닝을 위한 변경 작업을 수행한 뒤, 다시 또 다른 베이스라인 셋을 수집하는 과정을 거치는 것이 일반적입니다. 이렇게 수집된 두 가지 셋을 서로 비교하여 변경 작업의 효과를 평가할 수 있습니다. AWR에서는 기존에 수집된 스냅샷을 통해 이러한 작업이 가능합니다. 예를 들어 매우 많은 자원을 사용하는 apply_interest라는 프로세스가 오후 1시부터 3시까지 실행되었고, 이 기간 동안 스냅샷 ID 56에서 59까지가 수집되었다고 합시다. 이 스냅샷들을 위해 apply_interest_1이라는 이름의 베이스라인을 아래와 같이 정의할 수 있습니다:
exec dbms_workload_repository.create_baseline (56,59,'apply_interest_1')

위 명령은 스냅샷 56에서 59까지를 ‘apply_interest_1’이라는 이름의 베이스라인으로 표시합니다. 기존에 설정된 베이스라인은 아래와 같이 확인합니다:
select * from dba_hist_baseline;

      DBID BASELINE_ID BASELINE_NAME        START_SNAP_ID END_SNAP_ID
---------- ----------- -------------------- ------------- -----------
4133493568           1 apply_interest_1                56          59

튜닝 과정을 거친 후, 또 다른 이름(예: apply_interest_2)의 베이스라인을 생성하여, 이 두 가지 베이스라인에 해당하는 스냅샷의 메트릭을 비교할 수 있습니다. 이처럼 비교 대상을 한정함으로써 성능 튜닝의 효과를 한층 향상시킬 수 있습니다. 분석이 끝나면 drop_baseline(); 프로시저로 베이스라인을 삭제할 수 있습니다 (이 때 스냅샷은 그대로 보존됩니다). 또 오래된 스냅샷이 삭제되는 과정에서, 베이스라인과 연결된 스냅샷은 삭제되지 않습니다.
결론
이 문서는 AWR의 매우 기초적인 기능만을 소개하고 있습니다. 더욱 자세한 내용을 확인하시려면 Oracle Database 10g 제품 문서를 확인하시기 바랍니다. 기술백서(“ The Self-Managing Database: Automatic Performance Diagnosis)에서도 AWR과 ADDM를 매우 깊이 있게 다루고 있습니다. 제 18주에는, ADDM을 이용하여 실제 문제를 해결하는 방법에 대해 자세하게 설명할 예정입니다.
 
 
 
 
제 7 주
SQL*Plus의 향상된 기능
Oracle Database 10g의 SQL*Plus 툴에는 프롬프트, 파일 조작 기능 등 몇 가지 눈에 띄는 기능 개선이 추가되었습니다.
DBA가 하루에 가장 많이 사용하는 툴은 무엇일까요? 아마 GUI 대신 오래된 작업 방식을 고수하고 있는 본인과 같은 DBA들이라면 SQL*Plus 커맨드 라인 툴을 그 첫 번째로 꼽을 것입니다.
Oracle Database 10g에서 Enterprise Manager 10g의 기능이 한층 강화되었음에도 불구하고, 초심자와 숙련된 DBA 모두에게 있어 SQL*Plus는 앞으로도 오랫동안 유용하게 활용될 것입니다.
이번 연재에서는 SQL*Plus 10.1.0.2에 추가된 유용한 기능을 살펴 보고자 합니다. 이 강좌를 따라 해 보려면 Oracle Database 10g에 포함된 sqlplus를 사용해야 함을 주의하시기 바랍니다 (Oracle9i Database의 sqlplus을 사용해서 10g 데이타베이스에 접속해서는 안됩니다).
프롬프트의 활용
지금 나는 어디에 있는가? 그리고 나는 누구인가? 지금 형이상학적인 질문을 던지려는 것이 아닙니다. SQL*Plus 환경의 관점에서 사용자의 위치를 묻는 질문입니다. SQL*Plus가 지금까지 천편일률적으로 제공했던 SQL> 프롬프트는 사용자가 누구이고 어디에 연결되었는지에 대한 아무런 정보도 제공하지 않습니다. 이전 릴리즈에서는 프롬프트를 바꾸려면 복잡한 코딩이 필요했습니다. SQL*Plus 10.1.0.2는 아래와 같은 간단한 명령만으로 프롬프트를 바꿀 수 있습니다:
set sqlprompt "_user _privilege> "

그러면 SQL*Plus 프롬프트는 아래와 같은 형식으로 표시됩니다:
SYS AS SYSDBA>

위의 경우는 SYS 사용자가 SYSDBA로서 접속한 상황임을 의미합니다. 위에서 _user와 _privilege라는 두 개의 변수가 활용되는 방법을 참고하십시오. _user는 현재 사용자를 _privilege는 로그인에 사용되는 privilege를 뜻합니다.
이번에는 다른 방법을 써 봅시다. 아래는 프롬프트에 오늘 날짜가 함께 표시되도록 하는 명령입니다:
SQL> set sqlprompt "_user _privilege 'on' _date >"
SYS AS SYSDBA on 06-JAN-04 >

여기에 database connection identifier를 추가할 수도 있습니다. 이 방법은 사용자의 “위치”를 수시로 확인해야 하는 환경에서 대단히 유용합니다.
SQL> set sqlprompt "_user 'on' _date 'at' _connect_identifier >"
ANANDA on 06-JAN-04 at SMILEY >

이번에는 오늘 날짜에 시간과 분까지 함께 표시하도록 해 보겠습니다.
ANANDA on 06-JAN-04 at SMILEY > alter session set nls_date_format = 'mm/dd/yyyy hh24:mi:ss';

Session altered.

ANANDA on 01/06/2004 13:03:51 at SMILEY >

이처럼 몇 번의 간단한 키 입력 만으로 매우 많은 정보를 포함하는 SQL 프롬프트가 만들어졌습니다. 이 설정을 glogin.sql 파일에 저장하면 앞으로도 계속 같은 프롬프트를 사용할 수 있습니다.
불필요한 인용부호의 생략
Oracle9i이 internal login을 더 이상 지원하지 않는다고 발표되었을 때, 많은 DBA들은 불만의 함성을 터뜨렸습니다. Internal login이 없다면 커맨드 라인 상에서 SYS 패스워드를 입력할 수 없고 따라서 보안 관리가 어려워진다는 이유였습니다. 오라클은 그 해결책으로 운영체제 프롬프트 상에서 인용부호를 사용하는 방법을 제시했습니다:
sqlplus "/ as sysdba"

DBA들은 이러한 변화에 만족하지 않았지만 참고 받아들일 수 밖에 없었습니다. Oracle Database 10g에서는 이러한 요구사항이 없어졌으며, 아래와 같은 방법으로 인용부호를 사용하지 않고 SYSDBA권한으로 로그인하는 것이 가능합니다.
sqlplus / as sysdba

이러한 변화는 단순히 입력할 문자의 수가 줄었다는 것만을 의미하지 않습니다. Unix와 같은 운영체제에서 escape 문자를 사용할 필요가 없어졌다는 것도 새로운 이점의 하나입니다.
파일 조작 기능의 향상
DBA가 문제 해결 과정에서 임시로 만든 SQL 구문이 있다고 가정해 봅시다. 이 DBA는 만든 구문을 나중에 다시 재사용하기 위해 저장하고 싶어할 수도 있습니다. 이럴 때 어떻게 해야 할까요? 아마도 아래와 같은 방법으로 파일에 개별 저장하는 방법을 쓰게 될 것입니다:
select something1 ....
save 1
select something else ....
save 2
select yet another thing ....
save 3

결국 위의 구문을 모두 사용하려면 그에 해당하는 세이브 파일을 모두 불러내어야 합니다. 이 얼마나 번거로운가요! SQL*Plus 10.1.0.2는 여러 구문을 파일에 append하는 형태로 저장하는 기능을 제공합니다. 위의 경우라면 아래와 같은 명령을 사용할 수 있습니다:
select something1 ....
save myscripts
select something else ....
save myscripts append
select yet another thing ....
save myscripts append

이렇게 하면 모든 구문을 myscript.sql 파일에 append 된 형태로 저장할 수 있으므로, 여러 파일에 나누어 저장한 뒤 이를 다시 하나로 연결할 필요가 없게 됩니다.
스풀링(spooling)에서도 append 형태의 저장 방식이 사용됩니다. 이전 릴리즈에서는 SPOOL RESULT.LST 명령으로 result.lst 파일을 생성할 수 있었지만, 기존에 같은 이름의 파일이 존재하는 경우 아무런 경고도 없이 덮어쓰기가 실행된다는 문제가 있었습니다. 이 때문에 실제로 작업을 수행하는 과정에서 중요한 파일이 덮어씌워져 버리는 곤란한 상황이 발생하곤 했습니다. 10g에서는 spool 명령을 수행하면서 append 방식으로 저장하도록 설정할 수 있습니다:
spool result.lst append

덮어쓰기를 원한다면 위의 append 조건 대신 REPLACE 조건을 삽입하면 됩니다. (REPLACE는 디폴트로 적용됩니다.) 아래 명령을 사용하면 세이브하기 전에 기존 파일이 존재하는지 점검합니다:
spool result.lst create
Use another name or "SPOOL filename[.ext] REPLACE"

This approach will prevent the overwriting of the file result.lst.
Login.sql 관련 문제
login.sql과 glogin.sql이라는 파일을 기억하십니까? SQL*Plus가 실행되면 현재 디렉토리에 있는 login.sql이 자동으로 실행됩니다. 하지만 심각한 기능상의 문제가 존재했습니다. Oracle9i 및 이하 버전의 login.sql 파일에 아래와 같은 내용이 포함되어 있는 경우를 생각해 봅시다:
set sqlprompt "_connect_identifier >"

데이타베이스DB1에 접속하기 위해 SQL*Plus를 실행하면 아래와 같이 프롬프트가 표시됩니다:
DB1>

이 프롬프트 상에서 데이타베이스 DB2로의 접속을 시도해 봅시다:
DB1> connect
scott/tiger@db2
Connected
DB1>

DB2로 접속한 상태임에도 프롬프트가 여전히 DB1으로 표시되고 있습니다. 이유는 간단합니다. login.sql 파일은 데이타베이스 연결 시에 실행되지 않으며 SQL*Plus 시작 시에만 실행되기 때문입니다. Oracle Database 10g에서는 이러한 문제가 해결되었습니다. login.sql은 SQL*Plus가 시작되는 시점뿐 아니라 새로운 연결이 설정되는 경우에도 자동 실행됩니다. 10g 환경에서 DB1에 접속해 있다가 다른 데이타베이스로 연결을 변경하는 경우, 아래와 같이 프롬프트도 같이 변경됩니다.
In Oracle Database 10g, this limitation is removed. The file login.sql is not only executed at SQL*Plus startup time, but at connect time as well. So in 10g, if you are currently connected to database DB1 and subsequently change connection, the prompt changes.
SCOTT at DB1> connect
scott/tiger@db2
SCOTT at DB2> connect john/meow@db3
JOHN at DB3>

변화를 원치 않는다면?
어떤 이유로든, SQL*Plus의 개선된 기능을 사용하고 싶지 않은 경우도 있을 수 있습니다. 그런 경우라면, 아래처럼 –C 옵션을 적용하면 됩니다:
sqlplus -c 9.2

위와 같이 입력하는 경우 9.2 버전의 SQL*Plus 환경이 실행됩니다.
Use DUAL Freely
아래와 같은 명령을 실제로 사용하는 개발자(또는 DBA)의 수가 얼마나 될 것이라 생각하십니까?
select USER into <some variable> from DUAL

아마 거의 모든 이들이 사용하고 있을 것입니다. DUAL은 호출될 때마다 새로운 논리적 I/O(Buffer I/O)를 생성합니다. 이 기능은 매우 유용하게 활용됩니다. DUAL은 <somevariable> := USER와 같은 구문만큼이나 자주 사용되고 있습니다. 하지만 오라클 코드는 DUAL을 특수한 형태의 테이블로서 취급하며, 따라서 일반적인 튜닝 방법은 적용할 수 없다는 문제가 있습니다.
Oracle Database 10g에서라면 이에 관련한 걱정은 할 필요가 없습니다. DUAL이 특수한 테이블이기 때문에, 논리적 I/O를 나타내는 consistent gets의 값도 줄어들며, event 10046 trace에서 확인할 수 있는 것처럼 optimization plan도 다른 형태로 나타납니다.
Oracle9i의 경우
Rows     Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT   GOAL: CHOOSE
      1   TABLE ACCESS (FULL) OF 'DUAL'
  
10g의 경우
Rows     Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT   MODE: ALL_ROWS
      0   FAST DUAL


Oracle 9i에서 사용되는 DUAL의 FULL TABLE SCAN 대신, 10g에서는 FAST DUAL optimization plan을 사용하고 있다는 점을 주목하시기 바랍니다. 이러한 기능 개선을 통해 DUAL 테이블을 자주 사용하는 애플리케이션의 연속적인 읽기 작업 성능이 대폭적으로 향상되었습니다.
참고: 엄밀하게 말하자면 DUAL 관련 기능 개선은 SQL*Plus가 아닌 SQL Optimizer의 기능이라고 보는 것이 타당할 것입니다. 여기에서는 이 기능에 접근하기 위해 주로 사용되는 툴이 SQL*Plus라는 이유로 이 기능을 소개합니다.
그 밖에 유용한 팁
그 밖에 SQL*Plus에 관련한 몇 가지 팁이 이 시리즈 전반에 걸쳐 소개되고 있습니다. 예를 들어, RECYCLEBIN 개념은 제 5주 Flashback Table 관련 연재에서 소개됩니다.
일반에 알려진 것과 달리, COPY 명령은 여전히 사용 가능합니다. 하지만 향후 릴리즈에서는 기능이 삭제될 것이라 합니다. (Oracle9i 시절부터 듣던 얘기가 아닌가요?) 이 명령이 적용된 스크립트를 사용하는 중이라면 고민할 필요가 없습니다. 사용 가능할 뿐 아니라 기술지원도 제공됩니다. 더군다나 에러 메시지 리포팅에 관련한 기능 개선도 일부 이루어졌습니다. 테이블이 LONG 칼럼을 포함하는 경우, 해당 테이블에 대한 복제본을 생성하려면 COPY 명령에 의존할 수 밖에 없습니다. CREATE TABLE AS SELECT 명령은 long 데이타 타입의 컬럼을 포함하는 테이블을 지원하지 않습니다.
 
 
 
 
제 8 주
Automatic Storage Management
마침내, DBA들은 스토리지 디스크를 추가, 이동, 삭제하는 반복적인 일상 업무로부터 해방될 수 있게 되었습니다.
오라클 데이타베이스에 사용할 새로운 서버와 스토리지 서브시스템을 지금 막 접수한 상황이라고 가정해 봅시다. 운영체제를 구성하는 문제를 제외하고, 데이타베이스를 설치하기 전에 먼저 선행되어야 할 가장 중요한 작업이 무엇일까요? 그것은 바로 스토리지 시스템 레이아웃을 생성하는 일, 좀 더 구체적으로 말해 보호 레벨(protection level)을 정의하고 적합한 RAID(Redundant Array of Inexpensive Disks) 셋을 구성하는 일일 것입니다.
데이타베이스 설치 과정에서 스토리지를 구성하는 작업은 상당히 많은 시간을 소요합니다. 적합한 디스크 구성을 선택하기 위해서는 매우 신중한 계획과 분석이 필요하며, 무엇보다도 스토리지 테크놀로지, 볼륨 관리자, 파일 시스템 등에 대한 깊은 지식을 요구합니다. 이 과정에서 수행되는 설계 작업은 대충 아래와 같은 단계로 정리할 수 있습니다. (아래는 매우 일반적인 내용만을 포함하고 있으며, 실제 작업은 구성에 따라 달라질 수 있습니다.)
스토리지가 운영체제 레벨에서 인식되는지 확인하고, 중복성(redundancy) 및 보호 레벨(protection level)을 결정합니다 (hardware RAID).
논리적 볼륨 그룹을 생성하고, 필요한 경우 스트라이핑 또는 미러링 구성을 선택합니다.
논리적 볼륨 관리자(logical volume manager)를 이용하여 논리적 볼륨 상에 파일 시스템을 생성합니다.
Oracle 프로세스가 디바이스에 대한 열기, 읽기, 쓰기를 수행할 수 있도록 접근권한 설정을 합니다.
파일시스템 상에 데이타베이스를 생성하고, 가능한 경우 리두 로그, 임시 테이블스페이스, 언두 테이블스페이스 등을 별도의 non-RAID 디스크에 배치합니다.
대부분의 환경에서는, 이러한 작업의 대부분은 스토리지 시스템에 조예가 깊은 전문가에 의해 수행됩니다. 여기서 말하는 “전문가”는 DBA와 다른 별도의 인력을 의미하는 경우가 많습니다.
하지만 스트라이핑, 미러링, 논리적 파일시스템 생성과 같은 모든 작업이 단지 Oracle Database만을 위해 수행된다는 점을 감안한다면, 오라클에서 이러한 절차를 단순화할 수 있는 테크닉을 직접 제공하는 것이 순리에 맞지 않을까요?
Oracle Database 10g가 바로 이를 위한 기능을 제공합니다. Automatic Storage Management(ASM)은 위에서 언급된 작업의 상당 부분을 DBA가 오라클 프레임워크 내에서 직접 수행할 수 있도록 하는 자동화 옵션입니다. ASM을 이용하면 별도의 비용을 지불하지 않고도 Oracle Database 10g가 기본적으로 지원하는 기능만을 활용하여 높은 확장성과 성능을 갖는 파일시스템/볼륨 관리자 환경을 구현할 수 있습니다. 또 디스크, 볼륨 관리자, 파일 시스템 관리에 대한 전문적인 지식을 가지고 있을 필요도 없습니다.
이번 연재에서는, 실제 환경에서 ASM을 활용하기 위한 기본적인 방법을 설명합니다. ASM은 제한된 지면을 통해 섭렵하기에는 너무도 방대하고 강력한 기능입니다. 더 자세한 정보를 원하신다면 결론부분에서 소개하는 자료들을 참고하시기 바랍니다.
ASM이란 무엇인가?
데이타베이스에 사용할 디스크가 10개 있다고 가정해 봅시다. ASM을 이용하는 경우, OS에서는 아무 것도 수행할 필요가 없습니다. ASM은 일련의 물리적 디스크를 “디스크그룹(diskgroup)”이라는 논리적 개체로 자동으로 그룹화합니다. ASM이 사용하는 파일시스템은 사용자 파일을 저장할 수 없으며 버퍼링 기능을 제공하지 않으므로 범용 파일시스템으로 사용될 수는 없습니다. 하지만 (버퍼링 기능이 포함되지 않았기 때문에) 직접 액세스(direct access)를 통해 로우 디바이스(raw device) 수준의 성능을 내는 동시에 파일 시스템이 제공하는 편의성과 유연성을 활용할 수 있다는 장점을 제공합니다.
논리적 볼륨 관리자는 일반적으로 블록의 논리적 주소를 물리적 주소로 변환하는 함수를 제공합니다. 이 변환 작업에는 CPU 자원이 사용됩니다. 또 (RADI-5 등의) 스트라이프 구성에 새로운 디스크가 추가되는 경우, 전체 데이타 셋에 대해 비트 단위의 이동작업이 수행되어야 합니다.
반면 ASM은 파일 익스텐트(extent)를 물리적 디스크 블록으로 변환하기 위해 별도의 오라클 인스턴스를 사용합니다. 이러한 설계 덕분에 파일 익스텐트의 위치를 확인하는 작업을 보다 신속하게 수행할 수 있을 뿐 아니라, 디스크를 추가하거나 이동하는 경우에도 파일 익스텐트의 위치를 재조정할 필요가 없다는 이점을 제공합니다. ASM 인스턴스는 ASM이 실행되기 위해서 반드시 필요하며 사용자에 의해 변경될 수 없습니다. 동일 서버 내에 위치한 여러 개의 오라클 데이타베이스 인스턴스는 하나의 ASM 인스턴스를 공유합니다.
ASM 인스턴스는 “인스턴스”이긴 하지만 데이타베이스를 포함하지 않습니다. 디스크에 관련된 모든 메타데이타는 디스크그룹 자체에 저장되며, 최대한 “self-describing”한 형태로 기술됩니다.
ASM이 제공하는 이점을 간략히 정리하면 아래와 같습니다:
디스크의 추가 — 디스크의 추가 작업이 매우 간단합니다. 다운타임이 전혀 발생하지 않으며, 파일 익스텐트는 자동으로 재분배됩니다.
I/O 분산 – I/O는 전체 디스크에 골고루 분산됩니다. 이에 관련하여 수작업이 전혀 불필요하며, 성능 병목이 발생할 가능성도 그만큼 줄어듭니다.
스트라이프 “width”의 설정 – 스트라이핑의 데이타 전송 단위는 Redo Log 파일(128K 단위 전송)처럼 작게, 또는 데이타파일(1MB 단위 전송)처럼 크게 설정할 수 있습니다.
버퍼링 – ASM 파일시스템에는 버퍼링 기능이 구현되어 있지 않으며, 따라서 direct I/O를 이용해 성능 향상이 가능합니다.
Kernerlized Async I/O – kernelized asynchronous I/O를 위해 별도의 셋업 과정을 거칠 필요가 없으며, VERITAS Quick I/O와 같은 써드 파티 파일 시스템을 이용할 필요도 없습니다.
미러링 – 하드웨어 미러링을 적용할 수 없는 경우, 소프트웨어 미러링을 쉽게 구성할 수 있습니다.
ASM을 이용한 데이타베이스 생성
ASM을 이용해 데이타베이스를 생성하는 방법을 구체적으로 설명해 보겠습니다:
1. ASM Instance의 생성
Database Creation Assistant(DBCA)에서 아래와 같이 초기화 매개변수를 설정하여 ASM 인스턴스를 생성합니다:
INSTANCE_TYPE = ASM

ASM 인스턴스는 서버 부팅 과정에서 가장 먼저 시작되고, 서버 셧다운 과정에서 가장 마지막으로 중지되어야 합니다.
이 매개변수의 디폴트 값은 RDBMS이며, 이는 일반 데이타베이스 환경을 의미합니다.
2. Diskgroup의 셋업
ASM 인스턴스를 시작한 뒤, 구성된 디스크를 이용해 디스크그룹을 생성합니다.
CREATE DISKGROUP dskgrp1
EXTERNAL REDUNDANCY
DISK
'/dev/d1',
'/dev/d2',
'/dev/d3',
'/dev/d4',
... and so on for all the specific disks ...
;

위의 예에서는 dksgrp1이라는 이름의 디스크그룹을 생성하면서 /dev/d1, /dev/d2 등의 물리적 디스크를 개별적으로 지정했습니다. 이처럼 디스크를 일일이 지정할 수도 있지만, 아래와 같이 와일드카드를 사용하는 것도 가능합니다.
DISK '/dev/d*'

위 명령에서 EXTERNAL REDUNDANCY는 디스크에 장애가 발생하는 경우 디스크그룹이 다운됨을 의미합니다. 이러한 구성은 하드웨어 미러링 등의 구성이 별도로 지원되는 경우에 사용됩니다. 하드웨어 기반의 미러링이 사용되지 않는 경우라면, ASM에서 “failgroup”으로 지정된 디스크그룹을 생성하여 이를 대신할 수 있습니다.
CREATE DISKGROUP dskgrp1
NORMAL REDUNDANCY
FAILGROUP failgrp1 DISK
'/dev/d1',
'/dev/d2',
FAILGROUP failgrp2 DISK
'/dev/d3',
'/dev/d4';

위의 명령에서 d3와 d4가 d1과 d2의 미러(mirror)로서 1:1 대응되는 것이 아님에 주의하시기 바랍니다. ASM은 모든 디스크를 한꺼번에 활용하여 중복성(redundancy)을 구현합니다. 예를 들어, 디스크그룹의 d1에 생성된 특정 파일은 d4에 복제본을 가지고 있는 반면, d3에 생성된 다른 파일은 d2에 복제본을 가지고 있을 수 있습니다. 디스크에 장애가 발생한 경우 다른 디스크에 저장된 복제본을 이용하여 운영을 재개할 수 있습니다. d1과 d2가 연결된 컨트롤러가 다운된 경우에도, ASM은 failgroup으로 지정된 디스크를 이용하여 데이타 무결성을 보장합니다.
3. Tablespace의 생성
이제 ASM이 적용된 스토리지의 데이타파일을 사용하여 메인 데이타베이스의 테이블스페이스를 생성해 봅시다.
CREATE TABLESPACE USER_DATA DATAFILE '+dskgrp1/user_data_01'
SIZE 1024M
/

이걸로 끝입니다. 이제 셋업 과정은 모두 완료되었습니다.
디스크그룹이 가상 파일시스템(virtual file system)으로서 이용되고 있음을 참고하시기 바랍니다. 이러한 구성은 데이타파일 이외의 다른 오라클 파일을 생성하는 경우에도 유용하게 활용됩니다. 예를 들어 아래와 같이 온라인 리두 로그를 생성할 수 있습니다.
LOGFILE GROUP 1 (
    '+dskgrp1/redo/group_1.258.3',
    '+dskgrp2/redo/group_1.258.3'
  ) SIZE 50M,
...

관련 자료
앞에서 언급한 것처럼, 이 문서는 지면 문제로 ASM 기능에 대한 모든 내용을 다루지 않고 있지 않습니다. 하지만 Oracle Technology Network는 ASM과 관련한 많은 정보를 제공하고 있습니다.
"Storage on Automatic," (Lannes Morris-Murphy) – ASM 소개 자료로서 매우 훌륭한 설명을 담고 있습니다.
ASMLib, , Linux 환경을 위한 ASM 관련 라이브러리로, ASM의 기능을 더욱 확장시켜 줍니다. 라이브러리 모듈에 대한 테크니컬 자료와 소스 코드의 링크를 함께 제공합니다.
Oracle Database Administrator's Guide 10g Release 1 (10.1) 제 12장은 ASM에 관련하여 매우 자세한 배경 정보를 제공하고 있습니다. 
아카이브 로그 역시 디스크그룹에 저장되도록 설정할 수 있습니다. 실제로 Oracle Database에 관련된 거의 모든 것이 ASM 기반 디스크그룹에서 생성 가능합니다. 백업 또한 ASM이 활용되는 분야의 하나입니다. 저가형 디스크를 이용해 데이타베이스 복구 영역을 생성한 다음, RMAN을 통해 데이타파일과 아카이브 로그파일 백업을 생성할 수 있습니다. (RMAN에 관련한 다음 연재에서 이 기능에 대해 자세히 설명할 예정입니다.)
ASM이 Oracle Database에 의해 생성되는 파일만을 지원한다는 사실을 주의하시기 바랍니다. ASM은 일반 파일 시스템을 대체하는 수단으로 이용될 수 없으며 바이너리 또는 플랫 파일을 저장할 수 없습니다.
유지 보수
디스크그룹의 유지보수를 위해 DBA가 일반적으로 수행하는 몇 가지 작업에 대해 설명하겠습니다. 디스크그룹 diskgrp1에 디스크를 추가하여 볼륨을 확장하고자 하는 경우, 아래와 같은 명령을 사용합니다:
alter diskgroup dskgrp1 add disk '/dev/d5';

어떤 디스크가 어떤 디스크그룹에 포함되었는지를 확인하려면 아래와 같이 입력합니다:
select * from v$asm_disk;

이 명령은 ASM 인스턴스가 관리하는 모든 데이타베이스의 디스크의 목록을 표시합니다. 특정 디스크를 제거하고자 하는 경우 아래 명령을 사용합니다:
alter diskgroup dskgrp1 drop disk diskb23;

결론
ASM을 이용하면 오라클 데이타베이스의 파일 관리 작업 환경을 한층 향상시키고, 고도의 확장성과 성능을 갖춘 스토리지 환경을 구성할 수 있습니다. ASM은 디스크의 자유로운 추가, 이동, 제거가 가능한 다이내믹 데이타베이스 환경을 구현하고 DBA를 반복적인 업무로부터 해방시키는데 필요한 툴셋을 제공합니다.
 
 
 
 
제 9 주
RMAN
한층 강력해진 RMAN 유틸리티는 개선된 증분백업, 증분백업의 오프라인 복구, 복구 파일 미리보기, resetlog를 이용한 복구, 파일 압축 등에 관련한 다양한 신기능을 제공합니다.
RMAN이 오라클 데이타베이스 백업 툴의 실질적인 표준으로서 인정되고 있다는 사실은 대부분의 사람들이 동의할 것입니다. 하지만 RMAN의 이전 버전에 문제가 많았던 것도 사실입니다. 필자 역시 RMAN의 기능적인 한계에 불만을 가진 사용자 중 하나였습니다.
Oracle Database 10g는 이러한 문제의 많은 부분을 해결하고 RMAN을 한층 강력하고 유용한 툴로 변화시켰습니다. 그러면 한 번 살펴보기로 합시다.
증분 백업 (Incremental Backup) 기능의 개선
RMAN은 이전부터 증분 백업을 위한 옵션을 제공해 왔습니다. 하지만 이 기능을 실제로 사용하는 경우는 극히 드물었습니다.
증분 백업은 마지막으로 증분 백업이 수행된 이후 변경된 블록만을 백업하는 방식입니다. 예를 들어 Day 1에 전체 백업(level_0)이 수행되고 Day 2와 Day 3에 두 차례의 증분 백업(level_1)이 수행된 경우를 생각해 봅시다. 두 개의 증분 백업은 각각 Day 1과 Day 2, Day 2와 Day3 사이에 변경된 블록만을 포함하고 있습니다. 이와 같은 백업 정책을 사용함으로써 백업 사이즈와 백업에 필요한 디스크 공간을 절감하고, 백업 윈도우를 단축할 수 있을 뿐 아니라 네트워크를 통해 전송되는 데이타 양을 줄일 수 있습니다.
증분 백업은 데이타 웨어하우스 환경에서 특히 유용합니다. 데이타 웨어하우스 작업의 많은 부분은 NOLOGGING 모드로 수행되므로 변경 내역이 아카이브 로그 파일에 저장되지 않으며, 따라서 미디어 복구가 불가능합니다. 데이타 웨어하우스 환경의 데이타 규모와 이 데이타의 대부분이 거의 변경되지 않는다는 사실을 고려할 때, 전체 백업은 효과적이지 못하며 현실적으로 불가능할 수도 있습니다. 그 대신 RMAN을 사용해서 증분 백업을 수행하는 것이 좋은 대안이 될 수 있습니다..
그렇다면 DBA들이 증분 백업 방식을 이용하지 않는 이유는 무엇일까요? Oracle9i와 그 이전 버전의 경우, RMAN은 증분 백업을 수행하기 위해 전체 데이타 블록에 대한 스캔을 수행했습니다. 이러한 작업이 시스템에 너무 큰 부담을 주기 때문에 증분 백업이 효율적이지 않다는 평가를 받게 된 것입니다.
Oracle Database 10g의 RMAN 기능은 이러한 점에서 크게 개선되었습니다. Oracle Database 10g는 (파일시스템의 저널과 유사한 용도를 갖는) 별도의 파일을 통해 마지막 백업 이후 변경된 블록을 추적합니다. RMAN은 (전체 데이타 블록을 스캔하는 대신) 이 파일을 참조하여 어떤 블록을 백업해야 하는지 결정합니다.
아래 명령을 통해 추적 메커니즘(tracking mechanism)을 활성화시킬 수 있습니다:
SQL> alter database enable block change tracking using file '/rman_bkups/change.log';

위 명령은 /rman_bkups/change.log 바이너리 파일을 생성하고 이 파일에 블록 변경 내역을 저장합니다. 아래 명령을 사용하면 추적 메커니즘을 비활성화할 수 있습니다:
SQL> alter database disable block change tracking;

현재 블록 변경 내역의 추적이 수행되고 있는지 확인하려면 아래 쿼리를 사용합니다:
SQL> select filename, status from v$block_change_tracking;

Flash Recovery Area
Oracle9i에서 처음 소개된 Flashback 쿼리는 언두 테이블스페이스를 사용하여 이전 버전으로의 “회귀(flash-back)”을 수행하며, 그 원리상 아주 오래 전의 과거 시점으로는 되돌릴 수 없다는 한계를 갖습니다. 이러한 문제의 대안으로서 제공되는 Flash Recovery는 리두 로그와 유사한 형태의 flashback log을 생성함으로써, 원하는 특정 시점으로 데이타베이스의 상태를 되돌릴 수 있게 합니다. Flash Recovery를 사용하려면 먼저 데이타베이스에 flash recovery area를 생성하고, 그 크기를 정의한 뒤 아래와 같은 SQL 명령을 통해 데이타베이스를 flash recovery mode로 설정하면 됩니다:
alter system set db_recovery_file_dest = '/ora_flash_area';
alter system set db_recovery_file_dest_size = 2g;
alter system set db_flashback_retention_target = 1440;
alter database flashback on;

Flashback 기능을 사용하려면 데이타베이스가 아카이브 로그 모드로 설정되어 있어야 합니다. Flash Recovery가 활성화되면 디렉토리 /ora_flash_area에 최대 2GB 크기의 Oracle Managed File이 생성됩니다. 모든 데이타베이스 변경 사항은 이 파일에 기록되며, 이 파일을 사용하여 과거의 특정 시점으로 데이타베이스를 복구할 수 있습니다.
RMAN은 /ora_flash_area 디렉토리를 디폴트 백업 파일 저장위치로 사용하며, 따라서 백업 파일은 테이프가 아닌 디스크에 저장됩니다. 이 경우 백업 파일을 얼마나 오랫동안 보존할 것인지 설정할 수 있으며, 정의된 보존 기간이 지난 후 추가 공간이 필요해지면 파일은 자동으로 삭제됩니다.
Flash recovery area가 반드시 파일시스템 또는 디렉토리일 필요는 없으며, ASM(Automatic Storage Management) 디스크그룹으로 지정할 수도 있습니다. Flash recovery area를 ASM 디스크그룹으로 지정하려면 아래와 같은 명령을 사용합니다:
alter system set db_recovery_file_dest = '+dskgrp1';

ASM과 RMAN을 함께 사용하면, 별도의 추가비용 없이 Serial ATA 드라이브 또는 SCSI 드라이브 등의 저가형 디스크를 사용해서 뛰어난 확장성과 가용성을 갖춘 스토리지 환경을 구성할 수 있습니다. (ASM에 대한 자세한 설명은 이 시리즈의 제 8 주 연재를 참고하시기 바랍니다.) 이와 같이 구성함으로써 테이프 기반 솔루션만큼 저렴한 비용으로 디스크 백업 환경을 구축하는 동시에 백업 프로세스의 실행 속도를 향상시킬 수 있습니다.
이 접근법의 또 한 가지 장점으로 사용자 실수에 대한 보호 기능을 들 수 있습니다. ASM 파일은 일반적인 파일시스템 환경이 아니기 때문에, DBA와 시스템 관리자의 실수로 손상될 가능성이 매우 적습니다.
증분 병합 (Incremental Merge)
아래와 같은 백업 스케줄을 갖는 환경을 가정해 봅시다:
일요일 - Level 0 (전체 백업), tag level_0
월요일 - Level 1 (증분 백업), tag level_1_mon
Tuesday - Level 1 (incremental) with tag level_1_tue
... (이하 생략)
이와 같은 백업정책 하에서, 토요일에 데이타베이스 장애가 발생한 경우, 10g 이전의 환경에서는 tag level_0를 복구하고 나머지 6개의 증분 백업본을 모두 복구해야만 했습니다. 이러한 작업에는 매우 오랜 시간이 걸리며, 이는 실제로 DBA가 증분 백업을 즐겨 사용하지 않는 이유 중 하나이기도 합니다.
Oracle Database 10g RMAN은 이러한 작업환경을 극적으로 개선했습니다. Oracle Database 10g RMAN의 증분 백업 명령은 아래와 같은 형태로 수행됩니다:
RMAN> backup incremental level_1 for recover of copy with tag level_0 database;

위에서 우리는 RMAN이 incremental level_1 백업을 수행하고 그 결과를 level_0의 전체 백업본과 병합(merge)하도록 설정했습니다. 이 명령을 수행하면 그 날의 전체 백업 이미지를 갖는 level_0 백업본이 새로이 생성됩니다.
예를 들어, 화요일에 수행된 증분 백업(level_1)은 이전의 전체 백업(level_0)과 병합되어 화요일 버전의 새로운 전체 백업본이 생성됩니다. 마찬가지로 토요일에 수행된 증분백업 역시, 금요일의 전체백업본과 병합되어 새로운 전체백업으로 저장됩니다. 따라서 토요일에 데이타베이스가 장애가 발생한다면, level_0 백업본 하나와 아카이브 로그 몇 개만을 이용하여 데이타베이스를 복구할 수 있습니다. 이러한 방법으로 복구에 소요되는 시간을 극적으로 절감하고, 백업 속도를 향상시키는 한편, 전체 백업의 수행 횟수를 줄일 수 있습니다.
압축 파일(Compressed Files)
Flash recovery area에 디스크 백업을 보관하는 경우에도, 디스크 공간의 한계라는 문제는 여전히 남습니다. 특히 네트워크를 통해 백업을 수행하는 환경이라면, 백업본의 크기를 최대한 작게 유지하는 구성이 권장됩니다. 이를 위해 Oracle Database 10g RMAN은 백업 명령에 새로운 압축 옵션을 추가하였습니다:
RMAN> backup as compressed backupset incremental level 1 database;

COMPRESSED 키워드가 사용된 형태를 주의해 보시기 바랍니다. 이 키워드를 사용하는 경우 백업 데이타의 압축을 통해 백업 성능을 향상할 수 있으며, 복구 과정에서는 별도의 압축해제 작업 없이도 RMAN이 파일을 읽어 들일 수 있습니다. 압축을 설정한 경우, 백업 수행 과정에서 아래와 같은 메시지가 출력됩니다.
channel ORA_DISK_1: starting compressed incremental level 1 datafile backupset

또, RMAN list output 명령을 통해 백업 압축 설정 여부를 확인할 수도 있습니다.
RMAN> list output;

BS Key  Type LV Size       Device Type Elapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ ---------------
3       Incr 1  2M         DISK        00:00:00     26-FEB-04     
        BP Key: 3   Status: AVAILABLE  Compressed: YES  Tag: TAG20040226T100154
        Piece Name: /ora_flash_area/SMILEY10/backupset/2004_02_26/o1_mf_ncsn1_TAG20040226T100154_03w2m3lr_.bkp
  Controlfile Included: Ckp SCN: 318556       Ckp time: 26-FEB-04
  SPFILE Included: Modification time: 26-FEB-04

모든 압축 알고리즘이 그러하듯, 이 방법을 쓰는 경우 CPU에 추가적인 부담을 주게 됩니다. 반면, 더 많은 RMAN 백업을 디스크에 보관할 수 있다는 장점이 있습니다. 또 Physical Standby Database에서 RMAN 백업을 실행하면 원본 서버에 부담을 주지 않고 백업을 수행할 수 있습니다.
Look Before You Leap: Recovery Preview
Oracle Database 10g의 RMAN은 한 걸음 더 나아가 복구 작업에 사용할 수 있는 백업본을 미리 확인하는 Recovery Preview 기능을 지원합니다.
RMAN> restore database preview;

위 작업의 실행 결과는 Listing 1에서 확인하실 수 있습니다. 테이블스페이스 별로 백업본을 개별적으로 확인하는 것도 가능합니다:
restore tablespace users preview;

Preview 기능을 활용하여 백업 인프라스트럭처가 정상적으로 운영되고 있는지 정기적으로 점검할 수 있습니다.
Resetlog와 복구 작업
커런트 온라인 리두 로그(current online redo log) 파일이 손실되어, 불완전한 데이타베이스 복구(incomplete database recovery)를 수행할 수 밖에 없는 상황을 가정해 봅시다 (이러한 경우는 흔치 않지만 실재로 존재합니다). 이 경우 가장 큰 문제는 resetlog입니다. 불완전 복구를 수행한 뒤에 resetlog 키워드를 사용하여 log thread의 시퀀스 넘버를 1로 재설정하고 데이타베이스를 오픈해야 하는데, 이렇게 하는 경우 이전에 백업된 데이타가 무용지물이 될 뿐 아니라 복구 작업 자체가 더욱 어려워지게 됩니다.
Oracle9i와 그 이전 버전에서는 데이타베이스를 resetlog 이전의 상태로 복구하려면 전혀 새로운 환경에 데이타베이스를 새로 구축할 수 밖에 없었습니다. Oracle Database 10g에서는 이러한 문제가 해결되었습니다. 컨트롤 파일에 추가된 새로운 기능 덕분에, RMAN이 resetlog 수행 이전 또는 이후의 모든 백업 이미지를 복구에 이용할 수 있게 된 것입니다. 또 백업을 수행하기 위해 데이타베이스를 셧다운할 필요도 없게 되었습니다. 이 기능을 사용하면, resetlog 작업 이후 데이타베이스를 바로 오픈하고 운영을 재개하는 것이 가능합니다.
Ready for RMAN
Oracle Database 10g RMAN은 한층 향상된 백업 관리 툴로 거듭 태어났습니다. 증분 백업에 관련한 기능 개선만으로도 RMAN은 더 이상 무시할 수 없는 툴이 되었습니다.
Oracle Database 10g RMAN에 대한 보다 자세한 정보는,“Oracle Database Backup and Recovery Basics 10g Release 1 (10.1)” 문서의 Chapter 4을 참고하시기 바랍니다.
 
 
 
 
제 10 주
감사 기능의 확장
Oracle Database 10g 의 개선된 감사(Audit Trail) 기능을 이용해 매우 상세한 수준의 사용자 접근 기록을 관리하고, 수작업에 의존한 트리거 기반의 감사 작업을 최소화할 수 있습니다.
사용자 Joe가 아래와 같이 테이블 로우에 대한 업데이트를 수행한 경우를 가정해 봅시다.
update SCOTT.EMP set salary = 12000 where empno = 123456;

이 작업이 데이타베이스에는 어떠한 형태의 기록으로 남게 될까요? Oracle9i Database와 그 이전 버전에서는 “누가” 접근했는지에 대한 기록은 남았지만, “어떤” 작업을 했는지에 대해서는 아무런 기록도 남지 않았습니다. 예를 들어, 사용자 Joe가 SCOTT가 소유한 EMP 테이블을 업데이트했다는 사실은 알 수 있지만, 그가 사번 123456을 가진 직원의 salary 컬럼을 업데이트했다는 사실은 알 수 없습니다. 또 salary 컬럼의 변경 전 값 역시 기록되지 않습니다. 이처럼 상세한 변경 내역을 추적하려면, 트리거를 적용하거나 Log Miner를 이용해 아카이브 로그를 뒤지는 수 밖에 없었습니다.
두 가지 방법 모두 변경된 컬럼과 값을 확인할 수는 있지만 이에 수반되는 비용이 만만치 않다는 문제가 따릅니다. 감사 목적으로 적용되는 트리거는 성능적으로 심각한 부담을 줍니다. 이러한 이유 때문에 사용자 정의 트리거의 적용을 아예 금지하는 경우도 많습니다. Log Miner는 성능 자체에는 아무런 영향을 주지 않으나 변경 내역을 추적하기 위해 아카이브 로그에 의존해야 한다는 문제가 있습니다.
Oracle9i에 추가된 Fine-Grained Auditing(FGA) 기능은 로우(row) 단위 변경 내역을 SCN 넘버와 함께 저장함으로써 이전의 데이타를 재구성할 수 있게 하지만, select 구문에 대해서만 적용 가능하고 update, insert, delete 등의 DML 구문에는 적용할 수 없습니다. 이러한 이유로, Oracle Database 10g 이전 버전에서 로우 단위의 데이타 변경 내역을 추적하려면 트리거를 적용하는 것 외에 다른 방법이 없었습니다.
Oracle Database 10g에서는 감사 작업과 관련하여 두 가지 중요한 기능 개선이 이루어졌습니다. 이 문서에서는 오라클이 제공하는 두 종류의 감사 관련 기능 – (모든 버전에서 제공되는) 표준 감사(standard audit) 기능과 (Oracle9i 이후 버전에서 제공되는) fine-grained audit 기능 – 의 관점에서 개선된 사항을 설명하고자 합니다.
새로운 기능들
첫 번째로, FGA는 select 이외의 다른 DML 구문을 지원합니다. 변경 내역은 이전과 마찬가지로 FGA_LOG$에 기록되며, DBA_FGA_AUDIT_TRAIL 뷰를 통해 확인할 수 있습니다. 또 특정 컬럼이 액세스되는 경우, 또는 정의된 일련의 컬럼이 액세스되는 경우에만 트리거가 동작하도록 설정하는 것이 가능합니다 (10g 환경에서의 FGA 기능에 대한 상세 정보를 확인하시려면 필자의 테크니컬 아티클을 확인하시기 바랍니다.)
“AUDIT” SQL 명령으로 구현되는 표준 감사 기능은 특정 오브젝트의 감사를 위한 환경을 쉽고 빠르게 설정하려는 경우 유용합니다. 예를 들어, Scott가 소유자인 EMP 테이블에 대한 모든 업데이트를 추적하려면 아래와 같은 명령을 사용합니다:
audit UPDATE on SCOTT.EMP by access;

위 명령은 SCOTT.EMP 테이블에 업데이트가 발생할 때마다 그 내역을 AUD$ 테이블에 기록합니다. 감사 기록은 DBA_AUDIT_TRAIL 뷰를 통해 조회할 수 있습니다.
이 기능은 10g 이전의 버전에서도 제공되어 오던 것입니다. 하지만 이전 릴리즈에서는 제한적인 정보(구문을 실행한 사용자, 시간, 터미널 ID, 등)만을 추적할 수 있었으며, 바인딩 되는 변수 값과 같은 중요한 정보의 추적이 불가능했습니다. 10g에서는 이전 버전에서 제공되던 것에 추가하여 여러 가지 중요한 정보를 수집할 수 있도록 개선되었습니다. 감사 정보를 저장하는 AUD$ 테이블에도 몇 가지 새로운 컬럼이 추가되었으며, 이전과 마찬가지로 DBA_AUDIT_TRAIL을 통해 확인할 수 있습니다. AUD$ 테이블에 추가된 컬럼에 대해 좀 더 자세히 살펴보기로 합시다.
EXTENDED_TIMESTAMP. 이 컬럼은 감사 기록의 타임스탬프 값을 TIMESTAMP(6) 포맷으로 저장합니다 (TIMESTAMP(6) 포맷은 Time Zone 정보와 함께 그리니치 평균 시간(Universal Coordinated Time으로 불리기도 합니다)을 소수점 이하 9자리 초 단위로 표현합니다). 이 포맷으로 저장된 시간 정보의 예가 아래와 같습니다:
2004-3-13 18.10.13.123456000 -5:0

위 데이타는 미국 동부 표준 시간을 기준으로 한 2004년 3월 13일 시간 정보를 표시하고 있습니다 (-5.0”은 UTC 보다 5시간 이전을 기준으로 함을 의미합니다).
이와 같은 확장형 포맷을 사용함으로써 매우 세밀한 시간 간격으로 감사 기록을 관리할 수 있고, 여러 시간대에 걸쳐 사용되는 데이타베이스 환경에서 한층 유용한 정보를 얻을 수 있습니다.
GLOBAL_UID and PROXY_SESSIONID. 사용자 인증을 위해 Oracle Internet Directory와 같은 아이덴티티 관리 솔루션을 사용하는 경우, 데이타베이스가 사용자를 표시하는 방법도 조금 달라지게 됩니다. 예를 들어, 인증된 사용자가 (데이타베이스 사용자가 아닌) 엔터프라이즈 사용자인 경우를 생각해 봅시다. 이 경우 DBA_AUDIT_TRAIL 뷰의 USERNAME 컬럼에 enterprise userid가 표시되며, 따라서 해당 컬럼의 정보에 일관성이 없게 됩니다. Oracle Database 10g에서는 enterprise userid를 위한 GLOBAL_UID 컬럼을 별도로 제공하며, 이 컬럼을 이용하여 디렉토리 서버에 엔터프라이즈 사용자에 대한 정보를 질의할 수 있습니다.
멀티-티어 애플리케이션 환경에서 엔터프라이즈 사용자가 proxy user를 통해 데이타베이스에 접속하는 경우도 있습니다. 사용자에게 프록시 인증을 제공하는 명령이 아래와 같습니다:
alter user scott grant connect to appuser;

위 명령은 사용자 SCOTT가 APPUSER라는 proxy user를 통해 데이타베이스에 접속할 수 있게 합니다. 이 경우, Oracle 9i는 COMMENT_TEXT에 “PROXY”라는 값을 저장하지만 proxy user의 session id는 저장하지 않습니다. 10g에서는 PROXY_SESSIONID에 proxy session id를 저장합니다.
INSTANCE_NUMBER. Oracle Real Application Clusters (RAC) 환경에서 사용자가 실제로 어느 인스턴스에 연결되어 있는지 확인할 수 있다면 여러모로 도움이 될 것입니다. 10g에서는 INSTANCE_NUMBER 컬럼에 초기화 매개변수 파일에 지정된 해당 인스턴스의 인스턴스 번호를 저장합니다.
OS_PROCESS. Oracle9i와 그 이전 버전에서는 SID 값만을 저장하고 운영체제의 process id는 저장하지 않았습니다. 하지만 서버 프로세스의 OS process id가 Trace파일과 상호참조를 위해 필요한 경우가 있을 수 있습니다. 10g는 이를 위해 OS_PROCESS 컬럼을 제공합니다.
TRANSACTIONID. 이번에는 정말 중요한 정보를 소개할 차례입니다. 사용자가 아래와 같은 쿼리를 실행하는 경우를 가정해 봅시다:
update CLASS set size = 10 where class_id = 123;
commit;

위 명령은 트랜잭션으로서의 조건을 만족하며, 따라서 명령에 대한 감사 기록이 생성됩니다. 그렇다면, 실제로 생성된 감사 기록을 어떻게 확인할 수 있을까요? TRANSACTIONID 컬럼에 저장된 transaction id와 FLASHBACK_TRANSACTION_QUERY 뷰를 조인하면 됩니다. FLASHBACK_TRANSACTION_QUERY 뷰를 조회하는 간단한 예가 다음과 같습니다:
select start_scn,  start_timestamp,
   commit_scn, commit_timestamp, undo_change#, row_id, undo_sql
from flashback_transaction_query
where xid = '<the transaction id>';

10g에서는 트랜잭션에 관련한 일반적인 정보 이외에도 undo change#와 rowid 등을 추가로 저장합니다. 트랜잭션 변경의 undo를 위한 SQL 쿼리는 UNDO_SQL 컬럼에, 변경된 로우의 rowid 값은 ROW_ID 컬럼에 저장됩니다.
System Change Number. 변경 전의 값을 저장하기 위해서 어떤 방법을 사용하고 계십니까? Oracle9i의 FGA를 이용하는 경우, flashback 쿼리를 통해 변경 전의 값을 알 수 있습니다. 이 작업을 위해서는 변경 작업에 사용된 SCN을 알고 있어야 하며, 이 정보는 감사 기록의 System Change Number 컬럼에 저장됩니다. 아래와 같은 쿼리를 사용하면 변경 전의 값을 확인할 수 있습니다.
select size from class as of SCN 123456
where where class_id = 123;

This will show what the user saw or what the value was prior to the change.
DB 감사 기능의 확장
처음에 우리가 제기했던 문제가 무엇인지 다시 상기해 보겠습니다. 표준 감사(standard auditing)을 통해 캡처되지 않던 정보들인 사용자가 실행한 SQL 구문과 바인드 변수들이 문제였습니다. Oracle Database 10g에서는 초기화 매개변수의 간단한 변경 작업만으로 이러한 목적을 달성할 수 있습니다. 매개변수 파일에 아래 항목을 삽입하면 됩니다.
audit_trail = db_extended

이 매개변수는 SQL텍스트와 컬럼에 사용된 변수 값의 기록을 활성화합니다. 이 기능은 10g 이전 버전에서는 지원되지 않았습니다.
트리거가 필요한 경우
롤백된 결과의 취소. 감사 기록은 원본 트랜잭션으로부터 파생된 autonomous transaction을 통해 생성됩니다. 그렇기 때문에 원본 트랜잭션이 롤백 되는 경우에도 감사 기록은 커밋됩니다.
간단한 예를 들어 설명해 보겠습니다. CLASS 테이블의 UPDATE 작업에 대한 감사를 수행하는 경우를 가정해 봅시다. 사용자가 SIZE 컬럼의 값을 20을 10으로 변경하는 구문을 실행한 뒤 아래와 같이 롤백했습니다:
update class set size = 10 where class_id = 123;
rollback

결국 SIZE 컬럼은 (10이 아닌) 20의 값을 갖게 됩니다. 하지만 감사 기록에는 (롤백이 수행되었음에도) 변경 작업이 수행된 것처럼 기록이 됩니다. 사용자가 롤백을 수행하는 빈도가 높은 경우, 이러한 현상으로 인해 곤란한 문제가 생길 수 있습니다. 이러한 경우라면 커밋된 변경내역만을 캡처하기 위해 트리거를 사용할 수 밖에 없습니다. 즉 사용자 정의된 audit trail에 기록하도록 CLASS테이블에 대한 트리거가 있다면, CLASS 테이블에 대한 변경 작업이 롤백 되는 경우, 설정된 트리거 역시 롤백 됩니다.
변경 전 값의 캡처. 오라클이 제공하는 감사 기록은 변경 이전/이후의 값을 제공하지 않습니다. 예를 들어, 위에서 예로 든 변경 작업에 대한 감사기록은 실행된 구문과 SCN 넘버를 저장하고 있지만 변경 전 값(20)은 저장하지 않습니다. SCN 넘버를 이용한 flashback 쿼리를 통해 이전 값을 확인할 수 있지만, 이것도 해당 정보가 undo 세그먼트에 저장되어 있는 경우에만 가능합니다. 해당 정보가 undo_retention period 설정된 보관 기간을 초과한 경우, 이전 값을 조회할 수 있는 방법은 없습니다. 트리거를 이용하면 undo_retention period의 설정값에 관계없이 변경전 값을 영구적으로 저장할 수 있습니다.
통합 감사 기록
FGA와 표준 감사(standard auditing) 기능은 서로 유사한 형태의 정보를 제공하므로, 이 두 가지를 함께 사용함으로써 매우 다양한 정보를 얻을 수 있습니다. Oracle Database 10g는 두 종류의 정보를 통합한 DBA_COMMON_AUDIT_TRAIL 뷰를 제공합니다. 이 뷰는 DBA_AUDIT_TRAIL 뷰와 DBA_FGA_AUDIT_TRAIL 뷰의 UNION ALL로 구성됩니다. (하지만 두 감사 작업이 제공하는 정보의 성격에 분명한 차이가 있는 것도 사실입니다.)
결론
10g로 오면서, 감사 기능은 단순한 “액션 레코더(action recorder)” 또는 “패스트 리코딩 메커니즘(fast-recording mechanism)”에서 매우 상세한 수준의 사용자 액티비티를 저장하는 수단으로 변화되었으며, 이 기능을 활용하여 수작업으로 수행되던 트리거 기반 감사 작업을 최소화할 수 있습니다. 또 표준 감사(standard auditing)과 FGA의 감사 결과를 통합함으로써, 데이타베이스 액세스에 대한 추적이 한층 용이해졌습니다.
더욱 자세한 정보는, Oracle Database Security Guide 10g Release 1 (10.1) 문서의 제 11 장을 참고하시기 바랍니다.
 
 
 
 
제 11 주
Wait 인터페이스
10g의 wait 인터페이스는 ADDM에 의해 아직 캡처 되지 않은 현 시점의 성능 문제를 진단하고 해결하기 위한 유용한 정보를 제공합니다.
"데이타베이스가 너무 느리네요!"
성능에 불만을 가진 사용자들은 이렇게 말하곤 합니다. 여러분들도 필자와 같다면, DBA로 근무하면서 이런 이야기를 수없이 들어왔을 것입니다.
그렇다면 성능 문제를 해결하기 위해 어떻게 대처하십니까? 사용자의 불만을 무시하는 방법도 있겠지만(대부분의 DBA에게 이런 사치는 허용되지 않으므로), 데이타베이스 내부 또는 외부에 세션 wait 이벤트가 발생했는지 확인하는 것이 첫 번째로 하는 일이 될 것입니다.
오라클은 이를 위해 단순하면서도 강력한 메커니즘을 제공합니다. V$SESSION_WAIT 뷰가 바로 그것입니다. V$SESSION_WAIT 뷰를 통해 세션이 대기 중인 이벤트가 무엇이고 얼마나 자주, 얼마나 오랫동안 대기했는지 등의 정보를 확인할 수 있습니다. 예를 들어 특정 세션이 “db file sequential read” 이벤트를 대기하고 있는 경우, 컬럼 P1과 P2는 세션이 대기 중인 블록의 file_id와 block_id를 각각 표시하게 됩니다. 대부분의 경우, V$SESSION_WAIT 뷰만으로 wait 이벤트에 관련한 충분한 정보를 확인할 수 있습니다. 하지만 다음과 같은 두 가지 약점이 있습니다:
For most wait events this view is sufficient, but it is hardly a robust tuning tool for at least two important reasons:
V$SESSION_WAIT 뷰는 현 시점의 상태만을 표시합니다. wait 이벤트가 종료되면, 그 히스토리 정보 역시 소실되어 버립니다. 또 V$SESSION_EVENT 뷰는 세션이 시작된 이후의 누적된 정보를 제공하지만 그 정보가 상세하지 않습니다.
V$SESSION_WAIT 뷰는 wait 이벤트에 대한 정보만을 포함하고 있습니다. 그 밖의 다른 정보(userid, terminal 등)를 확인하려면 V$SESSION 뷰와 조인해야 합니다.
Oracle Database 10g는 최소한의 작업으로 보다 많은 정보를 얻을 수 있도록 wait 인터페이스를 혁신적으로 개선하였습니다. 이번 연재에서는, wait 인터페이스와 관련하여 Oracle Database 10g가 제공하는 새로운 기능을 소개하고 성능 문제 해결을 위한 활용 방안을 설명합니다. 대부분의 경우 ADDM(Automatic Database Diagnostic Manager)이 성능 분석 툴로 활용되겠지만, ADDM에 의해 아직 수집되지 않은 현 시점의 성능 문제를 분석하는 데에는 wait 인터페이스가 유용합니다.
Session Wait 뷰의 기능 향상
먼저 V$SESSION_WAIT의 개선된 기능에 대해 예를 통해 설명하도록 하겠습니다.
사용자의 세션이 갑자기 느려졌다는 불만이 제기된 경우를 가정해 봅시다. 먼저 사용자 세션의 SID를 확인하고, 해당 SID에 대해 V$SESSION_WAIT 뷰를 조회합니다. 그 결과가 아래와 같습니다:
SID                      : 269
SEQ#                     : 56
EVENT                    : enq: TX - row lock contention
P1TEXT                   : name|mode
P1                       : 1415053318
P1RAW                    : 54580006
P2TEXT                   : usn<<16 | slot
P2                       : 327681
P2RAW                    : 00050001
P3TEXT                   : sequence
P3                       : 43
P3RAW                    : 0000002B
WAIT_CLASS_ID            : 4217450380
WAIT_CLASS#              : 1
WAIT_CLASS               : Application
WAIT_TIME                : -2
SECONDS_IN_WAIT          : 0
STATE                    : WAITED UNKNOWN TIME

굵은 글씨체로 표시된 컬럼을 주목하시기 바랍니다. WAIT_CLASS_ID, WAIT_CLASS#, WAIT_CLASS 등은 모두 10g에서 새로 추가된 컬럼들입니다. WAIT_CLASS는 wait의 유형을 구분해 주는 컬럼으로, idle한 wait이므로 무시해도 되는지 또는 유효한 wait인지를 판단하는 중요한 기준으로 활용됩니다. 위의 예에서는 wait class가 “Application”으로 표시되고 있으며, 따라서 주목할 만한 이유가 충분한 것으로 판단할 수 있습니다.
이러한 컬럼들은 튜닝 과정에서 매우 요긴하게 활용됩니다. 예를 들어 다음과 같은 쿼리를 작성하여 세션 wait에 관련한 정보를 얻을 수 있습니다.
select wait_class, event, sid, state, wait_time, seconds_in_wait
from v$session_wait
order by wait_class, event, sid
/

쿼리 실행 결과의 예가 다음과 같습니다:
WAIT_CLASS  EVENT                       SID STATE                WAIT_TIME SECONDS_IN_WAIT
----------  -------------------- ---------- ------------------- ---------- ---------------
Application enq: TX -                   269 WAITING                      0              73
            row lock contention       
Idle        Queue Monitor Wait          270 WAITING                      0              40
Idle        SQL*Net message from client 265 WAITING                      0              73
Idle        jobq slave wait             259 WAITING                      0            8485
Idle        pmon timer                  280 WAITING                      0              73
Idle        rdbms ipc message           267 WAITING                      0          184770
Idle        wakeup time manager         268 WAITING                      0              40
Network     SQL*Net message to client   272 WAITED SHORT TIME           -1               0

여기 몇 가지 이벤트(Queue Monitor Wait, JobQueue Slave등)가 “Idle” 이벤트로 표시되고 있음을 확인할 수 있습니다. 이러한 항목들은 nonblocking wait로 간주하고 고려 대상에서 제외할 수도 있습니다. 하지만 “idle” 이벤트가 다른 문제를 암시하는 경우도 있습니다. 예를 들어, “idle”로 표시되는 SQL*Net 관련 이벤트는 네트워크 지연율이 높음을 나타낼 수도 있습니다.
WAIT_TIME이 -2의 값을 갖는 경우도 참고할 필요가 있습니다. Windows와 같은 일부 플랫폼은 fast timing mechanism을 지원하지 않습니다. 해당 플랫폼에 초기화 매개변수 TIMED_STATISTICS 가 설정되어 있지 않은 경우, 정확한 시간 통계를 얻을 수 없습니다. 이 경우 Oracle9i에서는 관련된 컬럼에 비정상적으로 높은 숫자가 표시되며, 이로 인해 성능 문제의 진단이 더욱 어려워질 수 있습니다. 10g에서는 이러한 경우 일률적으로 -2의 값을 표시합니다. 즉, -2는 플랫폼이 fast timing mechanism을 지원하지 않으며 TIMED_STATISTICS 매개변수가 설정되어 있지 않음을 의미합니다. (이 문서의 뒷부분에서는 fast timing mechanism이 사용 가능한 것으로 가정하고 설명을 진행합니다.)
Session 뷰와 Session Wait 뷰의 통합
세션에 대한 자세한 정보를 얻기 위해서 V$SESSION_WAIT를 V$SESSION과 조인해야만 했던 사실을 기억하고 계실 겁니다. 10g에서는 V$SESSION 뷰 안에 V$SESSION_WAIT의 정보가 기본적으로 포함됩니다. V$SESSION이 wait 이벤트에 관련하여 추가로 제공하는 컬럼이 아래와 같습니다:
EVENT#                     NUMBER
EVENT                      VARCHAR2(64)
P1TEXT                     VARCHAR2(64)
P1                         NUMBER
P1RAW                      RAW(4)
P2TEXT                     VARCHAR2(64)
P2                         NUMBER
P2RAW                      RAW(4)
P3TEXT                     VARCHAR2(64)
P3                         NUMBER
P3RAW                      RAW(4)
WAIT_CLASS_ID              NUMBER
WAIT_CLASS#                NUMBER
WAIT_CLASS                 VARCHAR2(64)
WAIT_TIME                  NUMBER
SECONDS_IN_WAIT            NUMBER
STATE                      VARCHAR2(19)

이 컬럼들은 V$SESSION_WAIT에서 제공되는 것들과 동일한 이름을 가지며 동일한 정보를 제공합니다. 결국 이벤트에 대한 세션 wait 정보를 확인하기 위해 V$SESSION_WAIT를 따로 조회할 필요가 없게 된 것입니다.
그럼 다시 처음에 설명한 예로 돌아가 봅시다. SID 269의 세션이 “enq: TX - row lock contention”이벤트를 대기 중이며, 이는 이 세션이 다른 세션이 점유하고 있는 락(lock)을 대기 중임을 의미합니다. 문제를 진단하기 위해서는 “다른” 세션이 무엇인지 확인해야 합니다. 그렇다면 어떤 방법을 써야 할까요?
Oracle9i와 이전 버전에서는 매우 복잡한 쿼리를 실행해야만 락을 소유한 세션의 SID를 알아낼 수 있었습니다. 10g에서는 다음과 같은 간단한 쿼리로 해결 가능합니다:
select BLOCKING_SESSION_STATUS, BLOCKING_SESSION
from v$session
where sid = 269

BLOCKING_SE BLOCKING_SESSION
----------- ----------------
VALID                    265

이렇게 간단한 작업만으로 SID 265 세션이 세션 269를 블로킹하고 있음이 확인되었습니다.
얼마나 많은 Wait가 발생했는가?
아직도 사용자를 만족시키기에는 이릅니다. 사용자의 세션이 느려진 이유는 도대체 무엇일까요? 다음과 같은 쿼리를 먼저 실행해 봅시다:
select * from v$session_wait_class where sid = 269;

결과는 다음과 같이 표시됩니다:
SID SERIAL# WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS    TOTAL_WAITS TIME_WAITED
---- ------- ------------- ----------- ------------- ----------- -----------
 269    1106    4217450380           1 Application           873      261537
 269    1106    3290255840           2 Configuration           4           4
 269    1106    3386400367           5 Commit                  1           0
 269    1106    2723168908           6 Idle                   15      148408
 269    1106    2000153315           7 Network                15           0
 269    1106    1740759767           8 User I/O               26           1

위 결과는 세션 wait에 대한 매우 상세한 정보를 제공하고 있습니다. 위 결과를 통해 애플리케이션에 관련한 세션 wait 이벤트가 873회, 총 261,537 centi-second에 걸쳐 발생되었으며, 네트워크 관련한 wait 이벤트가 15회 발생되었음을 확인할 수 있습니다.
이 방법을 응용하여, wait class에 관련한 시스템의 전반적인 통계를 확인할 수도 있습니다. (여기에서도 시간은 centi-second 단위로 표시됩니다.)
select * from v$system_wait_class;

WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS    TOTAL_WAITS TIME_WAITED
------------- ----------- ------------- ----------- -----------
   1893977003           0 Other                2483       18108
   4217450380           1 Application          1352      386101
   3290255840           2 Configuration          82         230
   3875070507           4 Concurrency            80         395
   3386400367           5 Commit               2625        1925
   2723168908           6 Idle               645527   219397953
   2000153315           7 Network              2125           2
   1740759767           8 User I/O             5085        3006
   4108307767           9 System I/O         127979       18623

대부분의 성능 문제는 독립적으로 존재하지 않으며, 문제의 패턴을 암시하는 단서로서 해석되는 것이 일반적입니다. 이러한 패턴을 확인하려면 wait class의 히스토리 뷰를 조회해야 합니다:
select * from v$waitclassmetric;

V$WAITCLASSMETRIC 뷰는 지난 1분 동안의 wait class 통계를 제공합니다.
select wait_class#, wait_class_id,
average_waiter_count "awc", dbtime_in_wait,
time_waited,  wait_count
from v$waitclassmetric
/

WAIT_CLASS# WAIT_CLASS_ID  AWC DBTIME_IN_WAIT TIME_WAITED WAIT_COUNT
----------- ------------- ---- -------------- ----------- ----------
          0    1893977003    0              0           0          1
          1    4217450380    2             90        1499          5
          2    3290255840    0              0           4          3
          3    4166625743    0              0           0          0
          4    3875070507    0              0           0          1
          5    3386400367    0              0           0          0
          6    2723168908   59              0      351541        264
          7    2000153315    0              0           0         25
          8    1740759767    0              0           0          0
          9    4108307767    0              0           8        100
         10    2396326234    0              0           0          0
         11    3871361733    0              0           0          0

WAIT_CLASS_ID 컬럼을 주목하시기 바랍니다. 지난 1분 동안 4217450380의 WAIT_CLASS_ID 값을 갖는 wait class를 2개의 세션이 총 5회, 1,499 centi-second에 걸쳐 대기하였음을 알 수 있습니다. 그렇다면 이 wait class는 무엇일까요? V$SYSTEM_WAIT_CLASS를 조회하면 이 wait class가 바로 "Application” class임을 확인할 수 있습니다.
DBTIME_IN_WAIT 컬럼도 매우 유용하게 활용됩니다. Automatic Workload Repository(AWR)를 주제로 한 제 6 주 연재에서, 10g가 한층 세분화된 시간 통계를 제공하며, 데이타베이스 내부에서 실제로 사용된 시간을 정확하게 확인할 수 있음을 설명한 바 있습니다. DBTIME_IN_WAIT가 바로 데이타베이스 내부에서 사용된 시간을 표시하는 컬럼입니다.
단서는 항상 남는다
해당 사용자의 세션이 종료되자 DBA는 안도의 한숨을 내쉽니다. 하지만 도대체 어떤 wait 때문에 세션에 성능 문제가 발생했는지에 대한 궁금증이 가시지 않습니다. V$SESSION_WAIT를 조회하면 쉽게 해답을 얻을 수 있겠지만, 이제 wait 이벤트가 종료된 상황이므로 이 뷰에는 더 이상 기록이 남아있지 않을 것입니다. 이런 경우 어떻게 하시겠습니까?
10g는 액티브 세션의 마지막 10개 이벤트에 관련한 session wait 히스토리 정보를 자동 저장하고 관리하며, 이 결과는 V$SESSION_WAIT_HISTORY 뷰를 통해 조회할 수 있습니다:
select event, wait_time, wait_count
from v$session_wait_history
where sid = 265
/

EVENT                           WAIT_TIME WAIT_COUNT
------------------------------ ---------- ----------
log file switch completion              2          1
log file switch completion              1          1
log file switch completion              0          1
SQL*Net message from client         49852          1
SQL*Net message to client               0          1
enq: TX - row lock contention          28          1
SQL*Net message from client           131          1
SQL*Net message to client               0          1
log file sync                           2          1
log buffer space                        1          1

세션이 inactive 상태가 되거나 연결이 끊어진 경우, 관련된 기록도 뷰에서 삭제됩니다. 하지만 히스토리 정보는 AWR 테이블에 별도로 저장됩니다. AWR의 V$ACTIVE_SESSION_HISTORY 뷰는 session wait에 관련한 정보를 제공합니다. (AWR에 관련한 자세한 정보는 본 시리즈의 제 6 주 연재를 참고하시기 바랍니다.)
결론
Oracle Database 10g의 향상된 wait 모델을 사용하여 한층 쉽게 성능 분석 작업을 진행할 수 있습니다. 세션 히스토리 정보를 이용하면 문제의 징후가 사라진 이후에도 문제 원인을 진단할 수 있습니다. 또 wait를 wait class로 구분함으로써, 각 wait 유형별 영향을 이해하고 효율적으로 대처할 수 있게 됩니다.
wait 이벤트 관련 다이내믹 성능 뷰에 대한 보다 자세한 정보는 Oracle Database Performance Tuning Guide 10g Release 1 (10.1)의 제 10 장을 확인하시기 바랍니다.
 
 
 
 
제 12 주
Materialized Views
10g에서는 강제적인 query rewrite, tuning advisor 등의 새로운 기능을 통해 materialized view의 관리 기능을 향상시켰습니다.
스냅샷(snapshot)이라 불리기도 하는 Materialized view(MV)는 오라클에서 오래 전부터 구현해 온 기능의 하나입니다. MV는 쿼리 결과를 별도 세그먼트에 저장하고, 쿼리가 재실행되는 경우 사용자에게 미리 저장된 결과를 전달함으로써 쿼리를 여러 차례 재실행하는 데 따르는 성능적인 부담을 줄여줍니다. MV는 데이타 웨어하우스 환경에서 특히 유용합니다. 또 “fast refresh” 메커니즘을 이용해 MV를 전체적으로 또는 부분적으로 refresh할 수 있습니다.
다음과 같은 materialized view를 구현한 경우를 가정해 봅시다:
create materialized view mv_hotel_resv
refresh fast
enable query rewrite
as
select distinct city, resv_id, cust_name
from hotels h, reservations r
where r.hotel_id = h.hotel_id';

어떻게 하면 이 MV가 완벽하게 동작하는데 필요한 오브젝트들이 모두 생성되었는지 확인할 수 있을까요? Oracle Database 10g 이전 버전에서는, DBMS_MVIEW 패키지의 EXPLAIN_MVIEW 프로시저와 EXPLAIN_REWRITE 프로시저를 이용해 이를 확인할 수 있었습니다. 이 프로시저들은 10g에서도 여전히 사용 가능합니다. 이 프로시저들을 이용하면 특정 MV에 “fast refreshability”, “query rewritability” 등의 기능 구현 여부를 정확하게 확인할 수 있었지만, 어떻게 하면 이러한 기능을 구현할 수 있는지에 대한 조언을 구할 수는 없었습니다. 이를 위해서는, 각각의 MV 구조를 비주얼한 방법으로 확인해야만 했으며, 실질적으로 이 방법은 효용성이 없었습니다.
10g에서는 새로 추가된 DBMS_ADVISOR 패키지에 포함된 TUNE_MVIEW 프로시저를 통해 이러한 작업을 간단하게 수행할 수 있습니다. 먼저 IN 매개변수에 MV 생성 스크립트의 텍스트를 저장한 후 패키지를 호출합니다. 프로시저는 자동 생성된 이름을 가진 Advisor Task를 생성하며, OUT 매개변수를 통해 사용자에게 생성된 Advisor의 이름을 반환합니다.
예를 들어 설명해 보겠습니다. 먼저 SQL*Plus에서 OUT 매개변수에 저장할 변수를 정의해야 합니다.
SQL> -- first define a variable to hold the OUT parameter
SQL> var adv_name varchar2(20)
SQL>  begin
  2  dbms_advisor.tune_mview
  3     (
  4        :adv_name,
  5        'create materialized view mv_hotel_resv refresh fast enable query rewrite as
            select distinct city, resv_id, cust_name from hotels h,
     reservations r where r.hotel_id = h.hotel_id');
  6* end;

다음에는 adv_name 변수를 조회하여 Advisor의 이름을 확인합니다.
SQL> print adv_name

ADV_NAME
-----------------------
TASK_117

다음으로, DBA_TUNE_MVIEW 뷰를 질의하여 Advisor가 제공하는 권고내역을 확인합니다. 이 명령을 실행하기 전에 SET LONG 999999 명령을 실행하는 것을 잊지 마시기 바랍니다. (DBA_TUNE_MVIEW 뷰의 STATEMENT 컬럼은 CLOB 데이타타입을 사용하므로, 문자 출력을 80개로 제한하는 디폴트 환경을 수정해야 합니다.)
select script_type, statement
from   dba_tune_mview
where  task_name = 'TASK_117'
order  by script_type, action_id;

실행 결과는 아래와 같습니다:
SCRIPT_TYPE    STATEMENT
-------------- ------------------------------------------------------------
IMPLEMENTATION CREATE MATERIALIZED VIEW LOG ON "ARUP"."HOTELS" WITH ROWID,
               SEQUENCE ("HOTEL_ID","CITY")  INCLUDING NEW VALUES

IMPLEMENTATION ALTER MATERIALIZED VIEW LOG FORCE ON "ARUP"."HOTELS" ADD
               ROWID, SEQUENCE ("HOTEL_ID","CITY")  INCLUDING NEW VALUES

IMPLEMENTATION CREATE MATERIALIZED VIEW LOG ON "ARUP"."RESERVATIONS" WITH
               ROWID, SEQUENCE ("RESV_ID","HOTEL_ID","CUST_NAME")
               INCLUDING NEW VALUES

IMPLEMENTATION ALTER MATERIALIZED VIEW LOG FORCE ON "ARUP"."RESERVATIONS"
               ADD ROWID, SEQUENCE ("RESV_ID","HOTEL_ID","CUST_NAME")
               INCLUDING NEW VALUES

IMPLEMENTATION CREATE MATERIALIZED VIEW ARUP.MV_HOTEL_RESV   REFRESH FAST
               WITH ROWID ENABLE QUERY REWRITE AS SELECT
               ARUP.RESERVATIONS.CUST_NAME C1, ARUP.RESERVATIONS.RESV_ID
               C2, ARUP.HOTELS.CITY C3, COUNT(*) M1 FROM ARUP.RESERVATIONS,
               ARUP.HOTELS WHERE ARUP.HOTELS.HOTEL_ID =
               ARUP.RESERVATIONS.HOTEL_ID GROUP BY
               ARUP.RESERVATIONS.CUST_NAME, ARUP.RESERVATIONS.RESV_ID,
               ARUP.HOTELS.CITY

UNDO           DROP MATERIALIZED VIEW ARUP.MV_HOTEL_RESV

SCRIPT_TYPE 컬럼은 제공되는 조언의 유형을 의미합니다. 대부분의 내용이 실제 구현에 관련된 권고사항으로 구성되어 있으므로 SCRIPT_TYPE으로 “IMPLEMENTATION”이 설정된 것을 확인할 수 있습니다. 사용자가 승인하는 경우, 제시된 권고사항은 ACTION_ID 컬럼에 정의된 순서대로 실행됩니다.
Advisor가 제시한 권고사항을 자세히 살펴보면, 우리가 비주얼 분석 작업을 통해 생성하는 것과 유사한 내용으로 구성되어 있다는 사실을 알 수 있을 것입니다. 위에서 제시된 권고사항은 매우 논리적입니다. Fast refresh를 구현하려면 베이스 테이블MATERIALIZED VIEW LOG가 생성되어야 하며, 이 때 “including new values”와 같은 조건을 포함하여야 합니다. STATEMENT 컬럼은 이러한 권고사항을 구현하기 위해 실행되는 SQL 구문을 담고 있습니다.
구현 작업의 마지막 단계로서, Advisor는 MV 생성 과정에서 수정이 필요한 부분을 지적해 줍니다. 위의 예에서 무엇이 달라졌는지 확인해 보시기 바랍니다. count(*)가 MV에 추가되었습니다. MV가 “fast refresh”를 지원하는 것으로 설정했기 때문에 count(*)가 반드시 포함되어야 하며, Advisor는 이 부분이 생략된 것을 발견하고 권고사항에 포함시킨 것입니다.
프로시저 TUNE_MVIEW 는 EXPLAIN_MVIEW 와 EXPLAIN_REWRITE가 제공하는 것보다 수준 높은 조언을 제공하며, MV를 생성하는 보다 쉽고 효율적인 방법도 함께 제시합니다. 때로 Advisor는 질의를 보다 효율적으로 하기 위한 방법으로 하나 이상의 MV를 제안하기도 합니다.
어떤 분은 그게 과연 얼마나 유용할까라고 의문을 던질 수도 있을 것입니다. 숙련된 DBA라면 누구나 MV 생성 스크립트에서 빠진 부분을 찾아내어 직접 수정할 수 있기 때문입니다. 사실 Advisor가 하는 역할이 바로 이것입니다. Advisor는 마치 숙련된 DBA처럼 전문적인 권고를 제시합니다. 한 가지 분명하게 다른 점은, Advisor가 돈을 안받고 일할 뿐 아니라 휴가나 월급인상을 요구하지도 않는다는 사실입니다. 이러한 기능이 있음으로 해서, 선임 DBA가 하급 DBA에게 반복적인 업무를 인계하고 보다 전략적인 목표에 집중할 수 있게 되는 것입니다.
TUNE_MVIEW 프로시저를 실행할 때 Advisor name을 미리 지정해서 매개변수를 통해 전달할 수도 있습니다. 이렇게 하는 경우 Advisor는 자동 생성된 이름 대신 사용자가 지정한 이름을 사용합니다.
쉬워진 구현 작업
이제 권고사항을 확인하고 바로 구현 작업에 들어갈 준비가 되었습니다. 위 실행결과의 STATEMENT 컬럼을 조회한 결과를 별도 스크립트 파일에 스풀링한 다음, 그 파일을 실행하는 것도 한 방법입니다. 아니면 그보다 쉬운 방법으로 별도 제공되는 프로시저를 실행할 수도 있습니다:
begin
   dbms_advisor.create_file (
      dbms_advisor.get_task_script ('TASK_117'), 
   'MVTUNE_OUTDIR',
   'mvtune_script.sql'
);
end;
/

이 프로시저는 아래와 같은 방법으로 디렉토리 오브젝트가 미리 생성되어 있음을 가정합니다:
create directory mvtune_outdir as '/home/oracle/mvtune_outdir';

dbms_advisor를 호출하면 /home/oracle/mvtune_outdir 디렉토리에 mvtune_script.sql이라는 이름의 파일이 생성됩니다. 이 파일을 열어 보면 다음과 같은 내용이 포함되어 있음을 확인할 수 있을 것입니다:
Rem  SQL Access Advisor: Version 10.1.0.1 - Production
Rem
Rem  Username:        ARUP
Rem  Task:            TASK_117
Rem  Execution date:
Rem

set feedback 1
set linesize 80
set trimspool on
set tab off
set pagesize 60

whenever sqlerror CONTINUE

CREATE MATERIALIZED VIEW LOG ON
    "ARUP"."HOTELS"
    WITH ROWID, SEQUENCE("HOTEL_ID","CITY")
    INCLUDING NEW VALUES;

ALTER MATERIALIZED VIEW LOG FORCE ON
    "ARUP"."HOTELS"
    ADD ROWID, SEQUENCE("HOTEL_ID","CITY")
    INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW LOG ON
    "ARUP"."RESERVATIONS"
    WITH ROWID, SEQUENCE("RESV_ID","HOTEL_ID","CUST_NAME")
    INCLUDING NEW VALUES;

ALTER MATERIALIZED VIEW LOG FORCE ON
    "ARUP"."RESERVATIONS"
    ADD ROWID, SEQUENCE("RESV_ID","HOTEL_ID","CUST_NAME")
    INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW ARUP.MV_HOTEL_RESV
    REFRESH FAST WITH ROWID
    ENABLE QUERY REWRITE
    AS SELECT ARUP.RESERVATIONS.CUST_NAME C1, ARUP.RESERVATIONS.RESV_ID C2, ARUP.HOTELS.CITY
       C3, COUNT(*) M1 FROM ARUP.RESERVATIONS, ARUP.HOTELS WHERE ARUP.HOTELS.HOTEL_ID
       = ARUP.RESERVATIONS.HOTEL_ID GROUP BY ARUP.RESERVATIONS.CUST_NAME, ARUP.RESERVATIONS.RESV_ID,
       ARUP.HOTELS.CITY;

whenever sqlerror EXIT SQL.SQLCODE

begin
  dbms_advisor.mark_recommendation('TASK_117',1,'IMPLEMENTED');
end;
/

이 파일은 권고사항을 구현하기 위해 필요한 모든 정보를 포함하고 있으며, 수작업으로 파일을 생성하는 수고를 덜어줍니다. DBA 로봇이 다시 한 번 그 위력을 발휘하는 순간입니다.
Rewrite이 불가능한 경우의 실행 차단
이제 여러분들도 Query Rewrite 기능이 얼마나 중요하고 유용한지 깨닫게 되셨으리라 믿습니다. Query Rewrite는 I/O 작업과 프로세싱 작업을 줄여주고 결과를 한층 빠르게 얻을 수 있게 합니다.
위의 예를 기준으로 계속 설명해 보겠습니다. 사용자가 다음과 같은 쿼리를 실행하는 경우를 생각해 봅시다:
Select city, sum(actual_rate)
from hotels h, reservations r, trans t
where t.resv_id = r.resv_id
and h.hotel_id = r.hotel_id
group by city;

실행 통계는 아래와 같이 확인되었습니다:
0   recursive calls
0   db block gets
6   consistent gets
0   physical reads
0   redo size
478 bytes sent via SQL*Net to client
496 bytes received via SQL*Net from client
2   SQL*Net roundtrips to/from client
1   sorts (memory)
0   sorts (disk)

consistent gets가 6의 값을 갖는 것에 주목하시기 바랍니다. 이것은 매우 낮은 수치입니다. 이는 3 개의 테이블을 기반으로 생성된 2개의 MV를 이용하도록 쿼리가 재작성 되었기 때문에 얻어진 결과입니다. Select 작업은 테이블이 아닌 MV를 통해 수행되었으며, 그 덕분에 훨씬 적은 I/O와 CPU를 사용했습니다.
하지만 Query Rewrite가 실패하면 어떻게 될까요? 실패의 이유에는 여러 가지가 있을 수 있습니다. 초기화 매개변수 query_rewrite_integrity이 “TRUSTED”로 설정되고 MV status가 “STALE”로 설정되었다면 쿼리는 재작성 되지 않을 것입니다. 쿼리를 실행하기 전에 세션 매개변수를 설정함으로써 이 현상을 테스트해 볼 수 있습니다:
alter session set query_rewrite_enabled = false;

위 명령을 실행하고 나면, explain plan은 MV가 아닌 3개 테이블로부터 select를 수행하는 것으로 변경됩니다. 실행 통계도 아래와 같이 달라지게 됩니다:
0   recursive calls
0   db block gets
16  consistent gets
0   physical reads
0   redo size
478 bytes sent via SQL*Net to client
496 bytes received via SQL*Net from client
2   SQL*Net roundtrips to/from client
2   sorts (memory)
0   sorts (disk)

consistent gets의 값이 6에서 16으로 크게 증가했음을 확인할 수 있습니다. 추가 자원을 활용하기 어려운 실제 환경에서는, 이러한 변화를 용납하기는 어려우며, 따라서 쿼리를 재작성 하는 방법을 선택할 수 밖에 없습니다. 이러한 경우 쿼리가 재작성 되는 경우에만 실행 가능하도록 설정해야 할 수도 있습니다.
Oracle9i Database와 그 이전 버전에서는 단 한 가지 옵션만 가능했습니다. Query Rewrite를 disable할 수는 있었지만 베이스 테이블에 대한 액세스는 막을 수 없었습니다. 반면 Oracle Database 10g는 REWRITE_OR_ERROR라는 힌트를 이용하여 베이스 테이블에 대한 접근을 차단하는 기능을 제공합니다. 위의 쿼리는 아래와 같은 형태로 재작성될 수 있습니다:
select /*+ REWRITE_OR_ERROR */ city, sum(actual_rate)
from hotels h, reservations r, trans t
where t.resv_id = r.resv_id
and h.hotel_id = r.hotel_id
group by city;

에러 메시지는 아래와 같이 표시됩니다:
from hotels h, reservations r, trans t
     *
ERROR at line 2:
ORA-30393: a query block in the statement did not rewrite

ORA-30393은 구문이 MV를 사용할 수 있는 형태로 재작성될 수 없으며, 이로 인해 구문 실행에 실패하였음을 의미하는 에러입니다. 이 방법을 사용하여 시스템 리소스를 많이 잡아먹는 쿼리를 사전에 차단할 수 있습니다. 다만 한 가지 주의할 점은, MV 중 (전체가 아닌) 하나만이라도 이용이 가능한 경우 쿼리가 실행된다는 사실입니다. 예를 들어 MV_ACTUAL_SALES은 사용할 수 있지만 MV_HOTEL_RESV는 사용할 수 없는 경우라 해도, 쿼리는 재작성되고 실행되며, 에러는 발생하지 않습니다. 이 경우 execution plan은 아래와 같습니다:
Execution Plan
----------------------------------------------------------
0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=11 Card=6 Bytes=156)
1    0   SORT (GROUP BY) (Cost=11 Card=6 Bytes=156)
2    1     HASH JOIN (Cost=10 Card=80 Bytes=2080)
3    2       MERGE JOIN (Cost=6 Card=80 Bytes=1520)
4    3         TABLE ACCESS (BY INDEX ROWID) OF 'HOTELS' (TABLE) (Cost=2 Card=8 Bytes=104)
5    4           INDEX (FULL SCAN) OF 'PK_HOTELS' (INDEX (UNIQUE)) (Cost=1 Card=8)
6    3         SORT (JOIN) (Cost=4 Card=80 Bytes=480)
7    6           TABLE ACCESS (FULL) OF 'RESERVATIONS' (TABLE) (Cost=3 Card=80 Bytes=480)
8    2       MAT_VIEW REWRITE ACCESS (FULL) OF 'MV_ACTUAL_SALES' (MAT_VIEW REWRITE) (Cost=3 Card=80 Bytes=560)

이 쿼리는 MV_ACTUAL_SALES은 사용하지만 MV_HOTEL_RESV는 사용하지 않고, 대신 HOTELS 테이블과 RESERVATIONS 테이블에 직접 액세스합니다. 만일 HOTELS 또는 RESERVATIONS 테이블에 풀 테이블 스캔이 발생한다면, MV를 사용하는 경우보다 훨씬 많은 리소스를 사용하게 될 것입니다. 쿼리와 MV를 설계하는 과정에서 반드시 참고해야 할 부분입니다.
물론 Resource Manager를 이용하면 리소스 사용을 통제할 수도 있습니다. 하지만 REWRITE_OR_ERROR 힌트를 이용하면 Resource Manager가 호출되기도 전에 쿼리의 실행을 사전 차단하는 것이 가능합니다. Resource Manager는 옵티마이저 통계에 근거하여 필요한 리소스를 예측하며, 통계가 존재하지 않거나 그 정확도가 떨어지는 경우 잘못된 예측을 할 수도 있습니다. 반면 REWRITE_OR_ERROR 힌트를 이용하면 통계와 무관하게 테이블 액세스를 차단할 수 있다는 장점이 있습니다.
Explain Plan의 개선 기능
앞의 explain plan 조회결과 예에서 아래 행을 참고하시기 바랍니다:
MAT_VIEW REWRITE ACCESS (FULL) OF 'MV_ACTUAL_SALES' (MAT_VIEW REWRITE)

MAT_VIEW REWRITE 액세스 방식은 10g에서 처음 소개되는 것입니다. 이것은 테이블 또는 세그먼트가 아닌 MV가 액세스되고 있음을 의미합니다. 이 프로시저를 사용하면 테이블과 MV 중 어느 쪽이 사용되고 있는지를 바로 확인할 수 있습니다.
결론
10g에 새로 추가된tuning advisor의 강력한 권고 기능을 이용하여 MV를 더 쉽게 관리할 수 있습니다. 필자는 개인적으로, 튜닝 권고내역이 바로 실행 가능한 형태의 완성된 스크립트로 제공된다는 점이 마음에 듭니다. 리소스를 최대한 아껴야 하는 의사결정 시스템에서는, REWRITE_OR_ERROR 힌트를 사용하여 쿼리 재작성이 불가능한 경우 실행 자체를 차단하는 방법이 매우 유용하게 사용될 수 있습니다.
10g에서 MV를 관리하는 방법에 대한 보다 자세한 정보는 Oracle Database Data Warehousing Guide 10g Release 1 (10.1)의 제 8 장을 참고하시기 바랍니다.
 
 
 
 
제 13 주
Enterprise Manager 10g
마침내, 초심자와 전문가 모두를 위해 Oracle 관리와 운영에 관한 문제를 한꺼번에 해결해 줄 수 있는 툴이 완성되었습니다.
여러분이 일상적인 DBA 업무를 위해 주로 사용하는 툴은 무엇입니까? 사용자 그룹 모임에서 똑같은 질문을 던진 적이 있었습니다.
답변은 DBA의 경력에 따라 달랐습니다. 오랜 경력의 관리자일 수록 SQL*Plus 커맨드 라인 툴을 가장 선호하였고 (필자 역시 그러합니다), 다른 이들의 경우 몇 가지 써드 파티 제품을 중심으로 의견이 갈라졌습니다. 하지만 초심자 수준의 DBA의 경우에는 Enterprise Manager(EM)을 단연 선호하는 툴로 꼽았습니다.
이러한 결과는 충분히 예상할 수 있는 것입니다. Oracle Enterprise Manager는 지난 수 년 동안 꾸준히 발전되어 왔습니다. 처음에 캐릭터 모드 디스플레이의 SQL*DBA로 시작된 EM은 클라이언트 운영체제 기반의 툴로, 그리고 최종적으로는 자바 기반 환경으로 진화되었습니다. EM은 대부분의 DBA 작업을 수행하기에 충분한 수준의 정보를 제공하며, 새로운 문법을 배우기 귀찮아하는 사용자, 또는 GUI 툴을 사용하여 사용자 추가, 데이타파일 수정, 롤백 세그먼트 점검 등의 일상적인 작업을 수행하고자 하는 관리자들을 위한 솔루션으로 자리잡았습니다.
하지만 EM이 기대만큼 빠르게 확산되지 않은 이유 중 하나는, EM이 데이타베이스 서버의 발전속도를 따라잡지 못했다는 사실에 있습니다. 예를 들어 Oracle9i Database의 EM은 (이미 Oracle8i부터 지원되던 기능인) subpartitioning을 지원하지 않았습니다..
Oracle Database 10g에 포함된 EM의 새로운 버전은 과거의 문제로부터의 결별을 선언합니다. 새로운 아키텍처와 새로운 인터페이스가 적용되었으며, 초심자와 숙련된 사용자를 모두 만족할 수 있는 강력하고도 포괄적인 DBA 툴박스를 제공합니다. 더 중요한 사실은, 추가적인 비용 없이 데이타베이스와 함께 기본으로 제공된다는 것입니다. 만일 지금 써드 파티 툴을 검토하고 있는 중이라면, 그 경쟁 제품으로서 EM을 심각하게 고려해 볼 필요가 있습니다. 여러분이 (필자처럼) 커맨드 라인 툴의 맹신자라 하더라도, EM이 여러 상황에서 매우 유용하게 사용될 수 있음을 깨닫게 될 것입니다.
이번 연재에서는 EM의 새로운 기능을 소개합니다. Enterprise Manager가 제공하는 기능의 영역이 워낙 광범위하기 때문에 전체 기능을 종합적으로 다루기는 불가능합니다. 대신, 몇 가지 기본적인 내용을 설명하고 관련 자료를 소개하는 한편, (이 시리즈의 기본 취지에 맞추어) 현실적인 문제를 해결하기 위해 툴을 활용하는 사례들을 제공하고자 합니다.
아키텍처
EM 10g는 Database 10g 소프트웨어와 함께 디폴트로 설치됩니다. 클라이언트 운영체제를 기반으로 하던 이전 버전과 달리, 새로운 버전은 (DB Console이라 불리는) HTTP 서버의 형태로 데이타베이스 서버 상에 설치됩니다 (그림 1 참고). EM 인터페이스는 모든 종류의 웹 브라우저를 지원합니다.
 

그림 1: EM 아키텍처
DB Console의 포트 번호는 $ORACLE_HOME/install/portlist.ini 파일에 정의되어 있습니다. 이 파일의 예가 아래와 같습니다 (포트 번호는 설치 예에 따라 달라질 수 있습니다).
Ultra Search HTTP port number = 5620
iSQL*Plus HTTP port number = 5560
Enterprise Manager Agent Port =
Enterprise Manager Console HTTP Port (starz10) = 5500
Enterprise Manager Agent Port (starz10) = 1830
위 파일에서 데이타베이스 starz10의 Agent가 포트 1830에서, EM 콘솔이 포트 5500에서 리스닝 하고 있음을 확인할 수 있습니다. 아래 URL을 입력하면 EM 로그온 스크린을 호출할 수 있습니다:
http://starz/em/console/logon/logon
로그온 스크린에서는 DBA 사용자로서 로그인이 가능합니다. 이번 예에서는 SYS 사용자로 로그인해 보겠습니다.
메인 데이타베이스 홈 페이지
로그인 후, 메인 데이타베이스의 홈 페이지가 표시됩니다. 홈 페이지의 상단 부분은 데이타베이스의 중요 정보를 요약 형식으로 제공하고 있습니다 (그림 2 참고).
 

그림 2: 메인 데이타베이스 홈 페이지 (상단)
위 그림에서 참고할 부분에 동그라미 표시를 하고 번호를 매겼습니다. 제일 먼저 “General” (1)이라 표시된 영역을 참고하시기 바랍니다. 이 영역은 데이타베이스에 관련한 가장 기초적인 정보(인스턴스 네임, 데이타베이스 시작 시간 등)를 제공합니다. Oracle Home 항목의 하이퍼링크를 클릭하면 같은 홈을 공유하는 모든 제품과 오라클 데이타베이스가 표시됩니다. Listeners 항목의 하이퍼링크는 하이퍼링크 상에 표시된 리스너를 통해 등록된 모든 데이타베이스와 인스턴스의 정보로 연결됩니다. 그리고 마지막으로 호스트 명(starz)이 표시됩니다.
"Host CPU" (2) 항목에서는 CPU 관련 정보가 간략하게 제공됩니다. "Active Sessions" (3) 항목은 액티브 세션 통계와 세션의 현재 실행 상태에 대한 정보 (4)를 제공합니다. 위 그림에서는 세션이 사용한 시간 중 99%가 wait에 사용되었음을 확인할 수 있습니다 (그 원인은 뒤에서 확인하기로 합니다). "High Availability" (5) 항목은 가용성에 관련한 정보를 제공합니다. 예를 들어 “Instant Recovery Time”은 인스턴스의 MTTR 목표, 다시 말해 인스턴스 장애 발생 시 복구(instance crash recovery)에 얼마나 많은 시간이 사용될 것인지를 의미합니다.
"Space Usage" (6) 항목을 주목하시기 바랍니다. 이 항목은 23 개의 세그먼트에 대한 경고 메시지가 존재함을 알려주고 있습니다 (경고 메시지의 내용에 대해서는 뒷부분에서 확인하기로 합니다). "Diagnostic Summary" (7)는 데이타베이스의 진단 결과를 요약하고 있습니다. “Performance Finding”의 숫자는, 10g에 새로 추가된 성능 진단 엔진인 ADDM(Automatic Database Diagnostic Monitor)이 발견한 성능 이슈의 수를 의미합니다. 또, EM은 환경을 자동으로 분석하여 베스트 프랙티스를 위반한 사례가 있는지 점검하는 기능을 제공합니다. 분석 작업의 결과는 “Policy Violation”에 표시됩니다. 마지막으로 “Alert Log”는 최근 발생한 ORA error에 대한 정보를 제공합니다. 이 정보는 매우 중요한 가치를 갖습니다. Alert log에 대한 자동 검색을 통해 Oracle 에러를 확인해 줌으로써, 수작업으로 에러 메시지를 찾는 시간을 상당 수준 절감할 수 있습니다.
그림 3은 데이타베이스 홈 페이지의 하단 영역을 보여주고 있습니다. 여기에서는 메시지의 상세한 내용을 확인할 수 있습니다. "Alerts" (1) 항목은 주목할 필요가 있는 알림(alert) 메시지들의 목록을 표시합니다. 제일 첫 번째 메시지(2)는 Archiver 프로세스에 hang이 발생했음을 알려 주고 있습니다. 그 이유를 확인하기 위해 메시지에 연결된 링크를 클릭하면 에러 정보를 담은 alert.log 파일의 상세한 내용이 표시됩니다. 이 경우, flashback recovery area의 공간이 부족한 것이 원인임을 확인되었고, 공간 확보 작업을 거침으로써 Archiver가 다시 정상적으로 동작하게 될 것입니다.
 

그림 3: 메인 데이타베이스 홈 페이지 (하단)
또 다른 알림 메시지(3)은 wait에 관한 정보를 표시하고 있습니다. 데이타베이스가 69%의 시간을 “Application” wait class에 관련된 wait에 사용하고 있습니다. 홈 페이지의 상단에 있던 wait에 관련한 세션 정보를 기억하십니까? 이 메시지를 통해 그 원인이 확인된 셈입니다. 하이퍼링크를 클릭하면 실제 발생 중인 wait에 대한 상세 정보가 표시됩니다.
다음의 알림 메시지(4)는 감사에 관련된 내용입니다. 사용자 SYS가 특정 클라이언트 머신으로부터 데이타베이스에 접속했습니다. 하이퍼링크를 클릭하면 연결에 관련한 상세 정보를 얻을 수 있습니다. 마지막 메시지(5)는 몇 가지 invalid 오브젝트에 대해 알려주고 있습니다. 하이퍼링크를 클릭하면 invalid 오브젝트에 대한 상세 정보 화면이 표시됩니다.
지금까지 확인한 것처럼, 데이타베이스 홈 페이지는 주목할 필요가 있는 모든 정보를 표시하는 대시보드의 역할을 담당합니다. 세부적인 정보로 화면을 가득 채우는 대신, 인터페이스를 매우 간결한 형태로 정리하고 한 번의 마우스 클릭만으로 상세한 정보를 확인할 수 있도록 배려하였습니다. 이 모든 정보를 직접 수집할 수도 있겠지만 그렇게 하려면 많은 시간과 노력이 필요할 것입니다. EM 10g는 설치 후 별도의 구성 과정을 거치지 않고도 필요한 모든 정보를 제공합니다.
일반적 용례
이번에는 새로운 EM을 활용하여 보다 일상적인 업무를 해결하는 사례에 대해 알아보기로 합시다.
DBA가 수행하는 일상 업무의 하나로 테이블 및 인덱스의 변경을 들 수 있습니다. 데이타베이스 홈 페이지에서 “Administration” 탭을 선택하여 (그림 3의 6번) 클릭합니다. 이 페이지를 통해서 undo segment의 설정, 테이블스페이스 및 스키마 오브젝트의 생성, Resource manager설정, Scheduler의 설정 등의 데이타베이스 관리 작업을 수행할 수 있습니다. “Tables” 탭을 클릭하면 그림 4와 같은 화면이 표시됩니다.
 

그림 4: 테이블 관리
붉은 원 안에 표시된 플래시 심볼을 주목하시기 바랍니다. 이 심볼은 값의 목록을 불러오기 위해 사용하는 버튼입니다. 화면에서 LOV 심볼을 클릭하면 데이타베이스에 존재하는 사용자의 목록이 표시되어 그 중 하나를 선택할 수 있게 합니다. “Go” 버튼을 클릭하면 해당 사용자를 위한 테이블의 목록이 표시됩니다. 이 과정에서 와일드카드 문자(%)를 사용하는 것도 가능합니다. 예를 들어 “%TRANS%”는 테이블명에 TRANS라는 문자열을 포함하는 모든 테이블을 표시하는 조건으로 사용됩니다.
예를 들어 설명해 보겠습니다. 컬럼의 변경을 위해 TRANS 테이블을 선택합니다 하이퍼링크를 클릭하면 “Edit Table” 스크린이 표시됩니다 (그림 5 참고).
 

그림 5: 테이블 관리
ACTUAL_RATE 컬럼의 데이타 타입을 NUMBER(10)에서 NUMBER(11)으로 변경하고자 하는 경우, 숫자(그림 5의1번 참고)를 변경한 후 “Apply”를 클릭합니다. 이 작업에 사용되는 SQL 구문을 확인하려면 “Show SQL” 버튼을 클릭합니다.
같은 화면에서 용량의 증가 현황에 관련한 정보를 확인할 수도 있습니다. 나중에 세그먼트 관리에 관한 연재에서 자세히 설명하겠지만, 일정 기간 동안 오브젝트 크기가 증가한 추이를 관찰하는 것이 가능합니다. EM은 같은 정보를 그래픽 형태로 표시합니다. 이 정보를 얻으려면 “Segment” 탭(그림5의 2번 참고))을 클릭합니다. 그러면 그림 6에서 보여지는 것과 같은 Segment 스크린이 표시됩니다.
 

그림 6: Segment 스크린
붉은 색 원 안에 표시된 항목들을 주목하십시오: 이 화면은 얼마나 많은 공간이 세그먼트에 할당되었고(2), 얼마나 많은 공간이 실제로 사용되고 있으며(1), 얼마나 많은 공간이 낭비되고 있는지(3)를 알려줍니다. 스크린의 하단(4)에는 오브젝트에 할당된 공간과 사용된 공간을 그래픽을 통해 표시하고 있습니다. 이 경우, 테이블의 용량은 일정하게 유지되고 있음을 알 수 있습니다.
그 밖에도 다양한 테이블 관련 작업을 수행할 수 있습니다. 예를 들어 “Constraints” 탭은 제약조건 관리에 활용됩니다.
EM을 이용한 성능 튜닝
지금까지 확인한 것처럼, EM은 룩앤필 면에서 많은 변화를 겪었지만 과거 Java 버전에서 제공되던 기능을 모두 그대로 포함하고 있습니다. 하지만 이전 버전과 분명하게 구분되는 점은, EM이 Oracle Database의 새로운 기능을 모두 지원한다는 사실입니다. (예를 들어 EM을 이용하여 subpartition 기능을 구현할 수 있게 되었습니다.)
하지만 숙련된 DBA라면 툴이 더 많은 기능을 제공할 수 있기를 원할 것입니다. 성능 문제에 관련한 트러블슈팅 및 사전 예방적인 성능튜닝과 같은 경우입니다. 한 가지 예를 들어보겠습니다. 앞부분의 예에서 데이타베이스가 “Application” wait class에 대한 대기에 많은 시간을 소모하고 있음을 확인한 바 있으며 그 원인을 진단하길 원하고 있습니다(그림 3의 3)). 어떠한 튜닝 작업이든 CPU, 디스크, 호스트 서브시스템의 상호 관계를 확인하는 것이 중요하며, 따라서 이러한 모든 변수들을 하나의 맥락으로 파악할 수 있다면 도움이 될 것입니다. 이를 위해 데이타베이스 홈 페이지에서 “Performance” 탭을 클릭합니다. 그림 7에서 보여지는 것과 같은 화면이 뜰 것입니다.
 

그림 7: Performance 탭
같은 시간대를 기준으로 다양한 성능 지표가 표시되고 있으며, 따라서 다양한 성능 변수의 상호관계를 쉽게 파악할 수 있습니다. 그림 7 (3)번의 급격한 부하 증가 현상은 Scheduler 태스크의 실행 주기와 일치합니다. 또 같은 기간 동안 7개의 세션이 Scheduler 관련 wait를 위해 대기하였음을 알 수 있습니다. 그렇다면 어떤 영향이 있었을까요? 같은 시기의 CPU 성능지표를 확인하시기 바랍니다 (초록색 영역). (4)번의 기준선으로 미루어 CPU의 사용률이 가장 높게 올라간 것을 확인할 수 있습니다. 그 이전과 이후에는 CPU 사용량이 급격하게 증가한 경우가 한 차례도 없었습니다. (1) 번의 Run Queue Length가 증가한 것은 Scheduler가 실행되면서 과도한 메모리를 요구했기 때문으로 보이며, 이로 인해 페이징 작업(2)이 늘어난 것을 알 수 있습니다. 이처럼 모든 현상을 하나의 맥락으로 이해함으로써 데이타베이스 성능 문제를 보다 정확하게 진단할 수 있습니다.
뒷부분의 Run Queue Length(5)와 Paging Rate(6) 곡선은 Physical Reads(7)의 곡선과 일치합니다. 그 원인은 무엇일까요?
위의 결과를 “Sessions: Waiting and Working” 그래프와 비교해 보면, 대부분의 세션이 “Application” wait class를 대기하고 있었음을 알 수 있습니다. 하지만 해당 시간대에 대기 중이었던 이벤트가 무엇이었는지 분명하게 파악할 필요가 있습니다. 해당 시간대의 영역을 클릭하면 그림 8에서 보여지는 것과 같은 Active Sessions 스크린이 표시됩니다.
 

그림 8: Active Sessions Waits
위 화면을 통해 세션이 enq: TX - row lock contention 이벤트를 대기 중이었음을 알 수 있습니다. 그렇다면 그 원인이 된 SQL 구문은 무엇일까요? 이미 화면에 문제의 SQL 구문에 대한 SQL ID(8rkquk6u9fmd0)가 표시되고 있습니다 (붉은색 원 참고). 해당 SQL ID를 클릭하면 그림 9와 같은 SQL Details 스크린이 표시됩니다.
 

그림 9: SQL Details 스크린
위 스크린을 통해 SQL 구문과 execution plan을 포함하는 상세 정보를 확인할 수 있습니다. 이 경우 SQL이 row lock contention을 발생시킨 것을 알 수 있으며, 따라서 애플리케이션 설계가 성능 문제의 원인이 된 것으로 결론을 내릴 수 있습니다.
Latch Contention
"Performance" 탭을 클릭한 결과가 아래 그림과 같은 경우를 가정해 봅시다.
 

그림 10: Performance 탭 (두 번째 예)
그림에서 붉은색 사각형으로 표시된 영역의 성능 지표를 주목하시기 바랍니다. 오전 12시 20분을 전후하여 CPU에 관련한 wait가 많이 발생했고, 이로 인해 CPU의 run queue 사이즈가 증가했음을 알 수 있습니다. 이제 wait 현상의 원인을 분석할 차례입니다.
먼저 그래프의 CPU 경합에 관련된 정보 영역을 클릭하여 (“Click Here”표 표시된 부분 참고) wait에 관련한 상세한 정보를 확인합니다.
 

그림 11: Active Session Waits
"Active Sessions Working: CPU Used" 그래프의 회색으로 표시된 영역(1)을 참고하시기 바랍니다. 마우스를 드래그하여 해당 영역의 위치를 바꿀 수도 있으며, 이 경우, 아래의 파이 차트(2와 3)는 선택된 시간대를 기준으로 다시 계산됩니다. 위 그림에서 ID 8ggw94h7mvxd7를 갖는 SQL 구문에 많은 부하가 걸리고 있음을 알 수 있습니다(2). 또 사용자 ARUP의 SID 265 세션이 가장 많은 자원을 사용하고 있다는 사실도 확인할 수 있습니다(3). 해당 세션을 클릭하면 “Session Details” 스크린이 표시됩니다. “Wait Events” 탭을 클릭하여 세션에 관련된 wait 이벤트의 상세한 정보를 확인할 수 있습니다 (그림 12 참고).
 

그림 12: Wait Event 상세 정보
위 그림에서, library cache에 대한 wait가 118 centisecond로 가장 오랜 시간이 걸리고 있음을 확인합니다. “Latch: Library Cache”의 하이퍼링크를 클릭하면 그림 13과 같은 화면이 나타납니다.
 

그림 13: Wait Histogram
위 화면은 10g 이전 버전에서는 제공되지 않던 정보를 표시하고 있습니다. Latch 경합에 관련된 문제를 진단하면서, 118 centisecond의 대기시간이 여러 세션들의 짧은 wait들이 합산된 결과인지, 아니면 하나의 세션이 오랜 시간을 대기한 결과인지 어떻게 알 수 있을까요?
위의 히스토그램이 그 정보를 제공합니다. 약 250여 개의 세션이 wait에 1 millisecond (첫 번째 붉은색 원 참고)를 사용했으며, 180여 개의 세션이 4~8 millisecond(두 번째 붉은색 원 참고)를 사용했음을 알 수 있습니다. 따라서 매우 짧은 시간의 wait가 원인이 되고 있으며, 따라서 latch 경합이 심각한 수준이 아니라는 결론을 내릴 수 있습니다.
데이타베이스 홈 페이지에서 “Advisor Central” 탭을 클릭하면, ADDM, SQL Access Advisor를 비롯한 각종 Advisor 툴에 접근할 수 있습니다. ADDM은 자동으로 성능지표를 수집하여 Advisor Central 페이지에 그 결과를 표시하며, 각각의 결과를 클릭하면 ADDM이 제시하는 권고안을 확인할 수 있습니다. SQL Tuning Advisor가 제시하는 권고안도 이 페이지에서 확인할 수 있습니다. (ADDM과 SQL Tuning Advisor에 대한 자세한 내용은 향후 연재에서 설명합니다.)
더욱 쉬워진 유지보수 작업
데이타베이스 홈 페이지의 “Maintenance” 탭은 백업 및 복구, 데이타 익스포트/임포트 (Data Pump), 데이타베이스 클로닝 등의 유지보수 작업에 관련한 툴의 정보를 제공합니다. 이 화면에서 유지보수 정책에 위반된 내역을 확인하고 베스트 프랙티스를 구현할 수 있습니다.
결론
이 문서는 EM의 기능 중 극히 일부만을 설명하고 있습니다. 이 문서는 EM의 기능을 전반적으로 설명하기보다, 특정한 업무를 위해 EM을 사용하는 예에 초점을 맞추어 논의를 진행했습니다.
Oracle 10g EM은 초보 DBA가 Oracle Database 관리의 개념을 이해하는데 매우 유용한 툴입니다. EM의 활용에 관련한 테크닉은 "2-Day DBA" reference manual"에 잘 설명되어 있습니다. DBA 업무를 처음 시작하는 관리자라면 반드시 읽어 보실 것을 권합니다.
 
 
 
 
제 14 주
Virtual Private Database
VPD에 새롭게 추가된 4가지 policy type, 컬럼 단위 policy 적용, column masking 등의 신기능을 활용하여 한층 강력하고 유연한 보안 환경을 구현할 수 있습니다.
Fine Grained Access Control이라는 용어로 불리기도 하는 Virtual Private Database(VPD)는 로우(row) 레벨의 강력한 보안 기능을 제공합니다. VPD는 Oracle8i에서 처음 소개된 이후, 교육용 소프트웨어에서 금융 애플리케이션에 이르기까지 다양한 영역에서 활용되고 있습니다.
VPD는 접수된 데이타 쿼리를 사용자의 권한에 맞도록 테이블의 일부분만을 포함하는 부분적인 뷰에 대한 쿼리로 자동 변경합니다. VPD는 모든 쿼리에 대해 사용자에게 접근 허용된 로우(row)만을 필터링하도록 쿼리 조건을 추가합니다. 예를 들어 사용자가 SCOTT가 account manager로 할당된 account만을 보아야 하는 경우, VPD는 쿼리를 아래와 같이 재작성합니다:
select * from accounts;

to:
select * from accounts
where am_name = 'SCOTT';

DBA가 ACCOUNTS 테이블에 보안 정책을 설정하면, 설정된 정책에는 policy function이라 불리는 함수가 적용됩니다. 이 함수는 “where am_name = 'SCOTT'“와 같은 문자열을 반환하고, 생성된 문자열은 쿼리 조건에 추가되는 predicate으로 활용됩니다. VPD 기능에 대해 친숙하지 않은 경우라면, 오라클 매거진의 기사 "Keeping Information Private with VPD를 참고하실 것을 권장 드립니다."
Policy Types
이처럼 반복적인 파싱을 통해predicate을 생성하는 것은 성능적으로 부담이 될 수 있습니다. 경우에 따라서는 성능 개선을 위한 대안을 고려할 수 있습니다. 대부분의 경우 predicate은 사용자가 누구이고, 그 사용자의 권한이 어디까지이고, 사용자의 상급 관리자가 누구인지 등의 여부에 따라 다이내믹하게 결정됩니다. Policy function에 의해 생성 및 반환되는 문자열은 매우 다이내믹한 성격을 가지며, 따라서 오라클은 정확성을 보장하기 위해서 매번 policy function을 반복적으로 수행합니다. 이는 성능 및 자원사용률 면에서 낭비를 초래할 수 있습니다. 이처럼 predicate이 실행할 때마다 달라지는 경우의 policy를 “dynamic” policy라 부릅니다. Dynamic policy는 Oracle9i 데이타베이스와 그 이전 릴리즈에서 이미 지원되어 왔습니다.
이와 별도로, Oracle Database 10g는 성능 향상을 목적으로 context_sensitive, shared_context_sensitive, shared_static, static 등의 다양한 policy 유형을 추가로 제공합니다: 이제 각 policy 유형의 의미와 활용 방안을 알아 보기로 합시다.
Dynamic Policy. 하위 버전과의 호환성을 유지하기 위한 목적에서, 10g의 디폴트 policy 유형은 “dynamic”으로 설정되어 있습니다. Dynamic policy는 테이블이 액세스 될 때마다 각각의 로우(row) 및 모든 사용자에 대해서 policy function을 실행합니다. Dynamic policy가 predicate를 활용하는 방법에 대해 좀 더 자세히 알아보겠습니다:
where am_name = 'SCOTT'

where 키워드를 제외한다면, predicate은 크게 두 부분으로 나뉘어집니다. 등호 기호의 앞부분(am_name)과 뒷부분(‘SCOTT’)로 나뉘어집니다. 대부분의 경우, 뒷부분에는 사용자 데이타로부터 제공되는 변수와 같습니다. (예를 들어 사용자가 SCOTT라면 값은 ‘SCOTT’가 됩니다.) 등호 기호의 앞부분은 static한 문자열로 이루어지며, 따라서 각 로우(row) 별로 policy function을 반복적으로 수행할 필요가 없습니다. 이처럼 등호 기호의 앞부분과 뒷부분의 static / dynamic 여부를 미리 알고 있다면 부분적으로 성능을 개선하는 것이 가능해집니다. 10g에서는 이를 위해 “context_sensitive” 타입을 지원하며, dbms_rls.add_policy 호출 과정에서 이 타입을 매개변수로 사용할 수 있습니다:
policy_type => dbms_rls.context_sensitive

이번에는 여러 개의 컬럼을 갖는 ACCOUNTS 테이블에 대한 예를 설명하겠습니다. ACCOUNTS 테이블에 포함된 BALANCE 컬럼은 해당 계좌의 잔액을 표시합니다. 특정 사용자가 application context에 의해 정의된 액수 이하의 잔액을 갖는 계좌들을 조회할 수 있도록 허용되었다고 가정해 봅시다. 하드 코딩을 통해 계좌 잔액의 액수를 입력하는 대신 Policy function을 이용해 다음과 같이 application context를 활용할 수 있습니다:
create or replace vpd_pol_func
(
   p_schema in varchar2,
   p_table in varchar2
)
return varchar2
is
begin
   return 'balance < sys_context(''vpdctx'', ''maxbal'')';
end;

Application context VPDCTX 의MAXBAL 속성을 설정해 두고 함수가 런타임에 값을 가져오도록 할 수 있습니다.
위의 코드 예제를 주의 깊게 살펴 보시기 바랍니다. Predicate은 크게 두 부분(‘<’기호 이전과 이후)으로 나뉘어집니다. 앞부분의 “balance”는 static한 문자열입니다. 뒷부분은 application context가 변경되기 전까지는 원래 값을 그대로 유지하므로 어느 정도 static하다고 볼 수 있습니다. 따라서 application context속성이 변경되지 않는 한, 전체 predicate이 static하다고 판단할 수 있으며, 따라서 함수를 재실행할 필요가 없습니다. Oracle Database 10g는 policy type이 context sensitive로 지정된 경우 이러한 최적화 알고리즘을 사용합니다. 세션에서 context 변경이 발생하지 않는 경우 함수는 재실행되지 않으며, 상당한 수준의 성능 향상 효과를 볼 수 있습니다.
Static Policy. 경우에 따라서는 보다 static한 형태의 predicate이 사용될 수도 있습니다. 위의 예제에서는 maximum balance를 변수로서 정의했습니다. 이러한 접근방식은 Oracle userid가 많은 웹 사용자에 의해 공유되고 사용자의 권한에 따라 이 변수(application context)가 변경되어야 하는 웹 애플리케이션 환경에서 유용합니다. 예를 들어 TAO와 KARTHIK이라는 두 사용자가 APPUSER라는 동일한 데이타베이스 사용자로 접근하는 경우에도, 각 세션 별로 설정된 application context에 의해 서로 다른 권한을 할당 받게 됩니다. 다시 말해 MAXBAL의 값은 Oracle userid가 아닌 TAO와 KARTHIK의 개별 세션 별로 바인드 됩니다.
Static policy의 경우 predicate은 아래와 같이 보다 예측 가능한 형태로 제시됩니다.
LORA와 MICHELLE는 각각 Acme Bearings와 Goldtone Bearings의 어카운트 관리자입니다. 두 사람은 데이타베이스에 연결할 때 개인 ID를 사용하며 각자에게 허용된 로우(row)만을 조회할 수 있습니다. Lora의 경우 predicate은 “where CUST_NAME = 'ACME'”, Michelle의 경우 predicate은 “where CUST_NAME = 'GOLDTONE'”입니다. 이 경우 predicate은 사용자ID와 연결되며, 따라서 그들에 의해 생성된 어떤 세션이든 application context가 제공하는 같은 값을 predicate으로 사용하게 됩니다.
10g는 이러한 경우 SGA 캐시에 predicate을 저장하고 해당 세션에 대해서는 policy function을 재실행하지 않고 계속적으로 재활용합니다. Policy function은 아래와 같습니다:
create or replace vpd_pol_func
(
   p_schema in varchar2,
   p_table in varchar2
)
return varchar2
is
begin
   return 'cust_name = sys_context(''vpdctx'', ''cust_name'')';
end;

Policy는 아래와 같이 정의됩니다:
policy_type => dbms_rls.static

이와 같은 접근법을 사용하면 policy function이 단 한 차례만 수행됨을 보장할 수 있습니다. 세션에서 application context가 변경되는 경우에도 함수는 재실행되지 않으므로 성능이 대폭적으로 향상됩니다.
Static policy는 여러 구독자(subscriber)가 사용하는 애플리케이션 환경에서 유용합니다. 이 경우 여러 사용자 또는 구독자가 단일 데이타베이스의 데이타를 공유하게 됩니다. 구독자가 로그인하면, 로그인 과정에서 “after-login trigger”가 동작하여 application context를 설정하고 policy function을 실행함으로써 predicate을 얻게 됩니다.
하지만 static policy는 양날의 칼과도 같습니다. 위의 예에서는, application context의 VPDCTX.CUST_NAME속성의 값이 세션 내에서 변경되지 않는다고 가정했습니다. 만일 그 가정이 잘못되었다면 어떻게 될까요? 속성 값이 변해도 policy function이 재실행되지 않으므로 predicate에 새로운 값이 반영되지 않을 것이며, 따라서 완전히 잘못된 결과가 나올 것입니다. 그러므로 static policy를 사용할 때는 주의할 필요가 있으며, 속성 값이 변하지 않음을 분명히 확신할 수 있을 때에만 static policy를 사용해야 합니다. 이러한 가정이 불가능하다면, context sensitive policy를 사용하는 것이 무난합니다.
Shared Policy Types. 코드를 재활용하고 파싱된 코드의 활용도를 최대로 높이려면, 여러 테이블에 공통적으로 적용되는 policy function을 구현할 필요가 있습니다. 예를 들어, 위의 예에서 계좌 별로 두 개의 테이블(SAVINGS와 CHECKING)이 존재하지만 규칙은 똑같이 적용되는 경우를 가정해 봅시다. 사용자는 자신에게 허용된 것 이외의 계좌 잔액은 조회할 수 없습니다. 이 경우 CHECKING 테이블과 SAVINGS 테이블에 사용되는 policy function은 동일합니다. 생성되는 policy의 유형은 context_sensitive로 가정합니다.
다음과 같은 이벤트가 순서대로 발생한다고 가정해 봅시다:
1. 세션 연결
2. application context 설정
3. select * from savings;
4. select * from checking;
Application context가 3번, 4번 과정에서 변경되지 않았음에도 조회되는 테이블이 다르기 때문에 policy function은 재실행될 것입니다. 하지만 policy function이 같기 때문에 재실행할 필요는 없었습니다. 10g는 동일한 policy를 여러 오브젝트가 공유하는 기능을 제공합니다. 위의 예의 경우 policy type은 다음과 같이 정의됩니다:
New in 10g is the ability to share a policy across objects. In the above example, you would define the policy type of these policies as:
policy_type => dbms_rls.shared_context_sensitive

이처럼 policy를 “shared”로 지정함으로써 함수의 불필요한 실행을 방지하고 성능을 향상시킬 수 있습니다.
Selective Columns
이번에는 특정 컬럼이 select 된 경우에만 VPD policy가 적용되는 경우를 생각해 봅시다. ACCOUNTS 테이블이 아래와 같은 레코드를 갖는다고 가정합니다:
ACCTNO ACCT_NAME    BALANCE
------ ------------ -------
     1 BILL CAMP    1000
     2 TOM CONNOPHY 2000
     3 ISRAEL D     1500   

Michelle은 balance가 1,600이 넘는 account를 조회할 수 없습니다. Michelle이 다음과 같은 쿼리를 실행한 경우:
select * from accounts;

아래와 같은 결과를 확인하게 될 것입니다:
ACCTNO ACCT_NAME    BALANCE
------ ------------ -------
     1 BILL CAMP    1000
     3 ISRAEL D     1500   

1,600이 넘는 balance를 갖는 acctno 2는 실행 결과에 포함되지 않았습니다. Michelle의 관점에서 볼 때 이 테이블은 3개가 아닌 2개의 로우를 갖습니다. 따라서 Michelle이 아래와 같은 쿼리를 실행하는 경우에도 그 결과는 3이 아닌 2가 반환됩니다:
select count(*) from accounts;

하지만 security policy에 예외 조건을 적용할 필요도 있습니다.
지금 Michelle은 모든 account balance를 조회하려 하는 것이 아니고 그저 데이타의 count만을 확인하려 하는 것입니다. Michelle이 조회할 수 없는 레코드의 count를 포함시키는 것을 허용하는 것을 고려할 수도 있을 것입니다. 10g는 이러한 경우를 위해 dbms_rls.add_policy 호출 과정에서 사용할 수 있는 새로운 매개변수를 추가하였습니다:
sec_relevant_cols => 'BALANCE'

이 매개변수가 사용된 경우, 사용자가 BALANCE 컬럼을 명시적으로 또는 암시적으로(예: select *) 조회하는 경우에 한해 VPD policy는 해당 로우를 조회 대상에서 제외시킵니다. 하지만 그 밖의 경우(예를 들어 사용자가 전체 로우의 count를 조회하는 경우)에는 테이블의 모든 로우에 대한 select가 허용됩니다. 이 경우 아래와 같이 쿼리를 수행하면 그 결과로 2가 아닌 3이 반환됩니다:
select count(*) from accounts;

하지만 아래의 쿼리는 두 개의 레코드만을 반환합니다.
select * from accounts;

Column Masking
이번에는 다른 조건이 붙는 경우를 생각해 봅시다. 일정한 임계값 이상의 balance를 갖는 레코드에 대한 조회를 완전히 제한하는 대신, 임계값 이상의 balance 컬럼에 대해 마스킹(masking)을 수행하는 조건으로 모든 레코드를 반환하는 방법을 선택할 수도 있습니다.
Michelle은 1,600 이상의 balance를 갖는 account를 조회할 수 없습니다. Michelle이 아래와 같은 쿼리를 실행하면:
select * from accounts;

acctno 1과 acctno3의 두 가지 레코드만을 확인하게 됩니다. 그 대신 아래와 같은 결과를 보기 원할 수 있습니다:
ACCTNO ACCT_NAME    BALANCE
------ ------------ -------
     1 BILL CAMP    1000
     2 TOM CONNOPHY <null>
     3 ISRAEL D     1500   

위의 경우 모든 레코드가 표시되지만, 2000의 balance를 가진 acctno2 레코드의 BALANCE 컬럼은 null로 표시됩니다. 이러한 방법을 “column masking”이라 부르며, dbms_rls.add_policy 호출 과정에서 아래 매개변수를 사용하여 활성화할 수 있습니다:
sec_relevant_cols_opt =>  dbms_rls.all_rows

이 방법은 특정 컬럼에 대한 보안 유지가 필요한 경우 매우 유용하게 활용되며, 구현과정에서 별도의 코딩이 불필요합니다. 또 이 방법을 데이타 암호화의 대안으로 활용할 수도 있습니다.
결론
Oracle Database 10g의 VPD 기능은 매우 강력한 형태로 발전되었으며, policy를 기준으로 선택적인 컬럼을 마스킹하거나, 특정 컬럼이 액세스되는 경우에만 policy를 적용하는 등의 다양한 요구사항을 지원합니다. 또 애플리케이션의 성격에 따라 다른 policy를 적용함으로써 성능을 향상시킬 수도 있습니다.
VPD와 dbms_rls 패키지에 대한 자세한 설명은 PL/SQL Packages and Types Reference의 Chapter 79, 또는 Oracle Database Security Guide를 참고하시기 바랍니다. 필자가 Don Burleson과 공동집필한 Oracle Privacy Security Auditing (Rampant TechPress)도 참고가 될 것입니다.
 
 
 
 
제 15 주
세그먼트의 관리

Oracle Database 10g가 새로 제공하는 공간 재확보 기능, 온라인 테이블 재구성, 스토리지 증가량 예측 기능 등을 이용하여 세그먼트의 공간을 효율적으로 관리할 수 있습니다.
오래 전, Oracle Database의 경쟁 RDBMS 제품을 평가해 달라는 요청을 받은 일이 있습니다. 경쟁사의 프리젠테이션이 진행되는 동안, 청중들이 가장 감탄했던 기능이 바로 온라인 재구성(online reorganization) 기능이었습니다. 이 제품은 (오라클로 따지면 세그먼트에 해당하는) 영역의 데이타 블록을 온라인 상태에서 재배치하는 기능을 제공했습니다.
당시 오라클이 제공하던 Oracle9i Database는 이러한 기능을 제공하지 못했습니다. 이제 Oracle Database 10g는 온라인 상태에서 낭비되는 공간을 재확보하고 오브젝트를 보다 컴팩트(compact)한 형태로 관리할 수 있게 하는 기능을 추가적으로 제공합니다.
이 기능을 자세히 살펴 보기에 앞서, 이전에는 세그먼트 관리를 어떤 방법으로 수행했는지 설명하도록 하겠습니다.
기존의 관리 방법
그림 1과 같은 형태로 채워진 세그먼트를 가정해 봅시다. 작업이 수행되면서 그림 2와 같이 일부 로우(row)가 삭제되고 나면 낭비되는 공간이 생기게 됩니다. 낭비되는 공간은 (i) 남아있는 블록의 마지막 영역과 기존 테이블의 마지막 영역의 사이에서, 그리고 (ii) 로우가 부분적으로만 삭제된 블록 내부에서 발생합니다.
 

그림 1: 테이블에 할당된 블록. (로우는 회색 사각형으로 표시됨)
오라클이 이 영역에 대한 할당을 바로 해제하지 않고, 새로운 insert 작업 및 기존 로우의 확장에 대비한 예비 공간으로 활용합니다. 지금까지의 점유되었던 공간의 최고점을 High Water Mark(HWM)이라 부릅니다 (그림 2 참고).
 

그림 2: 일부 로우가 삭제된 후 (HWM은 변경되지 않았음)
하지만 이와 같은 접근 방식에는 두 가지 문제점이 존재합니다:
사용자의 쿼리가 풀 테이블 스캔을 발생시키는 경우, 오라클은 (설사 관련된 데이타가 전혀 존재하지 않는 경우라 하더라도) HWM 아래쪽의 모든 영역을 스캔합니다. 이로 인해 풀 테이블 스캔에 소요되는 시간이 길어질 수 있습니다.
로우가 direct path 정보와 함께 insert 되는 경우 (예를 들어 APPEND 힌트를 사용한 Insert, 또는 SQL*Loader direct path를 통해 insert 되는 경우) 새로 추가되는 데이타 블록은 HWM의 위쪽 영역에 추가됩니다. 따라서 HWM의 아래쪽 영역은 낭비된 채로 남게 됩니다.
Oracle9i와 그 이전 버전에서 공간을 재확보하려면, 테이블을 drop하고 다시 생성한 다음 데이타를 다시 로드하는 방식, 또는 ALTER TABLE MOVE 명령을 사용하여 테이블을 다른 테이블스페이스로 이동하는 방식을 사용해야 했습니다. 이 두 가지 방식은 모두 오프라인 상태에서 수행되어야 한다는 문제가 있습니다. 그 대안으로 online table reorganization 기능을 사용할 수도 있지만, 이를 위해서는 기존 테이블 크기의 두 배나 되는 공간이 필요했습니다.
10g의 경우 이러한 작업은 훨씬 간소화되었습니다. 10g의 Automatic Segment Space Management(ASSM)이 해당 테이블스페이스에 활성화되어 있는 경우, 세그먼트, 테이블, 인덱스를 shrink하고 free block을 재확보한 뒤 다른 용도로 할당하도록 데이터베이스로 반환됩니다. 그 자세한 방법을 알아보기로 합시다.
10g의 세그먼트 관리 기능
웹사이트를 통해 온라인으로 접수된 예약 정보를 보관하는 BOOKINGS라는 이름의 테이블이 존재한다고 가정해 봅시다. 확인 절차를 거친 예약은 BOOKINGS_HIST 테이블에 저장되고 해당 레코드는 BOOKINGS 테이블에서 삭제됩니다. 예약에서 확인까지 걸리는 시간은 고객에 따라 다릅니다. 이 경우 레코드 삭제로 인해 남은 공간이 충분하지 않은 경우에는 레코드가 테이블 HWM의 위쪽 영역에 insert 됩니다.
이제 낭비되는 공간을 재확보할 차례입니다. 먼저 해당 세그먼트에서 얼마나 많은 공간을 확보할 수 있는지 확인해야 합니다. 이 테이블은 ASSM이 적용된 테이블스페이스에 위치하고 있으므로, 아래와 같이 DBMS_SPACE 패키지의 SPACE_USAGE 프로시저를 사용해야 합니다:
declare

   l_fs1_bytes number;
   l_fs2_bytes number;
   l_fs3_bytes number;
   l_fs4_bytes number;
   l_fs1_blocks number;
   l_fs2_blocks number;
   l_fs3_blocks number;
   l_fs4_blocks number;
   l_full_bytes number;
   l_full_blocks number;
   l_unformatted_bytes number;
   l_unformatted_blocks number;
begin
   dbms_space.space_usage(
      segment_owner      => user,
      segment_name       => 'BOOKINGS',
      segment_type       => 'TABLE',
      fs1_bytes          => l_fs1_bytes,
      fs1_blocks         => l_fs1_blocks,
      fs2_bytes          => l_fs2_bytes,
      fs2_blocks         => l_fs2_blocks,
      fs3_bytes          => l_fs3_bytes,
      fs3_blocks         => l_fs3_blocks,
      fs4_bytes          => l_fs4_bytes,
      fs4_blocks         => l_fs4_blocks,
      full_bytes         => l_full_bytes,
      full_blocks        => l_full_blocks,
      unformatted_blocks => l_unformatted_blocks,
      unformatted_bytes  => l_unformatted_bytes
   );
   dbms_output.put_line(' FS1 Blocks = '||l_fs1_blocks||' Bytes = '||l_fs1_bytes);
   dbms_output.put_line(' FS2 Blocks = '||l_fs2_blocks||' Bytes = '||l_fs2_bytes);
   dbms_output.put_line(' FS3 Blocks = '||l_fs3_blocks||' Bytes = '||l_fs3_bytes);
   dbms_output.put_line(' FS4 Blocks = '||l_fs4_blocks||' Bytes = '||l_fs4_bytes);
   dbms_output.put_line('Full Blocks = '||l_full_blocks||' Bytes = '||l_full_bytes);
end;
/
The output is:
FS1 Blocks = 0 Bytes = 0
FS2 Blocks = 0 Bytes = 0
FS3 Blocks = 0 Bytes = 0
FS4 Blocks = 4148 Bytes = 0
Full Blocks = 2 Bytes = 16384

실행 결과를 통해 4,148개의 블록이 75-100%의 free space(FS4)를 포함하고 있으며, 이를 제외하고는 free space가 전혀 존재하지 않음을 확인할 수 있습니다. Full block은 단 2개에 불과합니다. 따라서 4,148 개의 블록에서 공간을 확보할 수 있습니다.
이제 테이블에 row-movement가 활성화되어 있는지 점검해야 합니다. row-movement를 활성화 하기 위해서는 아래와 같이 입력합니다:
alter table bookings enable row movement;

또는 Enterprise Manager 10g의 Administration 페이지에서 작업할 수도 있습니다. 또, 테이블의 모든 rowid 기반 트리거가 비활성화되어 있는지 점검해야 합니다. (로우가 이동되면서 rowid가 변경될 수 있기 때문입니다.)
마지막으로, 아래 명령을 사용하여 테이블의 기존 로우를 재구성합니다.
alter table bookings shrink space compact;

이 명령은 그림 3과 같은 형태가 되도록 블록 내부의 로우를 재배치하고, HWM 아래쪽 영역에 free block을 확보합니다. (하지만 HWM 자체는 변경되지 않습니다.)
 

그림 3: 재구성작업을 거친 뒤의 테이블 블록
작업이 완료된 후 공간 사용률에 변화가 있는지 확인해 봅시다. 앞에서 소개한 PL/SQL 코드를 사용하여 얼마나 많은 블록이 재구성되었는지 확인할 수 있습니다:
FS1 Blocks = 0 Bytes = 0
FS2 Blocks = 0 Bytes = 0
FS3 Blocks = 1 Bytes = 0
FS4 Blocks = 0 Bytes = 0
Full Blocks = 2 Bytes = 16384

이제 매우 중요한 변화가 있었음을 확인할 수 있습니다. FS4 블록 (75-100%의 여유 공간을 갖는 블록)의 수가 4,148에서 0으로 바뀌었습니다. 또 FS3 블록(50-75%의 여유 공간을 갖는 블록)의 수가 0에서 1로 증가했습니다. 반면 HWM은 변경되지 않았으며, 전체 공간사용률에도 아무런 변화가 없었습니다. 사용중인 전체 공간은 아래와 같이 확인할 수 있습니다:
SQL> select blocks from user_segments where segment_name = 'BOOKINGS';

   BLOCKS
---------
     4224

테이블이 점유중인 블록의 수(4,224)는 변경되지 않았으며, HWM도 기존 위치를 그대로 유지하고 있습니다. 다음과 같은 명령을 사용하면 HWM의 위치를 아래쪽을 이동하고 상위 영역을 재확보할 수 있습니다:
alter table bookings shrink space;

여기서 COMPACT 키워드가 사용되지 않은 점을 주목하시기 바랍니다. 위 구문을 실행하면 테이블이 사용되지 않은 블록을 반환하고 HWM을 재설정합니다. 아래와 같이 테이블에 할당된 공간을 확인하고 그 결과를 점검할 수 있습니다:
SQL> select blocks from user_segments where segment_name = 'BOOKINGS';

    BLOCKS
----------
         8

블록의 수가 4,224 개에서 8개로 줄었습니다. 그림 4에서 보여지는 것처럼 테이블 내에서 사용되지 않던 모든 공간이 반납되어 다른 세그먼트에서 활용할 수 있게 되었습니다.
 

그림 4: Shrink 작업 수행 후 free block이 데이타베이스로 반납된 결과
Shrink 작업은 온라인 상태에서 수행되며 사용자에게 아무런 영향을 미치지 않습니다.
테이블 인덱스에 대한 shrink 작업도 아래와 같이 수행할 수 있습니다:
alter table bookings shrink space cascade;

온라인 shrink 명령은 낭비되는 공간을 재확보하고 HWM을 재설정하는 매우 강력한 기능입니다. 필자는 개인적으로 HWM 재설정 기능의 유용성을 높이 평가합니다. HWM을 재설정함으로써 풀 테이블 스캔의 성능을 향상시킬 수 있기 때문입니다.
Shrinking 작업 대상 세그먼트 찾기
온라인 shrink 작업을 수행하기 전에, 압축율을 비약적으로 향상시킬 수 있는 대상 세그먼트를 찾아내는 작업을 수행해야 할 수도 있습니다. dbms_space 패키지에 내장된 verify_shrink_candidate 함수를 사용하여 이 작업을 간단하게 마무리할 수 있습니다. 아래 PL/SQL 코드는 대상 세그먼트가 1,300,000 바이트로 shrink 될 수 있는지 테스트합니다:
begin
   if (dbms_space.verify_shrink_candidate
         ('ARUP','BOOKINGS','TABLE',1300000)
   ) then
       :x := 'T';
   else
       :x := 'F';
   end if;
end;
/

PL/SQL procedure successfully completed.

SQL> print x

X
--------------------------------
T

If you use a low number for the target shrinkage, say 3,000:
begin
   if (dbms_space.verify_shrink_candidate
         ('ARUP','BOOKINGS','TABLE',30000)
   ) then
       :x := 'T';
   else
       :x := 'F';
   end if;
end;

이 경우 변수 x의 값은 ‘F’로 반환되었습니다. 이는 테이블이 3,000 바이트로 shrink 될 수 없음을 의미합니다.
인덱스 크기의 예측
이번에는 특정 테이블, 또는 여러 개의 테이블에 대해 인덱스를 생성해야 하는 경우를 가정해 봅시다. 컬럼, uniqueness 등의 구조에 관련한 일반적인 고려사항을 제외하고 가장 중요한 작업을 들라면, 인덱스의 크기를 예상하는 일을 꼽을 수 있을 것입니다. 테이블스페이스의 공간이 새로운 인덱스를 수용할 수 있을 만큼 충분한지 확인해야 합니다.
Oracle9i Database와 그 이전 버전의 경우, DBA들은 스프레드시트 또는 별개의 프로그램의 사용하여 인덱스의 크기를 예측하곤 했습니다. 10g에서는 새로 추가된 DBMS_SPACE 패키지를 이용해서 이 작업을 간단하게 마무리할 수 있습니다. 그렇다면 그 실제 활용 사례를 알아봅시다.
BOOKINGS 테이블의 booking_id 컬럼과 cust_name 컬럼을 대상으로 하는 새로운 인덱스를 추가해야 합니다. 새로운 인덱스가 얼마나 많은 공간을 사용하게 될까요? 아래와 같은 PL/SQL 스크립트를 실행하면 간단하게 확인할 수 있습니다:
declare
   l_used_bytes number;
   l_alloc_bytes number;
begin
   dbms_space.create_index_cost (
      ddl => 'create index in_bookings_hist_01 on bookings_hist '||
        '(booking_id, cust_name) tablespace users',
      used_bytes => l_used_bytes,
      alloc_bytes => l_alloc_bytes
   );
   dbms_output.put_line ('Used Bytes      = '||l_used_bytes);
   dbms_output.put_line ('Allocated Bytes = '||l_alloc_bytes);
end;
/  

실행 결과가 아래와 같습니다:
Used Bytes      = 7501128
Allocated Bytes = 12582912

인덱스의 크기를 증가시킬 수 있는 매개변수(INITRANS 등)를 사용한 경우를 가정해 봅시다.
declare
   l_used_bytes number;
   l_alloc_bytes number;
begin
   dbms_space.create_index_cost (
      ddl => 'create index in_bookings_hist_01 on bookings_hist '||
        '(booking_id, cust_name) tablespace users initrans 10',
      used_bytes => l_used_bytes,
      alloc_bytes => l_alloc_bytes
   );
   dbms_output.put_line ('Used Bytes      = '||l_used_bytes);
   dbms_output.put_line ('Allocated Bytes = '||l_alloc_bytes);
end;
/

실행 결과는 아래와 같습니다:
Used Bytes      = 7501128
Allocated Bytes = 13631488

INITRANS 매개변수의 값을 높인 결과 Allocated Bytes가 훨씬 증가했음을 확인할 수 있습니다. 이와 같은 방법으로 인덱스가 사용하게 될 공간의 크기를 쉽게 예측할 수 있습니다.
하지만 두 가지 주의해야 할 점이 있습니다. 먼저, 이 프로세스는 “SEGMENT SPACE MANAGEMENT AUTO”가 활성화된 테이블스페이스에만 적용 가능합니다. 두 번째로, 패키지는 테이블 통계를 근거로 인덱스의 크기를 예측합니다. 따라서 테이블의 통계가 최신 상태를 유지하고 있는지 점검하는 것이 중요합니다. 가장 주의할 점은, 테이블에 통계가 존재하지 않는 경우 패키지가 에러를 발생시키는 대신 엉뚱한 계산 결과를 제시한다는 사실입니다.
테이블 크기의 예측
이번에는 BOOKING_HIST 테이블이 평균 30,000의 row length를 가진 로우로 구성되어 있고 테이블의 PCTFREE 매개변수가 20으로 설정된 경우를 가정해 보겠습니다. PCT_FREE를 30으로 올리는 경우 테이블의 크기가 얼마나 증가하게 될까요? PCT_FREE가 10% 증가한 만큼, 테이블의 크기도 10% 증가하게 될까요? DBMS_SPACE 패키지의 CREATE_TABLE_COST 프로시저를 사용하면 간단하게 확인할 수 있습니다. 테이블의 크기를 예측하기 위한 코드가 아래와 같습니다:
declare
   l_used_bytes number;
   l_alloc_bytes number;
begin
   dbms_space.create_table_cost (
       tablespace_name => 'USERS',
       avg_row_size => 30,
       row_count => 30000,
       pct_free => 20,
       used_bytes => l_used_bytes,
       alloc_bytes => l_alloc_bytes
   );
   dbms_output.put_line('Used: '||l_used_bytes);
   dbms_output.put_line('Allocated: '||l_alloc_bytes);
end;
/
실행 결과는 다음과 같습니다:
Used: 1261568
Allocated: 2097152
테이블의 PCT_FREE 매개변수를 30에서 20으로 아래와 같이 조정한 후 다시 실행합니다:
pct_free => 30
we get the output:
Used: 1441792
Allocated: 2097152
사용된 공간의 크기가 1,261,568에서 1,441,792로 증가했습니다. 이는 PCT_FREE 매개변수가 데이타 블록에 더 많은 여유 공간을 할당하기 대문입니다. 증가된 비율은 예상대로 10%가 아닌 14%로 확인되었습니다. 이처럼 DBMS_SPACE 패키지를 사용하여 PCT_FREE와 같은 매개변수를 변경하는 경우 또는 테이블을 다른 테이블스페이스로 이동하는 경우의 테이블 크기를 예측할 수 있습니다.
세그먼트의 크기 예측
Acme Hotel은 주말을 맞아 수요가 급증할 것을 예상하고 있습니다. DBA는 증가하는 수요를 감당하기에 충분한 공간이 남아 있는지 확인하려 합니다. 테이블의 크기가 얼마나 증가할지 어떻게 예측할 수 있을까요?
10g가 제공하는 예측 기능의 정확성은 우리를 놀라게 하기에 충분합니다. 결과를 얻기 위해서는 아래와 같은 쿼리를 실행하기만 하면 됩니다.
select * from
table(dbms_space.OBJECT_GROWTH_TREND
('ARUP','BOOKINGS','TABLE'));

dbms_space.object_growth_trend() 함수는 PIPELINEd 포맷으로 레코드를 반환하며, TABLE() casting을 통해 그 결과를 확인할 수 있습니다. 출력된 결과가 아래와 같습니다:
TIMEPOINT                      SPACE_USAGE SPACE_ALLOC QUALITY
------------------------------ ----------- ----------- ------------
05-MAR-04 08.51.24.421081 PM       8586959    39124992 INTERPOLATED
06-MAR-04 08.51.24.421081 PM       8586959    39124992 INTERPOLATED
07-MAR-04 08.51.24.421081 PM       8586959    39124992 INTERPOLATED
08-MAR-04 08.51.24.421081 PM     126190859  1033483971 INTERPOLATED
09-MAR-04 08.51.24.421081 PM       4517094     4587520 GOOD
10-MAR-04 08.51.24.421081 PM     127469413  1044292813 PROJECTED
11-MAR-04 08.51.24.421081 PM     128108689  1049697234 PROJECTED
12-MAR-04 08.51.24.421081 PM     128747966  1055101654 PROJECTED
13-MAR-04 08.51.24.421081 PM     129387243  1060506075 PROJECTED
14-MAR-04 08.51.24.421081 PM     130026520  1065910496 PROJECTED

출력된 결과는 시간(TIMEPOINT 컬럼)별로 BOOKINGS 테이블 크기의 증가 추이를 보여주고 있습니다. SPACE_ALLOC 컬럼은 테이블에 할당된 바이트 수를 의미하며 SPACE_USAGE 컬럼은 그 중 몇 바이트가 실제로 사용되고 있는지를 나타내고 있습니다. 이 정보는 Automatic Workload Repository(AWR, 본 연재 제 6 주 참고)에 의해 수집된 데이타를 기반으로 합니다. 위 데이타 중 실제로 데이타가 수집된 것은 2004년 3월 9일입니다 (QUALITY 컬럼의 값이 “GOOD”인 것으로 확인합니다). 따라서 해당 시점의 할당 공간 및 사용 공간의 수치는 정확하다고 판단할 수 있습니다. 반면, 이후 모든 데이타의 QUALITY 컬럼은 “PROJECTED”의 값을 가지며, 이는 데이타가 AWR에 의해 수집된 데이타를 근거로 추정된 것임을 의미합니다.
3월 9일 이전 데이타의 경우 QUALITY 컬럼의 값이 “INTERPOLATED”로 표시되어 있습니다. 이 데이타는 수집되거나 추정된 것이 아니며, 단순히 수집된 데이타의 패턴에 대한 interpolation을 통해 얻어진 것입니다. 이처럼 데이타가 수집되지 않은 과거 시점이 존재하는 경우, 그 값은 interpolation을 통해 계산됩니다.
결론
세그먼트 단위의 관리 기능을 이용하여 세그먼트 내부의 공간에 대한 설정을 변경하고, 테이블 내부의 여유 공간을 재확보하거나 온라인 테이블 재구성 작업을 통해 성능을 향상시킬 수 있습니다. 10g의 새로운 기능은 테이블 재구성에 관련된 반복적인 업무를 절감하는 효과를 제공합니다. 특히 온라인 세그먼트에 대한 shrink 기능은, 내부 fragmentation을 제거하고 high water mark를 조정함으로써 풀 테이블 스캔의 성능을 극적으로 향상시키는 효과가 있습니다.
Shrink 작업에 관한 자세한 정보는 Oracle Database SQL Reference의 관련 항목을 참고하시기 바랍니다. DBMS_PACKAGE는 PL/SQL Packages and Types Reference의 Chapter 88에서 설명되고 있습니다. 기술백서 The Self-Managing Database: Proactive Space & Schema Object Management는Oracle Database 10g의 공간 관리에 관련한 새로운 기능을 종합적으로 설명하고 있습니다. Oracle Database 10g의 온라인 데모 또한 OTN을 통해 제공되고 있습니다.
 
 
 
 
제 16 주
Transportable Tablespaces
10g의 transportable tablespace는 서로 다른 플랫폼 간의 데이타 이동을 지원하므로, 데이타 배포 작업을 한층 쉽고 빠르게 수행할 수 있습니다. 또, external table을 이용한 다운로드 기능을 활용하여 데이타 이동 및 변환 작업을 보다 효율적으로 완료할 수 있습니다.
데이타베이스 간의 데이타 이동 작업을 어떻게 처리하십니까? 여러 가지 방법이 있겠지만 그 중에서도 가장 돋보이는 것이 바로 transportable tablespace입니다. Transportable tablespace는 대상 테이블스페이스 집합이 자체적으로 다른 테이블스페이스에 있는 오브젝트를 참조하는 것이 없는 “self-contained”이어야 하며, 테이블스페이스를 읽기전용 상태로 설정한 뒤 메타데이타만을 먼저 익스포트(export)하고, OS 레벨의 카피 작업을 통해 데이타파일을 타겟 플랫폼으로 복사한 다음, 데이타 딕셔너리에 메타데이타를 임포트(이 프로세스를 “plugging”이라 부르기도 합니다.)하는 방식으로 데이타를 전송합니다. .
OS 파일 카피 작업은 SQL*Loader를 이용한 익스포트/임포트 작업과 같은 데이타 이동 방식에 비해 일반적으로 훨씬 빠른 처리 성능을 보입니다. 하지만 Oracle9i Database와 그 이전 버전의 경우, 소스 데이타베이스와 타겟 데이타베이스가 동일 OS플랫폼으로 구성되어야 한다는 제약사항 때문에 그 유용성에 제한을 받았습니다 (예를 들어 Solaris와 HP-UX 간의 테이블스페이스 전송은 불가능했습니다).
Oracle Database 10g에서는 이러한 기능 제약이 사라졌습니다. OS byte order가 동일하기만 하면 서로 다른 플랫폼 간이라도 테이블스페이스 전송이 가능해졌습니다. byte order에 대한 상세한 설명은 이 세션의 범위를 넘어서지만, 간략히 살펴보면 Windows를 포함하는 일부 운영체제의 경우, 멀티-바이트 바이너리 데이타를 저장할 때 least significant byte를 최하위 메모리 주소에 저장하는 방식을 사용합니다. 이러한 시스템을 “little endian”이라 부릅니다. 반면, Solaris를 비롯한 다른 운영체제는 most significant byte를 최하위 메모리 주소에 저장하며, 이러한 시스템을 “big endian”이라 부릅니다. Big-endian 시스템이 little-endian 시스템으로부터 데이타를 읽어 들이려면 변환 프로세스를 거쳐야 합니다. 그렇지 않은 경우, byte order 문제로 데이타가 올바르게 표시되지 않습니다. (Byte order에 대한 상세한 설명은 Embedded Systems Programming 2002년 1월호 기사, "Introduction to Endianness"를 참고하시기 바랍니다.) 하지만 동일한 endian을 갖는 플랫폼 간에 테이블스페이스를 전송하는 경우에는 변환 작업이 필요하지 않습니다.
그렇다면 어떤 운영체제가 어떤 byte order를 사용하는지 어떻게 알 수 있을 까요? 아래와 같은 쿼리를 사용하면 바로 확인할 수 있습니다:
SQL> select * from v$transportable_platform order by platform_id;


PLATFORM_ID PLATFORM_NAME                       ENDIAN_FORMAT
----------- ----------------------------------- --------------
          1 Solaris[tm] OE (32-bit)             Big
          2 Solaris[tm] OE (64-bit)             Big
          3 HP-UX (64-bit)                      Big
          4 HP-UX IA (64-bit)                   Big
          5 HP Tru64 UNIX                       Little
          6 AIX-Based Systems (64-bit)          Big
          7 Microsoft Windows IA (32-bit)       Little
          8 Microsoft Windows IA (64-bit)       Little
          9 IBM zSeries Based Linux             Big
         10 Linux IA (32-bit)                   Little
         11 Linux IA (64-bit)                   Little
         12 Microsoft Windows 64-bit for AMD    Little
         13 Linux 64-bit for AMD                Little
         15 HP Open VMS                         Little
         16 Apple Mac OS                        Big
인텔 기반 Linux 운영체제를 사용하는 SRC1서버의 USERS 테이블스페이스를, Microsoft Windows 기반 TGT1 서버로 전송하는 경우를 생각해 봅시다. 이 경우 소스 플랫폼과 타겟 플랫폼 모두 little endian type 시스템입니다. USERS 테이블스페이스의 데이타파일은 users_01.dbf입니다. 전송 작업은 아래와 같은 절차를 거쳐 수행됩니다:
테이블을 READ ONLY 상태로 설정합니다:
alter tablespace users read only;
테이블을 익스포트 합니다.. 운영체제 프롬프트에서 다음과 같이 입력합니다:
exp tablespaces=users transport_tablespace=y file=exp_ts_users.dmp
exp_ts_users.dmp 파일은 메타데이타만을 포함하고 있으므로 그 크기가 매우 작습니다.
exp_ts_users.dmp 파일과 users_01.dbf 파일을 TGT1 서버로 복사합니다. FTP를 사용하는 경우에는 binary 옵션을 설정합니다.

데이타베이스에 테이블스페이스를 “플러깅(plugging)” 합니다. 운영체제 프롬프트에서 다음과 같이 입력합니다.
imp tablespaces=users transport_tablespace=y file=exp_ts_users.dmp datafiles='users_01.dbf'
4번째 단계를 마치고 나면 타겟 데이타베이스에 USERS 테이블스페이스가 생성되며, 테이블스페이스의 컨텐트도 사용 가능한 상태가 됩니다.
시스템 SRC1과 TGT1은 각각 Linux, Windows 운영체제를 사용한다는 사실을 명심하시기 바랍니다. 만일 Oracle9i 환경이었다면 TGT1의 데이타베이스가 users_01.dbf 데이타파일을 인식하지 못했을 것이고, 결국 전체 프로세스가 실패로 돌아갔을 것입니다. 이러한 경우라면 일반적인 익스포트/임포트 기능을 이용하거나, 플랫 파일을 생성한 뒤 SQL*Loader로 로드하거나, 데이타베이스 링크를 통해 direct load insert를 실행해야 할 것입니다.
10g에서는 타겟 데이타베이스가 다른 플랫폼으로부터 전송된 데이타파일을 정상적으로 인식하므로, 이러한 대안을 고려할 필요가 없습니다. 위의 예에서는 OS의 byte order 역시 동일하므로 (little endian), 변환 작업을 수행할 필요도 없습니다.
이 기능은 데이타 웨어하우스의 데이타가, 특수한 목적으로 운영되는 소규모 데이타 마트(data mart)에 정기적으로 전송되는 환경에서 특히 유용합니다. 10g 환경으로 구성된 경우, 데이타 웨어하우스는 대형 엔터프라이즈급 서버에, 데이타 마트는 Linux 기반 인텔 머신과 같은 저가형 서버에 구성하는 것이 가능해집니다. 이처럼 transportable tablespace를 사용하여 다양한 하드웨어와 운영체제를 조합한 환경을 구현할 수 있습니다.
서로 다른 endian을 갖는 시스템 간의 데이타 전송
소스 플랫폼과 타겟 플랫폼이 서로 다른 endian을 갖는 경우 어떻게 데이타 전송을 처리할 수 있을까요? 앞에서 설명한 것처럼 타겟 서버와 소스 서버의 byte order가 다르면 전송된 데이타를 올바르게 인식할 수 없으므로, 단순 카피 작업으로 데이타 파일을 이동하는 것이 불가능합니다. 하지만 방법은 있습니다. 바로 Oracle 10g RMAN 유틸리티가 데이타파일을 다른 byte order로 변환하는 기능을 지원하고 있습니다.
위의 예에서, 만일 SRC1 서버가 Linux(little endian)를 기반으로 하고, TGT1 서버가 HP-UX(big endian)을 기반으로 한다면, 3단계와 4단계의 사이에 변환을 위한 별도의 단계를 적용해야 합니다. RMAN을 사용하면 Linux 환경의 데이타파일을 HP-UX 포맷으로 변환할 수 있습니다 (단 테이블스페이스가 읽기전용 상태로 설정되어 있어야 합니다).
RMAN> convert tablespace users
2> to platform 'HP-UX (64-bit)'
3>  format='/home/oracle/rman_bkups/%N_%f';

Starting backup at 14-MAR-04
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00004 name=/usr/oradata/dw/starz10/users01.dbf
converted datafile=/home/oracle/rman_bkups/USERS_4
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:07
Finished backup at 14-MAR-04
위 과정을 거치면 /home/oracle/rman_bkups 디렉토리에 표준 RMAN 파일 포맷의 파일이 <tablespace_name>_<absolute_datafile_no> 의 파일명으로 생성됩니다. 결국 USERS 테이블스페이스 자체는 전혀 변경되지 않았고, HP-UX 환경을 위한 새로운 파일이 생성되었습니다. 이제 이 파일을 타겟 시스템으로 복사한 뒤 위에서 설명한 것과 같은 처리 과정을 거치면 됩니다.
RMAN 변환 명령은 매우 강력합니다. 위와 같은 명령을 사용하는 경우, RMAN은 순차적으로 데이타파일을 생성합니다. 여러 개의 데이타파일을 포함하는 테이블스페이스를 처리할 때에는 여러 개의 변환 프로세스를 병렬적으로 수행하도록 명령할 수도 있습니다. 그렇게 하려면 위 명령에 아래 구문을 삽입하면 됩니다:
parallelism = 4
위와 같이 하면 네 개의 RMAN 채널이 생성되어 각각 별도의 데이타파일에 대해 변환 작업을 수행합니다. 하지만 parallelism이 정말로 효과를 발휘하는 것은, 많은 수의 테이블스페이스를 한꺼번에 변환할 때입니다. 아래는 두 개의 테이블스페이스(USERS와 MAINTS)를 HP-UX 포맷으로 변경하는 예입니다:
RMAN> convert tablespace users, maints
2> to platform 'HP-UX (64-bit)'
3> format='/home/oracle/rman_bkups/%N_%f'
4> parallelism = 5;

Starting backup at 14-MAR-04
using target database controlfile instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=244 devtype=DISK
allocated channel: ORA_DISK_2
channel ORA_DISK_2: sid=243 devtype=DISK
allocated channel: ORA_DISK_3
channel ORA_DISK_3: sid=245 devtype=DISK
allocated channel: ORA_DISK_4
channel ORA_DISK_4: sid=272 devtype=DISK
allocated channel: ORA_DISK_5
channel ORA_DISK_5: sid=253 devtype=DISK
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00004 name=/usr/oradata/dw10/dw10/users01.dbf
channel ORA_DISK_2: starting datafile conversion
input datafile fno=00005 name=/usr/oradata/dw10/dw10/users02.dbf
channel ORA_DISK_3: starting datafile conversion
input datafile fno=00006 name=/usr/oradata/dw10/dw10/maints01.dbf
channel ORA_DISK_4: starting datafile conversion
input datafile fno=00007 name=/usr/oradata/dw10/dw10/maints02.dbf
converted datafile=/home/oracle/rman_bkups/USERS_4
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
converted datafile=/home/oracle/rman_bkups/USERS_5
channel ORA_DISK_2: datafile conversion complete, elapsed time: 00:00:00
converted datafile=/home/oracle/rman_bkups/MAINTS_6
channel ORA_DISK_3: datafile conversion complete, elapsed time: 00:00:01
converted datafile=/home/oracle/rman_bkups/MAINTS_7
channel ORA_DISK_4: datafile conversion complete, elapsed time: 00:00:01
Finished backup at 14-MAR-04
위의 실행결과에서, 변환된 파일이 기존 파일명과 무관하고 이해하기도 어려운 파일명을 갖게 되는 것을 볼 수 있습니다 (예를 들어, users01.dbf는 USERS_4로 변환됩니다). 원하는 경우 데이타파일의 naming format을 변경할 수 있습니다. 이 프로세스는 Data Guard에서 사용하는 데이타파일 naming 방식과 유사합니다:
RMAN> convert tablespace users
2> to platform 'HP-UX (64-bit)'
3> db_file_name_convert '/usr/oradata/dw10/dw10','/home/oracle/rman_bkups'
4> ;

Starting backup at 14-MAR-04
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00004 name=/usr/oradata/dw10/dw10/users01.dbf
converted datafile=/home/oracle/rman_bkups/users01.dbf
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00005 name=/usr/oradata/dw10/dw10/users02.dbf
converted datafile=/home/oracle/rman_bkups/users02.dbf
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:01
Finished backup at 14-MAR-04

위와 같이 하면 기존의 파일명을 그대로 유지할 수 있습니다. /home/oracle/rman_bkups 디렉토리에 가 보면, users01.dbf와 users02.dbf가 생성된 것을 확인할 수 있습니다. 위 예제의 경우, 파일의 변환 작업은 소스 플랫폼에서 수행되었습니다. 필요한 경우 타겟 플랫폼에서 변환을 수행할 수도 있습니다. 예를 들어, users01.dbf를 HP-UX 기반의 TGT1 서버로 카피한 후 아래와 같이 HP-UX 포맷으로 변환할 수 있습니다:
In the above cases, we converted the files on the source platform. However, you can do that on the target platform as well. For example, you can copy file users01.dbf to host TGT1 running HP-UX and then convert the file to HP-UX format with:
RMAN> convert
2> datafile '/usr/oradata/dw10/dw10/users01.dbf'
3> format '/home/oracle/rman_bkups/%N_%f'
4> ;
이렇게 함으로써 해당 디렉토리에 지정된 포맷의 파일을 생성할 수 있습니다.
그렇다면 데이타파일을 굳이 타겟 플랫폼에서 변환하는 이유가 무엇일까요? 첫 번째로, 소스 플랫폼의 테이블스페이스를 READ ONLY 상태로 두는 기간이 짧아지므로 다운타임을 줄일 수 있다는 점을 들 수 있습니다. 데이타파일을 3중 미러 형태로 구성하고 테이블스페이스를 읽기 전용으로 설정한 다음, 3번째 미러를 분리한 후 곧바로 테이블스페이스를 읽기/쓰기 모드로 변경할 수도 있습니다. 분리된 3번째 미러는 타겟 시스템에 마운트된 후 변환됩니다. 이렇게 하면 테이블스페이스가 읽기 전용 상태에 있는 기간을 최소화할 수 있습니다.
또 다른 이유로 성능을 들 수 있습니다. 지속적으로 부하가 발생하는 OLTP 데이타베이스에서 RMAN 변환 작업을 수행함으로써 시스템에 불필요한 부담을 주게 될 수 있습니다. 그 대신, 병렬 작업에 최적화된 데이타 웨어하우스 서버에서 오프라인 형태로 변환 작업을 처리하는 것이 바람직할 수 있습니다.
External Table을 데이타 전송 매개체로 활용하기
Oracle9i Database에서 처음 소개된 external table은 일정한 형식을 갖춘 일반 텍스트 파일을 테이블처럼 보이게 하고 SQL 구문을 통해 접근할 수 있게 하는 기능입니다. OLTP 데이타베이스에서 운영 중인 TRANS 테이블의 컨텐트를, external table을 사용하여 데이타 웨어하우스 데이타베이스로 이동해야 하는 경우를 생각해 봅시다. 그 과정이 아래와 같습니다:
OLTP 데이타베이스에서, TRANS 테이블의 컨텐트를 포함하는 텍스트 파일을 생성합니다. 생성된 텍스트 파일을 /home/oracle/dump_dir 디렉토리에 trans_flat.txt라는 이름으로 저장합니다. (SQL 구문을 이용하여 텍스트 파일의 생성이 가능합니다.)
spool trans_flat.txt
select <column_1> ||','|| <column_2> ||','|| ...
from trans;
spool off
ftp, rcp 등의 전송 메커니즘을 사용하여 파일을 데이타 웨어하우스 서버에 복사합니다. (파일은 /home/oracle/dump_dir 디렉토리에 위치하고 있습니다.) 데이타 웨어하우스 데이타베이스에서 dump_dir 디렉토리를 생성합니다:

On the data warehouse database, create a directory object named dump_dir as:
create directory dump_dir as '/home/oracle/dump_dir';
external table을 생성합니다:
create table trans_ext
(
   ... <columns of the table> ...
)
organization external
(
   type oracle_loader
   default directory admin
   access parameters
   (
      records delimited by newline
      badfile 'trans_ext.bad'
      discardfile 'trans_ext.dis'
      logfile 'trans_ext.log'
      fields terminated by ","  optionally enclosed by '"'
      (
          ... <columns> ...
      )
   )
   location ('trans_flat.txt')
)
reject limit unlimited;
Direct load insert, merge 등의 일반적인 방법을 사용하여 external table을 일반 테이블로 로드합니다.
위에서 텍스트 파일을 생성하는 첫 번째 단계는 가장 많은 시간을 소요합니다. SQL 구문을 사용하여 텍스트를 생성하고 파일에 스풀링하는 과정은 절차 상으로는 간단하지만 실행 시간이 오래 걸립니다. SQL*Plus 대신 Pro*C 또는 OCI 프로그램을 사용하여 처리 시간을 어느 정도 단축할 수 있지만 그래도 꽤 오랜 시간이 필요합니다. 컬럼을 수작업으로 지정하는 것도 작업을 지체시키는 요인이 됩니다.
이 두 가지 문제는 10g에서 완전히 해결되었습니다. 이제 external table 생성 프로세스를 사용하여 테이블을 포터블 포맷으로 신속하게 언로드할 수 있습니다. 위 예의 첫 번째 단계는 아래와 같은 간단한 SQL 구문으로 대치됩니다:
create directory dump_dir as '/home/oracle/dump_dir';

create table trans_dump
organization external
(
   type oracle_datapump
   default directory dump_dir
   location ('trans_dump.dmp')
)
as
select * from trans
/
위 명령은 /home/oracle/dump_dir 디렉토리에 trans_dump.dmp라는 이름의 파일을 생성합니다. 이 파일은 ASCII 텍스트 파일이 아닙니다. 메타데이타는 일반 텍스트이지만, 실제 데이타는 raw 포맷을 사용하고 있습니다. 하지만, 이 파일은 export dump 파일과 마찬가지로 모든 운영체제에서 호환 가능하며, 데이타의 다운로드가 매우 빠르게 수행된다는 점에서 export와 차별화됩니다. 이 파일을 데이타 웨어하우스 서버에 카피하고 위에서 설명한 것과 동일한 방법으로 external table을 생성할 수 있습니다.
그렇다면 지금까지 설명한 방법이 기존에 사용되어 오던 데이타 전송 메커니즘과 어떤 차이가 있는 것일까요? 첫 번째로, 복잡한SQL 구문을 작성하지 않고도 포터블 파일을 매우 빠르게 생성할 수 있습니다. 두 번째로, 이 파일을 external table의 input으로 적용해서 일반적인 테이블을 다루듯 다른 테이블로의 데이타 로드 작업을 간단하게 완료할 수 있습니다. 또 아래와 같은 구문을 사용하면 external table로의 데이타 다운로드 성능을 향상시킬 수 있습니다:
create table trans_dump
organization external
(
   type oracle_datapump
   default directory dump_dir
   location ('trans_dump.dmp')
)
parallel 2
as
select * from trans
/
위 명령은 병렬적인 형태로 파일 생성 작업을 수행하도록 합니다. 이 방법은 멀티-CPU 환경에서 유용합니다. 이와 별도로, 동시에 여러 개의 external table을 생성하도록 할 수도 있습니다:
create table trans_dump
organization external
(
   type oracle_datapump
   default directory dump_dir
   location ('trans_dump_1.dmp','trans_dump_2.dmp')
)
parallel 4
as
select * from trans
/
위 명령은 trans_dump_1.dmp와 trans_dump_2.dmp라는 두 개의 파일을 생성합니다. 이 방법은 파일을 여러 개의 물리적 디바이스 또는 컨트롤러로 분산하고 I/O 성능을 향상시키는데 유용합니다.
결론
10g의 transportable tablespace를 적극적으로 활용함으로써, 분석된 데이타가 더 신속하게, 그리고 더 높은 빈도로 사용자에게 제공되는 환경을 구현할 수 있습니다. 또 이 기능은 오프라인 미디어를 통해 이기종 시스템의 데이타베이스로 데이타를 배포하는 데에도 이용됩니다. External table을 이용한 다운로드 기능은 대용량 데이타 처리를 위한 ETL 툴로써 손색이 없습니다.
Furthermore, by making transportable tablespaces viable, 10g makes data refreshes quicker and more frequent so that analyzed data is available to end users sooner. This capability can also be used to publish data via offline media to different databases, regardless of their host systems. Using external table downloads the utility to move large quantities of data as an ETL tool is finally available to the end user.
10g의 테이블스페이스 전송 기능에 대한 자세한 설명은 Oracle Database Administrator's Guide의 Chapter 8, "Transporting Tablespaces Between Databases" 섹션을 참고하시기 바랍니다.
 
 
 
 
제 17 주
Automatic Shared Memory Management
오라클 인스턴스의 메모리 풀에 필요한 만큼의 메모리를 할당하는 작업 때문에 번거로우셨습니까? ? Automatic Shared Memory Management 기능을 이용하여 필요한 영역에 메모리를 자동으로 할당할 수 있습니다.
여러분이 초심자이든, 또는 숙련된 DBA이든 아래와 같은 에러를 최소한 한 번쯤은 경험해 보셨을 것입니다:
ORA-04031: unable to allocate 2216 bytes of shared memory ("shared pool"... ...

또는:
ORA-04031: unable to allocate XXXX bytes of shared memory
("large pool","unknown object","session heap","frame")

또는:
ORA-04031: unable to allocate bytes of shared memory ("shared pool",
 "unknown object","joxlod: init h", "JOX: ioc_allocate_pal")

첫 번째 에러의 원인은 명백해 보입니다. shared pool에 할당된 메모리가 사용자 요청에 응답하기에 충분하지 못하기 때문입니다 (이 경우 shared pool의 크기가 문제가 아니라, 바인드된 변수를 사용하지 않는 데 따르는 과도한 파싱 작업으로 인해 발생한 fragmentation이 원인일 수도 있습니다. 이것인 필자가 즐겨 언급하는 주제이긴 하지만, 여기에서는 당면한 과제에 집중하기로 합시다.) 두 번째와 세 번째 에러는 각각 large pool과 Java pool의 공간이 충분하지 못한 것이 원인이 되어 발생합니다.
애플리케이션의 변경 작업을 거치지 않고 이 에러를 해결해야 합니다. 그렇다면 어떤 방법을 사용해야 할까요? 결국 사용 가능한 메모리를 오라클 인스턴스가 사용하는 모든 풀에 어떻게 분배할 것인가의 문제로 귀결됩니다.
어떻게 배분할 것인가?
오라클 인스턴스의 System Global Area (SGA)는 buffer cache, shared pool, Java pool, large pool, redo log buffer 등의 메모리 영역을 포함하고 있습니다. 각각의 풀은 고정된 크기의 운영체제의 메모리 공간을 점유하며, 그 크기는 초기화 매개변수 파일을 통해 DBA가 지정할 수 있습니다.
4종류의 풀(db block buffer cache, shared pool, Java pool, large pool)은 SGA 공간의 대부분을 차지합니다. (redo log buffer는 상대적으로 작은 공간을 사용할 뿐 아니라, 그 성격상 이 문서에서 논의되는 내용과 무관합니다.) DBA는 각각의 영역에 할당된 메모리가 충분한지 점검해야 합니다.
각 영역의 크기를 2GB, 1GB, 1GB, 1GB로 설정하기로 결정한 경우를 가정해 봅시다. 먼저 아래와 같이 초기화 매개변수를 설정하여 데이타베이스 인스턴스의 풀 사이즈를 변경합니다:
db_cache_size = 2g
shared_pool_size = 1g
large_pool_size = 1g
java_pool_size = 1g

이제 이 매개변수를 자세히 분석해 봅시다. 과연 설정된 값이 정확하다는 걸 보증할 수 있을까요?
아마 여러분 모두 나름대로 의심을 품고 있을 것입니다. 실제로 각각의 풀에 필요한 만큼의 공간이 정확히 할당되었다고 자신할 수 있는 이는 아무도 없습니다. 필요한 메모리 공간은 데이타베이스 내부 프로세싱에 따라 결정되며, 이는 시시각각으로 변화하기 때문입니다.
예제를 통해 설명해 보겠습니다. “전형적인” OTLP 데이타베이스 환경에 상대적으로 적은 용량의 메모리가 buffer cache에 할당되어 있습니다. 어느 날, 사용자가 일별 마감 보고서를 작성하기 위해 대규모의 테이블 스캔 작업을 실행합니다. Oracle9i Database는 온라인 상태에서 메모리 할당량을 변경하는 기능을 제공합니다. 전체 메모리 용량이 제한되어 있는 상황에서, DBA는 large pool과 Java pool에 할당된 일부 공간을 buffer cache로 돌리기로 결정합니다:
alter system set db_cache_size = 3g scope=memory;
alter system set large_pool_size = 512m scope=memory;
alter system set java_pool_size = 512m scope=memory;

이 방법은 일시적으로 그 효과를 발휘합니다. 하지만 large pool을 사용하는 RMAN 작업이 야간에 실행되면서 large pool의 용량이 부족해집니다. DBA가 이번에는 db cache의 용량 일부를 large pool에 할당합니다.
RMAN 작업은 완료되었지만, 다음에는 Java pool을 사용하는 배치 프로그램이 실행됩니다. Java pool에 관련한 에러를 확인한 DBA는 Java pool과 db cache의 용량을 확보하기 위해 아래와 같이 실행합니다:
alter system set db_cache_size = 2G scope=memory;
alter system set large_pool_size = 512M scope=memory;
alter system set java_pool_size = 1.5G scope=memory;

다음날 아침, OLTP 작업이 재개되고 DBA는 똑같은 과정을 다시 반복해야 합니다!
이러한 악순환의 고리를 끊어버리기 위해 각각의 풀에 최대한의 용량을 영구적으로 할당하는 방법을 고려할 수 있습니다. 하지만 사용 가능한 실제 메모리보다 많은 용량을 SGA 영역에 할당함으로써 스와핑과 페이징이 빈번하게 발생하는 위험을 감수해야만 합니다. 차라리 수작업으로 메모리를 재할당하는 방법이 (번거롭긴 하지만) 적절해 보입니다.
또 다른 방법으로 각 풀에 합리적인 선의 최소 용량을 할당하는 방법을 생각해 볼 수 있습니다. 하지만 요구되는 용량이 증가할 때마다 성능이 저하될 것입니다.
어떤 방법을 사용하든 SGA에 할당된 전체 메모리 용량은 변하지 않는 반면, 각각의 풀에 할당되는 용량은 자주 변경되어야 합니다. 그렇다면, RDBMS가 사용자의 요구를 감지하고 메모리를 자동으로 재할당한다면 작업이 훨씬 수월해지지 않을까요?
Oracle Database 10g의 Automatic Shared Memory Management가 바로 이러한 기능을 제공합니다. SGA_TARGET 매개변수를 통해 SGA의 전체 사이즈를 설정하고 나면, SGA 내부의 각 풀은 워크로드를 기준으로 다이내믹하게 관리됩니다. 결국 DBA가 해야 할 일은 SGA_TARGET 매개변수를 설정하는 것 밖에 없게 됩니다.
Automatic Shared Memory Management 설정
예를 통해 설명해 보겠습니다. 먼저, SGA의 전체 크기를 결정합니다. 현재 얼마나 많은 용량이 할당되어 있는지 확인하려면 아래와 같이 입력합니다:
SQL> select sum(value)/1024/1024 from v$sga;

SUM(VALUE)/1024/1024
--------------------
                 500
SGA의 현재 크기는 약 500MB로 설정되어 있으므로 이 수치를 SGA_TARGET에 적용하면 됩니다. 다음으로 아래와 같이 구문을 실행합니다:
alter system set sga_target = 500M scope=both;

위와 같이 설정함으로써, 각각의 풀에 대한 용량을 설정할 필요가 없게 됩니다. 이제 각각의 풀에 관련한 매개변수의 값을 0으로 설정하거나, 해당 항목을 완전히 삭제합니다.
shared_pool_size = 0
large_pool_size = 0
java_pool_size = 0
db_cache_size = 0    

데이타베이스를 다시 시작하고 변경된 설정을 적용합니다.
같은 작업을 Enterprise Manager 10g에서 수행할 수도 있습니다. 데이타베이스 홈 페이지에서 “Administration” 탭을 선택한 후 “Memory Parameter”를 클릭합니다. 메모리 관련 매개변수가 수동 설정되어 있는 경우에는 설정된 항목별로 “Enable” 버튼이 표시될 것입니다. “Automatic Shared Memory Management” 옆에 있는 “Enable” 버튼을 눌러 Automatic Shared Memory Management 기능을 활성화합니다. 나머지 작업은 Enterprise Manager에 의해 자동 수행됩니다.
설정 작업을 마친 후 각 풀의 크기를 확인하려면 아래와 같이 실행합니다:
SQL> select current_size from v$buffer_pool;

CURRENT_SIZE
------------
         340

SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool;

POOL             MBYTES
------------ ----------
java pool             4
large pool            4
shared pool         148
설정 작업을 마친 후 각 풀의 크기를 확인하려면 아래와 같이 실행합니다:
 

그림 1: 초기 할당 결과
이제 오라클에서 사용 가능한 메모리 크기가 500MB에서 300MB로 줄었다고 가정해 봅시다. 먼저 SGA 영역을 위해 설정된 target size를 변경해야 할 것입니다:
alter system set sga_target = 300M scope=both;

다시 메모리 할당 현황을 점검하면 아래와 같은 결과를 확인할 수 있습니다:
SQL> select current_size from v$buffer_pool;

CURRENT_SIZE
------------
         244

SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool;

POOL             MBYTES
------------ ----------
java pool             4
large pool            4
shared pool          44

전체 사용 공간은 240+4+4+44 = 296MB로, 전체 용량(300MB)와 거의 일치합니다. SGA_TARGET을 변경한 후의 메모리 할당 내역이 그림 2와 같습니다.
 

그림 2: SGA size를 300MB로 변경한 후의 할당 결과
풀의 크기는 다이내믹하게 조정됩니다. 워크로드가 증가하면 그에 비례하여 풀의 크기도 증가하고, 다른 풀에 관련된 워크로드가 증가하는 경우에는 줄어들기도 합니다. 이러한 확장/수축 과정은 DBA의 개입 없이 자동적으로 수행됩니다. 앞부분에 설명한 예에서 대량의 large pool을 사용하는 RMAN 작업이 시작되는 경우, large pool은 자동적으로 4MB에서 40MB로 증가합니다. 그림 3에서 보여지는 것처럼, 추가로 필요한 36MB는 db block buffer에서 가져오고, 결과적으로 db block buffer는 줄어들 것입니다.
 

그림 3: large pool의 수요가 증가하는 경우의 자동 할당 결과
변경되는 풀의 크기는 워크로드에 따라 달라집니다. SGA의 전체 크기도 언제나 SGA_TARGET에서 지정한 최대치를 넘지 않으므로, 실제 메모리보다 많은 영역을 할당하여 과도한 페이징과 스와핑을 발생시키는 문제를 방지할 수 있습니다. SGA_MAX_SIZE 매개변수를 조정하면 SGA_TARGET의 값을 가능한 최대치인 SGA_MAX_SIZE까지 다이내믹하게 증가시킬 수 있습니다.
자동 튜닝을 지원하지 않는 Pool.
SGA에서 관리되는 풀 중 일부는 다이내믹한 변경을 허용하지 않으며, 따라서 명시적으로 설정되어야 합니다. 특히 비표준 블록 사이즈를 갖는 buffer pool과 KEEP / RECYCLE 풀의 경우가 그러합니다. 데이타베이스의 블록 사이즈가 8K인 환경에서, 2K, 4K, 16K, 32K 등의 블록 사이즈를 갖는 풀들을 구성하려면, 수작업으로 설정하는 방법 밖에 없습니다. 이렇게 설정된 풀의 크기는 고정된 값을 유지하며, 부하 수준에 따라 확장되거나 수축되지 않습니다. KEEP/RECYCLE 풀을 구성하는 경우에도 마찬가지입니다. log buffer 역시 다이내믹하게 조정되지 않습니다. 또한 log_buffer 매개변수를 통해 설정된 값은 고정된 값을 유지합니다. (10g에서는 “Streams pool”이라는 새로운 유형의 풀을 지원합니다. 이 풀은 streams_pool_size 매개변수를 통해 설정되며, 역시 자동 메모리 튜닝을 지원하지 않습니다.)
여기서 한 가지 의문이 생깁니다. 비표준 블록 사이즈를 갖는 풀을 설정하는 경우, 다른 풀들에 관련한 메모리 자동 관리 기능에는 어떤 영향이 있을까요?
자동 튜닝이 불가능한 매개변수(예: db_2K_cache_size)를 설정하는 경우, 데이타베이스는 SGA_TARGET에서 이 매개변수의 값을 차감한 후 남은 공간을 활용하여 자동 메모리 관리를 수행합니다. 예를 들어, 아래와 같이 설정된 경우를 가정해 봅시다:
sga_target = 500M
db_2k_cache_size = 50M

다른 풀 관련 매개변수는 설정되어 있지 않은 것으로 가정합니다. 이 경우, 2KB buffer pool에 할당된 50MB를 제외한 450MB가 default block size buffer pool(db_cache_size), shared pool, Java pool, large pool 등의 자동 관리에 이용됩니다. 자동 튜닝이 불가능한 매개변수에 변경이 발생하는 경우, 자동 튜닝에 사용되는 메모리 크기 역시 변경됩니다. 예를 들어, db_2K_cache_size의 값을 50MB에서 100MB로 변경하면, shared pool, large pool, default buffer pool에 사용되는 메모리 크기는 450MB에서 400MB로 자동 변경됩니다 (그림 4 참조).
 

그림 4: 자동 튜닝을 지원하지 않는 버퍼 매개변수를 변경한 경우
하지만 메모리가 충분하거나, 위에서 언급한 위험요소를 걱정할 필요가 없다면 Automatic Memory Management 기능을 사용하지 않아도 무방합니다. 이 경우 SGA_TARGET 매개변수를 정의하지 않거나 그 값을 (ALTER SYSTEM 명령을 통해서, 또는 매개변수 파일 편집을 통해서) 0으로 설정하면 됩니다. SGA_TARGET이 0으로 설정되면, 각 풀의 현재 크기가 매개변수 값으로 자동 설정됩니다.
Enterprise Manager의 활용
Enterprise Manager 10g을 이용해서 이 매개변수들을 조작할 수도 있습니다. 데이타베이스 홈 페이지에서 “Memory Parameters”를 클릭하면 그림 5와 같은 화면이 표시됩니다.
 

Enterprise Manager 10g을 이용해서 이 매개변수들을 조작할 수도 있습니다. 데이타베이스 홈 페이지에서 “Memory Parameters”를 클릭하면 그림 5와 같은 화면이 표시됩니다.
붉은색 원으로 표시된 항목을 참고하시기 바랍니다. 데이타베이스는 Automatic Shared Memory Management 모드로 동작하고 있으며 전체 메모리 크기는 564MB로, SGA_TARGET 매개변수에 설정된 값과 동일합니다. 이 화면에서 설정값을 수정하고 Apply 버튼을 누르면 매개변수 값이 자동으로 조정됩니다.
각 풀의 최소 메모리 크기 지정
SGA_TARGET을 600MB로 설정하고 Automatic Shared Memory Management를 이용하는 경우를 가정해 봅시다. 자동 설정된 풀의 크기가 아래와 같습니다:

풀 사이즈 (MB)
Buffer 404
Java 4
Large 4
Shared 148

Java pool과 large pool의 크기(각각 4MB)가 너무 작다고 판단되는 경우, 각 영역의 최소값을 (8MB, 16MB 등으로) 설정하여 온라인 상태에서 적용할 수 있습니다. 아래와 같이 ALTER SYSTEM 명령을 통해 최소값을 명시하면 그 결과가 다이내믹하게 적용됩니다:
alter system set large_pool_size = 16M;
alter system set java_pool_size = 8M;

이제 풀의 크기를 다시 조회하면 아래와 같이 달라진 것을 확인할 수 있습니다:
SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool;

POOL             MBYTES
------------ ----------
java pool             8
large pool           16
shared pool         148

SQL> select current_size from v$buffer_pool;

CURRENT_SIZE
------------
         388

재할당된 풀의 메모리 크기가 아래와 같습니다:

풀 사이즈 (MB)
Buffer 388
Java 8
Large 16
Shared 148

Java pool과 large pool은 각각 8MB, 16MB로 재조정되었고, 전체 SGA의 크기는 600MB 이하를 유지하고 있습니다 (buffer pool의 크기가 404MB에서 388MB로 감소했습니다). 물론 Automatic Shared Memory Management는 여전히 동작하고 있습니다. 방금 전에 설정한 값은 풀의 최소 크기를 정의한 것이며, 이제 Java pool과 large pool은 8MB, 16MB 이하의 크기로 줄어들지 않을 것입니다.
결론
Oracle SGA에서 관리되는 각 풀의 메모리 요구량은 시스템 상황에 따라 끊임없이 변화합니다. Oracle Database 10g의 Automatic Shared Memory Management 기능은 필요한 영역에 자원을 다이내믹하게 할당함으로써, 시스템 메모리 자원을 보다 효율적으로 이용할 수 있게 합니다. 이처럼 메모리 관리를 효율화함으로써 메모리 요구량을 줄이고, 하드웨어 비용을 절감할 수도 있습니다.
다음 주 주제: Automatic Database Diagnostic Monitor (ADDM) 의 Chapter 7을 참고하십시오.
 
 
 
 
제18 주
ADDM과 SQL Tuning Advisor
이제 Oracle Database가 직접 제공하는 SQL 튜닝 서비스를 활용해 보십시오! SQL Profile를 이용하여 쿼리 성능을 향상시키고 ADDM을 통해 일반적인 성능 문제를 쉽고 빠르게 해결하는 방법을 배워보십시오.
오늘은 조용한 하루입니다. 데이타베이스에도 문제가 없어 보입니다. DBA는 긴장을 풉니다. 미루어 두었던 RMAN 매개변수, 블록 사이즈 점검 작업을 하기에 좋은 날입니다.
갑자기 개발자 한 명이 DBA의 자리로 달려 옵니다. 그가 사용하는 SQL 쿼리의 성능이 저하되었습니다. 그가 말합니다. “가능한 한 빨리 해결해 주셨으면 좋겠습니다.”
어쩌면 긴장을 너무 빨리 풀었는지도 모릅니다. 데이타베이스의 성능과 보안을 향상시키려는 기존의 계획은 뒤로 밀리고, 오늘도 급한 불을 끄기 위해 하루를 보내야 합니다.
DBA는 반복적인 잡무에서 벗어나 좀 더 전략적인 과제에 집중할 수 있기를 원합니다. 그렇다면 반복적인 업무를 대신해 줄 조수를 하나 고용하면 좋지 않을까요?
Oracle Database 10g에 추가된 Automatic Database Diagnostic Monitor(ADDM)이 바로 이런 역할을 해 줍니다. ADDM은 데이타베이스 성능 통계에 대한 철저한 분석을 통해 성능 병목을 확인하고, SQL 구문에 대한 분석을 통해 성능 향상을 위한 조언을 제공합니다. 또 SQL Tuning Advisor와 연동된 기능을 제공하기도 합니다. 이번 연재에서는, ADDM을 이용한 성능 향상 방안에 대해 설명합니다.
Automatic Database Diagnostic Monitor (ADDM)
제 6 주 연재에서, Automatic Workload Repository (AWR)에 대해 설명한 바 있습니다. AWR은 데이타베이스로부터 상세한 성능 관련 지표를 주기적으로 수집하여 저장합니다. 스냅샷 생성 작업이 완료될 때마다, ADDM이 호출되어 서로 다른 스냅샷의 데이타와 성능 지표를 비교 분석하고 성능 향상을 위한 조언을 제공합니다. 문제가 발견된 후, ADDM은 다른 어드바이저 툴(SQL Tuning Advisor 등)을 호출하여 해결 방법을 찾아내기도 합니다.
예를 통해 ADDM의 기능을 설명해 보도록 하겠습니다. 원인이 확인되지 않은 성능 문제에 대한 진단 작업에 착수한 경우를 가정해 봅시다. DBA는 문제가 되는 SQL 구문이 무엇인지 확인해 둔 상태입니다. 그러나 실제 환경에서는 이와 같은 유용한 단서도 모를 경우도 있습니다.
10g에서 진단 작업을 수행하는 과정에서, drill-down분석을 위해 적절한 시간 간격을 두고 생성된 스냅샷들을 선택할 수 있습니다. Enterprise Manager 10g의 데이타베이스 홈 페이지에서 “Advisor Central”을 선택하고 “ADDM”을 클릭하면 그림 1과 같은 화면이 표시됩니다.
 

그림 1: ADDM 태스크의 생성
이 화면에서 ADDM을 이용한 분석 작업을 생성할 수 있습니다. 성능 문제가 오후 11시에 발생했음을 알고 있는 DBA는, “Period Start”와 “Period End”의 값을 설정하여 해당 시간 대의 스냅샷들을 선택합니다. (붉은색 원으로 표시된) 카메라 모양의 아이콘을 클릭하여 스냅샷 시작 시간과 종료 시간을 지정할 수도 있습니다. 시간대를 설정하고 난 뒤 “OK” 버튼을 누르면 그림 2와 같은 화면이 표시됩니다.
 

그림 2: ADDM 분석 결과
ADDM은 해당 시간대에 관련한 두 가지 성능 문제를 발견해 냈습니다. 일부 SQL 구문이 지나치게 많은 CPU 시간을 사용하고 있으며, 이로 인해 데이타베이스의 성능이 전체적으로 저하되었습니다. 발견된 내용을 근거로, ADDM은 해당 구문에 대한 SQL 튜닝을 수행할 것을 권고하고 있습니다.
각각의 문제 항목을 클릭하면 그림 3에서 보여지는 것과 같은 상세 정보를 얻을 수 있습니다.
 

그림 3: ADDM 분석 결과 상세 정보
위 화면에서 문제의 원인이 된 SQL 구문을 확인할 수 있습니다. ADDM은 SQL Tuning Advisor를 이용해 이 SQL 구문에 대한 분석 작업을 수행할 것을 권고하고 있습니다. “Run Advisor Now” 버튼을 클릭하면 SQL Tuning Advisor가 호출되어 분석 작업을 시작합니다.
그림 2 화면의 “View Report” 버튼을 참고하시기 바랍니다. 개별 웹 페이지 별로 권고 사항을 제시하는 것과 별도로, ADDM은 전체 분석 결과에 대한 텍스트 리포트를 생성합니다. Listing 1에서 생성된 텍스트 리포트의 내용을 확인하실 수 있습니다. 텍스트 리포트는 문제가 되는 SQL 구문과 그 hash value 등의 상세한 정보를 제공합니다. 또 텍스트 리포트의 SQL ID 정보를 이용하여 SQL Tuning Advisor 또는 커맨드 라인을 통한 분석 작업을 수행할 수 있습니다.
ADDM은 AWR 스냅샷이 생성될 때마다 호출되고, 가장 최근의 스냅샷과의 비교를 통해 권고사항을 제시합니다. 따라서 비교해야 할 두 스냅샷이 서로 인접한 경우에는 (이미 보고서가 생성되어 있으므로) 별도로 ADDM 태스크를 실행할 필요가 없으며, 스냅샷이 인접해 있지 않은 경우에만 ADDM 태스크를 실행할 필요가 있습니다.
ADDM의 기능이 단순히 SQL 구문의 분석에 한정되지 않는다는 사실을 명심하시기 바랍니다. 과거 연재에서 확인한 것과 같이, ADDM은 메모리 관리, 세그먼트 관리, redu/undo 등의 영역에 대한 다양한 분석 기능을 제공합니다. 제한된 지면을 통해 ADDM의 기능을 모두 설명하는 것은 어차피 불가능하므로, 지금부터는 SQL Tuning Advisor에 초점을 맞추어 설명을 진행하도록 하겠습니다.
SQL Tuning Advisor를 이용한 Access분석
오라클 데이타베이스의 옵티마이저(optimizer)는 가능한 액세스 경로를 여럿 생성한 뒤, 오브젝트 통계정보를 기준으로 가장 적은 비용이 드는 하나를 선택하는 방식으로 runtime optimization을 수행합니다. 하지만 옵티마이저는 (시간의 제약을 받는 만큼) SQL 구문의 튜닝이 필요한지, 통계가 정확한지, 새로운 인덱스를 생성해야 하는지 등의 여부를 판단하지 않습니다. 반면 SQL Tuning Advisor는 일종의 “전문가 시스템”과 같은 역할을 합니다. 옵티마이저가 “현재 가능한 대안 중 최적의 결과를 얻을 수 있는 것은 무엇인가?”라는 질문에 대한 답변을 제공한다면, SQL Tuning Advisor는 “사용자의 요구사항을 기반으로 고려했을 때, 성능을 향상시키기 위해 할 수 있는 일이 무엇인가?”라는 질문의 답을 제공합니다.
이러한 “전문가 시스템”으로서의 작업은 CPU 등의 자원을 많이 소모합니다. 이러한 이유로 SQL Tuning Advisor는 데이타베이스가 Tuning Mode로 설정된 경우에만 SQL 구문에 대한 분석작업을 수행합니다. Tuning Mode는 튜닝 태스크를 생성하는 과정에서 SCOPE 및 TIME 매개변수를 설정함으로써 지정됩니다. 사용자에 대한 영향을 최소화하려면 데이타베이스 활동이 적은 시간대를 선택하여 Tuning Mode를 사용하는 것이 바람직합니다.
이제 예를 통해 설명하도록 하겠습니다. 문제가 되는 SQL 구문이 아래와 같습니다:
select account_no from accounts where old_account_no = 11
실제로 튜닝하기 어렵지 않은 구문이지만, 이해를 돕기 위해 간단한 구문을 사용하였습니다. 어드바이저는 Enterprise Manager 또는 커맨드 라인을 통해 실행할 수 있습니다.
먼저, 커맨드 라인을 이용하는 방법을 알아봅시다. 아래와 같은 방법으로 dbms_sqltune 패키지를 호출하고 어드바이저를 실행합니다.
declare

   l_task_id     varchar2(20);
   l_sql         varchar2(2000);
begin
   l_sql := 'select account_no from accounts where old_account_no = 11';
   dbms_sqltune.drop_tuning_task ('FOLIO_COUNT');
   l_task_id := dbms_sqltune.create_tuning_task (
      sql_text  => l_sql,
      user_name  => 'ARUP',
      scope      => 'COMPREHENSIVE',
      time_limit => 120,
      task_name  => 'FOLIO_COUNT'
   );
   dbms_sqltune.execute_tuning_task ('FOLIO_COUNT');
end;
/
위 패키지는 FOLIO_COUNT라는 이름의 튜닝 태스크를 생성하고 실행합니다. 다음에는 아래와 같이 입력하여 태스크 실행 결과를 확인합니다.
set serveroutput on size 999999
set long 999999
select dbms_sqltune.report_tuning_task ('FOLIO_COUNT') from dual;

실행 결과는 Listing 2에서 확인할 수 있습니다. 어드바이저가 제공하는 권고 사항을 자세히 살펴보시기 바랍니다. 이 경우, 어드바이저는 OLD_ACCOUNT_NO 컬럼에 인덱스를 생성할 것을 권고하고 있습니다. 그 뿐 아니라, 인덱스가 생성된 경우의 비용을 계산하고, 기대되는 성능 향상 효과를 구체적인 형태로 제시하고 있습니다.
예로 든 구문 자체가 단순한 만큼, 굳이 어드바이저를 이용해서 이런 결과를 얻을 필요는 없었을 것입니다. 하지만 보다 복잡한 형태의 쿼리에 성능 문제가 발생한 경우라면, 어드바이저를 통해 수작업으로는 불가능한 성능 개선 효과를 얻을 수 있습니다.
중급 레벨 튜닝: Query Restructuring
조금 더 복잡한 쿼리를 분석하는 경우를 생각해 봅시다:
select account_no from accounts a
where account_name = 'HARRY'
and sub_account_name not in
  ( select account_name from accounts
    where account_no = a.old_account_no and status is not null);

어드바이저는 다음과 같은 권고 사항을 제시하였습니다:
1- Restructure SQL finding (see plan 1 in explain plans section)
----------------------------------------------------------------
  The optimizer could not unnest the subquery at line ID 1 of the execution
  plan.

  Recommendation
  --------------
    Consider replacing "NOT IN" with "NOT EXISTS" or ensure that columns used
    on both sides of the "NOT IN" operator are declared "NOT NULL" by adding
    either "NOT NULL" constraints or "IS NOT NULL" predicates.

  Rationale
  ---------
    A "FILTER" operation can be very expensive because it evaluates the
    subquery for each row in the parent query. The subquery, when unnested can
    drastically improve the execution time because the "FILTER" operation is
    converted into a join. Be aware that "NOT IN" and "NOT EXISTS" might
    produce different results for "NULL" values.

이번에는 인덱스 생성과 같은 오브젝트 구조 변경을 제안하는 대신, NOT IN 대신 NOT EXIST를 사용하도록 쿼리를 수정할 것을 제안하고 있습니다. 어드바이저는 근본적인 원인을 통해 권장 내용의 근거를 설명하고, 그 결정을 DBA의 판단에 맡깁니다.
고급 튜닝: SQL Profiles
옵티마이저는 쿼리가 사용하는 오브젝트 통계정보(object statistics)를 점검한 뒤 가장 적은 비용을 사용하는 경로를 선택함으로써 execution plan을 생성합니다. 쿼리가 두 개 이상의 테이블을 참조하는 경우, 옵티마이저는 관련된 테이블의 통계를 모두 점검한 뒤 가장 적은 비용을 사용하는 경로를 선택하지만, 테이블 간의 관계에 대해서는 아무 것도 이해하지 못합니다.
예를 들어, DELINQUENT(연체) 상태가 $1,000 이하의 balance를 갖는 한 account가 있다는 경우를 가정해 봅시다. ACCOUNTS 테이블과 BALANCES 테이블을 join하는 쿼리에 status가 DELINQUENT인 데이타만을 필터링하는 조건을 추가함으로써, 보다 적은 수의 결과를 얻을 수 있을 것입니다. 옵티마이저는 이러한 테이블 간의 복잡한 관계를 이해하지 못합니다. 하지만 어드바이저의 경우는 다릅니다. 어드바이저는 데이터로부터 이들 관계정보를 “수집”해 낸 뒤 SQL Profile의 형태로 이를 저장합니다. 이제 SQL Profile에 접근할 수 있게 된 옵티마이저는 테이블의 데이타 분포뿐 아니라 데이타 간의 관계까지도 이해할 수 있게 됩니다. 이렇게 추가로 제공되는 정보를 활용하면 보다 뛰어난 수준의 execution plan을 생성하고 성능을 향상시킬 수 있습니다.
SQL Profile을 이용하면, 쿼리 힌트를 코드에 삽입하는 형태의 SQL 구문 튜닝이 불필요해집니다. 따라서 SQL Tuning Advisor를 이용하여, 코드에 전혀 손을 대지 않고도 패키지 애플리케이션을 튜닝할 수 있습니다.
오브젝트 통계가 하나 또는 그 이상의 오브젝트에 매핑되는 반면, SQL Profile은 쿼리에 매핑됩니다. 같은 테이블(ACCOUNTS와 BALANCES)을 참조하더라도 쿼리가 다르면 프로파일도 달라집니다.
SQL Tuning Advisor는 실행 과정에서 프로파일을 생성한 뒤 이를 “Accept”할 것을 권고합니다. 사용자가 “Accept”하지 않는 이상 프로파일은 구문에 반영되지 않습니다. 아래와 같이 실행하면 아무 때나 프로파일을 accept할 수 있습니다:
begin
   dbms_sqltune.accept_sql_profile (
      task_name   => 'FOLIO_COUNT',
      name        => 'FOLIO_COUNT_PROFILE'
      description => 'Folio Count Profile',
      category    => 'FOLIO_COUNT');
end;

위 명령은 어드바이저가 생성한 FOLIO_COUNT_PROFILE을 위의 예에서 설명한 FOLIO_COUNT 튜닝 태스크에 연관된 구문에 연결합니다. (DBA가 직접 SQL Profile을 생성할 수는 없으며, 어드바이저만이 SQL Profile을 생성할 수 있음을 참고하시기 바랍니다. 사용자는 SQL Profile의 사용 여부만을 선택할 뿐입니다.)
DBA_SQL_PROFILES 딕셔너리 뷰를 통해 생성된 SQL Profile을 확인할 수 있습니다. SQL_TEXT 컬럼은 프로파일이 할당된 SQL 구문을, STATUS 컬럼은 프로파일의 활성화 여부를 표시합니다. (프로파일이 특정 구문에 연결되어 있는 경우라 하더라도, 활성화하기 전에는 execution plan에 반영되지 않습니다.)
ADDM과 SQL Tuning Advisor의 활용
위에 예로 든 세 가지 경우 이외에도, SQL Tuning Advisor는 쿼리에서 사용하는 오브젝트에 통계가 누락되어 있는지의 여부를 확인해 줍니다. 요약하자면, 어드바이저는 다음과 같은 네 가지 유형의 작업을 수행합니다.
최적화를 위한 오브젝트들의 유효하고, 사용 가능한 통계정보를 보유하고 있는지 확인합니다.
성능 향상을 위해 쿼리를 재작성하는 방안을 권고합니다.
접근 경로를 확인하고 인덱스, MV(materialized view) 등을 추가하여 성능을 향상시킬 수 있는 방법을 조사하고 제안합니다.
SQL Profile을 생성하고, 이를 특정 쿼리에 연결합니다.
ADDM과 SQL Tuning Advisor가 유용하게 활용되는 경우를, 다음과 같은 세 가지 시나리오를 기준으로 검토해 볼 수 있습니다.
사후조치적 튜닝(Reactive Tuning): 애플리케이션의 성능이 갑자기 저하됩니다. DBA는 ADDM을 사용하여 문제가 되는 SQL 구문을 확인합니다. ADDM의 권고사항에 따라 SQL Tuning Advisor를 실행하고 문제를 해결합니다.
사전예방적 튜닝(Proactive Tuning): 애플리케이션은 정상적으로 동작합니다. DBA는 유지보수를 위해 필요한 작업을 실행하고 쿼리를 좀 더 개선할 방법이 있는지 확인하고자 합니다. DBA는 스탠드얼론 모드로 SQL Tuning Advisor를 실행하고 가능한 대안을 검토합니다.
개발단계 튜닝(Development Tuning): QA 단계 또는 운영 단계보다는, 개발 단계에서 쿼리 튜닝을 수행하는 것이 상대적으로 용이합니다. 이때 어드바이저의 커맨드 라인 버전을 사용하여 개별 SQL 구문을 튜닝할 수 있습니다.
Enterprise Manager의 활용
앞의 예는 SQL Tuning Advisor를 커맨드 라인 모드에서 사용하는 방법을 기준으로 설명되었습니다. 커맨드 라인 모드는 태스크 실행을 위한 스크립트 생성이 용이하다는 장점이 있습니다. 하지만, 사용자에 의해 이미 문제가 보고된 경우라면 Enterprise Manager 10g를 이용하는 방법이 더 효과적일 수 있습니다.
(제 13주) 연재에서, 새롭게 개선된 Enterprise Manager 인터페이스에 대해 소개한 바 있습니다. 이번에는 EM을 활용하여 SQL 구문을 진단하고 튜닝하는 방법을 설명해 보겠습니다. 데이타베이스 홈 페이지 하단의 “Advisor Central” 링크를 클릭하면 다양한 어드바이저를 위한 메뉴를 제공하는 화면이 표시됩니다. 이 화면 상단의 “SQL Tuning Advisor”를 클릭합니다 (그림 4 참조).
 

그림 4: Enterprise Manager의 Advisor Central 화면
이제 SQL Tuning Advisor가 실행됩니다. 다음 화면에서 "Top SQL"을 클릭합니다 (그림 5 참조).
 

그림 5: SQL Tuning Advisor
그림 6에서 보여지는 것과 같은 화면이 표시되며, 이 화면에서 표시되는 그래프를 통해 다양한 wait class에 관련된 정보를 시간대 별로 확인할 수 있습니다.
 

그림 6: Top SQL 화면
그래프의 관심 영역은 회색 사각형으로 표시됩니다. CPU wait이 높게 나타나는 영역에 마우스를 드래그하여 관심영역을 조정합니다. 화면의 하단에는 해당 시간대에 수행된 SQL 구문 관련 정보가 표시됩니다 (그림 7 참조).
 

그림 7: SQL 구문의 Activity 정보
상단(붉은색으로 표시된 부분)에는 가장 많은 CPU 자원을 소모하는 SQL 구문들이 표시되고 있습니다. 각 구문의 SQL ID를 클릭하면 그림 8과 같은 화면이 표시됩니다.
 

그림 8: SQL Details 화면
위 화면을 통해 문제가 되는 SQL 구문을 확인할 수 있습니다. “Run SQL Tuning Advisor” 버튼을 클릭하면 어드바이저가 실행되고 그림 9와 같은 화면이 표시됩니다.
 

그림 9: SQL Tuning Advisor의 스케줄링
어드바이저 스케줄러 화면에서, 태스크의 유형과 분석의 심도를 결정할 수 있습니다. 위 화면에서는 “comprehensive” analysis를 선택하고 어드바이저를 바로 실행하도록 설정하였습니다. 어드바이저의 실행이 완료되면 그림 10과 같은 화면을 통해 어드바이저의 권고 사항을 확인할 수 있습니다.
 

그림 10: Advisor Recommendation 화면
EM을 이용한 SQL Tuning Advisor 실행 방법은, 앞에서 설명한 커맨드 라인 버전을 이용하는 경우와 유사합니다. 하지만, 발생된 문제를 확인하여 드릴다운을 수행하고, 권고사항을 생성한 후 이를 승인하는 전체 과정이, 실제 발생한 문제를 해결하기에 편리한 형태로 구성되어 있다는 점에서 차이가 있습니다.
결론
ADDM은 성능 지표를 자동적으로 분석하고 오라클 전문가가 구현한 베스트 프랙티스 및 방법론을 기반으로 권고사항을 제시해 주는 강력한 성능 관리 툴입니다. 이 기능을 활용하여 발생된 문제와 그 원인을 확인할 수 있을 뿐 아니라, 취해야 할 조치에 대한 조언을 얻을 수 있습니다.
ADDM과 SQL Tuning Advisor에 대한 자세한 정보는 기술백서 Oracle Database 10g: The Self-Managing Database 와 The Self-Managing Database: Guided Application & SQL Tuning, 그리고 Oracle Database 2 Day DBA 매뉴얼의 제 10장 및 Oracle Database Performance Tuning Guide의 6장 and 13장을 참고하시기 바랍니다.
 
 
 
 
제 19 주
Scheduler
dbms_job 패키지의 실행 주기 설정을 수작업으로 관리하는 것이 번거로우십니까? 이제 10g데이타베이스가 제공하는 Scheduler를 이용해 보십시오.
여러분들 중 일부는 백그라운드 데이타베이스 작업 스케줄을 설정하기 위해 dbms_job 패키지를 사용하고 있을 것입니다. 하지만 필자가 알기로는 대부분의 DBA들이 dbms_job 패키지를 사용하지 않고 있습니다.
이 패키지는 PL/SQL 코드 세그먼트만을 처리할 수 있으며, 데이타베이스 외부의 운영체제 파일 또는 실행 파일 이미지를 처리할 수 없다는 기능적 한계를 갖고 있습니다. 이 때문에 DBA들은 Unix의 cron, Windows의 AT 명령 등을 사용하여 운영 체제 레벨에서 스케줄링을 설정하는 방법을 선택합니다. 또는 그래픽 사용자 인터페이스를 제공하는 써드 파티 툴을 사용하기도 합니다.
그러나 dbms_job은 이들과 다른 장점들이 있습니다. 이 중 하나는 데이터베이스가 실행되고 있는 경우에만 활성화된다는 것입니다. 만약 데이터베이스가 다운되어 있다면 해당 Job들은 실행되지 않습니다. 데이터베이스 외부에 존재하는 툴들은 수작업을 통해 데이터베이스가 실행되고 있는지 조사되어야 하며, 복잡한 작업일 수 있습니다. Dbms_job의 다른 장점으론 데이터베이스 내부에 존재한다는 것입니다. 그러므로 SQL*Plus와 같은 유틸리티를 이용해 쉽게 접근 가능하다는 것입니다.
Oracle Database 10g Scheduler는 모든 종류의 작업을 지원하는 내장형 작업 스케줄러 유틸리티를 제공합니다. 10g Scheduler의 가장 큰 장점은, 데이타베이스에 포함된 형태로 제공되므로 추가적인 비용이 들지 않는다는 것입니다. 이번 연재에서는 Scheduler의 기능에 대해 자세히 살펴보기로 합니다.
Creating Jobs Without Programs
개념의 이해를 돕기 위해 예를 통해 설명하겠습니다. 아카이브 로그 파일을 다른 파일시스템으로 이동하기 위해 아래와 같은 이름의 셸 스크립트를 생성했다고 가정해 봅시다:
/home/arup/dbtools/move_arcs.sh

별도의 프로그램을 생성하지 않고도 작업 유형으로 “Executable”을 지정하고 스케줄링을 설정할 수 있습니다.
begin
   dbms_scheduler.create_job
   (
      job_name      => 'ARC_MOVE_2',
      schedule_name => 'EVERY_30_MINS',
      job_type      => 'EXECUTABLE',
      job_action    => '/home/arup/dbtools/move_arcs.sh',
      enabled       => true,
      comments      => 'Move Archived Logs to a Different Directory'
   );
end;
/

또 Schedule Name을 설정하지 않고 작업을 생성하는 것도 가능합니다.
begin
   dbms_scheduler.create_job
   (
      job_name        => 'ARC_MOVE_3',
      job_type        => 'EXECUTABLE',
      job_action      => '/home/arup/dbtools/move_arcs.sh',
      repeat_interval => 'FREQ=MINUTELY; INTERVAL=30',
      enabled         => true,
      comments        => 'Move Archived Logs to a Different Directory'
   );
end;
/

앞의 두 가지 예를 통해 dbms_job과 비교했을 때의 Scheduler의 장점을 확인할 수 있습니다. Scheduler를 이용하면 PL/SQL 프로그램뿐 아니라 OS 유틸리티와 프로그램을 실행하는 것이 가능합니다. 이러한 기능을 활용하여 범용적인 데이타베이스 작업 관리 환경을 구현할 수 있습니다. 또 Scheduler는 자연 언어(natural language)를 사용하여 실행 주기를 정의할 수 있다는 매우 중요한 이점을 제공합니다. 스케줄을 매 30분 단위로 실행하고자 하는 경우, (PL/SQL 문법 대신) 자연 언어 형식의 표현을 사용하여 REPEAT_INTERVAL 매개변수를 아래와 같이 정의할 수 있습니다:
'FREQ=MINUTELY; INTERVAL=30'

좀 더 복잡한 예를 들어 설명해 보겠습니다. 운영 중인 애플리케이션이 오전 7시에서 오후 3시까지의 시간대에 집중적으로 사용된다고 가정해 봅시다. Statspack을 실행하면 월요일~금요일 오전 7시 ~ 오후 3시의 시스템 통계를 수집할 수 있습니다. DBMS_JOB.SUBMIT을 사용하여 작업을 생성하는 경우라면, NEXT_DATE 매개변수는 아래와 같이 정의됩니다:
DECODE
(
   SIGN
   (
      15 - TO_CHAR(SYSDATE,'HH24')
   ),
   1,
      TRUNC(SYSDATE)+15/24,
   TRUNC
   (
      SYSDATE +
      DECODE
      (
          TO_CHAR(SYSDATE,'D'), 6, 3, 1
      )
    )
    +7/24
)

위의 코드가 이해하기 쉽습니까? 전혀 그렇지 않습니다.
이번에는 DBMS_SCHEDULER를 이용하는 방법을 살펴 보겠습니다. REPEAT_INTERVAL 매개변수는 아래와 같이 간단하게 정의됩니다:
'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI; BYHOUR=7,15'

이 매개변수를 이용해 실행 주기를 다양한 형태로 설정할 수 있습니다. 몇 가지 예가 아래와 같습니다:
매월 마지막 일요일:
FREQ=MONTHLY; BYDAY=-1SUN

매월 세 번째 금요일:
FREQ=MONTHLY; BYDAY=3FRI

매월 뒤에서 두 번째 금요일
FREQ=MONTHLY; BYDAY=-2FRI

마이너스(-) 기호는 숫자가 뒤에서부터 계산된다는 의미입니다.
설정된 실행 주기가 올바른지 확인하려면 어떻게 해야 할까요? 캘린더 문자열을 이용해서 날짜를 미리 확인할 수 있다면 편리하지 않을까요? EVALUATE_CALENDAR_STRING 프로시저를 이용하여 실행 예정 시각을 미리 검토할 수 있습니다. 위의 예 – 월~금7:00 AM ~ 3:00 PM Statspack 실행 – 에서 설정된 실행 주기를 확인하는 방법이 아래와 같습니다:
set serveroutput on size 999999

declare
   L_start_date    TIMESTAMP;
   l_next_date     TIMESTAMP;
   l_return_date   TIMESTAMP;
begin
   l_start_date := trunc(SYSTIMESTAMP);
   l_return_date := l_start_date;
   for ctr in 1..10 loop
      dbms_scheduler.evaluate_calendar_string(
        'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI; BYHOUR=7,15',
         l_start_date, l_return_date, l_next_date
      );
      dbms_output.put_line('Next Run on: ' ||
          to_char(l_next_date,'mm/dd/yyyy hh24:mi:ss')
      );
      l_return_date := l_next_date;
   end loop;
end;
/

실행 결과는 다음과 같습니다:
Next Run on: 03/22/2004 07:00:00
Next Run on: 03/22/2004 15:00:00
Next Run on: 03/23/2004 07:00:00
Next Run on: 03/23/2004 15:00:00
Next Run on: 03/24/2004 07:00:00
Next Run on: 03/24/2004 15:00:00
Next Run on: 03/25/2004 07:00:00
Next Run on: 03/25/2004 15:00:00
Next Run on: 03/26/2004 07:00:00
Next Run on: 03/26/2004 15:00:00

위 결과로 미루어 설정된 내용에 문제가 없음을 확인할 수 있습니다.
작업과 프로그램의 연계
위의 사례는 특정 프로그램과 연결되지 않은 작업을 생성하는 방법을 설명하고 있습니다. 이번에는 특정 OS 유틸리티를 사용하는 프로그램을 생성하고, 실행 주기를 정의한 스케줄을 설정한 뒤, 이 두 가지를 조합하여 새로운 작업을 생성하는 방법을 설명합니다.
먼저 작업 내에서 프로그램을 사용한다는 사실을 데이타베이스가 인지하도록 해야 합니다. 이 프로그램을 생성하려면, CREATE JOB 권한을 갖고 있어야 합니다.
begin
    dbms_scheduler.create_program
    (
       program_name   => 'MOVE_ARCS',
       program_type   => 'EXECUTABLE',
       program_action => '/home/arup/dbtools/move_arcs.sh',
       enabled        => TRUE,
       comments       => 'Moving Archived Logs to Staging Directory'
    );
end;
/

이제 named program unit을 생성하여, 그 유형을 “executable”로 지정하고 실행될 program unit의 이름을 정의하였습니다.
다음으로, 매 30분 간격으로 실행되는 EVERY_30_MIN이라는 이름의 스케줄을 생성합니다:
begin
    dbms_scheduler.create_schedule
    (
       schedule_name   => 'EVERY_30_MINS',
       repeat_interval => 'FREQ=MINUTELY; INTERVAL=30',
       comments        => 'Every 30-mins'
    );
end;
/

프로그램과 스케줄을 생성한 뒤, 이 두 가지를 연관시킴으로써 새로운 작업을 생성합니다.
begin
   dbms_scheduler.create_job
   (
      job_name      => 'ARC_MOVE',
      program_name  => 'MOVE_ARCS',
      schedule_name => 'EVERY_30_MINS',
      comments      => 'Move Archived Logs to a Different Directory',
      enabled       => TRUE
   );
end;
/

이제 매 30분마다 move_arcs.sh 셸 스크립트를 실행하는 작업이 생성되었습니다. 이 스케줄은 데이타베이스 내부의 Scheduler 기능을 통해 관리되며, 따라서 cron 또는 AT 유틸리티를 사용할 필요가 없습니다.
Classes, Plans, and Windows
작업 스케줄링 시스템에 효과적으로 활용하려면 작업의 우선순위 지정이 가능해야 합니다. 예를 들어 OLTP 워크로드가 실행 중인 시간대에 통계 수집 작업이 갑자기 실행되어 성능을 저하시킬 수 있습니다. 통계 수집 작업이 OLTP 성능에 영향을 미치지 않도록 하기 위해, Scheduler가 제공하는 job classes, resource plans, and Scheduler Windows기능을 활용할 수 있습니다.
Job class는 할당된 자원을 공유하는 “resource consumer group”으로 매핑됩니다. Job class를 생성하기 위해, 먼저 OLTP_GROUP이라는 이름의 resource consumer group을 정의해 보겠습니다.
begin
   dbms_resource_manager.clear_pending_area();
   dbms_resource_manager.create_pending_area();
   dbms_resource_manager.create_consumer_group (
       consumer_group => 'oltp_group',  
       comment => 'OLTP Activity Group'
   );
   dbms_resource_manager.submit_pending_area();
end;
/

다음에는 resource plan을 생성합니다.
begin
   dbms_resource_manager.clear_pending_area();
   dbms_resource_manager.create_pending_area();
   dbms_resource_manager.create_plan
      ('OLTP_PLAN', 'OLTP Database Activity Plan');
   dbms_resource_manager.create_plan_directive(
      plan => 'OLTP_PLAN',
      group_or_subplan => 'OLTP_GROUP',
      comment => 'This is the OLTP Plan',
      cpu_p1 => 80, cpu_p2 => NULL, cpu_p3 => NULL, cpu_p4 => NULL,
      cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
      parallel_degree_limit_p1 => 4,
      active_sess_pool_p1 => NULL,
      queueing_p1 => NULL,
      switch_group => 'OTHER_GROUPS',
      switch_time => 10,
      switch_estimate => true,
      max_est_exec_time => 10,
      undo_pool => 500,
      max_idle_time => NULL,
      max_idle_blocker_time => NULL,
      switch_time_in_call => NULL
   );
   dbms_resource_manager.create_plan_directive(
      plan => 'OLTP_PLAN',
      group_or_subplan => 'OTHER_GROUPS',
      comment => NULL,
      cpu_p1 => 20, cpu_p2 => NULL, cpu_p3 => NULL, cpu_p4 => NULL,
      cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
      parallel_degree_limit_p1 => 0,
      active_sess_pool_p1 => 0,
      queueing_p1 => 0,
      switch_group => NULL,
      switch_time => NULL,
      switch_estimate => false,
      max_est_exec_time => 0,
      undo_pool => 10,
      max_idle_time => NULL,
      max_idle_blocker_time => NULL,
      switch_time_in_call => NULL
   );
   dbms_resource_manager.submit_pending_area();
end;
/

마지막으로 앞에서 생성된 resource consumer group을 이용해 job class를 생성합니다.
begin
   dbms_scheduler.create_job_class(
      job_class_name => 'OLTP_JOBS',
      logging_level => DBMS_SCHEDULER.LOGGING_FULL,
      log_history => 45,
      resource_consumer_group => 'OLTP_GROUP',
      comments => 'OLTP Related Jobs'
   );
end;
/

이 프로시저에서 사용된 매개변수들을 설명해 보겠습니다. LOGGING_LEVEL 매개변수는 해당 job class를 위해 얼마나 많은 로그 데이타를 기록할 것인지 정의하는데 사용됩니다. LOGGING_FULL은 job class에 포함된 작업의 모든 활동(생성, 삭제, 실행, 변경 등)을 로그에 기록함을 의미합니다. 로그는 DBA_SCHEDULER_JOB_LOG 뷰를 통해 확인할 수 있으며, LOG_HISTORY 매개변수에 저장된 대로 45일간 보관됩니다 (디폴트 값은 30일입니다). 이 class와 연관된 resource_consumer_group 도 정의되어 있습니다. DBA_SCHEDULER_JOB_CLASSES 뷰를 통해 정의된 job class들을 확인할 수 있습니다.
작업을 생성하는 과정에서, 필요한 경우 해당 작업을 job class에 할당할 수 있습니다. 예를 들어 collect_opt_stats() 저장 프로시저를 실행하여 옵티마이저 통계를 수집하는 COLLECT_STATS 작업을 생성하면서, 아래와 같이 job class를 할당할 수 있습니다.
begin
   dbms_scheduler.create_job
   (
      job_name        => 'COLLECT_STATS',
      job_type        => 'STORED_PROCEDURE',
      job_action      => 'collect_opt_stats',
      job_class       => 'OLTP_JOBS',
      repeat_interval => 'FREQ=WEEKLY; INTERVAL=1',
      enabled         => true,
      comments        => 'Collect Optimizer Stats'
   );
end;
/

위 명령을 실행하면 생성된 작업이 OLTP_JOBS 클래스에 할당됩니다. OLTP_JOBS 클래스에 적용되는 OLTP_GROUP resource plan을 통해 프로세스에 할당되는 CPU 자원, 다른 그룹으로 전환되기 전에 최대 실행 가능한 횟수, 전환되는 그룹 등을 설정할 수 있습니다. 동일한 job class에 할당된 작업은 동일한 resource plan의 적용을 받습니다. 이 기능을 활용하면 서로 다른 유형의 작업이 같은 리소스를 두고 경합을 벌이는 상황을 방지할 수 있습니다.
Scheduler Window는 특정 resource plan이 사용되는 시간대를 의미합니다. 예를 들어, 실시간 의사결정 작업에 관련한 업데이트 배치 작업이 주간에는 높은 우선순위를 갖는 반면 야간에는 낮은 우선순위를 갖는다고 가정해 봅시다. 이 경우 시간대별로 다른 resource plan을 정의하고, 정의된 내용을 Scheduler Window를 이용해 적용할 수 있습니다.
모니터링
실행 중인 작업의 상태는 DBA_SCHEDULER_JOB_LOG 뷰를 통해 확인할 수 있습니다. 이 뷰의 STATUS 컬럼은 작업의 현재 상태를 표시하는데 사용됩니다. 만일 STATUS 컬럼이 FAILED로 표시된다면, DBA_SCHEDULER_JOB_RUNS_DETAILS 뷰를 통해 그 원인을 확인할 수 있습니다.
관리
지금까지 여러 가지 유형의 오브젝트(program, schedule, job, job class 등)를 생성하는 방법에 대해 설명했습니다. 이렇게 생성된 오브젝트를 변경할 필요가 있다면, DBMS_SCHEDULER 패키지가 제공하는 API를 사용하면 됩니다.
Enterprise Manager 10g 홈 페이지에서 Administration 링크를 클릭하면, 그림 1과 같이 Administration 화면이 표시됩니다. Scheduler와 관련된 작업은 우측 하단의 “Scheduler” 항목에 표시됩니다 (그림의 붉은색 원 참조).
 

그림 1: Administration 페이지
이 페이지에서 제공되는 하이퍼링크를 활용하면 작업의 생성, 삭제, 관리와 같은 Scheduler 관련 작업을 쉽게 수행할 수 있습니다. 몇 가지 예를 들어 설명해 보겠습니다. 이미 작업을 생성해 둔 상태이므로, Job 탭을 클릭하면 그림 2와 같은 화면이 표시될 것입니다.
 

그림 2: 작업 스케줄의 확인
COLLECT_STATS 작업을 클릭하여 그 속성을 변경해 보도록 합시다. “Name” 필드를 클릭하면 그림 3과 같은 화면이 표시됩니다.
 

그림 3: 작업 매개변수
지금까지 확인한 것처럼, EM을 이용하면 작업, 스케줄, 옵션 등에 관련한 매개변수를 수정할 수 있습니다. 변경 작업을 완료한 뒤 “Apply” 버튼을 누르면 변경사항은 영구적으로 적용됩니다. “Apply” 버튼을 누르기 전에 “Show SQL” 버튼을 눌러 실행되는 SQL 구문을 확인하는 것도 가능합니다. 또 SQL 구문을 스크립트에 저장하여 나중에 실행하거나, 템플릿 용도로 활용할 수도 있습니다.
결론
Oracle Database 10g의 Scheduler는 dbms_job 인터페이스보다 훨씬 향상된 기능을 제공합니다. Scheduler에 대한 상세한 정보는 Oracle Database Administrator's Guide의 Chapter 25를 확인하시기 바랍니다.
 
 
 
 
제 20 주
그 밖의 유용한 기능
지금까지 소개한 기능 이외에도, Oracle Database 10g는 통계 자동 수집, undo 데이타 보존기간(undo retention)의 “guarantee”, 더욱 쉽고 강력해진 암호화 패키지 등의 유용한 기능을 제공합니다.
드디어 우리의 긴 여행도 막바지에 이르렀습니다. 지난 19주 동안 DBA의 작업을 쉽고 편하게 해 주는 다양한 툴, 팁, 테크닉을 소개해 드렸습니다.
지금까지 Oracle Database 10g의 특출한 기능이라 하더라도 DBA에게 많은 도움이 되지 않는다면 소개하지 않는 것을 원칙으로 했습니다. 마지막 연재도 Oracle 10g의 모든 기능을 섭렵하기에는 지면이 충분하지 않습니다. 이제 그간의 연재를 마무리하면서, 언급될 가치가 있는 Oracle 10g의 중요한 기능을 몇 가지 골라 소개하려 합니다.
자동적인 통계 수집
이미 많은 분들이 알고 계시겠지만, Oracle 10g에 오면서 마침내 Rules-Based Optimized(RBO)는 더 이상 지원되지 않는 (기능은 남아있지만) 것으로 결정되었습니다. Oracle9i Database를 사용하는 IT 조직은 Cost-Based Optimizer(CBO) 환경으로 업그레이드함으로써 계속적인 기술지원을 받을 수 있을 뿐 아니라 query rewrite, partition pruning과 같은 고급 기능을 활용할 수 있게 됩니다. 하지만 이 경우 통계(statistics)가 (정확히 말하면 통계의 부재가) 문제가 됩니다.
CBO가 최적의 실행 경로를 생성하려면 정확한 통계를 필요로 하며, DBA는 통계가 정기적으로 수집될 수 있도록 데이타베이스를 관리해야 합니다. 10g 이전의 환경에서는 (여러 가지 이유 때문에) 정확한 통계의 수집을 위한 DBA의 노력이 수포로 돌아가는 경우가 허다했습니다. 이러한 문제 때문에 CBO가 “제멋대로 동작한다”는, 다시 말해 임의적으로 실행 경로를 바꾸곤 한다는 이론이 제기되기도 했습니다.
10g는 통계의 자동적인 수집 기능을 제공하며, 따라서 이와 같은 문제를 상당부분 해결하였습니다. Oracle9i의 경우 테이블의 데이타가 얼마나 변경되었는지 확인하기 위해서는 테이블의 모니터링 옵션을 활성화하고 (ALTER TABLE... MONITORING) 해당 테이블에 대한 DBA_TAB_MODIFICATIONS 뷰를 조회해야 했습니다.
10g에서는 MONITORING 키워드가 사라진 대신, 초기화 매개변수 STATISTICS_LEVEL을 TYPICAL 또는 ALL로 설정함으로써 통계 수집을 자동화하는 기능을 제공합니다. (디폴트 값은 TYPICAL이며, 따라서 데이타베이스 설치 후 바로 통계 수집 작업이 자동 수행됩니다.) Oracle Database 10g는 사전 정의된 Scheduler (Scheduler에 대해서는 제 19 주에 설명했습니다) 작업 GATHER_STATS_JOB을 통해 통계 수집을 수행합니다. 이 작업은 STATISTICS_LEVEL 매개변수 값에 의해 활성화됩니다.
통계 수집 작업은 매우 많은 자원을 소모합니다. 따라서 이 작업으로 인해 운영 중인 애플리케이션의 성능이 저하되지 않음을 보장할 수 있어야 합니다. 10g는 통계 수집과 같은 자동 수행 작업을 위해 special resource consumer group인 AUTO_TASK_CONSUMER_GROUP을 정의하고 있습니다. 이 consumer group이 수행하는 작업은 디폴트 consumer group에 비해 낮은 우선순위를 가지며, 따라서 자동 수행되는 작업이 시스템의 성능을 저하시킬 가능성을 줄일 수 있습니다.
STATISTICS_LEVEL을 TYPICAL로 설정한 상태에서 통계가 자동 수집되지 않게 하려면 어떻게 해야 할까요? 간단합니다. 아래와 같은 명령을 사용하여 Scheduler 작업을 비활성화하면 됩니다.
BEGIN
   DBMS_SCHEDULER.DISABLE('GATHER_STATS_JOB');
END;

그렇다면 굳이 이렇게 할 설정할 필요가 있을까요? 여러 가지 이유로 이러한 설정이 필요한 상황이 있을 수 있습니다. 첫 번째로 테이블 내의 많은 레코드가 변경되었지만 데이타의 분포는 변하지 않은 경우를 들 수 있습니다 (데이타 웨어하우스 환경에서 이러한 경우가 많이 발견됩니다). 이 경우 통계를 다시 수집할 필요가 없으며 이전의 통계를 그대로 사용해도 무방합니다. 두 번째로 partition exchange를 이용하여 materialized view(MV)를 refresh하는 환경에서도, exchanged table의 통계를 임포트해서 사용하므로 MV에 대한 통계에 대해 별도의 수집을 원치 않을 경우입니다. 또 전체 통계 수집 작업을 중단하는 대신, 특정 테이블에 대한 자동 통계 수집만을 선택적으로 비활성화하는 것도 가능합니다.
통계 히스토리
옵티마이저 통계 수집 과정에서 문제가 될 수 있는 상황의 하나로 execution plan이 변경되는 경우를 들 수 있습니다. 새로운 통계가 수집되기 전까지 정상적으로 수행되던 쿼리가, 새로운 통계를 기반으로 생성된 execution plan으로 인해 오히려 성능이 악화될 수 있습니다. 이러한 문제는 실제로 빈번하게 발생합니다.
이러한 문제를 방지하기 위해서는, 새로운 통계를 수집하기 전에 현재 통계 정보를 저장합니다. 이와 같이 함으로써, 문제가 생겼을 때 바로 예전의 통계로 복구하거나, 두 통계의 차이점을 분석해서 원인을 확인할 수 있습니다.
예를 들어 REVENUE 테이블에 대한 통계 수집 작업이 5월 31일 오후 10시에 실행된 이후 쿼리 성능이 악화되었다고 가정해 봅시다. 아래 명령을 사용하여 Oracle이 저장한 이전 통계로 복구될 수 있습니다.
begin
   dbms_stats.restore_table_stats (
      'ARUP',
      'REVENUE',
      '31-MAY-04 10.00.00.000000000 PM -04:00');
end;

위 명령은 (TIMESTAMP 데이타 타입을 통해 명시한 대로) 5월 31일 오후 10시 시점을 기준으로 통계를 복구합니다. 이와 같이 함으로써 새로운 통계로 인해 발생한 문제를 해결할 수 있습니다.
복구에 이용할 수 있는 과거 통계의 보존 기간은 매개변수를 통해 설정할 수 있습니다. 현재 설정된 보존 기간을 확인하려면 아래와 같이 질의합니다:
SQL> select DBMS_STATS.GET_STATS_HISTORY_RETENTION from dual;

GET_STATS_HISTORY_RETENTION
---------------------------
                         31

위 결과를 통해 31일간의 통계 정보를 보존할 수 있습니다. 단 이 기간이 반드시 보장되는 것은 아닙니다. 복구 가능한 정확한 시점을 확인하려면 아래와 같이 입력합니다:
SQL> select DBMS_STATS.GET_STATS_HISTORY_AVAILABILITY from dual;

GET_STATS_HISTORY_AVAILABILITY
---------------------------------------------------------------------
17-MAY-04 03.21.33.594053000 PM -04:00

위 결과는 현재 가장 오래된 통계가 5월 17일 오전 3시 21분에 생성된 것임을 알려주고 있습니다.
내장 함수를 이용하여 통계의 보존 기간을 변경할 수 있습니다. 보존 기간을 45일로 변경하려면 다음과 같이 입력합니다:
execute DBMS_STATS.ALTER_STATS_HISTORY_RETENTION (45)

Guaranteed Undo Retention
Oracle9i에서 처음 소개된 Automatic Undo Retention 기능은 ORA-1555 “Snapshot Too Old” 에러가 발생할 가능성을 상당 수준 줄여줍니다. 하지만 이 에러는 (많이 줄어들기는 했지만) 여전히 발생하고 있습니다. 왜일까요?
이 질문에 대답하기 위해서는, 먼저 undo segment가 동작하는 원리를 이해해야 합니다. 오라클 데이타베이스의 데이타가 변경되면, (SGA 내부의) 캐시에 있는 블록이 즉각적으로 변경되면서, 기존의 데이타 이미지(past image)는 undo segment에 저장됩니다. 트랜잭션이 커밋 되면, 기존의 이미지는 더 이상 불필요하며, 따라서 삭제가 가능합니다. 하지만 Undo segment의 모든 공간이 액티브 트랜잭션에 의해 사용되고 있다면 세그먼트 내에서 가장 오래된 익스텐트(extent)에 덮어 쓰기를 시도합니다 (이 과정을 “wrapping”이라 부르기도 하며, V$ROLLSTAT 뷰의 WRAPS 컬럼을 통해 확인됩니다). 하지만, 롱-러닝 트랜잭션(long-running transaction)이 사용되는 경우와 같은 특별한 상황에서, 데이타베이스는 액티브 트랜잭션을 위해 세그먼트를 확장하기도 합니다 (V$ROLLSTAT 뷰의 EXTENDS 컬럼을 통해 확인됩니다). 쿼리가 데이터의 일관성을 보장하기 위해서 undo segment의 익스텐트(extent)에 저장된 이미지를 요구했지만 해당 익스텐트가 이미 재사용된 경우, 쿼리는 ORA-1555 에러를 발생시킵니다.
초기화 매개변수 UNDO_RETENTION을 통해 undo 데이타가 보존되는 기간을 (초 단위로) 설정할 수 있습니다. 이처럼 보존 기간을 설정함으로써, inactive 상태의 undo extent라 하더라도 일정 기간 삭제되지 않음을 보장할 수 있습니다. 이 방법을 사용하면 inactive 상태의 익스텐트(extent)가 재사용되는 상황을 예방하고, 따라서 ORA-1555 에러가 발생할 가능성을 줄일 수 있습니다.
하지만 UNDO_RETENTION 매개변수로 ORA-1555의 발생 가능성을 근본적으로 제거할 수는 없습니다. 세그먼트의 확장이 불가능한 경우, 데이타베이스는 가장 오래된 inactive 익스텐트를 강제로 재사용합니다. 따라서 일부 롱-러닝 트랜잭션으로부터 ORA-1555 에러가 발생할 가능성은 상존합니다.
10g에서는 이러한 문제가 해결되었습니다. 이제는 undo 테이블스페이스를 생성하면서 undo retention “guarantee”를 설정할 수 있습니다. 그 예가 아래와 같습니다:
CREATE UNDO TABLESPACE UNDO_TS1
DATAFILE '/u01/oradata/proddb01/undo_ts1_01.dbf'
SIZE 1024M
RETENTION GUARANTEE;

마지막 부분의 “RETENTION GUARANTEE”는 undo tablespace로 하여금 만료되지 않은 undo 익스텐트의 보존을 “보장”하도록 설정합니다. 기존 undo tablespace는 ALTER 구문을 이용하여 아래와 같이 수정할 수 있습니다:
ALTER TABLESPACE UNDO_TS2 RETENTION GUARANTEE;

익스텐트의 보존을 “보장”하는 것을 원치 않는 경우(Oracle 9i 방식)에는 다음과 같이 입력합니다:
ALTER TABLESPACE UNDO_TS2 RETENTION NOGUARANTEE;

테이블스페이스에 undo retention이 “guarantee” 되고 있는지의 여부는 아래와 같이 확인할 수 있습니다.
SELECT RETENTION
FROM DBA_TABLESPACES
WHERE TABLESPACE_NAME = 'UNDO_TS1';

End-to-End Tracing
성능 문제를 진단하기 위한 방법의 하나로, sql_trace를 활성화하여 데이타베이스 쿼리를 추적하고 tkprof와 같은 툴을 사용하여 그 결과를 분석하는 방법이 자주 사용됩니다. 하지만, 이 방법은 공유 서버(Shared Server) 아키텍처 상에 구현된 데이타베이스 환경에서는 그 유용성이 심각하게 제한됩니다. 이러한 경우 사용자의 요구사항을 처리하기 위해서 여려 공유서버 프로세스(shared server process)들이 생성됩니다. 사용자 BILL이 데이타베이스에 접근하려는 경우, dispatcher는 사용 가능한 공유 서버 중 하나와 사용자를 연결합니다. 현재 사용 가능한 서버가 존재하지 않는 경우, 새로운 공유 서버가 생성됩니다. 이 세션이 트레이스(trace) 작업을 시작하면, 해당 공유 서버의 프로세스에 의해 호출된 작업들의 트레이스가 수행됩니다.
이제 BILL의 세션이 idle 상태가 되고 LORA의 세션이 active 상태가 되었다고 가정합시다. BILL에게 서비스를 제공하던 공유 서버는 LORA의 세션에 할당되었습니다. 이 시점 이후의 트레이스 정보는 BILL의 세션이 아닌 LORA의 세션을 추적합니다. LORA의 세션이 inactive 상태가 되면, 공유 서버는 다른 active 세션에 할당되며, 다시 BILL 또는 LORA의 세션과는 전혀 무관한 트레이스정보를 만들어 냅니다.
10g에서는 end-to-end tracing 기능을 통해 이러한 문제를 해결하였습니다. 10g에서의 트레이스 작업은 세션 단위로 수행되지 않고 client identifier와 같은 정보를 기준으로 수행됩니다. 새로 추가된 DBMS_MONITOR 패키지가 바로 이러한 목적을 위해 사용됩니다.
예를 들어, identifier “account_update”를 갖는 모든 세션을 트레이스하려는 경우를 가정해 봅시다. 먼저 트레이스를 설정하기 위해서 아래와 같이 입력합니다:
exec DBMS_MONITOR.CLIENT_ID_TRACE_ENABLE('account_update');

위 명령은 “account_update”를 identifier로 하는 모든 세션에 대한 트레이스 작업을 활성화합니다. 데이타베이스에 연결하는 과정에서, BILL은 다음과 같은 명령을 통해 client identifier를 설정합니다:
exec DBMS_SESSION.SET_IDENTIFIER ('account_update')

“account_update”를 identifier로 하는 모든 세션을 트레이스 하도록 설정된 상황이므로, 위의 세션 역시 트레이스 되고 user dump destination 디렉토리에 트레이스 파일(trace file)이 생성됩니다. 다른 사용자가 데이타베이스에 연결하면서 client identifier를 “account_update”로 설정하는 경우, 새로운 세션 역시 자동으로 트레이스 됩니다. 결국 아래와 같은 명령을 통해 트레이스를 disable할 때까지, “account_update”를 client identifier로 하는 모든 세션이 트레이스 됩니다:
exec DBMS_MONITOR.CLIENT_ID_TRACE_ENABLE('account_update');

생성된 트레이스 파일은 tkprof 툴을 통해 분석할 수 있습니다. 하지만 각각의 세션이 별도의 트레이스 파일을 생성하는 문제가 있습니다. 문제를 효과적으로 분석하려면, 통합된 형태의 트레이스 파일이 필요할 것입니다.
trcsess 툴을 이용하면 “account_update”를 client identifier로 하는 모든 세션의 트레이스 정보를 추출하여 하나의 파일에 저장할 수 있습니다. 트레이스 정보를 통합하려면 user dump destination 디렉토리로 이동하여 다음과 같이 실행합니다:
trcsess output=account_update_trc.txt clientid=account_update *

위 명령을 실행하면 account_update_trc.txt 파일이 생성됩니다. 이 파일은 일반적인 트레이스 파일과 같은 포맷을 가지며, tkprof 툴을 이용하여 분석될 수 있습니다.
이처럼 end-to-end tracing 기능을 활용하여 트레이스 정보를 보다 쉽게 수집할 수 있습니다. 또 세션 별로 alter session set sql_trace = true 명령을 사용하는 대신, client identifier를 기준으로 트레이스를 enable/disable할 수 있습니다. 같은 패키지를 통해 제공되는 SERV_MOD_ACT_TRACE_ENABLE 프로시저를 사용하면 dbms_application_info패키지를 이용해서 설정된 특정 서비스, 모듈, 또는 액션의 조합으로 트레이스를 수행하는 것도 가능합니다.
데이타베이스 사용 현황
오라클 데이타베이스의 파티셔닝(partitioning) 기능은 별도로 구매해야 하는 옵션입니다. 요즘처럼 예산이 제한되는 상황에서는, 구입을 결정하기 전에 파티셔닝이 정말로 사용자에게 효과적으로 활용되고 있는지 먼저 고민하지 않을 수 없습니다.
이 질문을 사용자에게 던지는 대신 데이타베이스에게 물어보십시오. Automatic Workload Repository(제 6 주 연재에서 설명한 바 있습니다)는 설치된 모든 기능의 사용 정보를 1주 1회의 단위로 수집합니다.
데이타베이스의 사용 패턴을 보여주는 중요한 뷰가 두 가지 존재합니다. 첫 번째로, DBA_HIGH_WATER_MARK_STATISTICS 뷰는 현재 데이타베이스에 사용되는 각 기능의 최대값을 보여줍니다. 실행 결과의 예가 아래와 같습니다.
NAME             HIGHWATER LAST_VALUE DESCRIPTION
--------------- ---------- ---------- ----------------------------------------------------------
USER_TABLES            401        401 Number of User Tables
SEGMENT_SIZE    1237319680 1237319680 Size of Largest Segment (Bytes)
PART_TABLES             12          0 Maximum Number of Partitions belonging to an User Table
PART_INDEXES            12          0 Maximum Number of Partitions belonging to an User Index
USER_INDEXES           832        832 Number of User Indexes
SESSIONS                19         17 Maximum Number of Concurrent Sessions seen in the database
DB_SIZE         7940079616 7940079616 Maximum Size of the Database (Bytes)
DATAFILES                6          6 Maximum Number of Datafiles
TABLESPACES              7          7 Maximum Number of Tablespaces
CPU_COUNT                4          4 Maximum Number of CPUs
QUERY_LENGTH          1176       1176 Maximum Query Length

위에서 확인할 수 있는 것처럼, 이 뷰는 데이타베이스의 사용 패턴에 대한 몇 가지 중요한 정보를 제공합니다. 예를 들어 사용자가 최대 12 개의 partitioned table을 생성했지만, 현재는 하나도 사용되고 있지 않음(LAST_VALUE = 0)을 확인할 수 있습니다. 이 정보는 데이타베이스가 셧다운 되는 경우에도 그대로 유지되며, 마이그레이션 작업을 위한 계획 단계에서 매우 유용하게 활용될 수 있습니다.
하지만 위의 뷰가 제공하는 정보만으로는 부족한 부분이 있습니다. 위 결과를 통해 12개의 partitioned table이 생성되었다는 것을 확인할 수 있지만 이 기능이 마지막으로 사용된 시간은 알 수 없습니다. DBA_FEATURE_USAGE_STATISTICS 뷰를 사용하면 이러한 문제의 해답을 쉽게 찾을 수 있습니다. 파티셔닝 기능에 관련한 뷰의 조회 결과가 아래와 같습니다:
DBID                          : 4133493568
NAME                          : Partitioning
VERSION                       : 10.1.0.1.0
DETECTED_USAGES               : 12
TOTAL_SAMPLES                 : 12
CURRENTLY_USED                : FALSE
FIRST_USAGE_DATE              : 16-oct-2003 13:27:10
LAST_USAGE_DATE               : 16-dec-2003 21:20:58
AUX_COUNT                     :
FEATURE_INFO                  :
LAST_SAMPLE_DATE              : 23-dec-2003 21:20:58
LAST_SAMPLE_PERIOD            : 615836
SAMPLE_INTERVAL               : 604800
DESCRIPTION                   : Oracle Partitioning option is being used -
                                there is at least one partitioned object created.

이 뷰를 통해 파티셔닝 기능이 현재 데이타베이스에서 사용되지 않고 있으며 (CURRENTLY_USED : FALSE), 마지막으로 액세스된 시간이 2003년 12월 16일 오후 9시 20분임을 알 수 있습니다. 사용 현황 정보의 샘플링은 매 604,800초 (7일) 단위로 수행되고 있습니다 (SAMPLE_INTERVAL 컬럼). 그리고 LAST_SAMPLE_DATE 컬럼은 사용 현황 정보가 마지막으로 샘플링 된 시점을 표시하고 있습니다.
커맨드 라인 인터페이스 대신 Enterprise Manager 10g를 사용해서 같은 정보를 확인할 수도 있습니다. 이를 위해 EM에서 Administration 탭으로 이동 한 후 Configuration Management 항목 아래의 “Database Usage Statistics” 링크를 클릭합니다 (그림 1과 2 참조).
 

그림 1: Database Usage Statistics 페이지
 

그림 2: Database Usage Statistics – 기능별 드릴다운
더 쉽고 강력해진 암호화 옵션
DBMS_OBFUSCATION_TOOLKIT (DOTK) 패키지를 기억하십니까? Oracle9i 및 이전 버전에서 암호화를 적용하려면 이 패키지를 사용하는 것 이외에 다른 대안이 없었습니다. DOTK 패키지는 대부분의 보안제품처럼 대부분의 데이타베이스 환경에 적절한 수준의 보안 환경을 제공했지만, 숙련된 해커의 공격에 쉽게 무력화되는 약점이 있었습니다. DOTK 패키지에 결여된 중요한 기능의 하나로, 기존의 DES(Digital Encryption Standard) 및 DES3 (Triple DES)보다 강력한 암호화 기능을 제공하는 Advanced Encryption Standard(AES)를 들 수 있습니다.
10g에는 보다 강력한 암호화 패키지인 DBMS_CRYPTO가 추가되었습니다. 이 내장 패키지는 DOTK에 구현되지 않은 암호화 기능을 모두 포함하고 있을 뿐 아니라, 기존 함수와 프로시저에 대해서도 보다 개선된 기능을 제공합니다. (한 예로, DBMS_CRYPTO에는 최신 암호화 기술인 256 비트 AES 알고리즘이 포함되어 있습니다.) DBMS_CRYPTO의 ENCRYPT 함수(프로시저로도 사용됩니다)는 아래와 같은 매개변수를 사용합니다:

매개변수 설명
SRC 암호화 대상이 되는 입력 데이타입니다. RAW 데이타 타입만을 지원하며, 다른 데이타 타입의 경우 먼저 변환 과정을 거쳐야 합니다. character 변수 p_in_val에 대해 변환작업을 수행하려면 다음과 같이 실행합니다:

utl_i18n.string_to_raw (p_in_val, 'AL32UTF8');

문자열을 character set AL32UTF8, 데이타 타입RAW로 변환하기 위해 UTL_IL8N 패키지가 사용됩니다. DOTK와 달리, DBMS_CRYPTO는 character 변수를 매개변수로 사용하지 않습니다. 또 DOTK 패키지에서 요구하던 것처럼, character에 대한 padding을 수행하여 그 길이를 16의 배수로 만들 필요가 없습니다. ENCRYPT 함수(또는 프로시저)는 자동으로 padding을 수행합니다.
 
KEY 암호화 키를 정의합니다. 키의 길이는 사용되는 알고리즘에 따라 달라집니다.
 
TYP 암호화 타입과 padding 방법을 정의합니다. 예를 들어 AES 256-bit 알고리즘, Cipher Block Chaining, PKCS#5 padding을 사용하려는 경우 아래와 같이 입력합니다:
typ => dbms_cryptio.encrypt_aes256 +
       dbms_cryptio.chain_cbc +
    dbms_cryptio.pad_pkcs5

 

The ENCRYPT ENCRYPT 함수는 암호화된 값을 RAW 데이타 타입으로 반환합니다. 반환된 결과를 문자열로 변환하려면 아래와 같이 실행합니다:
utl_i18n.raw_to_char (l_enc_val, 'AL32UTF8')

which is the reverse of the casting to RAW.
암호화된 결과를 해독하려면 DECRYPT 함수(또는 프로시저로도 사용됩니다)를 사용합니다. 이처럼 DBMS_CRYPTO 패키지를 사용하여. 데이타베이스 환경에 개선된 보안 모델을 구현할 수 있습니다.
결론
Oracle Database 10g가 제공하는 새로운 기능을 모두 설명하는 것은 불가능에 가깝습니다. 하지만 지난 20주에 걸쳐, DBA에게 가장 중요한 의미를 갖는 일부 기능을 선별하여 소개했으며, 이번 주에는 지난 19주 동안 소개되지 않았던 몇 가지 기능을 마지막으로 설명해 드렸습니다. 이번 연재가 여러분에게 유익했기를 바랍니다. 의견이 있으신 경우 언제든 보내주시기 바라며, 여러분이 가장 마음에 들어 하는 기능이 어떤 것이었는지 알려주시면 제게 많은 참고가 될 것입니다.  

Posted by 1010
02.Oracle/DataBase2008. 11. 24. 17:18
반응형

출처 : http://radiocom.kunsan.ac.kr/lecture/oracle/backup_restore/what_is_backup.html



백업방법
http://radiocom.kunsan.ac.kr
오라클 DB 백업은 1)물리적 백업(physical backup)과, 2)논리적 백업(Logical backup)의 두가지 방법이 있다.

물리적 백업

물리적인 백업은 데이터베이스 파일(데이터 파일, 컨트롤 파일)을 백업하는 것을 뜻하며, DB가 아카이브 모드에서 수행중인 경우에는 아카이브 리두 로그 파일이 자동적으로 생성되므로 데이터 파일, 컨트롤 파일, 아카이브 리두 로그 파일이 백업된다.
물리적 백업은 다음과 같이 두 가지가 가능하다.

	• 오프라인 백업
	• 온라인 백업

오프라인 백업
Off-line backup은 테이블스페이스나 데이터 파일이 오프라인일 때 실행되는 백업으로, 가장 수행하기 쉬운 백업방법중의 하나이다.
오프라인 백업은 DB를 종료하고, Db와 관련된 모든 물리적인 파일(데이터 파일, 컨트롤 파일, 매개변수 파일)을 운영체제 명령어를 이용하여 복사한다.

이 백업은 데이터 파일의 크기가 매우 큰 경우, 많은 시간이 소요될 수 도 있다. 그래서 오프라인 백업을 whole-backup 또는 cold-backup이라 한다.

$ sqlplus system/manager as sysdba   ☜ DBA로 접속

SQL> select name from v$controlfile;   ☜ 컨트롤 파일의 위치를 확인
 
NAME
--------------------------------------------------------------------------------
/export/home/oracle/app/oracle/oradata/orcl/control01.ctl
/export/home/oracle/app/oracle/oradata/orcl/control02.ctl
/export/home/oracle/app/oracle/oradata/orcl/control03.ctl
 
SQL> select file_name from dba_data_files;   ☜ 데이터 파일의 확인
 
FILE_NAME
--------------------------------------------------------------------------------
/export/home/oracle/app/oracle/oradata/orcl/users01.dbf
/export/home/oracle/app/oracle/oradata/orcl/sysaux01.dbf
/export/home/oracle/app/oracle/oradata/orcl/undotbs01.dbf
/export/home/oracle/app/oracle/oradata/orcl/system01.dbf
 
SQL> select group#,member from v$logfile;   ☜ 리두 로그 파일을 확인
 
    GROUP# MEMBER
---------- ------------------------------------------------------------
         3 /export/home/oracle/app/oracle/oradata/orcl/redo03.log
         2 /export/home/oracle/app/oracle/oradata/orcl/redo02.log
         1 /export/home/oracle/app/oracle/oradata/orcl/redo01.log
 
SQL>
SQL> shutdown normal;    ☜ normal, transaction, immediate중 하나로 DB를 종료
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> !    ☜ 쉘 프롬프트로 일시 복귀함
$ su     ☜ root의 권한을 가짐
Password: 
# cp /export/home/oracle/app/oracle/oradata/orcl/control0*.ctl /export/home/work/.     
☜ 컨트롤 파일 복사
# cp /export/home/oracle/app/oracle/oradata/orcl/redo*.log /export/home/work/.
☜ 리두 로그 파일 복사 # cp /export/home/oracle/app/oracle/oradata/orcl/*.dbf /export/home/work/.
☜ 데이터 파일 복사 # cp dbs/*.ora /export/home/work/.
☜ 파라미터 파일 복사 # ls -l /export/home/work
☜ 복사되었나 확인 -rw-r----- 1 root other 2867200 Jan 4 11:07 control01.ctl -rw-r----- 1 root other 2867200 Jan 4 11:07 control02.ctl -rw-r----- 1 root other 2867200 Jan 4 11:07 control03.ctl -rw-r--r-- 1 root other 8384 Jan 4 11:14 init.ora -rw-r--r-- 1 root other 12920 Jan 4 11:14 initdw.ora -rw-r----- 1 root other 10486272 Jan 4 11:09 redo01.log -rw-r----- 1 root other 10486272 Jan 4 11:09 redo02.log -rw-r----- 1 root other 10486272 Jan 4 11:09 redo03.log -rw-r----- 1 root other 2560 Jan 4 11:14 spfileorcl.ora -rw-r----- 1 root other 461381632 Jan 4 11:10 sysaux01.dbf -rw-r----- 1 root other 471867392 Jan 4 11:11 system01.dbf -rw-r----- 1 root other 20979712 Jan 4 11:11 temp01.dbf -rw-r----- 1 root other 26222592 Jan 4 11:11 undotbs01.dbf -rw-r----- 1 root other 5251072 Jan 4 11:11 users01.dbf # exit ☜ root 권한에서 빠져나옴 $ exit ☜ 쉘프롬프트에서 오라클 프롬프트로 복귀 SQL> startup ☜ Instance 기동 ORACLE instance started. Total System Global Area 289406976 bytes Fixed Size 778796 bytes Variable Size 99360212 bytes Database Buffers 188743680 bytes Redo Buffers 524288 bytes Database mounted. Database opened. SQL>

자동으로 오프라인 백업실행하기
오프라인 백업은 데이터 파일의 크기가 작은 경우 쉽고, 간단하게 실행할 수 있지만, 데이터 파일이 큰 경우는 많은 시간이 소요되므로 스크립트를 사용하여 운영체제의 스케듈러에 의해 백업이 자동으로 실행되도록 할 수 있다.
다음과 같이 오프라인 자동 백업 스크립트를 작성하여 실행한다.

1단계 : 오라클 인스턴스 종료
	$ORACLE_HOME/bin/sqlplus system/manager as sysdba
	SHUTDOWN IMMEDIATE
	EXIT

2단계 : 데이터베이스와 관련된 모든 물리적 파일 복사
	cp /export/home/oracle/app/oracle/oradata/orcl/*.ctl backup/
	cp /export/home/oracle/app/oracle/oradata/orcl/*.dbf backup/
	cp /export/home/oracle/app/oracle/oradata/orcl/*.log backup/
	cp /export/home/oracle/app/oracle/oradata/orcl/*.ora backup/

3단계 : 데이터베이스 다시 시작
	$ORACLE_HOME/bin/sqlplus system/manager as sysdba
	STARTUP
 	EXIT
	EOF

온라인 백업
오프라인 백업이 DB가 종료한 상태에서 백업하는 것에 반해,
온라인 백업은 DB를 운영하는 도중에 백업을 실행하는 방법이다. 온라인 백업은 테이블스페이스 단위로 백업을 수행하며 ALTER TABLESPACE 명령으로 테이블스페이스를 백업모드로 설정하고, 데이터 파일을 운영체제에 복사한다.
온라인 백업을 hot backup 또는 open backup이라 한다. 온라인 백업은 오프라인 백업과 달리 모든 파일을 백업할 수 없고, 필요한 테이블스페이스만 백업할 수 있다.
$ sqlplus '/as sysdba'
SQL> select tablespace_name, file_name from dba_data_files;
 
TABLESPACE_NAME FILE_NAME
--------------- ------------------------------------------------------------
USERS           /export/home/oracle/app/oracle/oradata/orcl/users01.dbf
SYSAUX          /export/home/oracle/app/oracle/oradata/orcl/sysaux01.dbf
UNDOTBS1        /export/home/oracle/app/oracle/oradata/orcl/undotbs01.dbf
SYSTEM          /export/home/oracle/app/oracle/oradata/orcl/system01.dbf
 
SQL> alter tablespace users begin backup; 
☜ 테이블스페이스내의 모든 객체에 대해 변경된 데이터들이 데이터 파일에 적용되고, 메모리 영역과 리두 로그 파일에 일시적으로 저장된다.
 
Tablespace altered.
 
SQL> !
$ cp /export/home/oracle/app/oracle/oradata/orcl/users01.dbf bkup/.
$ ls -l bkup
total 10272
-rw-r-----   1 oracle   oinstall 5251072 Jan  4 14:07 users01.dbf
$ exit
 
SQL> alter tablespace users end backup;  
☜ 복사후 sql문을 실행하여 데이터파일에 저장되었던 변경된 데이터를 실제 데이터 파일에 반영한다.
 
Tablespace altered.
 
SQL> 
SQL> ALTER SYSTEM SWITCH LOGFILE;
    ☜ 인위적으로 로그 스위치를 실행하여 모든 데이터 파일 헤더에 저장되어 있는
체크포인트 번호를 통합
System altered. SQL>

논리적 백업

논리적 백업은 DB내의 논리적 객체들을 백업하는 방법으로, EXPORT 유틸리티를 사용하여 백업하고, IMPORT 유틸리티를 사용하여 복구한다.
EXPORT와 IMPORT 유틸리티가 백업/복구 이외에 다른 기능은 다음과 같다.

• 특정 사용자의 객체를 다른 사용자의 공간으로 이동시킬 수 있다.
• 운영체제가 다른 DB 사이에 데이터를 이동시킬 수 있다.
• 테이블, 뷰,인덱스 등을 백업하고 다시 복구함으로써 객체들의 구조가 재생성되어
   단편화(fragmentation)를 감소시킨다.
익스포트에서 사용 가능한 키워드는 EXP 유틸리티를 참조하고
또한 익스포트를 사용하여 논리적으로 DB를 백업하는 방법은
데이터 베이스 전체모드, 테이블스페이스 모드, 사용자모드, 테이블모드의 4 종류가 있다.

데이터베이스 전체모드 테이블스페이스 모드 사용자 모드 테이블 모드
•모든 테이블의 데이터
•인덱스
•테이블의 제약조건
•트리거
•클러스트
•시퀀스
•스냅샷
•스토어드 프로시저
•시노늄
•뷰
•프로파일/롤
•audit
•지정된 테이블스페이스의 테이블
•테이블의 데이터
•인덱스
•테이블의 제약조건
•트리거
•클러스트
•시퀀스
•스냅샷
•스토어드 프로시저
•시노늄
•뷰
•프로파일/롤
•audit
•정의된 사용자의 테이블
•테이블의 데이터
•사용자의 권한
•사용자의 인덱스
•테이블의 제약조건
•테이블의 트리거
•클러스트
•데이터베이스 링크
•스냅샷
•스토어드 프로시저
•시노늄
•뷰
•정의된 사용자의 테이블
•테이블의 데이터
•사용자의 권한
•사용자의 인덱스
•테이블의 제약조건
•트리거

전체백업과 부분백업
전체백업
모든 데이터 파일과 컨트롤 파일을 백업하는 방식으로, 가장 보편적인 방법이다. 전체 백업은 데이터베이스 모드에 관계없이 가능하지만,
아카이브 모드인 경우와 노아카이브 모드인 경우 전체 백업을 수행했을 때의 차이가 있다.
데이터베이스 전체에 대한 백업은 다음과 같은 방법으로 가능하다.
• 컨트롤 파일 뿐만 아니라 모든 데이터 파일을 복사하는 운영체제가 제공하는 유틸리티
• RMAN BACKUP DATABASE 명령어
• 데이터베이스 내의 각 데이터 파일에 대해 수행되는 RMAN COPY DATAFILE 명령어와
	 컨트롤 파일에 대해 실행되는 COPY CURRENT CONTROLFILE 명령어

부분백업
전체 데이터베이스를 백업하는 대신 테이블스페이스나 컨트롤 파일과 같이 일부분만을 백업하는 방법이다. 부분 백업은 아카이브 모드에서만 가능하므로, 현재 DB가 아카이브 모드인지 확인해야 한다. 부분 백업에는 테이블스페이스 백업, 데이터 파일 백업, 컨트롤 파일 백업, 아카이브 리두 로그 파일 백업이 있다.
데이터 파일의 백업 상태는
v$backup 뷰로 확인이 가능하다.
	SQL> select log_mode from v$database; ☜ 현제 DB의 아카이브 모드 확인
	SQL> alter database archivelog;  ☜ DB의 모드를 아카이브모드로 전환

테이블스페이스 백업/ 데이터 파일 백업

1) 온라인 테이블스페이스 백업하기
테이블스페이스 백업은 테이블스페이스를 구성하는 데이터 파일을 백업하는 것으로, DB가 아카이브모드라면, 온라인 또는 오프라인 상태에서도 가능하다.

SQL> select tablespace_name, file_name from dba_data_files;
 
TABLESPACE_NAME FILE_NAME
--------------- ------------------------------------------------------------
USERS           /export/home/oracle/app/oracle/oradata/orcl/users01.dbf
SYSAUX          /export/home/oracle/app/oracle/oradata/orcl/sysaux01.dbf
UNDOTBS1        /export/home/oracle/app/oracle/oradata/orcl/undotbs01.dbf
SYSTEM          /export/home/oracle/app/oracle/oradata/orcl/system01.dbf
 
SQL> alter tablespace users begin backup; 
☜ users 테이블스페이스에 대해 백업 시작을 알림
Tablespace altered. SQL> ! $ cp /export/home/oracle/app/oracle/oradata/orcl/users01.dbf bkup/. $ exit SQL> alter tablespace users end backup;
☜ users 테이블스페이스에 대해 백업 종료를 알림
Tablespace altered. SQL> select * from
v$backup; FILE# STATUS CHANGE# TIME ---------- ------------------ ---------- ------------ 1 NOT ACTIVE 0 2 NOT ACTIVE 0 3 NOT ACTIVE 0 4 NOT ACTIVE 2858563 04-JAN-06 SQL>
2) 오프라인 테이블스페이스 백업하기
사용중인 테이블스페이스를 오프라인시켜 백업할 수 있다. 그러나 SYSTEM 테이블스페이스와 현재 사용중인 롤백 세그먼트는 오프라인 시킬 수 없다는 것을 의미한다.
SQL> select tablespace_name, file_name from dba_data_files;
 
TABLESPACE_NAME FILE_NAME
--------------- ------------------------------------------------------------
USERS           /export/home/oracle/app/oracle/oradata/orcl/users01.dbf
SYSAUX          /export/home/oracle/app/oracle/oradata/orcl/sysaux01.dbf
UNDOTBS1        /export/home/oracle/app/oracle/oradata/orcl/undotbs01.dbf
SYSTEM          /export/home/oracle/app/oracle/oradata/orcl/system01.dbf
 
SQL> alter tablespace users offline normal;
 
Tablespace altered.
 
SQL> !
$ cp /export/home/oracle/app/oracle/oradata/orcl/users01.dbf bkup/.
$ exit
 
SQL> alter tablespace users online;
 
Tablespace altered.
 
SQL>

컨트롤 파일 백업
오라클 DB를 설치하면 CREATE DATABASE 문에 의해 기본적으로 생성되는 파일들이 있는데, 리두 로그 파일, SYSTEM 데이터 파일, UNDO 데이터 파일, TEMP 데이터 파일등의 경로와 파일명을 설정한다. 정상적으로 실행되면 컨트롤 파일이 생성된다
자동으로 생성된는 컨트롤 파일에는 CREATE DATABASE 문에 의해 정의된 파일의 모든 정보가 기록된다. DB가 MOUNT 단계가 되면 컨트롤 파일의 정보를 읽어 DB의 모든 상태를 점검한다. 이때 컨트롤 파일을 읽을 수 없으면 DB를 사용할 수 없다. 따라서 컨트롤 파일을 잘 관리해야 한다. DB를 설치하면 기본적으로 3개의 컨트롤 파일이 생성되는데 첫 번째 파일이 원본 컨트롤 파일고, 나머지 두 개의 파일은 원본에 대한 미러링(mirroring) 파일로 원본 컨트롤 파일에 문제가 발생하면 미러링 파일로 복구할 수 있다.
현재 DB에서 사용하고 있는 컨트롤 파일의 위치와 이름은
v$controlfile 뷰를 참조하여 확인할 수 있다.
SQL> select * from v$controlfile;
 
STATUS  NAME                                                         IS_
------- ------------------------------------------------------------ ---
        /export/home/oracle/app/oracle/oradata/orcl/control01.ctl    NO
        /export/home/oracle/app/oracle/oradata/orcl/control02.ctl    NO
        /export/home/oracle/app/oracle/oradata/orcl/control03.ctl    NO
 
SQL> 
컨트롤 파일을 백업하는 세가지 방법
방법1)
컨트롤 파일 백업
SQL> shutdown
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> !
$ cp /export/home/oracle/app/oracle/oradata/orcl/*.ctl bkup/.
$
$ ls dbs/*.ora
dbs/init.ora        dbs/initdw.ora      dbs/spfileorcl.ora
initDB명.ore 파일에 복사된 컨트롤 파일을 추가 한다.
	...
	CONTROL_FILES=(control01.ctl,..,control04.ctl)
	...
$ exit
 
SQL> startup
ORACLE instance started.
 
Total System Global Area  289406976 bytes
Fixed Size                   778796 bytes
Variable Size              99360212 bytes
Database Buffers          188743680 bytes
Redo Buffers                 524288 bytes
Database mounted.
Database opened.
SQL>
방법2) spfile을 사용한 컨트롤 파일 백업
SQL> ALTER SYSTEM SET control_files=
   '/export/home/oracle/app/oracle/oradata/orcl/control01.ctl',
   '/export/home/oracle/app/oracle/oradata/orcl/control02.ctl',
   '/export/home/oracle/app/oracle/oradata/orcl/control03.ctl', SCOPE=SPFILE;
SQL> SHUTDOWN
SQL> !
# cp control01.ctl control04.ctl
# exit
SQL> STARTUP
방법3) ALTER DATABASE 명령을 사용한 방법

	ALTER DATABASE BACKUP CONTROLFILE TO TRACE;
alter database 명령을 실행하여 컨트롤 파일을 백업하면 생성된 복사본은 바이너리 파일로 생성되는 대신 텍스트 형식으로 백업 파일을 저장한다. 만일 원본 컨트롤 파일과 복사본 컨트롤 파일 모두를 사용할 수 없다면, 이 파일을 사용하여 모든 컨트롤 파일을 재생성할 수 있다.
백업된 파일은 initDB명.ora 파일의 user_dump_dest 매개변수가 지정하는 경로에 *.trc 확장자로 생성된다.
이렇게 백업된 *.trc 콘트럴 파일로부터
컨트롤 파일을 다시 복구하는 방법은 이곳에 있음
다음과 같은 경우 alter database 명령문을 실행하여 컨트롤 파일에 대한 trc 파일을 생성하는 것이 좋다.
• ALTER DATABASE 명령어에 의해 db의 구조가 변경될 때
• CREATE TABLESACE 명령어에 의해 테이블스페이스가 추가 되거나 변경될 때
• DROP TABLESPACE 명령어를 사용하여 테이블스페이스가 삭제될 때
SQL> alter database backup controlfile to trace;
 
Database altered.
 
SQL> show parameter user_dump_dest;
 
NAME              TYPE        VALUE
----------------- ----------- ------------------------------------------------
user_dump_dest    string      /export/home/oracle/app/oracle/admin/orcl/udump
SQL>
Posted by 1010
02.Oracle/DataBase2008. 11. 21. 17:43
반응형

① 오라클 데이터베이스 시작하기
Database 의 시작과 종료는 반드시!! Oracle 계정으로 수행해야 합니다.
[root@ora9 /]# su oracle
[oracle@ora9 /]$ source $HOME/.bash_profile
oracle 계정으로 로그인 후 oracle 계정의 환경설정을 reload 합니다.
(처음부터 오라클 계정으로 로그인 하였다면 이 과정은 불필요합니다.)

[oracle@ora9 /]$ sqlplus /nolog
SQL>connect / as sysdba
SQL> startup
오라클 데이터베이스를 시작하고 종료하기 위해서는 OS에서의 인증과 암호 파일을 생성하는
툴인 orapwd를 통해야 한다. 그리고 sys 스키마의 권한인 sysdba 권한과 public 스키마
권한인 sysoper 권한의 특별한 시스템 권한을 소유한 사용자이어야 한다.

· sysdba : 데이터베이스 시작/종료, 아카이브 및 복구 작업, ALTER DATABASE OPEN,
MOUNT, BACKUP, CHANGE, CHARACHER SET 절의 명령어 실행
· sysoper : 데이터베이스 시작/종료, 아카이브 및 복구 작업, ALTER DATABASE OPEN,
MOUNT, BACKUP 절의 명령어 실행

SQL> SELECT * FROM v$version;
현재의 오라클 데이터베이스 인스턴스의 버전 확인하기

② 오라클 데이터베이스 종료하기
[oracle@ora9 /]$ sqlplus /nolog
SQL> connect / as sysdba
SQL> shutdown immediate

③ oratab 파일 편집하기
오라클 데이터베이스를 /etc/rc.d/ini.d에 스크립트로 설정하여 자동으로 실행하게 하여봅시다.
[root@ora9 /]# vi /etc/oratab
다음 부분을 수정 ([SID], [ORACLE_HOME], [자동실행/종료 플래그]로 구성되어 있습니다.)
ora9:/opt/oracle/product/9.2.0.1.0:N e ora9:/opt/oracle/product/9.2.0.1.0:Y

④ Parameter 파일 링크 (xxxxxxxxxxxx은 일정치 않은 숫자 입니다.)
[root @ora9 /]# cp /opt/oracle/admin/ora9/pfile/initora9.ora.xxxxxxxxxxxx \
/opt/oracle/product/9.2.0.1.0/dbs/initora9.ora

⑤ /etc/rc.d/init.d 에 등록하기
oracle9i 스크립트를 /etc/rc.d/init.d 에 복사합니다.
[root@ora9 /]# cp /usr/local/src/oracle9i /etc/rc.d/ini.t/
oracle9i에 실행권한을 부여합니다.
[root@ora9 /]# chmod 755 /etc/rc.d/init.d/oracle9i
실행수준 2,3,4에 해당하는 데이테베이스를 실행시키기 위하여 심볼릭 링크를 한다.
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc2.d/S99oracle9i
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc3.d/S99oracle9i
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc4.d/S99oracle9i
시스템을 재부팅하거나, 재실행 할 때에 데이터베이스를 중지하기 위하여 심볼릭 링크를 한다.
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc0.d/K01oracle9i
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc6.d/K01oracle9i
Oracle Database를 재시작 시켜본 후, LISTENER 데몬이 띄워져 잇는지 확인합니다.
[root@ora9 /]# /etc/rc.d/init.d/oracle9i restart
[root@ora9 /]# ps ax | grep LISTENER



리스너 간략정리



오라클 클라이언트에서 서버에 접속하기 위해서는 오라클 서버에 리스너(LISTENER)가 실행되어 있어야 됩니다.


◈ 리스너(Listener)란?

- 오라클 리스너는 네트워크를 이용하여 클라이언트에서 오라클 서버로 연결하기 위한
  오라클 네트워크 관리자 입니다.

- 오라클에서 네트워크를 통한 연결은 모두 리스너가 담당하며 리스너와 연결되기
  위해서는 클라이언트에 오라클 NET8이 설치되어 있고 이를 통해 오라클 서비스명이라는 것을
  만들어 접속해야 합니다.

- 오라클 서버에서 리스너를 시작시켜줘야 클라이언트들이 접속할 수 있습니다.

- lsnrctl명령어로 리스너를 관리 할 수 있습니다.


-- 리스너 시작하기
C:\>lsnrctl

LSNRCTL for 32-bit Windows: Version 8.1.6.0.0 - Production on 01-MAY-2002 23:34:57

(c) Copyright 1998, 1999, Oracle Corporation. All rights reserved.

LSNRCTL에 오신 것을 환영합니다. 정보를 보시려면 "help" 를 입력하십시오.

-- start를 입력하면 리스너가 시작됩니다.
LSNRCTL>start



-- 리스너 관련 명령어들
시작시 : LSNRCTL> start

멈출 때 : LSNRCTL> stop

재시작시 : LSNRCTL> reload

서비스 상태보기 : LSNRCTL> status

명령어 보기 : LSNRCTL> help




오라클 서버/클라이언트간의 네트워크 설정을 하기위해서는 서버에서는 listener.ora파일을 그리고
클라이언트에서는 tnsnames.ora파일을 설정해 주어야 합니다.


◈ listener.ora

- 오라클 서버에서 클라이언트의 요청을 듣고, 클라이언트와의 통신을 환경을 설정하는 파일입니다.

- 오라클 서버에 존재하며, 오라클 클라이언트에서 서버로 접속할 때 필요한 프로토콜 및 포트정보등을 설정하는 파일 입니다.

- 프로토콜은 주로 TCP/IP가 많이 사용됩니다.


◈ tnsnames.ora

- 오라클 Client측에서 오라클 서버로 접속할때 필요한 프로토콜 및 포트번호, 서버주소, 인스턴스등을 설정해주는 파일로서 클라이언트에 위치 합니다.


* 참고
- listener.ora와 tnsnames.ora파일의 위치는 ORACLE_HOME/network/ADMIN/에 존재 합니다.
- linstener.ora와 tnsnames.ora는 둘다 오라클 설치시 Net8 configuration 작업을 해주면 생성이 됩니다.


[출처:SMBW]


Posted by 1010
02.Oracle/DataBase2008. 11. 17. 14:35
반응형

ora-00000     성공적인 정상 종료입니다.
ora-00001     유일성 제약조건(%s.%s)에 위배됩니다.
ora-00017     트레이스 이벤트 설정이 세션에 요구되었습니다.
ora-00018     최대 세션 수를 초과했습니다.
ora-00019     최대 세션 라이선스 수를 초과했습니다.
ora-00020     최대 프로세스 수(%s)를 초과했습니다.
ora-00021     세션이 다른 프로세스에 첨부되어 있음; 세션을 변경할 수 없습니다.
ora-00022     부적절한 세션 번호; 액세스가 거절되었습니다.
ora-00023     세션이 프로세스 고유의 메모리를 참조함; 세션을 분리할 수 없습니다.
ora-00024     단일 프로세스 모드에서는 하나 이상의 프로세스가 로그인할 수 없습니다.
ora-00025     %s에 메모리를 할당하는데 실패했습니다.
ora-00026     누락 혹은 부적합한 세션 번호
ora-00027     현 세션을 제거할 수 없습니다.
ora-00028     세션이 제거되었습니다.
ora-00029     사용자 세션이 아닙니다.
ora-00030     사용자 세션 id가 존재하지 않습니다.
ora-00031     세션이 중단될 것입니다.
ora-00032     부적합한 세션 migration password
ora-00033     현세션이 migration password를 갖고있지 않습니다.
ora-00034     pl/sql 세션에서 %s를 할 수 없습니다.
ora-00035     license_max_users가 현재의 사용자 수보다 적을 수 없습니다.
ora-00050     엔큐를 하는 동안 o/s 오류가 발생했음. o/s 오류를 확인하십시오
ora-00051     자원 대기 중 시간 초과입니다.
ora-00052     최대 엔큐 자원 수(%s)를 초과했습니다.
ora-00053     최대 엔큐 수를 초과했습니다.
ora-00054     자원이 사용중이고, nowait가 지정되어 있습니다.
ora-00055     최대 dml 잠금 수를 초과했습니다.
ora-00056     개체 %s.%s에 대한 ddl 잠금이 비호환 모드로 되어 있습니다.
ora-00057     최대 임시 테이블 잠금 수가 초과했습니다.
ora-00058     이 데이타베이스를 마운트하기 위해서 db_block_size가 %s이어야 함(%s 아님).
ora-00059     최대 db_files 수를 초과했습니다.
ora-00060     자원 대기중 데드록이 검출되었습니다.
ora-00061     다른 하나의 인스턴스가 다른 dml_locks을 설정하고 있습니다.
ora-00062     dml 전(full) 테이블 잠금을 취할 수 없습니다. dml_locks은 0 입니다.
ora-00063     최대 log_files 수를 초과했습니다.
ora-00064     현 o/s (%s,%s)에 할당하기에는 개체가 너무 큽니다.
ora-00065     fixed_date의 초기화에 실패했습니다.
ora-00066     log_files는 %s이지만 호환성을 위해 %s 이어야합니다.
ora-00067     값 %s은 파라미터 %s에 대해 부적당하며, 최소한 %s 이어야 합니다.
ora-00068     값 %s은 파라미터 %s에 대해 부적당하며, %s와 %s 사이의 값이어야 합니다.
ora-00069     잠글 수 없습니다 -- %s에 대해 테이블 잠금을 할 수 없습니다.
ora-00070     명령어 %s 은 적당하지 않습니다.
ora-00071     프로세스 번호은 1 과 %s 사이어야 합니다.
ora-00072     프로세스 %s 은 활동적인 것이 아닙니다.
ora-00073     명령어 %s은 %s 와 %s 인수를 가지고 옵니다.
ora-00074     지정된 프로세스가 없습니다.
ora-00075     프로세스 %s 은 이 인스턴스에서 찾을 수 없습니다.
ora-00076     덤프 %s 을 찾을 수 없습니다.
ora-00077     덤프 %s 은 적당하지 않습니다.
ora-00078     이 이름으로 변수를 덤프 할 수 없습니다.
ora-00079     변수 %s 가 없습니다.
ora-00080     레벨 %s 로 지정된 글로벌 영역이 부적당합니다.
ora-00081     주소 범위 [%s, %s)은 읽기가능한 것이 아닙니다.
ora-00082     %s의 메모리 크기는 적당한 [1], [2], [4]%s%s%s%s%s의 설정으로 되어 있지 않습니다.
ora-00083     경고: 맵된 sga가 손상한것 같습니다.
ora-00084     글로벌 영역이 pga, sga, 또는 uga 이어야만 합니다.
ora-00085     현재 호출이 존재하지 않습니다.
ora-00086     사용자 호출이 존재하지 않습니다.
ora-00097     oracle sql 기능에서 사용하고 있는것이 sql92 %s 레벨서 존재하고 있지 않습니다.
ora-00100     데이터가 없습니다.
ora-00101     시스템 파라미터 mts_dispatchers에 대한 사용 문법이 부적합합니다.
ora-00102     %s 네트워크 프로토콜이 디스패쳐에 의해 사용될 수 없습니다.
ora-00103     부적합한 네트워크 프로토콜; 디스패쳐에 의해 사용되도록 예약되었음
ora-00104     데드록이 검출되었음; 모든 공유서버가 자원을 기다리고 있습니다.
ora-00105     디스패칭 기법이 %s 네트워크 프로토콜을 지원하도록 되어있지 않습니다.
ora-00106     디스패쳐에 연결되었을때는 데이타베이스를 기동/중지시킬 수 없습니다.
ora-00107     oracle의 리스너 프로세스에 연결하지 못했습니다.
ora-00108     비동기 연결이 가능하도록 디스패쳐를 설정하지 못했습니다.
ora-00111     최대 서버수는 %s입니다; %s개의 서버 추가중
ora-00112     경고: %s (지정 최대치) 디스패쳐만으로 생성되었습니다.
ora-00113     프로토콜명 %s가 너무 깁니다.
ora-00114     시스템 파라미터 mts_service에 대한 값이 없습니다.
ora-00115     연결이 거절됨; 디스패쳐 연결 레이블이 full 상태입니다.
ora-00116     mts_service명이 너무 깁니다.
ora-00117     시스템 파라미터 mts_servers의 범위를 벗어납니다.
ora-00118     시스템 파라미터 mts_dispatchers의 범위를 벗어납니다.
ora-00119     mts_listener_address 시스템 파라미터에 지정이 부적합합니다.
ora-00120     디스패칭 기법이 사용불가 혹은 설치되어있지 않습니다.
ora-00121     mts_dispatchers를 제외하고 mts_servers가 지정되었습니다.
ora-00122     네트워크 구성을 초기화할 수 없습니다.
ora-00123     비작업중인 공유 서버를 종료합니다.
ora-00124     mts_dispatchers가 mts_max_servers 없이 지정되었습니다.
ora-00150     중복된 트랜잭션 id
ora-00151     부적합한 트랜잭션 id
ora-00152     현 세션이 요구된 세션과 일치하지 않습니다.
ora-00200     제어 화일 %s을 생성할 수 없습니다.
ora-00201     제어 화일 버전 %s은 oracle 버전 %s과 호환되지 않습니다.
ora-00202     제어화일: %s
ora-00203     잘못된 제어화일을 사용하였습니다.
ora-00204     제어 화일 %s (블록 %s, 블록 수 %s) 읽기 오류입니다.
ora-00205     제어 화일 %s 식별 오류입니다.
ora-00206     제어 화일 %s (블록 %s, 블록 수 %s) 쓰기 오류입니다.
ora-00207     제어화일이 현재 사용중인 데이타베이스용이 아닙니다.
ora-00208     제어 화일명이 최대수 %s 를 초과했습니다.
ora-00209     블록 크기 %s 가 최대 %s 바이트를 초과했습니다.
ora-00210     제어 화일 %s 를 열 수 없습니다.
ora-00211     제어 화일 %s 가 앞의 제어 화일과 일치하지 않습니다.
ora-00212     블록 크기 %s가 최소한 필요한 크기 %s 바이트 미만입니다.
ora-00213     제어 화일 %s 재사용 불가; 구 화일 크기 %s, %s가 필요합니다.
ora-00214     제어 화일 %s의 버전 %s는 화일 %s 버전 %s와 일치하지 않습니다.
ora-00215     적어도 한 개의 제어 화일이 필요합니다.
ora-00216     제어 화일 %s 에 대한 물리 블록 크기를 확정할 수 없습니다.
ora-00217     제어 화일 %s의 물리적 블록 크기 %s가 %s와 일치하지 않습니다.
ora-00218     제어 화일 %s는 블록 크기를 %s로 작성되었지만 현재는 %s 입니다.
ora-00219     필요한 제어 화일 크기 %s 가 최대치 %s 보다 큽니다.
ora-00220     제어화일 %s가 첫 인스턴스에 의해 사용한 것과 일치하지 않습니다.
ora-00221     제어화일에의 쓰기오류
ora-00222     디스패쳐로 제어화일을 조회할 수 없습니다.
ora-00223     변환 데이타화일이 부적합하거나 틀린 버전입니다.
ora-00224     명시된 화일이 제어 화일이 아닙니다.
ora-00225     기대된 크기 %s 은( 제어화일 %s 관한) 실제 크기 %s 와 다릅니다.
ora-00250     아카이버가 작동되지 않았습니다.
ora-00251     사용되지 않는 오류
ora-00252     로그 %s (쓰레드 %s의)는 비었습니다. 아카이브할 수 없습니다.
ora-00253     제한치 %s가 길이 %s로 초과되었습니다 (아카이브 스트링 %s의)
ora-00254     아카이브 제어 스트링 %s 오류입니다.
ora-00255     로그 %s(쓰레드 %s, 시퀀스 번호 %s)의 아카이브 오류
ora-00256     아카이브 텍스트 스트링 %s의 변환시 오류가 발생했습니다.
ora-00257     아카이버 오류. 해제되기 전에는 내부 연결만 가능
ora-00258     noarchivelog 모드에서의 수동 아카이브는 로그를 지정해야합니다.
ora-00259     로그 %s(개방 쓰레드 %s의)가 현재 로그이므로 아카이브할 수 없습니다.
ora-00260     온라인 로그 시퀀스 %s(쓰레드 %s의)를 발견할 수 없습니다.
ora-00261     로그 %s(쓰레드 %s의)가 아카이브중이거나 수정중입니다.
ora-00262     현재 로그 %s(닫힌 쓰레드 %s의)를 스위치할 수 없습니다.
ora-00263     쓰레드 %s를 위해 아카이빙이 필요한 로그가 없습니다.
ora-00264     복구가 필요하지 않습니다.
ora-00265     인스턴스 복구가 요구됩니다. archivelog모드를 지정할 수 없습니다.
ora-00266     아카이브된 로그 화일의 이름을 필요로 합니다.
ora-00267     아카이브된 로그 화일의 이름을 필요로 하지 않습니다.
ora-00268     지정된 로그화일이 존재하지 않습니다 %s
ora-00269     지정된 로그화일은 쓰레드 %s의 (%s가 아닌) 부분임
ora-00270     아카이브 로그 생성시 오류
ora-00271     아카이브를 필요로 하는 로그가 없습니다.
ora-00272     아카이브 로그 기록시 오류
ora-00273     로그되지 않은 직접 로드 데이타의 매체 복구
ora-00274     부적절한 복구 옵션 %s
ora-00275     매체 복구가 이미 시작되었습니다.
ora-00276     키워드 change가 지정되었으나 변환 번호가 주어지지 않았습니다.
ora-00277     until 복구 플래그 %s에 부적절한 옵션
ora-00278     현 복구를 위해 로그화일 %s는 더이상 필요하지 않습니다.
ora-00279     변환 %s가 (%s에서 생성된) 쓰레드 %s에 필요합니다.
ora-00280     변환 %s(쓰레드 %s를 위한)가 시퀀스번호 %s에 있습니다.
ora-00281     매체 복구는 디스패쳐를 사용하여 수행되지 않습니다.
ora-00282     upi %s 호출이 지원되지 않으니, alter database recover를 사용하십시요
ora-00283     복구 세션이 오류로 인하여 취소되었습니다.
ora-00284     복구 세션이 진행중입니다.
ora-00285     time 키워드가 지정되었으나 시간이 주어지지 않았습니다.
ora-00286     이용가능한 멤버가 없거나, 적합한 데이타를 포함하고 있지 않습니다.
ora-00287     지정된 변환 번호 %s가 쓰레드 %s에 없습니다.
ora-00288     복구를 계속하려면 alter database recover continue를 입력하십시요
ora-00289     제안 : %s
ora-00290     로그화일을 아카이브 하려고 할때, o/s 오류가 발생했습니다.
ora-00291     parallel 옵션에 숫자값이 필요로합니다.
ora-00292     병렬 복구 기능이 설치되지 않았습니다.
ora-00293     제어 화일과 리두로그가 동기화 상태에서 벗어나 있습니다.
ora-00300     부적합한 리두 로그 블록 크기 %s가 지정됨 - 한계 %s 초과
ora-00301     로그 화일 %s를 추가 작성할 수 없습니다.
ora-00302     로그의 최대수 %s 를 초과했습니다.
ora-00304     요구된 인스턴스 번호는 사용중입니다.
ora-00305     로그 %s(쓰레드 %s의)는 일관되지 않습니다. 이것은 다른 데이타베이스에 속합니다.
ora-00306     이 데이타베이스에서는 %s 인스턴스가 한계입니다.
ora-00307     요구된 인스턴스 번호가 범위를 벗어납니다(최대치는 %s)
ora-00308     아카이브된 로그 %s를 열 수 없습니다.
ora-00309     로그가 잘못된 데이타베이스에 속해 있습니다.
ora-00310     아카이브된 로그는 시퀀스 %s를 포함하고 있습니다 시퀀스 %s가 필요합니다.
ora-00311     아카이브 로그로부터 헤더 정보를 읽을 수 없습니다.
ora-00312     온라인 로그 %s 쓰레드 %s: %s
ora-00313     로그 그룹 %s (쓰레드 %s의)의 멤버를 여는데 실패했습니다.
ora-00314     로그 %s(쓰레드 %s의, 시퀀스번호가 %s일)는 %s와 일치하지 않습니다.
ora-00315     로그 %s (쓰레드 %s의) 헤더의 쓰레드 번호 %s가 틀립니다.
ora-00316     로그 %s (쓰레드 %s의) 헤더내의 유형 %s는 로그화일이 아닙니다.
ora-00317     헤더에 있는 화일형 %s가 로그화일이 아닙니다.
ora-00318     로그 %s (쓰레드 %s의, 화일 크기가 %s인)가 %s와 맞지 않습니다.
ora-00319     로그 %s(쓰레드 %s의)가 틀린 로그 재설정 상태를 가지고 있습니다.
ora-00320     로그 %s(쓰레드 %s의)로부터 화일 헤더를 읽을 수 없습니다.
ora-00321     로그 %s(쓰레드 %s의)에서 로그화일 헤더를 수정할 수 없습니다.
ora-00322     로그 %s(쓰레드 %s의)는 현시점의 것이 아닙니다.
ora-00323     쓰레드 %s의 현 로그는 사용불가하며, 나머지 전부도 아카이브하여야 합니다.
ora-00324     로그 화일 %s의 변환명 %s가 너무 깁니다, 문자수 %s가 %s를 초과했습니다.
ora-00325     쓰레드 %s으로 아카이브된 로그가 헤더내에 틀린 쓰레드 번호 %s를 가지고 있습니다.
ora-00326     변환 %s에서 시작된 아카이브 로그, 이전의 변환 %s를 필요로 합니다.
ora-00327     로그 %s(쓰레드 %s의), 물리적인 크기 %s가 필요한 %s보다 작습니다.
ora-00328     변환 %s에서 끝난 아카이브 로그, 이후의 변환 %s를 필요로 합니다.
ora-00329     변환 %s에서 시작된 아카이브 로그, 변환 %s를 필요로 합니다.
ora-00330     변환 %s에서 끝난 아카이브 로그, 변환 %s를 필요로 합니다.
ora-00331     로그 버전 %s가 oracle 버전 %s와 호환성이 없습니다.
ora-00332     아카이브된 로그가 너무 작음 - 완전하게 아카이브되지 않았습니다.
ora-00333     재실행 로그 읽기 오류(블록 %s 카운트 %s)
ora-00334     아카이브된 로그: %s
ora-00335     온라인 로그 %s: 이 번호의 로그가 존재하지 않습니다.
ora-00336     로그 화일의 크기 %s가 최소 블록 수 %s 보다 작습니다.
ora-00337     로그 화일 %s가 존재하지 않고 크기가 지정되어 있지 않습니다.
ora-00338     로그 %s(쓰레드 %s의)가 제어화일보다 최근의 것입니다.
ora-00339     아카이브 로그가 redo 로그를 포함하고 있지 않습니다.
ora-00340     온라인 로그 %s(쓰레드 %s의) 처리시 io 오류입니다.
ora-00341     로그 %s(쓰레드 %s의)에 대한 헤더내에 로그 번호 %s가 틀립니다.
ora-00342     아카이브된 로그가 마지막 resetlogs 전에 생성되었습니다.
ora-00343     너무 많은 오류 발생, 로그 멤버가 클로즈됐습니다.
ora-00344     온라인 로그 %s를 재생성할 수 없습니다.
ora-00345     redo 로그 쓰기(write) 오류, 블록 %s 카운트 %s
ora-00346     로그 멤버가 stale로 표시되었습니다.
ora-00347     로그 %s(쓰레드 %s의)의 예상 블록크기 %s는 %s와 일치하지 않습니다.
ora-00348     단일 프로세스 redo 실패입니다 인스턴스를 중지해야 합니다.
ora-00349     %s 의 블록 크기 확보 실패입니다.
ora-00350     로그 %s(쓰레드 %s의)를 아카이브해야 합니다.
ora-00351     지정된 시간으로의 복구가 불가능합니다.
ora-00352     쓰레드 %s에 대한 모든 로그가 아카이브되어야 함 - 가용화할 수 없습니다.
ora-00353     블록 %s 변경 %s 시간 %s 부근에서 로그가 깨졌습니다.
ora-00354     redo 로그의 블록헤더가 깨짐
ora-00355     변환 번호가 잘못됨
ora-00356     변환 설명내에 일치하지 않는 길이
ora-00357     로그화일에 너무 많은 수의 멤버가 지정됨 (최대치는 %s)
ora-00358     너무 많은 화일 멤버가 지정됨 (최대치는 %s)
ora-00359     로그화일 그룹 %s가 존재하지 않습니다.
ora-00360     로그화일 멤버가 아닙니다 %s
ora-00361     마지막 로그 멤버 %s는 그룹 %s를 옮길수 없습니다.
ora-00362     그룹 %s내에 정당한 로그화일을 형성하기 위해 멤버를 필요로 합니다.
ora-00363     로그가 아카이브 버전이 아닙니다.
ora-00364     새로운 로그 멤버에 헤더를 기록할 수 없습니다.
ora-00365     지정한 로그가 다음 로그가 아닙니다.
ora-00366     로그 %s, 쓰레드 %s의, 화일 헤더에 체크섬 오류가 있습니다.
ora-00367     로그 화일 헤더에 체크섬 오류가 있습니다.
ora-00368     리두 로그 블록에 체크섬 오류가 있습니다.
ora-00369     쓰레드 %s의 현재 로그는 사용불가이며 다른 로그가 지워지고 있습니다.
ora-00370     kcbchange 작업수행시 데드록의 가능성이 있습니다.
ora-00371     빈 버퍼의 사용이 불가합니다.
ora-00372     화일 %s는 지금 수정될 수 없습니다.
ora-00373     온라인 로그 버전 %s가 oracle 버전 %s와 호환되지 않습니다.
ora-00374     지정된 파라미터 db_block_size = %s 가 부적절함 - 가능한 범위[%s..%s]
ora-00375     디폴트 db_block_size의 값을 얻을수 없습니다.
ora-00376     현재 화일 %s를 읽을 수 없습니다.
ora-00390     로그 %s(쓰레드 %s의)는 지워질것이므로 현재 로그가 될 수 없습니다.
ora-00391     전체 쓰레드는 동시에 새로운 로그 포맷으로 전환해야 합니다.
ora-00392     로그 %s(쓰레드 %s의)는 지워질것이므로 작업이 허용되지 않습니다.
ora-00393     오프라인 데이타화일 복구에 로그 %s(쓰레드 %s의)가 필요합니다.
ora-00400     release 값 %s는 파라미터 %s에 부적절합니다.
ora-00401     이번 release에서 지원되지 않은 파라미터 %s에 대한 값입니다.
ora-00402     %s release에 변경된 데이타베이스는 %s release에 사용될 수 없습니다.
ora-00403     %s (%s) 는 다른 인스턴스(%s)와 같지 않습니다.
ora-00404     변환 데이타 화일이 없습니다 %s
ora-00405     호환 가능한 유형 %s
ora-00406     compatible 파라미터는 %s 이상이어야 합니다.
ora-00407     릴리즈 %s.%s 에서 %s.%s로 향상이 허용되지 않습니다.
ora-00408     파라미터 %s는 true로 설정되었습니다.
ora-00436     oracle이 라이센스되어 있지 않습니다 oracle사에 연락해 주십시오.
ora-00437     oracle의 기능이 라이센스되어 있지 않습니다. oracle사에 연락해 주십시오
ora-00443     백그라운 프로세스 %s가 시작되지 않았습니다.
ora-00444     백그라운드 프로세스 %s 기동중 장애가 발생했습니다.
ora-00445     백그라운드 프로세스 %s가 %s초 후 기동되지 않았습니다.
ora-00446     백그라운드 프로세스가 부적절하게 기동되었습니다.
ora-00447     백그라운드 프로세스에 치명적인 오류가 발생했습니다.
ora-00448     백그라운드 프로세스가 정상 종료했습니다.
ora-00449     백그라운드 프로세스 %s 가 오류 %s 와 함께 종료되었습니다.
ora-00470     lgwr 프로세스가 오류로 종료되었습니다.
ora-00471     dbwr 프로세스가 오류로 종료되었습니다.
ora-00472     pmon 프로세스가 오류로 종료되었습니다.
ora-00473     arch 프로세스가 오류로 종료되었습니다.
ora-00474     smon 프로세스가 오류로 종료되었습니다.
ora-00475     trwr 프로세스가 오류로 종료되었습니다.
ora-00476     reco 프로세스가 오류로 종료되었습니다.
ora-00477     snp* 프로세스가 오류로 종료되었습니다.
ora-00480     lck* 프로세스가 오류로 종료되었습니다.
ora-00483     정지 처리중 프로세스가 오류로 종료되었습니다.
ora-00568     인터럽트 처리기의 최대수를 초과했습니다.
ora-00574     osndnt: $cancel 실패 (break)
ora-00575     osndnt: $qio 실패 (send out-of-band break)
ora-00576     인-밴드 브레이크 프로토콜 오류
ora-00577     아웃-밴드 브레이크 프로토콜 오류
ora-00578     재설정 프로토콜 오류
ora-00579     osndnt: 서버가 잘못된 연결요구를 받았습니다.
ora-00580     프로토콜 버전이 일치하지 않습니다.
ora-00581     osndnt: 문맥 영역을 할당할 수 없습니다.
ora-00582     osndnt: 문맥 영역을 해제할 수 없습니다.
ora-00583     osndnt: $trnlog 실패
ora-00584     연결을 끊을 수 없습니다.
ora-00585     잘못된 유형의 호스트명입니다.
ora-00586     osndnt: lib$asn_wth_mbx 실패
ora-00587     원격 호스트에 연결할 수 없습니다.
ora-00588     호스트로부터의 메시지가 너무 짧습니다.
ora-00589     호스트로부터의 메시지가 잘못된 데이타 길이를 갖습니다.
ora-00590     호스트로부터의 메시지가 잘못된 데이타 유형을 갖습니다.
ora-00591     틀린 바이트 수가 기록되었습니다.
ora-00592     osndnt: $qio 실패 (mailbox queue)
ora-00593     osndnt: $dassgn 실패 (network device)
ora-00594     osndnt: $dassgn 실패 (mailbox)
ora-00595     osndnt: $qio 실패 (receive)
ora-00596     osndnt: $qio 실패 (send)
ora-00597     osndnt: $qio 실패 (mailbox requeue)
ora-00598     osndnt: $qio 실패 (mailbox read)
ora-00600     내부 오류 코드, 인수 : [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s]
ora-00601     크린업 잠금이 충돌했습니다.
ora-00602     내부 프로그래밍 오류입니다 - bug로 등록하세요
ora-00603     oracle 서버 세션이 치명적인 오류로 종료되었습니다.
ora-00604     순환 sql 레벨 %s 에 오류가 발생했습니다.
ora-00606     내부 오류코드
ora-00701     데이타베이스의 기동에 필요한 개체를 변경할 수 없습니다.
ora-00702     부트스트랩 버전 %s가 버전 %s와 일치하지 않습니다.
ora-00703     행 캐쉬 인스턴스 잠금의 최대 수를 초과했습니다.
ora-00704     부트스트랩 프로세스 실패
ora-00816     오류 메세지 해석 오류입니다.
ora-00900     sql 문이 부적합합니다.
ora-00901     create 명령어가 부적합합니다.
ora-00902     데이타유형이 부적합합니다.
ora-00903     테이블명이 부적합합니다.
ora-00904     열명이 부적합합니다.
ora-00905     키워드가 없습니다.
ora-00906     좌괄호가 없습니다.
ora-00907     우괄호가 없습니다.
ora-00908     null 키워드가 없습니다.
ora-00909     인수의 개수가 부적합합니다.
ora-00910     데이타형에 지정된 길이가 너무 깁니다.
ora-00911     문자가 부적합합니다.
ora-00913     값의 수가 너무 많습니다.
ora-00914     add 키워드가 없습니다.
ora-00915     네트워크을 통한 dictionary table 액세스는 허가되지 않습니다.
ora-00917     코머가 누락되었습니다.
ora-00918     열의 정의가 애매합니다.
ora-00919     함수가 부적합합니다.
ora-00920     관계 연산자가 부적합합니다.
ora-00921     sql 명령어가 불완전합니다.
ora-00922     옵션이 부적합하거나 없습니다.
ora-00923     from 키워드가 있어야할 곳에 없습니다.
ora-00924     by 키워드가 없습니다.
ora-00925     into 키워드가 없습니다.
ora-00926     values 키워드가 없습니다.
ora-00927     등호가 없습니다.
ora-00928     select 키워드가 없습니다.
ora-00929     마침표(.)가 없습니다.
ora-00930    
ora-00931     식별자가 없습니다.
ora-00932     데이타 유형이 일치하지 않습니다.
ora-00933     sql 명령어가 올바르게 종료되지 않았습니다.
ora-00934     그룹 함수는 허가되지 않습니다.
ora-00935     그룹 함수의 내포 레벨이 너무 깊습니다.
ora-00936     식이 없습니다.
ora-00937     단일 그룹의 그룹 함수가 아닙니다.
ora-00938     함수의 인수가 충분하지 않습니다.
ora-00939     함수의 인수가 너무 많습니다.
ora-00940     alter 명령어가 부적합합니다.
ora-00941     클러스터 명이 없습니다.
ora-00942      테이블 또는 뷰가 존재하지 않습니다.
ora-00943     클러스터가 존재하지 않습니다.
ora-00944     클러스터 열의 수가 충분하지 않습니다.
ora-00945     지정한 클러스터 열이 존재하지 않습니다.
ora-00946     to 키워드가 없습니다.
ora-00947     값의 수가 충분하지 않습니다.
ora-00948     alter cluster 문은 제공되어 있지 않습니다.
ora-00949     원격 데이타베이스는 참조할 수 없습니다.
ora-00950     drop 옵션이 부적합합니다.
ora-00951     클러스터가 비어 있지 않습니다.
ora-00952     group 키워드가 없습니다.
ora-00953     색인명이 부적합합니다.
ora-00954     identified 키워드가 없습니다.
ora-00955     이미 사용된 개체명입니다.
ora-00956     감사 옵션이 부적합하거나 없습니다.
ora-00957     열명이 중복되었습니다.
ora-00958     check 키워드가 없습니다.
ora-00959     테이블 영역 %s 가 존재하지 않습니다.
ora-00960     선택 리스트에 애매한 열명이 있습니다.
ora-00962     너무 많은 group-by / order-by 식이 있습니다.
ora-00964     from 리스트에 테이블명이 없습니다.
ora-00965    
ora-00966     table 키워드가 없습니다.
ora-00967     where 키워드가 없습니다.
ora-00968     index 키워드가 없습니다.
ora-00969     on 키워드가 없습니다.
ora-00970     with 키워드가 없습니다.
ora-00971     set 키워드가 없습니다.
ora-00972     식별자의 길이가 너무 깁니다.
ora-00973     행수의 추정이 잘못되었습니다.
ora-00974     pctfree 값(백분율)이 부적합합니다.
ora-00975     날짜와 날짜의 가산은 할 수 없습니다.
ora-00976     level, prior, rownum 은 사용 할 수 없습니다.
ora-00977     감사 옵션이 중복되었습니다.
ora-00978     group by 구 없이 그룹 함수가 내포되었습니다.
ora-00979     group by 의 식이 없습니다.
ora-00980     동의어의 해석이 불가능합니다.
ora-00981     테이블 및 시스템 감사 옵션은 함께 지정될 수 없습니다.
ora-00982    
ora-00984     열을 사용할 수 없습니다.
ora-00985     프로그램명이 부적합합니다.
ora-00986     그룹명이 부적합하거나 없습니다.
ora-00987     사용자명이 부적합하거나 없습니다.
ora-00988     암호가 틀립니다.
ora-00989     사용자명에 대한 암호가 너무 많습니다.
ora-00990     권한이 부적합합니다.
ora-00991     mac 권한만이 프로시저에게 권한부여해 줍니다.
ora-00992     revoke 명령어의 형식이 부적합합니다.
ora-00993     grant 키워드가 없습니다.
ora-00994     option 키워드가 없습니다.
ora-00995     동의어의 식별자가 부적합합니다.
ora-00996     연접 연산자는 | 이 아니고 || 입니다.
ora-00997     long 데이타 유형은 사용할 수 없습니다.
ora-00998     이 식은 열의 별명과 함께 지정해야 합니다.
ora-00999     뷰명이 부적합합니다.
ora-01000     최대 열기 커서 수를 초과했습니다.
ora-01001     커서가 부적합합니다.
ora-01002     인출 시퀀스가 틀립니다.
ora-01003     해석된 문이 없습니다.
ora-01004     디폴트 사용자명 사용 불가. 로그온이 허락되지 않습니다.
ora-01005     널 암호가 입력되었습니다 로그온이 허락되지 않습니다.
ora-01006     바인드 변수가 없습니다.
ora-01007     변수가 선택 리스트에 없습니다.
ora-01008     모든 한계변수가 아닙니다.
ora-01009     필수 파라미터가 없습니다.
ora-01010     oci 조작이 부적합합니다.
ora-01011     v6 서버와 교신할때 v7 호환성 모드를 사용할 수 없습니다.
ora-01012     로그온되어 있지 않습니다.
ora-01013     현 조작의 취소가 요구되었습니다.
ora-01014     oracle의 정지 처리가 진행중입니다.
ora-01015     로그온이 순환적으로 호출되었습니다.
ora-01016     이함수는 인출 이후에만 호출될 수 있습니다.
ora-01017     사용자명/암호가 부적합, 로그온할 수 없습니다.
ora-01018     long 데이타 유형의 열이 아닙니다.
ora-01019     사용자쪽의 기억영역을 할당할 수 없습니다.
ora-01020     문맥의 상태가 불명확합니다.
ora-01021     지정한 문맥 크기가 부적합합니다.
ora-01022     이 구성에 데이타베이스 작업이 지원되지 않습니다.
ora-01023     커서 문맥가 없습니다부당한 커서번호)
ora-01024     oci 콜의 데이타 유형은 부적합합니다.
ora-01025     upi 파라미터가 부적합합니다.
ora-01026     바인드 목록에 크기가 2000이상인 다중 버퍼
ora-01027     데이타 정의에서는 바인드 변수를 사용할 수 없습니다.
ora-01028     내부 투 태스크(two task) 오류
ora-01029     내부 투 태스크(two task) 오류
ora-01030     select ... into 변수가 없습니다.
ora-01031     권한이 불충분합니다.
ora-01032     사용자 번호가 존재하지 않습니다.
ora-01033     oracle의 초기화 또는 정지 처리가 진행중입니다.
ora-01034     oracle을 사용할 수 없습니다.
ora-01035     oracle은 restricted session 권한을 갖는 사용자만 사용 가능합니다.
ora-01036     잘못된 변수명/번호
ora-01037     최대 커서 메모리가 초과되었습니다.
ora-01038     데이타베이스 화일 버전 %s에 oracle 버전 %s으로 기록할 수 없습니다.
ora-01039     사용되지 않는 오류
ora-01040     암호에 잘못된 문자가 있습니다 로그온을 할 수 없습니다.
ora-01041     내부오류. hostdef 확장이 존재하지 않습니다.
ora-01042     개방된 커서와 함께 세션을 분리하는 것은 허용되지 않습니다.
ora-01043     사용자쪽의 기억영역 파괴 [%s], [%s], [%s], [%s]
ora-01044     버퍼의 크기 %s (한계가 변수 %s)가 최대의 %s를 초과했습니다.
ora-01045     사용자 %s는 create session 권한을 가지고있지 않음; 로그온이 거절되었습니다.
ora-01046     확장할 문맥 영역을 획득할 수 없습니다.
ora-01047     위에 오류는 스키마=%s, 패키지=%s, 프로시저=%s에서 발생된 것입니다.
ora-01048     주어진 컨텍스트에서 지정된 프로시저를 찾을 수 없습니다.
ora-01049     스트림된 rpc에서 이름으로 바인드한것은 지원되지 않습니다.
ora-01050     문맥 영역을 개방하기 위한 영역을 획득할 수 없습니다.
ora-01051     잘못된 지연 rpc 버퍼 포맷
ora-01053     사용자 기억 영역 주소를 읽을 수 없습니다.
ora-01054     사용자 기억 영역 주소에 기록할 수 없습니다.
ora-01057     내부의 new upi 인터페이스 오류
ora-01058     internal new upi interface error
ora-01059     바인드 또는 실행전에 구문분석이 필요합니다.
ora-01060     배열 바인드 또는 실행이 허용되지 않습니다.
ora-01070     서버용으로 구버전의 오라클을 사용
ora-01071     oracle을 기동하지 않으면 조작 실행이 불가 합니다.
ora-01072     oracle은 기동중이 아닙니다 정지할 수 없습니다.
ora-01073     연결 오류. 콜(call)의 유형을 인식할 수 없습니다.
ora-01074     oracle은 정지되지 않습니다 먼저 로그오프해 주십시오
ora-01075     이미 로그온되어 있습니다.
ora-01076     단일 프로세스에 대한 복수 로그온은 제공되지 않습니다.
ora-01077     백그라운드 프로세스 초기화 오류입니다.
ora-01078     시스템 파라미터 처리 오류입니다.
ora-01079     oracle 데이타베이스가 작성되지 않았음 - 작업이 비정상 종료되었습니다.
ora-01080     oracle 정지중 오류가 발생했습니다.
ora-01081     이미 기동중인 oracle을 기동하려 했습니다.
ora-01082     row_locking = always 기능은 tps 옵션이 없는 oracle에서는 지원되지않습니다.
ora-01083     파라미터 값 %s는 다른 서버들의 값과 불일치합니다.
ora-01084     oci 호출에 부적당한 인수가 있습니다.
ora-01085     %s에 대한 지연 원격 프로시저 호출(rpc)에서 오류 발생
ora-01086     세이브포인트 %s 는 설정되어 있지 않습니다.
ora-01087     현재 oracle에 로그온되어 있습니다 기동할 수 없습니다.
ora-01088     액티브 프로세스가 있기 때문에 oracle을 정지할 수 없습니다.
ora-01089     정지 처리(즉시)중입니다 조작은 허가되지 않습니다.
ora-01090     정지 처리중입니다 연결할 수 없습니다.
ora-01091     기동중에 오류가 발생했습니다.
ora-01092     오라클 인스턴스 종료 분리가 되었습니다.
ora-01093     alter database close 문은 연결된 세션이 없는 경우에만 가능합니다.
ora-01094     alter database close 문이 수행중 입니다 연결은 허용되지 않습니다.
ora-01095     dml 문이 0개의 행을 처리 했습니다.
ora-01096     프로그램 버전 (%s)과 인스턴스 (%s)가 호환성이 없습니다.
ora-01097     트랜잭션 도중에 shutdown할 수 없습니다- 먼저 커밋 혹은 롤백하십시오
ora-01098     long insert중에 프로그램 인터페이스 오류
ora-01099     단일 프로세스 모드로 기동된 데이타베이스는 shares 모드로 마운트할 수 없습니다.
ora-01100     데이타베이스가 이미 마운트 되었습니다.
ora-01101     다른 인스턴스로 부터 생성된 데이타베이스가 현재 마운트 되었습니다.
ora-01102     데이타베이스가 exclusive 모드로 마운트할 수 없습니다.
ora-01103     제어 화일의 데이타베이스명 %s는 %s가 아닙니다.
ora-01104     제어 화일의 수(%s)가 %s 와 일치하지 않습니다.
ora-01105     올리기는 다른 인스턴스에 의해 마운트하는 것과 호환성이 없습니다.
ora-01106     내리기를 하기전에 데이타베이스를 디스마운트 합니다.
ora-01107     매체 복구를 위해 데이타베이스를 마운트해야 합니다.
ora-01108     화일 %s가 매체 복구 중에 있습니다.
ora-01109     데이타베이스가 개방되지 않습니다.
ora-01110     데이타 화일 %s: %s
ora-01111     데이타 화일 %s의 이름을 모릅니다- 올바른 화일로 재명명 하십시오.
ora-01112     매체 복구 처리가 개시되지 않았습니다.
ora-01113     화일 %s가 매체 복구되어야 합니다.
ora-01114     화일 %s의 블록쓰기 io 오류입니다블록 번호 %s).
ora-01115     화일 %s의 블록(블록 번호 %s) 읽기 io 오류입니다.
ora-01116     데이타베이스 화일 %s의 개방 오류입니다.
ora-01117     추가하는 화일 %s 의 블록 크기 %s 는 부적합합니다 제한은 %s 입니다.
ora-01118     데이타베이스 화일을 더 이상 등록할 수 없습니다 제한 %s 를 초과했습니다.
ora-01119     데이타베이스 화일 %s 의 작성 오류입니다.
ora-01120     온라인 데이타베이스 화일 %s은 삭제할 수 없습니다.
ora-01121     데이타 화일 %s를 재명명할 수 없습니다- 화일이 사용중이거나 복구중입니다.
ora-01122     데이타 화일 %s의 검증 체크에 실패 했습니다.
ora-01123     온라인 백업을 개시할 수 없습니다 매체 복구가 사용 불가로 되어 있습니다.
ora-01124     데이타 화일 %s을 복구할 수 없음 - 화일이 사용중이거나 복구중입니다.
ora-01125     매체 복구를 사용불가할 수 없음. 화일 %s 가 온라인 백업으로 설정됨.
ora-01126     데이타베이스는 exclusive로 마운트하고 개방하지 말아야 합니다.
ora-01127     데이타베이스명 %s가 최대 문자수 %s를 초과했습니다.
ora-01128     온라인 백업을 시작할 수 없음 - 화일 %s가 오프라인입니다.
ora-01129     디폴트 또는 임시 테이블 영역이 존재하지 않습니다.
ora-01130     데이타베이스 화일 버전 %s 는 oracle 버전 %s 와 호환되지 않습니다.
ora-01131     db_files 파라미터의 값 %s 가 최대수 %s 를 초과했습니다.
ora-01132     데이타베이스 화일명 %s 의 길이가 최대 문자수 %s 를 초과했습니다.
ora-01133     로그 화일명 %s 의 길이가 최대 문자수 %s 를 초과했습니다.
ora-01134     데이타베이스가 다른 인스턴스에 의해 배타 모드로 마운트했습니다.
ora-01135     dml/질의로 액세스된 화일 %s 는 오프 라인입니다.
ora-01136     화일 %s의 명시된 크기(%s 블록)가 원래 크기 %s 블록보다 작습니다.
ora-01137     데이타 화일 %s가 오프라인으로 되고 있는 중입니다.
ora-01138     데이타베이스가 이 인스턴스로 열거나 다른 인스턴스에 대해 닫아야 합니다.
ora-01139     resetlogs 옵션은 불완전한 데이타베이스의 복구 후에만 유효합니다.
ora-01140     온라인 백업을 종료할 수 없음 - 모든 화일이 오프라인입니다.
ora-01141     데이타 화일 %s의 재명명 오류 - 새로운 화일 %s 가 없습니다.
ora-01142     온라인 백업을 종료할 수 없음 - 백업할 수 있는 상태의 화일이 없습니다.
ora-01143     매체 복구를 사용불가하게할 수 없습니다 화일 %s가 매체복구를 필요로 합니다.
ora-01144     화일크기(%s 블록)가 최대치 %s 블록을 초과합니다.
ora-01145     매체 복구가 사용 가능하지 않으면 즉시 오프라인으로 할 수 없습니다.
ora-01146     온라인 백업을 시작할 수 없습니다 - 화일 %s가 이미 백업중에 있습니다.
ora-01147     system 테이블 영역 화일 %s가 오프 라인입니다.
ora-01148     이 작업을 하려면 데이타베이스가 exclusive 모드로 마운트해야 합니다.
ora-01149     정지처리 불가 - 화일 %s를 온라인 백업중 입니다.
ora-01150     쓰기 방지를 할수 없음 - 화일 %s를 온라인 백업중 입니다.
ora-01151     블록을 복구하려면 미디어 복구를 사용하고 필요하면 백업을 사용하십시오
ora-01152     화일 %s가 충분한 이전 백업으로 복구되지 않았습니다
ora-01153     비호환 매체 복구가 동작 상태입니다.
ora-01154     데이타베이스는 사용중 - 개방, 클로즈, 마운트, 디스마운트 할 수 없습니다.
ora-01155     데이타베이스는 개방, 클로즈, 마운트 혹은 디스마운트 중 입니다.
ora-01156     진행중인 복구 작업이 화일 액세스를 필요로 할 수 있습니다.
ora-01157     데이타 화일 %s를 식별할 수 없습니다- 화일이 발견되지 않음
ora-01158     데이타베이스 %s 가 이미 마운트했습니다.
ora-01159     화일이 동일한 데이타베이스의 화일이 아닙니다- 데이타베이스 id가 잘못됨.
ora-01160     화일이 %s가 아닙니다.
ora-01161     화일헤더에 있는 데이타베이스명 %s가 주어진 이름 %s 와 일치하지 않습니다.
ora-01162     화일 헤더에 블록 크기 %s가 db_block_size(%s)와 일치하지 않습니다.
ora-01163     size 절에 %s (블록)이 지정되었으나 헤더 %s와 일치해야 합니다.
ora-01164     maxlogfiles는 %s 를 초과할 수 없습니다.
ora-01165     maxdatafiles는 %s 를 초과할 수 없습니다.
ora-01166     화일번호 %s가 %s (%s)보다 큽니다.
ora-01167     두개의 화일들이 같은 화일 그룹번호 이거나 같은 화일입니다.
ora-01168     물리 블록 크기 %s가 다른 멤버들의 크기 %s와 일치하지 않습니다.
ora-01169     datafile 번호 1번이 없습니다.
ora-01170     화일이 존재하지 않습니다 %s
ora-01171     체크포인트 오류 때문에 데이타 화일 %s이 오프라인됩니다.
ora-01172     쓰레드 %s의 복구가 블록 %s(화일 %s의)에서 더이상 진행되지 못합니다.
ora-01173     데이타 dictionary
ora-01174     db_file %s는 호환성을 위해서 %s가 되어야 합니다.
ora-01175     데이타 dictionary가 인스턴스에서 허용하는 %s 보다 많은 수의 화일을 포함합니다.
ora-01176     데이타 dictionary가 제어 화일에서 허용하는 %s 보다 많은 수의 화일을 포함합니다.
ora-01177     데이타 화일이 dictionary와 일치하지 않습니다- 아마도 오래된 것입니다.
ora-01178     화일 %s가 마지막 create controlfile 이전에 생성됐음. 재 생성할 수 없습니다.
ora-01179     화일 %s 가 존재하지 않습니다.
ora-01180     데이타 화일 1을 생성할 수 없습니다.
ora-01181     최후의 resetlogs 이전에 생성된 화일 %s를 재생성할 수 없습니다.
ora-01182     데이타베이스 화일 %s를 생성할 수 없음 - 사용중이거나 복구중입니다.
ora-01183     shared모드로 데이타베이스를 마운트할 수 없습니다.
ora-01184     로그화일 그룹 %s는 이미 존재합니다.
ora-01185     로그화일 그룹 %s는 부적절합니다.
ora-01186     화일 %s의 검증 테스트에 실패했습니다.
ora-01187     검증 테스트에 실패했기 때문에 화일 %s를 읽을 수 없습니다.
ora-01188     헤더내의 블록 크기 %s가 실제 물리블록 크기 %s와 맞지 않습니다.
ora-01189     이전 화일과 다른 resetlogs가 사용되었습니다.
ora-01190     제어 화일 혹은 데이타 화일 %s는 마지막 resetlogs 이전의 것입니다.
ora-01191     화일 %s는 이미 오프라인임 - 정상적인 오프라인을 할 수 없습니다.
ora-01192     최소한 하나의 이용 가능한 쓰레드를 가져야합니다.
ora-01193     화일 %s는 복구 시작시 인식된 화일이 아닙니다.
ora-01194     화일 %s가 일관성을 갖기 위해서는 더 많은 복구가 필요로 합니다.
ora-01195     화일 %s의 온라인 백업은 일관성을 갖기위해 더 많은 복구가 필요로 합니다.
ora-01196     매체복구 세션의 실패로 인하여 화일 %s의 일관성이 결여되어 있습니다.
ora-01197     쓰레드 %s는 하나의 로그만을 포함하고 있습니다.
ora-01198     resetlogs인 경우 로그화일에 대한 크기를 지정하여야 합니다.
ora-01199     화일 %s는 온라인 백업 모드가 아닙니다.
ora-01200     실제 화일크기 %s는 맞는 크기인 %s 블록보다 작습니다.
ora-01201     헤더내의 화일 크기 %s가 제어화일내의 크기 %s와 일치하지 않습니다.
ora-01202     화일의 구현이 잘못됨 - 작성 시각이 틀립니다.
ora-01203     화일의 구현이 잘못됨 - 작성 scn이 틀립니다.
ora-01204     화일 번호가 %s (%s가 아님) - 틀린 화일입니다.
ora-01205     데이타 화일이 아님 - 헤더내의 유형 번호가 %s입니다.
ora-01206     화일은 이 데이타베이스의 일부가 아님 - 데이타베이스 id가 틀립니다.
ora-01207     화일이 제어화일보다 최근의 것임 - 오래된 제어화일입니다.
ora-01208     데이타 화일이 구버전임 - 현 버전을 액세스하지 않았습니다.
ora-01209     데이타 화일이 마지막 resetlogs 이전의 것입니다.
ora-01210     데이타 화일의 헤더가 매체 붕괴되었습니다.
ora-01211     버전 6의 데이타 화일이 버전7으로의 변환 화일이 아닙니다.
ora-01212     maxlogmembers는 %s를 초과할 수 없습니다.
ora-01213     maxinstance는 %s를 초과할 수 없습니다.
ora-01214     maxloghistory는 %s를 초과할 수 없습니다.
ora-01215     create controlfile이후의 가용 쓰레드 %s가 빠졌습니다.
ora-01216     create controlfile이후 쓰레드 %s는 사용불가되어야합니다.
ora-01217     로그화일 멤버가 다른 로그화일 그룹에 속해있습니다.
ora-01218     로그화일 멤버는 동일한 시간때에 만든것이 아닙니다.
ora-01219     데이타베이스가 열지 않았음: 고정 테이블/뷰에 대해서만 조회가 가능합니다.
ora-01220     데이테베이스가 개방 되기전에는, 화일을 기본으로하는 소트가 부적합합니다.
ora-01221     데이타 화일 %s는 백그라운드 프로세스에 대해 동일 화일이 아닙니다.
ora-01222     %s의 maxinstances는 maxlogfiles가 최소 %s이어야함(%s가 아님)
ora-01223     새로운 데이타베이스명을 부여하기 위해서는 resetlogs를 지정하여야 합니다.
ora-01224     헤더 %s내의 그룹번호가 group %s와 맞지 않습니다.
ora-01225     쓰레드 번호 %s가 maxinstances %s 보다 큽니다.
ora-01226     로그 멤버의 화일헤더가 다른 멤버와 일치하지 않습니다.
ora-01227     로그 %s는 다른 로그와 일치하지 않습니다.
ora-01228     기초 데이테베이스를 설치하려면 set database 옵션이 필요합니다.
ora-01229     데이타 화일 %s가 로그와 일치하지 않습니다.
ora-01230     읽기 전용으로 만들수 없습니다- %s 화일이 오프라인입니다.
ora-01231     쓰기 전용으로 만들수 없습니다- %s 화일이 오프라인입니다.
ora-01232     온라인 백업을 수행할 수 없습니다- %s 화일은 읽기 전용입니다.
ora-01233     %s 화일은 읽기 전용입니다- 컨트롤화일 백업을 사용해서 복구할 수 없습니다.
ora-01234     화일 %s의 백업을 종료할 수 없습니다 - 화일을 사용중이거나 복구중입니다.
ora-01235     %s 화일에 대한 end backup은 실패하고 %s에 대해서는 성공했습니다.
ora-01237     데이타화일 %s를 확장할 수 없습니다.
ora-01238     데이타화일 %s를 축소할 수 없습니다.
ora-01239     데이터베이스는 외부 캐시를 사용하기 위해서 archivelog 모드로 되어 있어야 합니다.
ora-01240     하나의 명령어에 너무 많은 데이터 화일을 추가합니다.
ora-01241     외부 캐시가 죽었습니다.
ora-01242     데이터 화일이 메디아 실패를 받았습니다: 데이터베이스는 noarchivelog 모드입니다.
ora-01243     시스템 테이블스페이스 화일이 메디아 실패를 받았습니다.
ora-01244     메디아 복구에 의해서 제어화일에 이름 없는 데이터화일이 추가되었습니다.
ora-01245     오프라인 화일 %s 은 resetlogs이 끝나면 없어집니다.
ora-01400     행의 입력으로 필수 열(not null)에 값이 지정되지 않았습니다.
ora-01401     열에 입력한 값이 너무 큽니다.
ora-01402     뷰의 with check option의 조건에 위배 됩니다.
ora-01403     데이타가 없습니다.
ora-01404     alter column은 색인을 너무 크게 만들 수 있습니다.
ora-01405     인출된 열의 값은 null입니다.
ora-01406     인출된 열의 값이 절사되었습니다.
ora-01407     입력 필수 열(not null)은 null로 갱신할 수 없습니다.
ora-01408     열 리스트에는 이미 색인이 작성되어 있습니다.
ora-01409     nosort 옵션은 사용할 수 없습니다 행이 오름차순으로 되어 있지 않습니다.
ora-01410     rowid가 부적합합니다.
ora-01411     표시기내에 열의 길이를 저장할 수 없습니다.
ora-01412     이 데이타 유형에 대해서는 0길이가 허용되지 않습니다.
ora-01413     팩형 십진수 버퍼안의 값이 부적합합니다.
ora-01414     배열을 바인드 할때 배열 길이가 부적합합니다.
ora-01416     두 개의 테이블을 outer-join할 수 없습니다.
ora-01417     하나의 테이블은 하나의 다른 테이블과 outer-join할 수 있습니다.
ora-01418     지정한 색인는 존재하지 않습니다.
ora-01419     datdts: 형식 코드 오류입니다.
ora-01420     datstd: 형식 코드 오류입니다.
ora-01421     datrnd/dattrn: 정도 지정자 오류입니다.
ora-01422     실제 인출은 요구된 것보다 많은 수의 행을 추출합니다.
ora-01423     실제 인출에서 여분의 행을 검사하는 중에 오류가 검출되었습니다.
ora-01424     에스케이프 문자 뒤에 누락 혹은 부당한 문자가 있습니다.
ora-01425     에스케이프 문자는 1자리 문자 스트링이어야 합니다.
ora-01426     수치 오버플로우
ora-01427     단일 행 부속 질의에 의해 2개 이상의 행이 리턴되었습니다.
ora-01428     인수 %s가 범위를 벗어났습니다.
ora-01430     추가하려는 열이 이미 테이블에 존재합니다.
ora-01431     grant 명령어 내부 불일치 오류입니다.
ora-01432     삭제할 공개 동의어가 존재하지 않습니다.
ora-01433     작성한 동의어가 이미 정의되어 있습니다.
ora-01434     삭제할 비공개 동의어가 존재하지 않습니다.
ora-01435     사용자가 존재하지 않습니다.
ora-01436     connect by의 루프가 발생되었습니다.
ora-01437     결합은 connect by와 함께 지정할 수 없습니다.
ora-01438     지정한 정도를 초과한 값이 열에 지정되었습니다.
ora-01439     데이타 유형을 변경할 열은 비어 있어야 합니다.
ora-01440     정도 또는 자리수를 축소할 열은 비어 있어야 합니다.
ora-01441     길이를 짧게 변경할 열의 값은 null이어야 합니다.
ora-01442     변경하고자 하는 열이 이미 not null입니다.
ora-01443     내부 오류 : 뷰 열의 데이타 유형이 부적합합니다.
ora-01444     내부 오류 : 내부 데이타 유형와 외부 데이타 유형은 부적합합니다.
ora-01445     키-보전 테이블 없이 결합 뷰으로 부터 rowid를 선택할 수 없습니다.
ora-01446     distinct, group by 등을 포함하는 뷰로부터 rowid를 선택할 수 없습니다.
ora-01447     클러스터 열에 alter table 문을 사용할 수 없습니다.
ora-01448     데이타 유형을 변경하기 전에 색인을 삭제해야 합니다.
ora-01449     열이 null값을 포함하고 있습니다 not null로 변경할 수 없습니다.
ora-01450     키의 최대 길이(%s)를 초과했습니다.
ora-01451     열이 이미 null로 되어 있습니다.
ora-01452     중복 키가 있습니다. 유일한 색인을 작성할 수 없습니다.
ora-01453     set transaction 사용시에는 트랜잭션의 최초문장 이어야 합니다.
ora-01454     수치 데이타 유형으로 변환할 수 없습니다.
ora-01455     열의 변환에 의해 정수 데이타 유형이 오버플로우되었습니다.
ora-01456     read only 트랜잭션은 삽입/삭제/갱신할 수 없습니다.
ora-01457     열의 변환에 의해 decimal 데이타 유형이 오버플로우되었습니다.
ora-01458     가변장 스트링의 지정된 길이가 부적합합니다.
ora-01459     가변장 스트링의 길이가 부적합합니다.
ora-01460     요구된 변환은 실행될 수 없습니다.
ora-01461     long 값은 long 열에만 입력할 수 있습니다.
ora-01462     2000 문자 이상은 입력할 수 없습니다.
ora-01463     자신에 대한 권한의 허가나 취소는 불가능합니다.
ora-01464     테이블 또는 뷰의 grant 오류입니다.
ora-01465     16진수의 지정이 부적합합니다.
ora-01466     테이블 정의가 변경되었습니다 데이타를 읽을 수 없습니다.
ora-01467     정렬 키가 너무 깁니다.
ora-01468     outer-join된 테이블은 1개만 지정할 수 있습니다.
ora-01469     prior의 뒤에는 열 명을 지정해 주십시오
ora-01471     개체와 같은 이름의 동의어는 작성할 수 없습니다.
ora-01472     connect by는 distinct, group by 를 동반한 뷰에 사용할 수 없습니다.
ora-01473     connect by 구에 부속 질의를 지정할 수 없습니다.
ora-01474     connect by 없이 start with 나 prior 는 지정할 수 없습니다.
ora-01475     바인드 변수의 데이타 유형 변경을 위해서는 커서를 재구문분석을 해야 합니다.
ora-01476     제수가 0 입니다.
ora-01477     사용자 데이타 영역 기술자가 너무 큽니다.
ora-01478     long 열은 배열 바인드에 사용할 수 없습니다.
ora-01479     버퍼내의 마지막 문자가 널(null)이 아닙니다.
ora-01480     str 바인드 값에 종료의 널이 없습니다.
ora-01481     숫자 형식 모델이 부적합합니다.
ora-01482     지정된 문자세트는 제공하지 않습니다.
ora-01483     date 또는 number 바인드 변수의 길이가 부적합합니다.
ora-01484     배열은 pl/sql문 범위에서만 해야 합니다.
ora-01485     실행 바인드 길이가 컴파일 바인드 길이와 다릅니다.
ora-01486     배열요소 크기가 너무 큽니다.
ora-01487     팩형 십진수가 제공된 버퍼에 비해 너무 큽니다.
ora-01488     부적절한 팩형 십진수 입니다.
ora-01489     스트링 연결의 결과가 너무 깁니다.
ora-01490     부적합한 analyze 명령입니다.
ora-01491     cascade 옵션이 부적합합니다.
ora-01492     현 트랜잭션이 이미 롤백 세그먼트에 연결되어 있습니다.
ora-01493     명시된 sample 길이가 부적합합니다.
ora-01494     지정된 size가 부적당합니다.
ora-01495     지정된 연결행 테이블이 없습니다.
ora-01496     지정된 연결행 테이블 형식이 틀립니다.
ora-01497     analyze cluster에 대한 옵션이 잘못되었습니다.
ora-01498     블록 체크 실패 - 트래스 화일을 보십시오
ora-01499     테이블/색인의 교차 참조 실패 - 트래스 화일을 보십시오
ora-01500     날짜/시간의 획득 오류입니다.
ora-01501     create database 문 오류입니다.
ora-01502     색인 %s는 직접 로드 상태입니다.
ora-01503     create controlfile이 실패했습니다.
ora-01504     데이타베이스명 %s가 db_name 파라미터 %s와 맞지않습니다.
ora-01505     로그 화일 등록 오류입니다.
ora-01506     데이타베이스 명을 올바르게 지정해 주십시오.
ora-01507     데이타베이스가 마운트하지 않았습니다.
ora-01508     화일 %s 의 줄 %s 에 오류. 데이타베이스를 생성할 수 없습니다.
ora-01509     지정한 이름 %s 가 실제의 이름 %s 와 일치하지 않습니다.
ora-01510     로그 화일 삭제 오류입니다.
ora-01511     로그/데이타 화일의 재명명 오류입니다.
ora-01512     로드 화일 %s의 재명명 오류 - 새로운 화일 %s가 없습니다.
ora-01513     운영 시스템으로 부터 부정확한 현시각이 보내졌습니다.
ora-01514     로그 명세에 오류: 그런 로그가 없습니다.
ora-01515     로그 그룹 %s의 삭제시 오류. 그런 로그가 없습니다.
ora-01516     로그/데이타 화일 %s 는 존재하지 않습니다.
ora-01517     로그 멤버: %s
ora-01518     2개 이상의 로그 화일을 create database 에 지정해 주십시오.
ora-01519     오류 발생(화일 %s 의 줄 %s 부근)
ora-01520     추가할 데이타 화일의 수(%s)가 최대수 %s 를 초과했습니다.
ora-01521     데이타 화일의 등록중 오류가 발생했습니다.
ora-01522     재명명할 화일 %s 가 없습니다.
ora-01523     데이타 화일 %s 는 이미 데이타베이스의 일부입니다. 재명명할 수 없습니다.
ora-01524     %s로 데이타 화일을 생성할 수 없음 - 화일이 이미 데이타베이스의 부분입니다.
ora-01525     데이타 화일의 재명명중 오류가 발생했습니다.
ora-01526     화일 %s 의 열기 오류가 발생했습니다.
ora-01527     화일을 읽는 도중 오류가 발생했습니다.
ora-01528     sql 문의 처리중 eof 오류입니다.
ora-01529     화일 %s 의 클로즈중 오류가 발생했습니다.
ora-01530     이 인스턴스는 이미 데이타베이스를 마운트했습니다.
ora-01531     이 인스턴스는 이미 데이타베이스를 개방했습니다.
ora-01532     인스턴스가 기동되어 있습니다. 데이타베이스를 생성할 수 없습니다.
ora-01533     화일 %s 는 테이블 영역에 속해 있지 않습니다. 재명명할 수 없습니다.
ora-01534     롤백 세그먼트 %s 가 존재하지 않습니다.
ora-01535     롤백 세그먼트 %s 는 이미 존재합니다.
ora-01536     테이블 영역 %s 에 대한 영역 할당량이 초과됐습니다.
ora-01537     데이타 화일 %s 는 이미 데이타베이스의 일부입니다 등록할 수 없습니다.
ora-01538     롤백 세그먼트를 획득할 수 없습니다.
ora-01539     테이블 영역 %s 가 온라인이 아닙니다.
ora-01540     테이블 영역 %s 가 오프라인이 아닙니다.
ora-01541     system 테이블 영역은 오프라인될 수 없습니다 필요하면 중지 하십시오
ora-01542     테이블 영역 %s 가 오프라인입니다. 영역을 할당할 수 없습니다.
ora-01543     테이블 영역 %s 는 이미 존재하고 있습니다.
ora-01544     시스템 롤백 세그먼트는 삭제할 수 없습니다.
ora-01545     롤백 세그먼트 %s 는 사용할 수 없습니다.
ora-01546     테이블 영역에 액티브 롤백 세그먼트 %s 가 있습니다.
ora-01548     액티브 롤백 세그먼트 %s 가 존재함, 테이블 영역의 삭제를 종료하십시오.
ora-01549     테이블 영역이 비어있지 않으므로 including contents를 사용해 주십시오.
ora-01550     시스템 테이블 영역은 삭제할 수 없습니다.
ora-01551     롤백 세그먼트 확장 오류입니다.
ora-01552     시스템 테이블 영역이 아닌 %s 에 시스템 롤백 세그먼트를 사용할 수 없습니다.
ora-01553     maxextents는 현재 할당된 %s 엑스텐트 수 이상이어야 합니다.
ora-01554     트랜잭션 슬롯이 없습니다.
ora-01555     스냅샷이 너무 오래 되었습니다(롤백 세그먼트가 너무 작습니다)
ora-01556     롤백 세그먼트를 위한 minextents는 1보다 커야만 합니다.
ora-01557     롤백 세그먼트 엑스텐트는 최저 %s 블록이 필요합니다.
ora-01558     롤백 세그먼트 %s 에 트랜잭션 번호가 없습니다.
ora-01559     롤백 세그먼트의 maxextents 는 2 이상입니다.
ora-01560     글로벌 해쉬 테이블의 크기가 %s와 일치하지 않습니다 (%s !=%s)
ora-01561     지정된 테이블 영역중의 개체가 삭제되지 않았습니다.
ora-01562     롤백 세그먼트 확장 실패입니다 (id = %s)
ora-01563     키워드 public 을 사용해 주십시오
ora-01564     롤백 세그먼트는 public 이 아닙니다.
ora-01565     화일 %s 의 식별 오류가 발생했습니다.
ora-01566     drop logfile에 화일이 2회 이상 지정되었습니다.
ora-01567     로그 %s를 삭제하면 쓰레드 %s에 남는 로그 화일이 2개 미만으로 됩니다.
ora-01568     public에 영역 할당량을 설정할 수 없습니다.
ora-01569     시스템 dictionary 테이블에 대한 데이타 화일이 너무 작습니다.
ora-01570     minextents는 현재 할당된 %s보다 클 수 없습니다.
ora-01571     로그 레코드 버전 %s 가 oracle의 버전 %s 과 호환되지 않습니다.
ora-01572     롤백 세그먼트용 글로벌 해쉬 테이블의 크기 %s가 롤백 세그먼트 번호 %s 에 대해 너무 작음
ora-01573     인스턴스의 정지 처리가 진행중. 더 이상의 변경은 허용되지 않습니다.
ora-01574     최대 동시 실행 트랜잭션 수를 초과했습니다.
ora-01575     영역 관리 자원의 대기중 시간이 초과되었습니다.
ora-01576     인스턴스 잠금 프로토콜 버전 %s는 oracle의 버전 %s 와 호환되지 않습니다.
ora-01577     로그 화일 %s는 이미 데이타베이스의 일부입니다 등록이 불가능합니다.
ora-01578     oracle 데이타 블록이 파손되었습니다 (화일 번호 %s, 블록 번호 %s)
ora-01579     복구중 기록(write) 오류가 발생했습니다.
ora-01580     제어 화일의 백업 화일 %s 를 작성하는 중에 오류가 발생했습니다.
ora-01581     이미 할당된 롤백 세그먼트(%s) 새로운 익스텐트(%s)를 사용하려 시도했습니다.
ora-01582     백업을 하기위해 제어 화일을 열 수 없습니다.
ora-01583     백업될 제어 화일의 블록 크기를 획득할 수 없습니다.
ora-01584     백업될 제어 화일의 화일 크기를 획득할 수 없습니다.
ora-01585     백업 화일 %s 를 인식할 수 없습니다.
ora-01586     백업을 하기위한 수신 화일 %s을 열 수 없습니다.
ora-01587     제어 화일의 백업 화일 복제중 오류가 발생했습니다.
ora-01588     데이타베이스를 열기 위해서는 resetlogs 옵션을 사용해야 합니다.
ora-01589     데이타베이스를 열기 위해서는 resetlogs/noresetlogs 옵션을 사용해야 함
ora-01590     가용 세그멘트 수(%s)가 최대치인 %s 를 초과합니다.
ora-01591     잠금이 in-doubt 분산 트랜잭션 %s에 주어졌습니다.
ora-01592     버전 6의 롤백 세그먼트(%s)를 oracle7 포맷으로 변환시 오류 발생
ora-01593     롤백 세그먼트의 최적크기(%s 블록)가 초기크기 계산(%s 블록)보다 작습니다.
ora-01594     해제될 롤백 세그먼트(%s) 익스텐트(%s)를 연결하려함
ora-01595     익스텐스(%s)(롤백 세그먼트 (%s)의) 해제시 오류
ora-01596     %s 파라미터에 시스템을 지정할 수 없습니다.
ora-01597     시스템 롤백 세그먼트를 온라인 혹은 오프라인시킬 수 없습니다.
ora-01598     롤백 세그먼트 %s가 온라인이 아닙니다.
ora-01599     롤백 세그먼트(%s)를 획득하는데 실패, 캐쉬 영역이 꽉찼습니다현재(%s)엔트리를 가짐)
ora-01600     많아야 하나의 %s (gc_files_to_locks의 %s절에)
ora-01601     gc_files_to_locks의 %s절에 부당한 버켓(bucket) 크기
ora-01602     gc_files_to_locks에 예정된 것보다 gc_db_locks에 더 많은 잠금임
ora-01603     gc_files_to_locks의 %s절에 부당한 그룹크기
ora-01604     gc_files_to_locks의 %s절에 부당한 화일 번호 범위
ora-01605     gc_files_to_locks의 %s절에 화일 번호 누락
ora-01606     gc_files_to_lock가 마운트한 다른 인스턴스의 그것과 동일하지 않습니다.
ora-01607     gc_lck_procs (%s)가 다른 인스턴스 (%s)와 같지 않습니다.
ora-01608     롤백 세그먼트 %s를 온라인화할 수 없음. 상태는 (%s)
ora-01609     로그 %s는 쓰레드 %s에 대한 현 로그 - 멤버를 삭제할 수 없습니다.
ora-01610     backup controlfile 옵션을 이용해서 복구가 끝나야만 합니다.
ora-01611     쓰레드번호 %s는 부적절함 - %s보다 커서는 안됩니다.
ora-01612     쓰레드 %s는 이미 가용되었습니다.
ora-01613     쓰레드 %s는 %s 로그만을 가짐 - 가용화를 위해서는 최소 2개의 로그를 필요로 함
ora-01614     쓰레드 %s는 사용중임 - 사용가능하게할 수 없습니다.
ora-01615     쓰레드 %s는 마운트됨 - 사용불가하게할 수 없습니다.
ora-01616     쓰레드 %s는 열려 있음 - 사용불가하게할 수 없습니다.
ora-01617     마운트할 수 없음: %s는 정당한 쓰레드 번호가 아님
ora-01618     쓰레드 %s는 사용가능하지 않았음 - 마운트할 수 없습니다.
ora-01619     쓰레드 %s는 다른 인스턴스에 의해 마운트했습니다.
ora-01620     마운트에 필요한 공용 쓰레드가 없습니다.
ora-01621     데이타베이스가 열려 있으면 현 로그의 멤버를 개명할 수 없습니다.
ora-01622     쓰레드 번호가 지정되어야함 - 디폴트는 없습니다.
ora-01623     로그 %s는 쓰레드 %s에 대한 현 로그임 - 삭제할 수 없습니다.
ora-01624     로그 %s가 쓰레드 %s 복구시 필요합니다.
ora-01625     롤백 세그먼트 %s는 이 인스턴스에 속해있지 않습니다.
ora-01626     롤백 세그먼트 번호 %s는 더 이상의 트랜잭션을 처리할 수 없습니다.
ora-01627     롤백 세그먼트 번호 %s는 온라인이 아닙니다.
ora-01628     롤백 세그먼트 %s에 대한 최대 익스텐스 수 (%s)에 도달했습니다.
ora-01629     테이블 영역 %s에 대한 실행취소의 저장시 최대 익스텐트 수(%s)에 도달했음
ora-01630     테이블 영역 %s의 임시 세그먼트에 최대 익스텐트 수(%s)가 되었습니다.
ora-01631     최대 익스텐트 수(%s)에 도달 (테이블 %s.%s)
ora-01632     최대 익스텐트 수(%s)에 도달 (색인 %s.%s)
ora-01633     이 조작에는 병렬 서버 옵션이 필요합니다.
ora-01634     롤백 세그먼트 번호 %s가 오프라인 되려합니다.
ora-01635     지정된 롤백 세그먼트 번호 %s가 가용하지 않습니다.
ora-01636     롤백 세그먼트 %s가 이미 온라인 상태입니다.
ora-01637     롤백 세그먼트 %s가 다른 인스턴스(수 %s)에 의해 사용됩니다.
ora-01638     %s 파라미터는 oracle 버전 %s에서 병렬 마운트를 허용하지 않습니다.
ora-01639     데이타베이스는 잠금 프로세스 없이 병렬로 마운트할 수 없습니다.
ora-01640     활성 트랙잰션으로 테이블 공간을 읽기 전용으로 만들수 없습니다.
ora-01641     테이블스페이스 %s은 온라인이 아닙니다 - 데이타 화일을 추가할 수 없습니다.
ora-01642     읽기 전용 %s 테이블 공간에 초기 백업이 필요하지 않습니다.
ora-01643     시스템 테이블 공간를 읽기 전용으로 만들 수 없습니다.
ora-01644     %s 테이블 공간은 이미 읽기 전용입니다.
ora-01645     읽기 쓰기를 하기위해서 이전에 시도한것이 반만 완성되었습니다.
ora-01646     %s 테이블 공간은 읽기 전용입니다- 읽기 쓰기를 할 수 없습니다.
ora-01647     %s 테이블 공간은 읽기 전용이어서, 거기에 공간을 할당할 수 없습니다.
ora-01648     로그 %s는 사용불가인 쓰레드 %s의 현재 로그입니다.
ora-01649     백업 컨트롤 화일에 대한 작업이 허용되지 않습니다.
ora-01650     롤백 세그먼트 %s를 %s에 의해 %s 테이블 공간에서 확장할 수 없습니다.
ora-01651     %s로 테이블 공간 %s에 저장 취소 세그먼트를 확장할 수 없습니다.
ora-01652     %s로 테이블 공간 %s에서 임시 세그먼트를 확장할 수 없습니다.
ora-01653     테이블 %s.%s를 %s에 의해 %s 테이블 공간에서 확장할 수 없습니다.
ora-01654     색인 %s.%s를 %s에 의해 %s 테이블 공간에서 확장할 수 없습니다.
ora-01655     크러스터 %s.%s를 %s에 의해 %s 테이블 공간에서 확장할 수 없습니다.
ora-01656     최대 번호 확장 (%s)가 %s.%s 크러스터에 도달했습니다.
ora-01657     부적당한 shrink 옵션 값
ora-01658     테이블스페이스 %s에 세그먼트에 대한 initial 익스텐트를 작성할 수 없습니다.
ora-01659     테이블스페이스 %s에 %s이상의 minextents를 할당할 수 없습니다.
ora-01660     테이블스페이스 %s 은 이미 영구적인 것입니다.
ora-01661     테이블스페이스 %s 은 이미 임시적인 것입니다.
ora-01662     테이블스페이스 %s 은 비어 있지 않아 임시로 만들 수가 없습니다.
ora-01663     테이블스페이스 %s 의 내용은 항상 변경합니다.
ora-01664     정렬 세그먼트로 확장된 트랜잭션은 중지 되었습니다.
ora-01665     제어화일은 대기 제어화일이 아닙니다.
ora-01666     제어화일은 대기 제어화일을 위한 것입니다.
ora-01667     리두 로그는 대기 데이터베이스와 상반됩니다.
ora-01668     데이터 화일의 오프라인을 위해서 대기 데이터베이스가 drop 옵션을 요구합니다.
ora-01669     대기 데이터베이스 제어화일은 데이터화일과 일치하지 않습니다.
ora-01670     대기 데이터베이스 복구에 새로운 데이터화일 %s 가 필요합니다.
ora-01671     제어화일은 백업합니다, 대기 제어화일을 만들 수 없습니다.
ora-01672     제어화일에 화일이 빠졌거나 하나 더 가지고 있습니다.
ora-01673     데이터 화일 %s 은 식별된것이 아닙니다.
ora-01674     데이터 화일 %s 은 현재 화일 대신 오래된 것을 가지고 있습니다.
ora-01676     대기 화일 이름은 %s의 변환을 하는데 최대 %s의 길이를 초과했습니다.
ora-01677     대기 화일 이름이 파라미터 변환을 다른 인스턴스와 다르게 했습니다.
ora-01678     파라미터 %s 은 패턴과 교체로 된 두가지 스트링을 가지고 있어야 합니다.
ora-01679     데이터베이스는 exclusive로 마운트 되어야 하고 열려 있지 않아야 합니다.
ora-01680     만약 gc_files_to_locks이 사용하고 있으면 gc_db_locks가 영일 수 없습니다.
ora-01700     리스트 내의 사용자명이 중복되었습니다.
ora-01701     클러스터가 부적합합니다.
ora-01702     뷰는 부적합합니다.
ora-01703     키워드 synonym이 없습니다.
ora-01704     스트링이 너무 깁니다.
ora-01705     상관 열에는 외부 결합을 지정할 수 없습니다.
ora-01706     사용자 함수의 결과가 너무 큽니다.
ora-01707     키워드 list가 없습니다.
ora-01708     access 또는 session을 지정해 주십시오
ora-01709     프로그램이 존재하지 않습니다.
ora-01710     키워드 of가 없습니다.
ora-01711     중복된 권한이 리스트되어 있습니다.
ora-01712     자신이 소유하지 않은 권한을 허가할 수 없습니다.
ora-01713     그 권한에 대해서는 grant option 이 존재하지 않습니다.
ora-01714     사용자 함수의 실행중 오류가 발생했습니다.
ora-01715     클러스터 색인에는 unique를 사용할 수 없습니다.
ora-01716     클러스터 색인에는 nosort를 사용할 수 없습니다.
ora-01717     secta : 액세스 모드 토큰이 부적합합니다.
ora-01718     by access | session절은 noaudit에 대해서는 허용되지 않습니다.
ora-01719     외부 결합 운영 (+)는 or 또는 in의 연산수를 허용하지 않습니다.
ora-01720     %s에 대한 허가(grant) 옵션은 존재하지 않습니다.
ora-01721     트랜잭션에서 userenv(commitscn)을 2회 이상 불렀습니다.
ora-01722     수치가 부적합합니다.
ora-01723     길이가 0인 열은 지정할 수 없습니다.
ora-01724     부동 소숫점 수치의 정도를 벗어났습니다 (1 to 126)
ora-01725     userenv(commitscn)는 여기에서 허용되지 않습니다.
ora-01726     테이블의 지정이 부적합합니다.
ora-01727     수치의 정도 범위(38 자리 이내)를 초과했습니다.
ora-01728     수치의 스케일 범위(-84 에서 127)를 초과했습니다.
ora-01729     데이타베이스 링크명을 지정해 주십시오
ora-01730     지정한 열명의 수가 부적합합니다.
ora-01731     뷰 정의가 부적합(순환)합니다.
ora-01732     뷰에 대한 데이타 조작이 부적합합니다.
ora-01733     가상 열은 사용할 수 없습니다.
ora-01734     잘못된 파라미터 - extent min 값이 extent max 보다 큽니다.
ora-01735     부적합한 alter table 옵션입니다.
ora-01736     [not] successful 을 지정해 주십시오.
ora-01737     공유, 배타 모드에서만 테이블을 잠금할 수 있습니다.
ora-01738     키워드 in 을 지정해 주십시오
ora-01739     키워드 mode 를 지정해 주십시오
ora-01740     이중 인용부를 지정해 주십시오
ora-01741     길이가 0인 식별자는 부적합합니다.
ora-01742     주석이 정확하게 종료되지 않았습니다.
ora-01743     내부적 불일치 : 사용자 함수 색인이 부적합합니다.
ora-01744     into구의 지정이 부적합합니다.
ora-01745     호스트/바인드 변수명이 부적합합니다.
ora-01746     인디케이터 변수는 사용할 수 없습니다.
ora-01747     열명을 올바르게 지정해 주십시오.
ora-01748     열명 그 자체만 사용할 수 있습니다.
ora-01749     자신의 권한으로는 grant/revoke 할 수 없습니다.
ora-01750     update/reference 는 열에 의해서가 아닌 테이블 전체로부터 revoke 될 수 있습니다.
ora-01751     부적당한 덤프 취소 옵션입니다.
ora-01752     뷰으로 부터 정확하게 하나의 키-보전된 테이블 없이 삭제할 수 없습니다.
ora-01753     열 정의가 클러스터 열의 정의와 일치하지 않습니다.
ora-01754     long 유형의 열은 테이블에 1 개만 포함될 수 있습니다.
ora-01755     영역 수나 블록 수를 지정해야만 합니다.
ora-01756     단일 인용부를 지정해 주십시오
ora-01757     개체 수를 지정해야 합니다.
ora-01758     not null 열을 추가하기 위해서는 테이블이 비어 있어야 합니다.
ora-01759     사용자 함수가 올바르게 정의되지 않았습니다.
ora-01760     함수의 인수가 부적합합니다.
ora-01761     결합문는 유일 테이블에 dml 작업으로 맵 할 수 없습니다.
ora-01762     vopdrv: 뷰의 질의 블록이 from 구에 없습니다.
ora-01763     갱신 또는 삭제가 외부 결합 테이블을 포함하고 있습니다.
ora-01764     결합의 새로운 갱신 값은 유일한것을 보증할 수 없습니다.
ora-01765     테이블의 소유자명을 지정할 수 없습니다.
ora-01766     데이타 사전 개체명을 사용할 수 없습니다.
ora-01767     update ... set 식은 부속 질의이어야 합니다.
ora-01768     수치 열이 너무 깁니다.
ora-01769     cluster 옵션 지정이 중복되었습니다.
ora-01770     cluster 옵션은 사용할 수 없습니다.
ora-01771     클러스터 테이블에 대한 옵션이 부적합합니다.
ora-01772     level에 대한 값을 지정해야 합니다.
ora-01773     지정한 create table 문에는 열 데이타 유형을 지정할 수 없습니다.
ora-01774     한번 이상 덤프 취소 옵션이 지정되었습니다.
ora-01775     동의어가 순환 고리 유형으로 정의되어 있습니다.
ora-01776     결합 뷰에 의하여 하나 이상의 기본 테이블을 수정할 수 없습니다.
ora-01777     with grant 옵션은 사용할 수 없습니다.
ora-01778     부속 질의의 내포 레벨의 제한을 초과했습니다.
ora-01779     키-보존된것이 아닌 테이블로 맵한 열을 수정할 수 없습니다.
ora-01780     스트링 상수가 필요합니다.
ora-01781     unrecoverable은 as select와 함께 지정해야 합니다.
ora-01782     클러스터 또는 클러스터 테이블에 대해서는 unrecoverable을 지정할 수 없습니다.
ora-01783     recoverable 또는 unrecoverable 중 하나만을 지정할 수 있습니다.
ora-01784     데이타베이스 미디어 복구가 사용불가이면 recoverable을 지정할 수 없습니다.
ora-01785     order by 항목은 select 리스트 식의 수라야 합니다.
ora-01786     for update 구는 사용할 수 없습니다.
ora-01787     질의 블록당 1개의 구만 허용됩니다.
ora-01788     connect by 구를 지정해 주십시오.
ora-01789     질의의 결과 열의 수가 틀립니다.
ora-01790     대응하는 식과 같은 데이타 유형이어야 합니다.
ora-01791     select 식이 부적합합니다.
ora-01792     테이블, 뷰에 지정 가능한 열의 최대수는 254 입니다.
ora-01793     지정 가능한 색인 열의 최대수는 16 입니다.
ora-01794     지정 가능한 클러스터 열의 최대수는 16 입니다.
ora-01795     리스트에 지정 가능한 식의 최대수는 254 입니다.
ora-01796     연산자의 지정이 부적합합니다.
ora-01797     연산자의 뒤에 any 또는 all을 지정해 주십시오.
ora-01798     exception 키워드가 누락되었습니다.
ora-01799     열은 부속 질의에 외부결합될 수 없습니다.
ora-01800     날짜 형식 내의 리터럴이 너무 길어서 처리할 수 없습니다.
ora-01801     날짜 형식이 내부 버퍼에 비해 너무 깁니다.
ora-01802     율리우스일의 지정이 범위를 초과했습니다.
ora-01803     날짜/시각의 획득 실패
ora-01810     형식 코드가 2 번 나타났습니다.
ora-01811     율리우스일에서 년간 통산일의 사용은 금지되어 있습니다.
ora-01812     년은 1 번만 지정할 수 있습니다.
ora-01813     시간은 1 번만 지정할 수 있습니다.
ora-01814     am/pm 과 a.m./p.m.은 혼재할 수 없습니다.
ora-01815     bc/ad 와 b.c./a.d.는 혼재할 수 없습니다.
ora-01816     월은 1 번만 지정할 수 있습니다.
ora-01817     요일은 1 번만 지정할 수 있습니다.
ora-01818     hh24와 am/pm은 혼재할 수 없습니다.
ora-01819     부호가 붙은 년과 bc/ad는 혼재할 수 없습니다.
ora-01820     날짜 지정에 포함된 형식 코드가 부적합합니다.
ora-01821     날짜 형식이 부적합합니다.
ora-01830     날짜 형식의 지정에 불필요한 데이타가 포함되어 있습니다.
ora-01831     년과 율리우스일은 혼재할 수 없습니다.
ora-01832     년의 일과 율리우스일은 혼재할 수 없습니다.
ora-01833     월과 율리우스일은 혼재할 수 없습니다.
ora-01834     월의 일과 율리우스일은 혼재할 수 없습니다.
ora-01835     요일과 율리우스일은 혼재할 수 없습니다.
ora-01836     시와 일의 초는 혼재할 수 없습니다.
ora-01837     시의 분과 일의 초는 혼재할 수 없습니다.
ora-01838     분의 초와 일의 초는 혼재할 수 없습니다.
ora-01839     지정된 월에 대한 날짜가 부적합합니다.
ora-01840     입력된 값의 길이가 날짜 형식에 비해 부족합니다.
ora-01841     년은 -4713 과 +4713 사이의 값으로 지정해 주십시오.
ora-01842     분기는 1 부터 4 사이의 값을 지정해 주십시오.
ora-01843     지정한 월이 부적합합니다.
ora-01844     주를 올바르게 지정해 주십시오 ( 1 에서 52 사이 )
ora-01845     주를 올바르게 지정해 주십시오 ( 1 에서 5 사이 )
ora-01846     지정한 요일이 부적합합니다.
ora-01847     날짜를 올바르게 지정해 주십시오 ( 1 에서 말일까지 )
ora-01848     날짜를 올바르게 지정해 주십시오 ( 1 에서 365 사이 )
ora-01849     시간을 올바르게 지정해 주십시오 ( 1 에서 12 사이 )
ora-01850     시간을 올바르게 지정해 주십시오 ( 0 에서 23 사이 )
ora-01851     분을 올바르게 지정해 주십시오 ( 0 에서 59 사이 )
ora-01852     초를 올바르게 지정해 주십시오 ( 0 에서 59 사이 )
ora-01853     초를 올바르게 지정해 주십시오 ( 0 에서 86399 사이 )
ora-01854     율리우스 날짜는 1에서 5373484 사이여야 합니다.
ora-01855     am/a.m. 또는 pm/p.m.이 필요합니다.
ora-01856     bc/b.c. 또는 ad/a.d.이 필요합니다.
ora-01857     시간대가 부적합합니다.
ora-01858     수치를 지정해야할 곳에 비수치 문자가 지정되었습니다.
ora-01859     문자를 지정해야할 곳에 비문자가 지정되었습니다.
ora-01860     년의 주는 1 에서 53 사이이어야 합니다.
ora-01861     스트링이 형식 스트링에 맞지 않습니다.
ora-01862     이 형식의 항목에 대한 잘못된 자리수
ora-01898     precision 지정자가 너무 많습니다.
ora-01899     잘못된 precision 지정자입니다.
ora-01900     키워드 logfile을 지정해 주십시오
ora-01901     키워드 rollback을 지정해 주십시오
ora-01902     키워드 segment를 지정해 주십시오
ora-01903     키워드 events를 지정해 주십시오
ora-01904     키워드 datafile을 지정해 주십시오
ora-01905     키워드 storage를 지정해 주십시오
ora-01906     키워드 backup을 지정해 주십시오
ora-01907     키워드 tablespace를 지정해 주십시오
ora-01908     키워드 exists를 지정해 주십시오
ora-01909     키워드 reuse를 지정해 주십시오
ora-01910     키워드 tables을 지정해 주십시오
ora-01911     키워드 contents를 지정해 주십시오
ora-01912     키워드 row를 지정해 주십시오
ora-01913     키워드 exclusive를 지정해 주십시오
ora-01914     시퀀스 번호에 대한 감사 옵션이 부적합합니다.
ora-01915     뷰에 대한 감사 옵션이 부적합합니다.
ora-01916     키워드 online, offline, resize, autoextend 또는 end를 지정하십시오
ora-01917     사용자 또는 롤 %s가 존재하지 않습니다.
ora-01918     사용자 %s가 존재하지 않습니다.
ora-01919     롤 %s가 존재하지 않습니다.
ora-01920     사용자명 %s가 다른 사용자나 롤명과 상충됩니다.
ora-01921     롤명 %s가 다른 사용자나 롤명과 상충됩니다.
ora-01922     %s를 삭제하려면 cascade를 지정하여야 합니다.
ora-01923     개체가 다른 사용자에 의해서 잠금 되어 cascade가 비정상 종료되었습니다.
ora-01924     롤 %s가 허가되지 않았거나 존재하지 않습니다.
ora-01925     가용 롤의 최대치 %s를 초과했습니다.
ora-01926     with grant option으로 롤을 grant할 수 없습니다.
ora-01927     허가하지 않은 권한을 revoke할 수 없습니다.
ora-01928     모든 권한에 대하여 grant 옵션이 허가되지는 않았습니다.
ora-01929     grant할 권한이 없습니다.
ora-01931     %s를 롤에게 허가할 수 없습니다.
ora-01932     롤 %s에 대한 admin 옵션이 허가되지 않았습니다.
ora-01933     롤에 대한 권한으로 저장 개체를 생성할 수 없습니다.
ora-01934     순환되는 롤 권한 부여가 감지되었습니다.
ora-01935     누락된 사용자 혹은 롤명
ora-01936     사용자나 롤을 생성시 소유자를 지정할 수 없습니다.
ora-01937     부적절한 롤명
ora-01938     create user에 대한 identified by가 지정되어야 합니다.
ora-01939     admin option만이 지정될 수 있습니다.
ora-01940     현재 연결되어 있는 사용자를 삭제할 수 없습니다.
ora-01941     키워드 sequence가 요구됩니다.
ora-01942     identified by 와 externally는 모두 지정될 수 없습니다.
ora-01943     identified by가 이미 지정되었습니다.
ora-01944     identified externally가 이미 지정되었습니다.
ora-01945     default role[s]가 이미 지정되었습니다.
ora-01946     default tablespace가 이미 지정되었습니다.
ora-01947     temporary tablespace가 이미 지정되었습니다.
ora-01949     role 키워드가 요구합니다.
ora-01950     테이블 영역 %s에 대한 권한이 없읍
ora-01951     role %s가 %s에 허가되지 않았습니다.
ora-01952     시스템 권한이 %s에 허가되지 않았습니다.
ora-01953     명령어가 더 이상 유효하지 않음,alter user를 보내십시오
ora-01954     create user에 default role절이 유효하지 않습니다.
ora-01955     default role %s가 사용자에게 허가되지 않았습니다.
ora-01956     os_roles이 사용될시 부적절한 명령어
ora-01957     키워드 min 혹은 max 를 지정해 주십시오
ora-01958     layer 옵션을 위한 정수가 필요합니다.
ora-01959     opcode 옵션을 위한 정수가 필요합니다.
ora-01960     부적절한 덤프 로그 화일 옵션입니다.
ora-01961     부적절한 덤프 옵션입니다.
ora-01962     화일 번호 혹은 시퀀스 번호를 지정해야 합니다.
ora-01963     블록 번호를 지정해야 합니다.
ora-01964     time 옵션을 위한 시간을 지정해야 합니다.
ora-01965     period 를 지정해야 합니다.
ora-01967     create controlfile 의 부적절한 옵션입니다.
ora-01968     resetlogs 혹은 noresetlogs 를 한번만 지정하십시오
ora-01969     resetlogs 혹은 noresetlogs 를 지정해야 합니다.
ora-01970     create controlfile에 대한 데이타베이스 명을 지정해야 합니다.
ora-01971     부적절한 alter tracing 옵션
ora-01972     alter tracing enable 혹은 disable에 대한 스트링을 지정해야 합니다.
ora-01973     변경 번호 누락
ora-01974     부적절한 아카이브옵션
ora-01975     변환 번호 %s에 부적절한 문자
ora-01976     변경 번호 누락
ora-01977     쓰레드 번호 누락
ora-01978     시퀀스 번호 누락
ora-01979     롤 %s에 대한 암호가 틀리거나 누락되었습니다.
ora-01980     os role 초기화시 오류
ora-01981     현 권한취소를 수행하려면 cascade constraints가 지정되어야 합니다.
ora-01982     테이블에 대한 부적절한 감사 옵션
ora-01983     default에 대한 부적절한 감사 옵션
ora-01984     프로시저/패캐지/함수에 대한 부적절한 감사 옵션
ora-01985     license_max_users 파라미터가 초과되어 사용자를 생성할 수 없습니다.
ora-01986     optimizer_goal에 대한 옵션 부적합
ora-01987     클라이언트 os 사용자명이 너무 깁니다.
ora-01988     원격 os 로그온이 허용되지 않습니다.
ora-01989     롤 %s는 운영 시스템에 의해 권한되지 않았습니다.
ora-01990     암호 %s 화일을 여는데 오류가 발생했습니다.
ora-01991     %s 암호 화일이 부적합합니다.
ora-01992     %s 암호 화일을 닫는데 오류가 발생했습니다.
ora-01993     %s 암호 화일을 쓰는 중에 오류가 발생했습니다.
ora-01994     grant 실패: 공용 암호 화일에다 사용자를 추가할 수 없습니다.
ora-01995     %s 암호 화일을 읽는 중에 오류가 발생했습니다.
ora-01996     grant 실패: %s 암호 화일이 꽉 찼습니다.
ora-01997     grant 실패: %s 사용자는 여기에 없습니다.
ora-01998     revoke 실패: sys 사용자는 항상 sysoper 와 sysdba를 가지고 있습니다.
ora-01999     암호 화일 모드는 %s 에서 %s로 바꾸었습니다.
ora-02000     누락된 %s 키워드
ora-02001     사용자 sys는 빈리스트 그룹와 함께 색인을 생성하는것을 허락하지 않습니다.
ora-02002     감사 추적 테이블에 기록 중 오류가 발생했습니다.
ora-02003     userenv 파라미터가 부적합합니다.
ora-02004     보안 위반
ora-02005     길이(-1)가 부적합합니다.
ora-02006     팩형 10진 형식 스트링이 부적합합니다.
ora-02007     allocate 또는 deallocate 옵션을 rebuild와 같이 사용할 수 없습니다.
ora-02008     숫자가 아닌 열에 대하여 0 이외의 스케일이 지정되었습니다.
ora-02009     화일에 지정된 크기는 0이 아니어야 합니다.
ora-02010     호스트 연결 스트링을 지정해 주십시오
ora-02011     데이타베이스 링크명이 중복되었습니다.
ora-02012     키워드 using 을 지정해 주십시오
ora-02013     키워드 connect 를 지정해 주십시오
ora-02014     for update 구를 사용해서 선택할 수 없습니다.
ora-02015     원격 테이블에 대하여 for update 구는 사용할 수 없습니다.
ora-02016     원격 데이타베이스에서는 start with 로 부속 질의를 사용할 수 없습니다.
ora-02017     정수 값을 지정해 주십시오
ora-02018     같은 이름의 데이타베이스 링크가 개방, 연결되어 있습니다.
ora-02019     원격 데이타베이스를 찾을 수 없을때 기술적으로 연결하십시오
ora-02020     너무 많은 데이타베이스 링크들이 사용되고 있습니다.
ora-02021     원격 데이타베이스에 ddl 조작들이 허용되지 않습니다.
ora-02022     원격 문장이 원격 개체를 갖는 최적화 되지않을 뷰를 사용합니다.
ora-02023     원격 데이타베이스는 start with, connect by 술어를 평가할 수 없습니다.
ora-02024     데이타 링크를 찾을 수 없습니다.
ora-02025     sql 문장에 있는 모든 테이블은 원격 데이타베이스에 있어야만 합니다.
ora-02026     키워드 link 를 지정해 주십시오
ora-02027     long 열은 복수 행의 갱신이 불가능합니다.
ora-02028     정확한 행의 번호를 인출 하는것이 지원되지 않습니다.
ora-02029     키워드 file 을 지정해 주십시오
ora-02030     고정 테이블/고정 뷰에서는 선택만 가능합니다.
ora-02031     고정 테이블에 대하여 rowid 를 지정할 수 없습니다.
ora-02032     클러스터 색인의 작성 이전에 클러스터 테이블을 사용할 수 없습니다.
ora-02033     이미 클러스터 색인이 존재하고 있습니다.
ora-02034     스피드 바인드가 허용되지 않습니다.
ora-02035     부당한 작업묶음의 조합입니다.
ora-02036     자동커서 개방시 묘사할 변수가 너무 많습니다.
ora-02037     초기화되지 않은 스피드 바인드 영역
ora-02038     배열 유형에 정의가 허용되지 않습니다
ora-02039     배열 유형에 값으로 바인드는 허용되지 않습니다
ora-02040     원격 데이타베이스는 %s는 두단계 커밋을 지원하지 않습니다.
ora-02041     클라이언트 데이타베이스는 트랜잭션을 시작하지 않습니다.
ora-02042     너무 많은 분산 트랜잭션들
ora-02043     %s를 실행하기 전에 현재 트랜잭션을 끝내야 합니다.
ora-02044     트랜잭션 관리자 로그인이 거부되었음: 트랜잭션이 진행중입니다.
ora-02045     글로벌 트랜잭션에 관여한 로컬 세션이 너무 많습니다.
ora-02046     분산 트랜잭션이 이미 시작되었습니다.
ora-02047     진행 중에 분산 트랜잭션을 결합할 수 없습니다.
ora-02048     로그잉하지 않고 분산 트랜잭션을 시작하려 했습니다.
ora-02049     시간초과: 분산 트랜잭션이 잠금으로 대기중 입니다.
ora-02050     트랜잭션 %s가 롤백되고, 다른 원격 db는 불명료한 상태입니다.
ora-02051     동일 트랜잭션내에 다른 세션이 실패했습다.
ora-02052     원격 트랜잭션이 %s에서 실패했습니다.
ora-02053     트랜잭션 %s가 커밋되고, 다른 원격 db는 불명료한 상태입니다.
ora-02054     트랜잭션 %s이 불명료한 상태입니다.
ora-02055     분산 수정 작업이 실패했음; 롤백이 요구됩니다.
ora-02056     2pc: %s: 잘못된 두 단계 명령어 번호 %s(%s로 부터의)
ora-02057     2pc: %s: 잘못된 두 단계 복구상태 번호 %s(%s로 부터의)
ora-02058     id %s를 가지는 준비된 트랜잭션이 없습니다.
ora-02059     커밋 코맨트의 ora-2pc-crash-test-%s
ora-02060     select for update문에 분산 테이블에 대한 결합이 지정되었습니다.
ora-02061     select for update에 분산 테이블 목록이 지정되었습니다.
ora-02062     분산 복구가 dbid %s를 받았습니다(%s가 기대되었으나)
ora-02063     %s%s가 선행됨 (%s%s로 부터)
ora-02064     분산 작업이 지원되지 않습니다.
ora-02065     alter system에 대한 부당한 옵션
ora-02066     누락 혹은 부당한 mts_dispatchers 텍스트
ora-02067     트랜잭션 혹은 세이브포인트 롤백이 요구됩니다.
ora-02068     %s%s로 부터의 다음의 치명적인 오류가 있습니다.
ora-02069     global_names 파라미터는 이 작업에 true라고 설정해야만 합니다.
ora-02070     데이타베이스 %s%s는 이문맥에서 %s를 지원하지 않습니다.
ora-02071     원격 데이타베이스 %s에 대한 능력을 초기화시 오류
ora-02072     분산 데이타베이스의 네트워크 프로토콜이서로 맞지 않습니다.
ora-02073     원격 수정에서는 시퀀스번호가 지원되지 않습니다.
ora-02074     분산 트랜잭션에 %s을 할 수 없습니다.
ora-02075     사용되지 않는 오류입니다.
ora-02076     수정된 테이블이나 long 열의 시퀀스가 동일한 노드에 있어야 합니다.
ora-02077     select문에서 long 열의 값을 가지고 올때는 동일한 노드에 있어야 합니다.
ora-02078     alter system fixed_date에 대한 지정이 잘못됐습니다.
ora-02079     새로운 세션이 분산 트랜잭션의 커밋에 동참할 수 있습니다.
ora-02080     데이타베이스 링크가 사용중입니다.
ora-02081     데이타베이스 링크가 열려있지 않았습니다.
ora-02082     루프백(loopback) 데이타베이스 링크는 연결 수식어를 가져야합니다.
ora-02083     데이타베이스명에 부적절한 문자 %s가 있습니다.
ora-02084     데이타베이스명에 요소가 누락되었습니다.
ora-02085     데이타베이스 링크 %s가 %s에 연결됩니다.
ora-02086     데이타베이스 (링크)명이 너무깁니다.
ora-02087     동일 트랜잭션내의 다른 프로세스에 의해 개체가 잠금 되었습니다.
ora-02088     분산 데이타베이스 옵션이 설치되지 않았습니다.
ora-02089     종속 세션에서는 commit이 허용되지 않습니다.
ora-02090     네트워크 오류: callback+passthru
ora-02091     트랜잭션이 롤백되었습니다.
ora-02092     분산 트랜잭션에 대한 트랜잭션 테이블 슬롯이 부족합니다.
ora-02093     transactions_per_rollback_segment(%s)가 가능한 최대치(%s) 보다 많습니다.
ora-02094     중복 옵션이 설치되지 않았습니다.
ora-02095     지정된 초기화 파라미터를 수정할 수 없습니다.
ora-02096     지정된 초기화 파라미터는 이 옵션으로 수정가능하지 않습니다.
ora-02098     색인-테이블 참조 (:i)를 파싱하는데 오류
ora-02099     내부 목적으로 사용됨, 출력되지 않아야 합니다.
ora-02100     pcc: 메모리 부족 (할당할 수 없습니다.
ora-02101     pcc: 일치하지 않는 커서 캐쉬(uce/cuc 불일치)
ora-02102     pcc: 일치하지 않는 커서 캐쉬(이 uce에 대한 cuc 엔트리가 없습니다.
ora-02103     pcc: 일치하지 않는 커서 캐쉬(cuc 참조가 범위를 벗어남)
ora-02104     pcc: 일치하지 않는 호스트 캐쉬(사용가능한 cuc가 없습니다)
ora-02105     pcc: 일치하지 않는 커서 캐쉬(캐쉬내에 cuc 엔트리가 없습니다)
ora-02106     pcc: 일치하지 않는 커서 캐쉬(oracursor nr이 잘못됐습니다)
ora-02107     pcc: 프로그램이 수행시 라이브러리에 대해 너무 오래됨: 다시 pcc하십시오
ora-02108     pcc: 수행시 라이브러리에 유효하지않은 디스크립터가 넘겨졌습니다.
ora-02109     pcc: 일치하지 않는 호스트 캐쉬(sit 참조가 범위를 벗어남)
ora-02110     pcc: 일치하지 않는 호스트 캐쉬(유효하지 않은 sqi 유형)
ora-02111     pcc: 힙 일관성 오류
ora-02112     pcc: select..into가 너무 많은 행을 리턴합니다.
ora-02140     테이블스페이스 이름이 부적합합니다.
ora-02141     offline 옵션이 부적합합니다.
ora-02142     적절한 alter tablespace 옵션을 지정해 주십시오
ora-02143     storage 옵션이 부적합합니다.
ora-02144     적절한 alter cluster 옵션을 지정해 주십시오
ora-02145     storage 옵션을 지정해 주십시오
ora-02146     shared 옵션이 복수 회 지정되었습니다.
ora-02147     shared 와 exclusive 는 혼용할 수 없습니다.
ora-02148     exclusive 옵션이 복수 회 지정되었습니다.
ora-02155     default 테이블 영역 식별자가 부적합합니다.
ora-02156     temporary의 테이블 영역 식별자가 부적합합니다.
ora-02157     alter user 옵션을 지정해 주십시오
ora-02158     create index 옵션이 부적합합니다.
ora-02159     설치된 dlm은 릴리즈가능한 잠금 모드를 지원하지 않습니다.
ora-02161     maxlogfiles에 대한 값이 부적합합니다.
ora-02162     maxdatafiles에 대한 값이 부적합합니다.
ora-02163     freelist groups에 대한 값이 부적합합니다.
ora-02164     datafile 구가 2개 이상 지정되었습니다.
ora-02165     create database 옵션의 지정이 부적합합니다.
ora-02166     archivelog 와 noarchivelog 가 함께 지정되었습니다.
ora-02167     logfile 구가 2 회 이상 지정되었습니다.
ora-02168     freelists에 대한 부당한 값
ora-02169     freelists 저장영역 옵션은 허용되지 않습니다.
ora-02170     freelist groups 저장영역 옵션은 허용되지 않습니다.
ora-02171     maxloghistory에 대한 부당한 값
ora-02172     사용불가 쓰레드에 대한 public 키워드는 적합하지 않습니다.
ora-02173     drop tablespace 옵션이 부적합합니다.
ora-02174     요구되는 쓰레드 번호의 누락
ora-02175     롤백 세그먼트 명이 부적합합니다.
ora-02176     create rollback segment 옵션이 부적합합니다.
ora-02177     요구되는 그룹 번호의 누락
ora-02178     올바른 구문 : set transaction read { only | write }
ora-02179     적당한 옵션: isolation level { serializable | read committed }
ora-02180     create tablespace 옵션이 부적합합니다.
ora-02181     rollback work 옵션이 부적합합니다.
ora-02182     세이브포인트명을 지정해 주십시오
ora-02183     적당한 옵션: isolation_level { serializable | read committed }
ora-02184     revoke 에서는 자원의 할당량을 지정할 수 없습니다.
ora-02185     commit 뒤에 work 이외의 토큰이 지정되었습니다.
ora-02186     테이블 영역의 자원 권한은 다른 권한과 동시에 지정할 수 없습니다.
ora-02187     할당량의 지정이 부적합합니다.
ora-02189     on <tablespace> 가 필요합니다.
ora-02190     키워드 tables를 지정해 주십시오
ora-02191     올바른 구문: set transaction use rollback segment <rbs>
ora-02192     pctincrease는 롤백 세그먼트 영역절에서는 허용되지 않습니다.
ora-02194     이벤트 지정 구문 오류 %s (중요치 않은 오류 %s), %s 부근에
ora-02195     %s 개체를 %s 테이블스페이스에서 만들도록 시도합니다.
ora-02196     permanent/temporary 옵션이 이미 지정되었습니다.
ora-02197     화일 리스트가 이미 지정되어 있습니다.
ora-02198     online/offline 옵션이 이미 지정되어 있습니다.
ora-02199     datafile 구를 지정해 주십시오
ora-02200     with grant option 은 public 에 대하여 사용할 수 없습니다.
ora-02201     시퀀스를 사용할 수 없습니다.
ora-02202     클러스터에서는 더이상의 테이블을 작성할 수 없습니다.
ora-02203     initial 영역 옵션은 허가되지 않습니다.
ora-02204     alter, index, references 그리고 execute는 뷰에서 사용할 수 없습니다.
ora-02205     select 와 alter 권한만이 시퀀스에 대하여 사용할 수 있습니다.
ora-02206     initrans 옵션 지정이 중복되었습니다.
ora-02207     initrans 옵션의 값이 부적합합니다.
ora-02208     maxtrans 옵션 지정이 중복되었습니다.
ora-02209     maxtrans 옵션의 값이 부적합합니다.
ora-02210     alter table 옵션을 지정해 주십시오
ora-02211     pctfree 또는 pctused 에 대한 값이 부적합합니다.
ora-02212     pctfree 옵션 지정이 중복되었습니다.
ora-02213     pctused 옵션 지정이 중복되었습니다.
ora-02214     backup 옵션 지정이 중복되었습니다.
ora-02215     tablespace 구가 중복되었습니다.
ora-02216     테이블 영역명을 지정해 주십시오
ora-02217     기억 영역(storage) 옵션 지정이 중복되었습니다.
ora-02218     initial 옵션의 값이 부적합합니다.
ora-02219     next 옵션의 값이 부적합합니다.
ora-02220     minextents 옵션의 값이 부적합합니다.
ora-02221     maxextents 옵션의 값이 부적합합니다.
ora-02222     pctincrease 옵션의 값이 부적합합니다.
ora-02223     부당한 optimal 저장 영역 옵션값
ora-02224     execute 권한은 테이블에 대해서는 허용되지 않습니다.
ora-02225     프로시저에 대해서는 execute 권한만이 유효합니다.
ora-02226     부당한 maxextents값 (허용 최대치: %s)
ora-02227     클러스터명이 부적합합니다.
ora-02228     size 지정이 중복되었습니다.
ora-02229     size 옵션의 값이 부적합합니다.
ora-02230     alter cluster 옵션이 부적합합니다.
ora-02231     적절한 alter database 옵션을 지정해 주십시오
ora-02232     mount 모드가 부적합합니다.
ora-02233     close 모드가 부적합합니다.
ora-02234     이 테이블에 대한 변경은 이미 로그되어 있습니다.
ora-02235     이 테이블은 다른 테이블에 이미 변경을 기록했습니다.
ora-02236     화일명이 부적합합니다.
ora-02237     화일 크기가 부적합합니다.
ora-02238     화일명 리스트의 화일 수가 다릅니다.
ora-02239     이 시퀀스를 참조하는 개체가 있습니다.
ora-02240     objno 혹은 tabno에 대한 부당한 값
ora-02241     extents (file <n> block <n> size <n>, ...)유형이어야 합니다.
ora-02242     alter index 옵션을 지정해 주십시오
ora-02243     alter index 또는 alter snapshot 옵션이 부적합합니다.
ora-02244     alter rollback segment 옵션이 부적합합니다.
ora-02245     롤백 세그먼트 명이 부적합합니다.
ora-02246     events 의 텍스트를 지정해 주십시오
ora-02247     alter session 옵션을 지정해 주십시오
ora-02248     alter session 옵션이 부적합합니다.
ora-02249     maxlogmembers에 값이 빠졌거나 부당한 값입니다.
ora-02250     적절한 제약명을 지정해 주십시오
ora-02251     부속 질의는 사용할 수 없습니다.
ora-02252     검사 제약 조건이 올바르지 않습니다.
ora-02253     제약을 지정할 수 없습니다.
ora-02254     default <expression>은 사용할 수 없습니다.
ora-02255     못쓰게된 7.1.5
ora-02256     참조하고 있는 열의 숫자, 유형 그리고 크기는 참조 열의 수와 일치해야 합니다.
ora-02257     열의 최대수를 초과했습니다.
ora-02258     null, not null 지정이 중복 또는 혼재되었습니다.
ora-02259     unique/primary key의 지정이 중복되었습니다.
ora-02260     테이블에는 기본 키를 1 개만 포함시킬 수 있습니다.
ora-02261     유일 키 또는 기본 키가 이미 존재하고 있습니다.
ora-02262     ora-%05d 발생. 열의 디폴트 값 식의 유형 검사 오류.
ora-02263     열의 데이타 유형을 지정해 주십시오
ora-02264     기존의 제약에 사용된 이름입니다.
ora-02265     참조 열의 데이타 유형이 정의되지 않았습니다.
ora-02266     외래 키에 의해 참조되는 유일/기본 키가 테이블에 있습니다.
ora-02267     열의 데이타 유형이 참조 열의 데이타 유형와 일치하지 않습니다.
ora-02268     참조 테이블에 기본 키가 없습니다.
ora-02269     키 열은 long 데이타 유형을 취할 수 없습니다.
ora-02270     이 열목록에 대한 유일 혹은 일차 키가 일치하지 않습니다.
ora-02271     제약명이 없습니다.
ora-02272     제약 열은 long 데이타 유형을 취할 수 없습니다.
ora-02273     유일/기본 키가 외부 키에 의해 참조되었습니다.
ora-02274     중복된 참조 제약 지정입니다.
ora-02275     참조 제약이 이미 테이블에 존재합니다.
ora-02276     디폴트 유형이 열의 유형과 일치하지 않습니다.
ora-02277     시퀀스명이 부적합합니다.
ora-02278     maxvalue/nomaxvalue 지정이 중복 또는 혼재되어 있습니다.
ora-02279     minvalue/nominvalue 지정이 중복 또는 혼재되어 있습니다.
ora-02280     cycle/nocycle 지정이 중복 또는 혼재되어 있습니다.
ora-02281     cache/nocache 지정이 중복 또는 혼재되어 있습니다.
ora-02282     order/noorder 지정이 중복 또는 혼재되어 있습니다.
ora-02283     개시 시퀀스 번호는 변경할 수 없습니다.
ora-02284     increment by 지정이 중복되었습니다.
ora-02285     start with 지정이 중복되었습니다.
ora-02286     alter sequence 옵션을 지정해 주십시오
ora-02287     시퀀스 번호는 이 위치에 사용할 수 없습니다.
ora-02288     open 모드가 부적합합니다.
ora-02289     시퀀스가 존재하지 않습니다.
ora-02290     체크 제약조건(%s.%s)이 위배되었습니다.
ora-02291     무결성 제약조건(%s.%s)이 위배되었습니다- 부모 키가 없습니다.
ora-02292     무결성 제약조건(%s.%s)이 위배되었습니다- 자식 레코드가 발견되었습니다.
ora-02293     (%s.%s)를 사용가능하게 할 수 없습니다 - 잘못된 제약을 점검
ora-02294     참조 제약을 추가할 수 없음 - 부모 키가 없습니다.
ora-02295     제약에 대한 하나 이상의 사용가능/사용불가 절이 있습니다.
ora-02296     제약 (%s.%s)을 사용가능하게 할 수 없음 - 부합하는 값이 없습니다.
ora-02297     제약 (%s.%s)을 사용불가하게 할 수 없음 - 종속관계가 있습니다.
ora-02298     제약 (%s.%s)을 사용가능하게 할 수 없음 - 부모 키가 없습니다.
ora-02299     제약 (%s.%s)을 사용가능하게 할 수 없음 - 중복 키가 있습니다.
ora-02351     레코드 %s: 거부되었습니다- 테이블 %s, 열 %s에서 오류
ora-02352     직접 패스 연결은 동기종 간에만 가능합니다.
ora-02353     복수 자리의 문자 오류
ora-02354     필드 %s에 대한 초기치를 위한 변환 오류가 발생했습니다.
ora-02355     constant 필드 %s에 변환 오류가 발생했습니다.
ora-02356     데이타베이스에 더 이상 영역이 없음 - 로드를 계속할 수 없습니다.
ora-02357     팩형 십진수 변환 오류
ora-02358     존 십진수 변환 오류
ora-02359     데이타 화일의 필드가 지정된 길이를 초과합니다.
ora-02360     논리 레코드의 끝 이전에 열을 찾을 수 없습니다 (trailing nullcols사용)
ora-02361     최초 인클로징 문자를 찾을 수 없습니다.
ora-02362     논리 레코드의 끝 - 두번째 인클로징 문자가 없습니다.
ora-02363     terminated 와 enclosed 가 지정된 필드에 종료 문자가 없습니다.
ora-02364     %s 레코드가 디스카드됨 - 모든 when 구의 조건을 만족하지 않습니다.
ora-02365     %s 색인이 로드되지 못함
ora-02366     %s 테이블의 다음 색인이 처리되었습니다.
ora-02367     %s 색인이 로드되었습니다.
ora-02368     %s 레코드가 디스카드됨 - 모든 열이 널입니다.
ora-02369     경고 : 가변길이 필드가 잘렸습니다.
ora-02370     %s 레코드 - %s 테이블의 %s 열에 경고 발생
ora-02371     직접 패스를 위해서는 로더가 %s.%s.%s.%s.%s 버전 이상 이어야 합니다.
ora-02372     상대시작 위치 > 절대필드 마감 위치
ora-02373     테이블 %s에 대한 입력 문의 구문분석시 오류
ora-02374     읽기 버퍼 큐에 대한 더 이상의 슬롯이 없습니다.
ora-02376     부당한 혹은 중복된 자원
ora-02377     자원의 부당한 한계치
ora-02378     중복된 자원명 %s
ora-02379     프로화일 %s이 이미 존재합니다.
ora-02380     프로화일 %s이 존재하지 않습니다.
ora-02381     public_default 프로화일을 삭제할 수 없습니다.
ora-02382     프로화일 %s에 사용자가 할당되어 있어, cascade 없이 삭제할 수 없습니다.
ora-02383     부당한 비용요소
ora-02390     composite_limit을 초과했음, 로그오프될 것입니다.
ora-02391     동시 sessions_per_user 한계치를 초과했습니다.
ora-02392     cpu 사용에 대한 세션 한계치를 초과했음. 로그오프될 것입니다.
ora-02393     cpu 사용에 대한 호출 한계치를 초과했습니다.
ora-02394     io 사용에 대한 세션 한계치를 초과했음. 로그오프될 것입니다.
ora-02395     io 사용에 대한 호출 한계치를 초과했습니다.
ora-02396     최대 유휴(idle) 시간을 초과했음. 다시 연결하십시오
ora-02397     private_sga 한계치 초과, 로그오프될 것입니다.
ora-02398     프로시저 영역 사용을 초과했습니다.
ora-02399     최대 연결시간을 초과했음. 로그오프될 것입니다.
ora-02401     다른 사용자의 뷰를 explain 할 수 없습니다.
ora-02402     plan_table이 없습니다.
ora-02403     플랜 테이블이 정확한 유형이 아닙니다.
ora-02404     지정된 플랜 테이블이 없습니다.
ora-02420     스키마에 대한 권한부여 절의 누락
ora-02421     누락 혹은 부당한 스키마 권한 식별자
ora-02422     누락 혹은 부당한 스키마 요소
ora-02423     스키마명이 스키마 권한 식별자와 맞지 않습니다.
ora-02424     잠재적인 순환 뷰 참조 혹은 불명의 참조 테이블
ora-02425     테이블의 생성실패
ora-02426     권한 부여 실패
ora-02427     뷰의 생성실패
ora-02428     외래키 참조를 추가할 수 없습니다.
ora-02429     유일/일차 키 적용을 위한 색인을 삭제할 수 없습니다.
ora-02430     제약(%s)을 가용화할 수 없음 - 그런 제약이 없습니다.
ora-02431     제약(%s)을 사용불가하게 할 수 없음 - 그런 제약이 없습니다.
ora-02432     일차키를 사용가능하게 할 수 없음 - 테이블에 일차키가 정의되지 않았습니다.
ora-02433     일차키를 사용불가하게 수 없음 - 테이블에 일차키가 정의되지 않았습니다.
ora-02434     유일성(%s)을 사용가능하게 할 수 없음 - 테이블에 일차키가 정의되지 않았습니다.
ora-02435     유일성(%s)을 사용불가하게 수 없음 - 테이블에 일차키가 정의되지 않았습니다.
ora-02436     check 제약에 날짜 또는 시스템 변수가 잘못 지정되었습니다.
ora-02437     (%s.%s)를 사용가능하게 할 수 없습니다 - 잘못된 기본 키입니다.
ora-02438     열 검사제약은 다른 열을 참조할 수 없습니다.
ora-02439     유일/일차 키 제약상에 유일하지 않은 색인이 있습니다.
ora-02440     참조 제약과 함께 create as select는 허용되지 않습니다.
ora-02441     존재하지 않는 일차 키를 삭제할 수 없습니다.
ora-02442     존재하지 않는 유일 키를 삭제할 수 없습니다.
ora-02443     존재하지 않는 제약 - 삭제할 수 없습니다.
ora-02444     참조 제약에서만 기본 테이블을 참조할 수 없습니다.
ora-02445     예외 테이블이 없습니다.
ora-02446     create table ... as select 실패 - 제약 위반 점검
ora-02450     부당한 해쉬 옵션 - 키워드 is 누락
ora-02451     hashkeys의 중복지정
ora-02452     부당한 hashkeys 옵션값
ora-02453     hash is의 중복 지정
ora-02454     블록(%s)당 해쉬 키의 수가 최대치 %s를 초과했습니다.
ora-02455     클러스터키 열의 수는 1 이어야 합니다.
ora-02456     열 지정 hash is는 number(*,0)이어야 합니다.
ora-02457     hash is 옵션에 정당한 열을 지정하여야 합니다.
ora-02458     hash cluster에 대하여 hashkeys가 지정되어야 합니다.
ora-02459     해쉬 키 값은 양의 정수이어야 합니다.
ora-02460     해쉬 클러스터에 대한 부적절한 색인 작업입니다.
ora-02461     index 옵션의 부적절한 사용입니다.
ora-02462     index 옵션의 중복지정
ora-02463     hash is 옵션의 중복지정
ora-02464     클러스터 정의는 hash와 index 양쪽 다 일수는 없습니다.
ora-02465     hash is 옵션의 부적절한 사용
ora-02466     hash clusters를 위해 size 옵션의 변경은 허용되지 않습니다.
ora-02467     식에 참조된 열을 클러스터 정의에서 찾을 수 없습니다.
ora-02468     식에서 상수 또는 시스템 변수가 잘못 지정되었습니다.
ora-02469     해쉬 식은 oracle 번호를 리턴하지 않습니다.
ora-02470     to_date, userenv, 또는 sysdate가 해쉬 식에서 잘못 사용되었습니다.
ora-02471     sysdate, uid, user, rownum, 또는 level이 해쉬 식에서 잘못 사용되었습니다.
ora-02472     해쉬 식에 pl/sql 함수를 사용할 수 없습니다.
ora-02473     클러스터 해쉬 식의 값을 구하는 동안 오류 발생
ora-02474     고정된 해쉬 영역이 (%s) 범위를 사용했는데 허용된 (%s) 최대값을 초과했습니다.
ora-02476     테이블에서 병렬 직접 로드에 의해 색인을 만들수 없습니다.
ora-02477     개체 %s에 병렬 직접 로드를 실행할 수 없습니다.
ora-02478     기초 세그먼트에 합병하는것은 maxextents 한계을 초과하는 것입니다.
ora-02479     병렬 로드에다 화일명을 바꾸는 중에 오류가 발생했습니다.
ora-02480     이벤트에 대한 너무 많은 이벤트 클래스가 지정되었습니다.
ora-02481     이벤트에 대한 너무 많은 id 범위가 지정되었습니다.
ora-02482     이벤트 클래스를 지정했으나 이벤트를 주지 않았습니다.
ora-02483     이벤트에 대한 부당한 id 값을 지정했습니다.
ora-02485     id 값의 하한치가 상한치보다 큽니다.
ora-02486     화일 %s에서 오류. init.ora 파라미터인 trace_dest를 확인하십시오
ora-02487     화일명 %s을 기록시 오류. init.ora 파라미터인 trace_dest를 검사하십시오
ora-02489     trace_block_size (%s)가 %s로 나누어져야 합니다.
ora-02490     resize 절에 필요한 화일 크기가 빠졌습니다.
ora-02491     autoextend 절에 필요한 on 또는 off 키워드가 빠졌습니다.
ora-02492     next 절에 필요한 화일 블록 증가 크기가 빠졌습니다.
ora-02493     next 절의 화일 증가 크기가 부적당합니다.
ora-02494     maxsize 절의 최대 화일 크기가 부적당하거나 빠졌습니다.
ora-02495     화일 %s의 크기를 조정할 수 없는데, 테이블스페이스 %s가 읽기전용이기 때문입니다.
ora-02700     osnoraenv: oracle_sid의 변환시 오류입니다.
ora-02701     osnoraenv: 오라클 이미지명의 변환시 오류입니다.
ora-02702     osnoraenv: orapop 이미지명의 변환시 오류입니다.
ora-02703     osnpopipe: 파이프 생성에 실패했습니다.
ora-02704     osndopop: 포크에 실패했습니다.
ora-02705     osnpol: 통신 채널의 폴링에 실패했습니다.
ora-02706     osnshs: 호스트명이 너무 깁니다.
ora-02707     osnacx: 문맥 영역을 할당할 수 없습니다.
ora-02708     osnrntab: 호스트로의 연결에 실패, oracle_sid가 불명입니다.
ora-02709     osnpop: 파이프 생성에 실패했습니다.
ora-02710     osnpop: 포크(fork)에 실패했습니다.
ora-02711     osnpvalid: 검증 채널로의 연결에 실패했습니다.
ora-02712     osnpop: malloc 실패
ora-02713     osnprd: 메세지 수신에 실패했습니다.
ora-02714     osnpwr: 메세지 송신에 실패했습니다.
ora-02715     osnpgetbrkmsg: 호스트로부터의 메시지가 부정확한 메시지 유형을 갖습니다.
ora-02716     osnpgetdatmsg: 호스트로부터의 메시지가 부정확한 메시지 유형을 갖습니다.
ora-02717     osnpfs: 기록된 바이트 수가 잘못되었습니다.
ora-02718     osnprs: 프로토콜 재설정 오류
ora-02719     osnfop: 포크(fork)에 실패했습니다.
ora-02720     osnfop: shmat 실패
ora-02721     osnseminit: 세마포 세트를 생성할 수 없습니다.
ora-02722     osnpui: orapop에 중지메시지를 송신할 수 없습니다.
ora-02723     osnpui: 중지메시지를 송신할 수 없습니다.
ora-02724     osnpbr: orapop에 중지메시지를 송신할 수 없습니다.
ora-02725     osnpbr: 중지메시지를 송신할 수 없습니다.
ora-02726     osnpop: 오라클 수행모듈의 액세스 오류입니다.
ora-02727     osnpop: orapop 수행모듈의 액세스 오류입니다.
ora-02728     osnfop: 오라클 수행모듈의 액세스 오류입니다.
ora-02729     osncon: 드라이버가 osntab내에 없습니다.
ora-02730     osnrnf: 사용자 로그온 디렉토리가 없습니다.
ora-02731     osnrnf: 버퍼의 malloc에 실패했습니다.
ora-02732     osnrnf: 일치하는 데이타베이스 별명을 발견할 수 없습니다.
ora-02733     osnsnf: 데이테베이스 스트링이 너무 깁니다.
ora-02734     osnftt: 공유 메모리의 사용허가를 재설정할 수 없습니다.
ora-02735     osnfpm: 공유 메모리 세그먼트를 생성할 수 없습니다.
ora-02736     osnfpm: 부적절한 공유메모리 번지의 디폴트치입니다.
ora-02737     osnpcl: orapop의 종료를 명령할 수 없습니다.
ora-02738     osnpwrtbrkmsg: 기록된 바이트 수가 잘못되었습니다.
ora-02739     osncon: 호스트 별명이 너무 깁니다.
ora-02750     osnfsmmap: 공유메모리 화일(?/dbs/ftt_<pid>.dbf)을 열 수 없습니다.
ora-02751     osnfsmmap: 공유메모리 화일을 배치할 수 없습니다.
ora-02752     osnfsmmap: 부당한 공유메모리 번지입니다.
ora-02753     osnfsmmap: 공유메모리 화일을 닫을 수 없습니다.
ora-02754     osnfsmmap: 공유메모리의 형질을 변경할 수 없습니다.
ora-02755     osnfsmcre: 공유메모리 화일(?/dbs/ftt_<pid>.dbf)을 생성할 수 없습니다.
ora-02756     osnfsmnam: 이름 변환에 실패했습니다.
ora-02757     osnfop: fork_and_bind 실패
ora-02758     내부배열의 할당에 실패했습니다.
ora-02759     요구 디스크립터가 충분하지 않습니다.
ora-02760     클라이언트의 화일 닫기 실패
ora-02761     취소될 화일 번호가 음수입니다.
ora-02762     취소될 화일 번호가 최대치보다 큽니다.
ora-02763     최소 한건의 요구도 취소할 수 없습니다.
ora-02764     부당한 패키지 모드입니다.
ora-02765     부당한 최대 서버수입니다.
ora-02766     요구 디스크립터의 부당한 최대치입니다.
ora-02767     서버당 하나 이하의 요구 디스크립터가 할당되었습니다.
ora-02768     최대 화일수가 부적절합니다.
ora-02769     sigterm에 대한 처리기 지정이 실패했습니다.
ora-02770     전체 블록수가 부적절합니다.
ora-02771     요구 타임아웃 값이 부적절합니다.
ora-02772     서버의 최대 유휴 시간이 부적절합니다.
ora-02773     클라이언트의 최대 대기시간이 부적절합니다.
ora-02774     요구 목록 래치의 타임아웃값이 부적절합니다.
ora-02775     요구 수행 신호가 부적절합니다.
ora-02776     요구 수행 신호값이 최대치를 초과합니다.
ora-02777     로그 디렉토리에 대한 stat실패
ora-02778     로그 디렉토리에 주어진 이름이 부적합합니다.
ora-02779     코아덤프 디렉토리에 대한 stat실패
ora-02780     코아덤프 디렉토리에 주어진 이름이 부적합합니다.
ora-02781     시간이 주어지는 플래그에 대한 값이 부적합합니다.
ora-02782     읽기/쓰기 기능이 모두 지정되지 않았습니다.
ora-02783     포스트/대기 기능이 모두 지정되지 않았습니다.
ora-02784     부적절한 공유 메모리 id가 지정되었습니다.
ora-02785     부적절한 공유 메모리 버퍼크기입니다.
ora-02786     공유 영역에 필요한 크기가 세그먼트 크기보다 큽니다.
ora-02787     세그먼트 목록에 대한 메모리를 할당할 수 없습니다.
ora-02788     async 프로세스 배열내에 커널 프로세스 포인터를 찾을 수 없습니다.
ora-02789     최대 화일 수에 도달했습니다.
ora-02790     화일명이 너무 깁니다.
ora-02791     비동기 i/o에 사용될 화일을 열 수 없습니다.
ora-02792     비동기 i/o에 사용될 화일을 fstat()할 수 없습니다.
ora-02793     비동기 i/o의 닫기 실패
ora-02794     클라이언트가 공유메모리에 대한 키를 얻을 수 없습니다.
ora-02795     요구 목록이 비었습니다.
ora-02796     수행된 요구가 정확한 상태에 있지 않습니다.
ora-02797     모든 요구에 응답할 수 없습니다.
ora-02798     요구 수가 부적절합니다.
ora-02799     신호 처리기를 대비할 수 없습니다.
ora-02800     요구가 시간 경과되었습니다.
ora-02801     작업이 시간 경과되었습니다.
ora-02802     모든 유휴 서버를 병렬모드에서 사용할 수 없습니다.
ora-02803     현재 시간의 추출에 실패했습니다.
ora-02804     로그 화일명에 대한 메모리 할당에 실패했습니다.
ora-02805     sigtpa에 대한 처리기를 지정할 수 없습니다.
ora-02806     sigalrm에 대한 처리기를 지정할 수 없습니다.
ora-02807     i/o 벡터에 대한 메모리 할당에 실패했습니다.
ora-02808     서버가 사용하는 flag array를 위한 메모리 할당에 실패했습니다.
ora-02809     jump 버퍼가 적절하지 않습니다.
ora-02810     메모리 맵화일에 대한 임시 화일명을 만들수 없습니다.
ora-02811     공유메모리 세그먼트를 첨부할 수 없습니다.
ora-02812     잘못된 첨부 번지입니다.
ora-02813     키를 얻기위한 임시화일명을 만들수 없습니다.
ora-02814     공유 메모리를 얻을 수 없습니다.
ora-02815     공유 메모리를 첨부할 수 없습니다.
ora-02816     프로세스를 죽일 수 없습니다.
ora-02817     읽기실패
ora-02818     요구된 것보다 적은 수의 블록이 읽혀졌습니다.
ora-02819     쓰기실패
ora-02820     요구된 수의 블록을 기록할 수 없습니다.
ora-02821     요구된 수의 블록을 읽을 수 없습니다.
ora-02822     부적절한 블록 오프셋
ora-02823     버퍼가 정열되지 않았습니다.
ora-02824     가용 요구 목록이 비었습니다.
ora-02825     자유롭게 선택할 수 있는 목록에 대한 요구가 해제되지 않았습니다.
ora-02826     부적절한 블록크기 입니다.
ora-02827     부당한 화일번호입니다.
ora-02828     가용 세그먼트 목록이 비었습니다.
ora-02829     적절한 크기의 세그먼트가 없습니다.
ora-02830     세그먼트는 파티션될 수 없음 - 가용 세그먼트가 없습니다.
ora-02831     세그먼트 할당해제 실패 - 세그먼트 목록이 비었습니다.
ora-02832     세그먼트 할당해제 실패 - 세그먼트가 목록에 없습니다.
ora-02833     서버가 화일을 닫을 수 없습니다.
ora-02834     서버가 화일을 열 수 없습니다.
ora-02835     서버가 클라이언트에 신호을 송신할 수 없습니다.
ora-02836     임시 키 화일을 생성할 수 없습니다.
ora-02837     임시 화일을 링크 해제할 수 없습니다.
ora-02838     알람 신호를 위한 신호처리기를 대비할 수 없습니다.
ora-02839     디스크로 블록을 sync하는데 실패했습니다.
ora-02840     클라이언트가 로그 화일을 여는데 실패했습니다.
ora-02841     기동시 서버가 죽었습니다.
ora-02842     클라이언트가 서버를 포크할 수 없습니다.
ora-02843     커널 플래그에 대한 부적절한 값입니다.
ora-02844     열기 허가 플래그에 대한 부적절한 값입니다.
ora-02845     시각 요구 플래그에 대한 부적절한 값입니다.
ora-02846     중지시킬 수 없는 서버입니다.
ora-02847     포스트시 서버가 종료되지 않았습니다.
ora-02848     비동기 i/o 패키지가 가동중이 아닙니다.
ora-02849     오류로 인한 읽기 실패
ora-02850     화일이 닫혔습니다.
ora-02851     비어있지 않아야할 요구 목록이 비었습니다.
ora-02852     위험 부분에 대한 부적절한 타임아웃 값입니다.
ora-02853     서버 목록 래치 타임아웃 값이 부적절합니다.
ora-02854     요구 버퍼의 수가 부적절합니다.
ora-02855     요구건수가 slaves수 보다 작습니다.
ora-03001     현재에는 구현되어 있지 않은 기능입니다.
ora-03002     이 연산자는 구현되어 있지 않습니다.
ora-03007     이 기능은 폐지되었습니다.
ora-03008     파라미터 compatible >= %s 가 %s에 필요합니다.
ora-03100     통신 영역이 할당되지 않음. 메모리가 충분하지 않습니다.
ora-03105     내부 프로토콜 오류
ora-03106     두 태스크 간의 통신 프로토콜 오류입니다.
ora-03107     oranet 버퍼 언더플로우입니다.
ora-03108     oranet: oracle은 이 인터페이스 버전을 지원하지 않습니다.
ora-03109     oranet 버퍼 오버플로우입니다.
ora-03110     oranet: oracle은 이 sql 버전을 지원하지 않습니다.
ora-03111     통신 채널에서 브레이크를 수신했습니다.
ora-03112     단일-태스크로 링크된 서버는 sql*net을 사용할 수 없습니다.
ora-03113     통신 채널에 eof 가 있습니다.
ora-03114     oracle에 연결되어 있지 않습니다.
ora-03115     지원되지 않은 네트워크 데이타 유형 또는 표현이 있습니다.
ora-03116     부적당한 버퍼 길이가 변환 루틴으로 전달되었습니다.
ora-03117     2-타스크 보존 영역 오버플로우
ora-03118     2-타스크 코루틴의 상태가 부적당합니다.
ora-03120     2-타스크 변환 루틴: 정수 오버플로우
ora-03121     인터페이스 드라이버가 연결되어 있지 않습니다 함수는 실행되지 않습니다.
ora-03122     사용자측에서 oracle측의 윈도우를 클로즈하려 했습니다.
ora-03123     작업이 막힘
ora-03124     2-타스크 내부 오류
ora-03125     클라이언트-서버 프로토콜에 위배됩니다.
ora-03126     네트워크 드라이버가 비-블로킹 작업을 지원하지 않습니다.
ora-03127     실행 작업이 종료되기 전에는 새로운 작업을 할 수 없습니다.
ora-03128     연결은 블로킹 모드입니다.
ora-03129     다음 구분이 삽입되도록 요청했습니다.
ora-03130     다음 구분이 인출 되도록 요청한 버퍼입니다.
ora-03131     다음 구분을 위한 버퍼가 잘못 제공되었습니다.
ora-03200     세그먼트 유형 명세가 부적당합니다.
ora-03201     그룹 번호 명세가 부적당합니다.
ora-03202     스캔 한계 명세가 부적당합니다.
ora-03203     동시 갱신은 영역 분석을 불가능하게 합니다.
ora-03230     세그먼트는 %s 블록만을 포함하고 있습니다.
ora-03231     initial 영역이 할당 해제되지 않았습니다.
ora-03274     allocate extent와 deallocate unused 옵션들이 지정되었습니다.
ora-03275     이중 deallocate 옵션으로 명세
ora-03276     allocate extent의 중복지정
ora-03277     부적절한 size의 지정
ora-03278     allocate extent 옵션의 중복지정
ora-03279     부적절한 instance가 지정되었음
ora-03280     부적절한 datafile 화일명의 지정
ora-03281     부적절한 allocate extent 옵션
ora-03282     allocate extent 옵션의 누락
ora-03283     지정된 데이타 화일 %s이 존재하지 않습니다.
ora-03284     데이타 화일 %s는 테이블스페이스 %s의 멤버가 아닙니다.
ora-03286     hash clusters에 대해 allocate extent가 정당하지 않습니다.
ora-03287     부적절한 freelist group의 지정
ora-03288     freelist group과 instance 파라미터가 함께 지정될 수 없습니다.
ora-03290     부적절한 truncate 명령어 - cluster 혹은 table 키워드의 누락
ora-03291     부적절한 truncate 옵션 - storage 키워드의 누락
ora-03292     잘릴 테이블이 클러스터의 일부입니다.
ora-03293     잘릴 클러스터는 hash cluster입니다.
ora-03296     데이타화일의 크기를 조정할 수 없습니다 - 화일 %s 이 없습니다.
ora-03297     요구된 resize 값보다 큰 %s 데이타 블록이 화일에 포함되어 있습니다.
ora-03298     데이타화일을 줄일 수 없습니다 - 화일 %s는 핫 백업중입니다.
ora-03299     딕셔너리 테이블 %s을 생성할 수 없습니다.
ora-04000     pctused 와 pctfree 의 합이 100을 초과할 수 없습니다.
ora-04001     시퀀스 파라미터 %s 는 정수라야 합니다.
ora-04002     increment 는 0이 아닌 정수라야 합니다.
ora-04003     시퀀스 파라미터 %s가 최대 크기 허용(%s 자리)를 초과했습니다.
ora-04004     minvalue 는 maxvalue 보다 작아야 합니다.
ora-04005     increment 는 ( maxvalue - minvalue ) 보다 작아야 합니다.
ora-04006     start with 에 minvalue 보다 작은 값은 지정할 수 없습니다.
ora-04007     minvalue 에 현재치보다 큰 값을 지정할 수 없습니다.
ora-04008     start with 에 maxvalue 보다 큰 값을 지정할 수 없습니다.
ora-04009     maxvalue 에 현재치보다 작은 값을 지정할 수 없습니다.
ora-04010     cache 에는 1 보다 큰 수치를 지정해야 합니다.
ora-04011     시퀀스 %s 은 %s 와 %s 범위 사이어야 합니다.
ora-04012     지정된 개체는 시퀀스가 아닙니다.
ora-04013     cache 에는 1 사이클보다 작은 값을 지정해야 합니다.
ora-04014     cycle이 명시하는 minvalue가 내림차순 시퀀스입니다.
ora-04015     cycle 을 실시하는 오름차순 시퀀스에는 maxvalue 를 지정해야 합니다.
ora-04016     시퀀스 %s 은 더 이상 존재하지 않습니다.
ora-04020     개체 %s%s%s%s%s의 잠금 시도중 데드록이 검출되었습니다.
ora-04021     개체 %s%s%s%s%s의 잠금 대기중 시간이 초과됐습니다.
ora-04028     개체 %s%s%s%s%s에 대한 diana를 생성할 수 없습니다.
ora-04029     %s%s%s를 조회하는 중에 ora-%s 오류가 발생했습니다.
ora-04030     %s바이트 (%s,%s)의 할당 시도중 프로세스 메모리의 부족현상 발생
ora-04031     %s 바이트의 공유 메모리를 할당할 수 없습니다 (%s,%s,%s)
ora-04041     패키지 본체의 생성전에 패키지 지정이 먼저 생성되어야 합니다.
ora-04042     프로시저,함수,패키지 혹은 패키지 본체가 존재하지 않습니다.
ora-04043     개체 %s가 존재하지 않습니다.
ora-04044     프로시저, 함수, 패키지는 이곳에서 허용되지 않습니다.
ora-04045     %s.%s의 재 컴파일/재 검증시 오류
ora-04046     컴파일 결과를 제공하기에는 너무 큽니다.
ora-04050     부적절한 혹은 누락된 프로시저, 함수, 혹은 패키지명입니다.
ora-04051     사용자 %s는 데이타베이스 링크 %s.%s를 사용할 수 없습니다.
ora-04052     원격 개체 %s%s%s%s%s를 찾는 동안 오류발생
ora-04053     원격 개체 %s%s%s%s%s의 검증시 오류발생
ora-04054     데이타베이스 링크 %s가 존재하지 않습니다.
ora-04060     %s를 수행하기 위한 권한이 부족합니다.
ora-04061     %s의 기존상태가 무효화되었습니다.
ora-04062     %s(%s의)이 변경되었습니다.
ora-04063     %s가 오류를 가집니다.
ora-04064     실행불가, %s가 무효화 되었습니다.
ora-04065     실행불가, %s가 변경 혹은 삭제되었습니다.
ora-04066     실행할수 없는 개체, %s
ora-04067     실행불가, %s가 존재하지 않습니다.
ora-04068     패키지%s%s%s의 기존 상태가 버려졌습니다.
ora-04070     부적절한 트리거명
ora-04071     before 혹은 after 키워드의 누락
ora-04072     부적절한 트리거유형
ora-04073     이 트리거유형에 대해서 열 목록은 부당합니다.
ora-04074     부적절한 referencing명
ora-04075     부적절한 트리거동작
ora-04076     부적절한 new 혹은 old지정
ora-04077     when절은 레이블 레벨의 트리거와 사용될 수 없습니다.
ora-04078     old와 new값이 같을 수 없습니다.
ora-04079     부당한 트리거 지정
ora-04080     트리거 %s가 존재하지 않습니다.
ora-04081     트리거 %s가 이미 존재합나다.
ora-04082     테이블 레벨 트리거에서 new 혹은 old 참조는 허용되지 않습니다.
ora-04083     부적절한 트리거 변수 %s
ora-04084     행 트리거후에 트리거의 new값을 변경할 수 없습니다.
ora-04085     old 참조변수의 값을 변경할 수 없습니다.
ora-04086     트리거 설명이 너무 깁니다 트리거 코드에 주석을 옮기십시오
ora-04087     rowid 참조 변수의 값을 변경할 수 없습니다.
ora-04088     트리거 %s의 수행시 오류
ora-04089     sys 소유의 개체에 대한 트리거를 작성할 수 없습니다.
ora-04090     %s는 동일 테이블, 이벤트 그리고 트리거 시간을 %s 로 지정하고 있습니다.
ora-04091     테이블 %s.%s가 변화하고 있어서 트리거/함수가 이를 볼 수 없습니다.
ora-04092     트리거 안에 %s를 할 수 없습니다.
ora-04093     long유형 열 참조는 트리거에서 허용되지 않습니다.
ora-04094     테이블 %s.%s은 부적합함, 트리거는 그것을 수정할 수 없습니다.
ora-04095     트리거 %s가 다른 테이블에 이미 존재함, 치환할 수 없습니다.
ora-04096     트리거 %s는 when 절이 있은데 너무 큽니다 한계치가 2k.
ora-04097     트리거 삭제 또는 수정을 시도시 ddl 대립이 생겼습니다.
ora-04098     트리거 %s 은 부적당하고 재검증에 실패했습니다.
ora-04099     트리거 %s 은 적당하지만 컴파일된 폼에 저장되지 않았습니다.
ora-06000     netasy: 포트 개방 실패
ora-06001     netasy: 포트 셋업 실패
ora-06002     netasy: 포트 읽기 실패
ora-06003     netasy: 포트 쓰기 실패
ora-06004     netasy: 대화 화일의 개방 실패
ora-06005     netasy: 대화 화일의 읽기 실패
ora-06006     netasy: 대화의 수행 실패
ora-06007     netasy: 잘못된 대화 유형
ora-06009     netasy: 대화 화일명이 너무 깁니다.
ora-06010     netasy: 대화 화일이 너무 깁니다.
ora-06011     netasy: 대화가 너무 깁니다.
ora-06017     netasy: 메시지 수신 실패
ora-06018     netasy: 메시지 송신 실패
ora-06019     netasy: 부적절한 로그인(연결) 스트링
ora-06020     netasy: 초기화 실패
ora-06021     netasy: 연결 실패
ora-06022     netasy: 채널 개방 실패
ora-06023     netasy: 포트 개방 실패
ora-06024     netasy: vtm 오류
ora-06025     netasy: 환경설정 오류
ora-06026     netasy: 포트 close 실패
ora-06027     netasy: 채널 close 실패
ora-06028     netasy: 로그인 하기위한 초기화를 할 수 없습니다.
ora-06029     netasy: 포트 할당 실패
ora-06030     netdnt: 연결 실패, 인식할 수 없는 노드명입니다.
ora-06031     netdnt: 연결 실패, 인식할 수 없는 개체명입니다.
ora-06032     netdnt: 연결 실패, 제어정보의 액세스가 거절되었습니다.
ora-06033     netdnt: 연결 실패, 상대편이 연결을 거절했습니다.
ora-06034     netdnt: 연결 실패, 상대편이 예기치않게 종료됐습니다.
ora-06035     netdnt: 연결 실패, 불충분한 자원입니다.
ora-06036     netdnt: 연결 실패, 개체로부터의 응답이 없습니다.
ora-06037     netdnt: 연결 실패, 노드에 도달할 수 없습니다.
ora-06038     netdnt: 연결 실패, 네트워크 드라이버가 로드되지 않았습니다.
ora-06039     netdnt: 연결 실패
ora-06040     netdnt: 부적절한 로그인 스트링입니다.
ora-06041     netdnt: 분리 실패
ora-06042     netdnt: 메시지 수신 실패
ora-06043     netdnt: 메시지 송신 실패
ora-06044     netdnt: 연결 실패, 바이트 갯수 할당량을 초과했습니다.
ora-06102     nettcp: 문맥 영역을 할당할 수 없습니다.
ora-06105     nettcp: 원격 호스트가 불명입니다.
ora-06106     nettcp: 소켓 생성 실패
ora-06107     nettcp: oracle 네트워크 서버가 없습니다.
ora-06108     nettcp: 호스트에 연결 실패
ora-06109     nettcp: 메시지 수신 실패
ora-06110     nettcp: 메시지 송신 실패
ora-06111     nettcp: 분리하는것이 실패
ora-06112     nettcp: 부적절한 버퍼크기입니다.
ora-06113     nettcp: 연결이 너무 많습니다.
ora-06114     nettcp: sid 찾기 실패
ora-06115     nettcp: 논리적인 oracle을 생성할 수 없습니다.
ora-06116     nettcp: orasrv 프로세스를 생성할 수 없습니다.
ora-06117     nettcp: orasrv를 생성할 수 없음: 할당량을 초과했습니다.
ora-06118     nettcp: orasrv와의 교신을 끝낼 수 없습니다.
ora-06119     nettcp: 가짜 클라이언트의 요구
ora-06120     nettcp: 네트워크 드라이버가 로드되지 않았습니다.
ora-06121     nettcp: 액세스 실패
ora-06122     nettcp: 셋업 실패
ora-06123     nettcp: keepalive를 지정할 수 없습니다.
ora-06124     nettcp: orasrv 대기시 시간경과
ora-06125     nettcp: orasrv가 예기치않게 종료했습니다.
ora-06126     nettcp: orasrv가 네트워크 연결을 열 수 없습니다.
ora-06127     nettcp: 사용자명을 변경할 수 없습니다.
ora-06128     nettcp: 우편함을 생성할 수 없습니다.
ora-06129     nettcp: 소켓의 소유권을 orasrv로 옮길 수 없습니다.
ora-06130     nettcp: 호스트의 액세스가 거부되었습니다.
ora-06131     nettcp: 사용자의 액세스가 거부되었습니다.
ora-06132     nettcp: 비밀번호가 틀림, 액세스가 거부되었습니다.
ora-06133     nettcp: 화일이 없습니다.
ora-06134     nettcp: 화일 액세스 권한이 위반되었습니다.
ora-06135     nettcp: 연결이 거절됨; 서버가 중지되고 있습니다.
ora-06136     nettcp: 연결교신중 오류 발생
ora-06137     nettcp: 연결교신중 오류 발생
ora-06138     nettcp: 연결교신중 오류 발생
ora-06140     nettcp: 그런 사용자가 없습니다.
ora-06141     nettcp: 사용자에 대한 권한이 없습니다.
ora-06142     nettcp: 사용자 정보의 획득시 오류
ora-06143     nettcp: 최대 연결수를 초과했습니다.
ora-06144     nettcp: sid (데이타베이스)는 사용할 수 없습니다.
ora-06145     nettcp: orasrv를 수행시킬 수 없음: 이미지가 설치되지 않았습니다.
ora-06200     twotask: 연결 실패, 우편함을 생성할 수 없습니다.
ora-06201     twotask: 연결 실패, 우편함에 연결할 수 없습니다.
ora-06202     twotask: 연결 실패, 서버 태스크를 만들 수 없습니다.
ora-06203     twotask: 연결 실패, 교신 실패
ora-06204     twotask: 연결 실패, orasrv2.com를 액세스할 수 없습니다.
ora-06205     twotask: 연결 실패, 논리명을 생성할 수 없습니다.
ora-06206     twotask: 메시지 수신 실패
ora-06207     twotask: 메시지 송신 실패
ora-06208     twotask: 부적당한 로그인(연결) 스트링
ora-06209     twotask: 연결 실패, 우편함이 이미 존재하고 있습니다.
ora-06210     twotask: 연결 실패, orasrv가 예기치 않게 종료되었습니다.
ora-06211     twotask: 연결 실패, orasrv를 기다리다가 시간 초과 되었습니다.
ora-06212     twotask: 연결 실패, 논리 이름 테이블이 꽉 차있습니다.
ora-06213     twotask: 연결 실패
ora-06214     twotask: 연결 실패, orasrv를 생성하기 위해 충분치 않은 할당량 입니다.
ora-06215     twotask: 연결 실패, orasrv 이미지가 설치가 않되게 보호된 것입니다.
ora-06216     twotask: 연결 실패, orasrv 이미지 화일을 발견할 수 없습니다.
ora-06250     netntt: 송수신 버퍼를 할당할 수 없습니다.
ora-06251     netntt: 주소 화일명을 해석할 수 없습니다.
ora-06252     netntt: 주소 화일을 열 수 없습니다.
ora-06253     netntt: 주소화일에서 인수를 read 할 수 없습니다.
ora-06254     netntt: 큐브로의 연결을 공유할 수 없습니다.
ora-06255     netntt: 원격 프로세스의 pid를 read 할수없습니다.
ora-06256     netntt: 원격 fork 실패
ora-06257     netntt: 섀도(shadow) 프로세스에 명령을 송신할 수 없습니다.
ora-06258     netntt: 문맥 영역을 할당할 수 없습니다.
ora-06259     netntt: 원격 프로세스에서 read 할수 없습니다.
ora-06260     netntt: 원격 프로세스로 write 할수 없습니다.
ora-06261     netntt: nrange() 실패
ora-06262     netntt: nfconn() 실패
ora-06263     netntt: pi_connect에 메모리 부족
ora-06264     netntt: 데이타 프로토콜 오류
ora-06265     netntt: break 프로토콜 오류
ora-06266     netntt: 잘못된 쓰기 길이
ora-06267     netntt: 오류 상태
ora-06268     netntt: /etc/oratab을 read 불가
ora-06300     ipa: 접속분리 실패
ora-06301     ipa: driver context 를 할당할 수 없습니다.
ora-06302     ipa: 원격 호스트에 연결 불가
ora-06303     ipa: 메세지 전송 오류
ora-06304     ipa: 메세지 수신 오류
ora-06305     ipa: 부적절한 메시지 유형
ora-06306     ipa: 메세지 write 길이 오류
ora-06307     ipa: 연결 재설정 실패
ora-06308     ipa: 더 이상 연결 불가
ora-06309     ipa: 이용 가능한 메세지 큐가 없음
ora-06310     ipa: 환경 변수가 지정되지 않았습니다.
ora-06311     ipa: 최대 서버수에 도달 했습니다.
ora-06312     ipa: 지정된 서비스명이 부정확합니다.
ora-06313     ipa: 공유 메모리 초기화 실패
ora-06314     ipa: event 설정 실패
ora-06315     ipa: 콘넥트 스트링 오류
ora-06316     ipa: 데이타베이스 sid 오류
ora-06317     ipa: 로컬 최대 사용자수 초과
ora-06318     ipa: 로컬 최대 콘넥션수 초과
ora-06319     ipa: 원격 최대 사용자수 초과
ora-06320     ipa: 원격 최대 연결 수 초과
ora-06321     ipa: 원격편에 도달할 수 없습니다.
ora-06322     ipa: 심각한 공유 메모리 오류
ora-06323     ipa: 이벤트 오류 발생
ora-06400     netcmn: 지정된 기본 호스트 뮨자열이 없습니다.
ora-06401     netcmn: 부적절한 드라이버 지정자
ora-06402     netcmn: 브레이크 메시지 수신시 오류
ora-06403     netcmn: 문맥 영역을 할당할 수 없습니다.
ora-06404     netcmn: 부당한 로그인 (연결) 스트링
ora-06405     netcmn: 프로토콜 재설정 오류
ora-06406     netcmn: 브레이크 메시지 송신시 오류
ora-06407     netcmn: 브레이크 처리환경을 구축할 수 없습니다.
ora-06408     netcmn: 부정확한 메시지 유형
ora-06413     연결이 개방되지 않았습니다.
ora-06416     netcmn: 테스트시 오류
ora-06419     netcmn: 서버가 오라클을 기동시킬 수 없습니다.
ora-06420     netcmn: sid의 찾기 실패
ora-06421     netcmn: 읽혀질 데이타에 오류가 발견되었습니다.
ora-06422     netcmn: 송신 데이타에 오류가 발견되었습니다.
ora-06423     netcmn: 수신 데이타에 오류가 발견되었습니다.
ora-06430     ssaio: 함수가 잘못된 인수로 요구되었습니다.
ora-06431     ssaio: 부적절한 블록번호
ora-06432     ssaio: 버퍼가 정열되지 않습니다.
ora-06433     ssaio: lseek 오류, 요구된 블록을 찾을 수 없습니다.
ora-06434     ssaio: 읽기 오류, 데이타베이스 화일로 읽을 수 없습니다.
ora-06435     ssaio: 쓰기 오류, 데이타베이스 화일에 기록할 수 없습니다.
ora-06436     ssaio: 비동기 i/o가 틀린 파라미터로 인하여 실패했습니다.
ora-06437     ssaio: 비동기 쓰기는 데이타베이스 화일에 기록할 수 없습니다.
ora-06438     ssaio: 비동기 읽기는 데이타베이스 화일로 부터 읽을 수 없습니다.
ora-06439     ssaio: 비동기 쓰기가 틀린 바이트 수를 리턴했습니다.
ora-06440     ssaio: 비동기 읽기가 틀린 바이트 수를 리턴했습니다.
ora-06441     ssvwatev: 함수 호출에 잘못된 파라미터가 넘겨졌습니다.
ora-06442     ssvwatev: 예기치 않은 오류로 실패했습니다.
ora-06443     ssvpstev: 함수 호출에 잘못된 파라미터가 넘겨졌습니다.
ora-06444     ssvpstev: 예기치 않은 오류로 실패했습니다.
ora-06445     ssvpstevrg: 함수 호출에 잘못된 파라미터가 넘겨졌습니다.
ora-06446     ssvpstevrg: 예기치 않은 오류로 실패했습니다.
ora-06447     ssvpstp: 함수 호출에 잘못된 파라미터가 넘겨졌습니다.
ora-06448     ssvpstp: 예기치 않은 오류로 실패했습니다.
ora-06449     리스트 io 혹은 sysvendor가 설치되지 않았습니다.
ora-06500     pl/sql: 기억 영역 오류입니다.
ora-06501     pl/sql 프로그램 오류
ora-06502     pl/sql: 값(수치) 오류입니다.
ora-06503     pl/sql: 함수가 값을 리턴하지 못했습니다.
ora-06504     pl/sql: result set 변수 또는 질의의 리턴 유형이 일치하지 않습니다.
ora-06508     pl/sql: 호출되는 lib 단위를 발견할 수 없습니다.
ora-06509     pl/sql: 이 패키지(package)에 대한 icd 벡터가 누락됐습니다.
ora-06510     pl/sql: 처리되지 않은 user-defined 예외 상황
ora-06511     pl/sql: 커서가 이미 열려있습니다.
ora-06512     %s줄 %s에서
ora-06513     pl/sql: pl/sql 테이블의 색인이 호스트 언어 배열의 범위를 벗어남
ora-06514     pl/sql: 원격 호출은 서버에 의해서 처리되지 않습니다.
ora-06540     pl/sql: 컴파일 오류
ora-06541     pl/sql: 컴파일 오류 - 컴파일 중지
ora-06542     pl/sql: 실행 오류
ora-06543     pl/sql: 실행 오류 - 실행 중지
ora-06544     pl/sql: 내부 오류, 인수: [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s]
ora-06550     줄 %s, 열%s:%s
ora-06551     pl/sql: 처리되지 않은 예외상황
ora-06552     pl/sql: %s
ora-06553     pls-%s: %s
ora-06554     패키지 dbms_standard는 pl/sql을 사용하기 전에 생성되야만 합니다.
ora-06555     이 이름은 현재 사용자 sys에 의해 사용되기 위해 예약되어 있습니다.
ora-06556     파이프가 비어 있어 unpack_message 요구를 이행할 수 없습니다.
ora-06557     icd 파이프에 대한 파라미터로 null 값은 허용되지 않습니다.
ora-06558     dbms_pipe 패키지에 있는 버퍼가 꽉 찼음. 더 이상의 항목이 사용될 수 없습니다.
ora-06559     %s로 잘못된 데이타유형이 요구되었습니다, 실제 데이타유형은 %s 입니다.
ora-06560     위치, %s 가 버퍼 크기 %s 보다 크거나 음수 입니다.
ora-06561     명령문이 dbms_sql 패키지에 의해 지원되지 않습니다.
ora-06562     out 인수의 형이 열의 형과 일치되거나 변수와 바인드되어야 합니다.
ora-06563     기술된 최상위 레벨의 프로시저/펑션이 하위레벨을 포함할 수 없습니다.
ora-06564     개체 %s가 존재하지 않습니다.
ora-06565     저장된 프로시저에서 %s를 실행할 수 없습니다.
ora-06566     행의 수 지정이 부적합합니다.
ora-06567     값의 수 지정이 부적합합니다.
ora-06568     폐기된 icd 프로시저가 호출되었습니다.
ora-06570     풀 개체 공유가 존재하지 않습니다.
ora-06571     %s 함수는 데이타베이스에 갱신하는것을 보증할 수 없습니다.
ora-06572     %s 함수는 out 인수를 가지고 있습니다.
ora-06573     %s 함수가 패키지 상태를 변경하는데, 여기서는 사용할 수 없습니다.
ora-06574     %s 함수는 패키지 상태를 참조하는데, 원격적으로 실행할 수 없습니다.
ora-06575     패키지 또는 함수 %s 은 부적당한 상태입니다.
ora-06580     해쉬 결합이 큰 행을 메모리에 보관하는 중에 메모리 부족이 일어났습니다.
ora-06600     lu6.2 driver: sna 소프트웨어가 로드되지 않음
ora-06601     lu6.2 driver: 부적절한 데이타베이스 id 스트링임
ora-06602     lu6.2 driver: 문맥 영역 할당시 오류
ora-06603     lu6.2 driver: 메모리 할당시 오류
ora-06604     lu6.2 driver: 원격 lu와 함께 세션을 할당할 수 없음
ora-06605     lu6.2 driver: 예기치 않은 줄 턴어라운드
ora-06606     lu6.2 driver: sna로 부터의 예기치 않은 응답
ora-06607     lu6.2 driver: 송신상태에서 재설정됨
ora-06608     lu6.2 driver: 수신상태에서 재설정됨
ora-06610     lu6.2 driver: 해제시 실패
ora-06611     lu6.2 driver: 송신 요구오류
ora-06612     lu6.2 driver: 데이타 송신오류
ora-06613     lu6.2 driver: 수신 및 대기오류
ora-06614     lu6.2 driver: 즉시 수신오류
ora-06615     lu6.2 driver: 송신오류
ora-06616     lu6.2 driver: lu로의 첨부에 실패했음
ora-06617     lu6.2 driver: pu로의 첨부에 실패했음
ora-06618     lu6.2 driver: 서브네트워크의 활성화에 실패했음
ora-06619     lu6.2 driver: 활성적인 원격 파트너를 할 수 없습니다.
ora-06620     lu6.2 driver: 부적절한 원격 파트너
ora-06621     lu6.2 driver: 할당 오류
ora-06622     lu6.2 driver: sna에 첨부할 수 없음
ora-06700     tli driver: 호스트로부터의 메시지 유형이 부정확합니다.
ora-06701     tli driver: 틀린 수의 바이트가 기록되었습니다.
ora-06702     tli driver: 문맥 영역을 할당할 수 없습니다.
ora-06703     tli driver: 브레이크 메시지의 송신 실패
ora-06704     tli driver: 브레이크 메시지의 수신 실패
ora-06705     tli driver: 원격 노드가 불명입니다.
ora-06706     tli driver: 서비스가 발견되지 않습니다.
ora-06707     tli driver: 연결실패
ora-06708     tli driver: 메시지 수신실패
ora-06709     tli driver: 메시지 송신실패
ora-06710     tli driver: 송신 인터럽트 브레이크 메시지 실패
ora-06711     tli driver: 바인드시 오류
ora-06712     tli driver: 인수시 오류
ora-06713     tli driver: 연결시 오류
ora-06720     tli driver: sid 찾기 실패
ora-06721     tli driver: 가 클라이언트 요구
ora-06722     tli driver: 연결설정 실패
ora-06730     tli driver: 크론(clone) 디바이스의 열기 실패
ora-06731     tli driver: t_call을 할당할 수 없습니다.
ora-06732     tli driver: t_discon을 할당할 수 없습니다.
ora-06733     tli driver: 분리 수신에 실패했습니다.
ora-06734     tli driver: 연결할 수 없습니다.
ora-06735     tli driver: 잘못된 연결을 닫는데 실패했습니다.
ora-06736     tli driver: 서버가 가동중이 아닙니다.
ora-06737     tli driver: 연결실패
ora-06741     tli driver: 프로토콜 디바이스를 열 수 없습니다.
ora-06742     tli driver: t_bind를 할당할 수 없습니다.
ora-06743     tli driver: t_bind를 할당할 수 없습니다.
ora-06744     tli driver: 리스너(listener)를 바인드할 수 없습니다.
ora-06745     tli driver: 리스너(listener)가 이미 가동중입니다.
ora-06746     tli driver: t_call을 할당할 수 없습니다.
ora-06747     tli driver: 청취(listen) 오류
ora-06748     tli driver: t_discon을 할당할 수 없습니다.
ora-06749     tli driver: 네트워크상에서 옵션이 허용되지 않습니다.
ora-06750     tli driver: sync 실패
ora-06751     tli driver: 번지 범위가 다릅니다.
ora-06752     tli: 시그널 설정시 오류
ora-06753     tli driver: name-to-address를 맹핑하는데 실패했습니다.
ora-06754     tli driver: 지역 호스트 번지를 얻을 수 없습니다.
ora-06755     tli driver: 이동 마감점을 닫을 수 없습니다.
ora-06756     tli driver: oratab을 열 수 없습니다.
ora-06757     tli driver: 서버가 틀린 명령을 취했습니다.
ora-06760     tli driver: 순차릴리스를 읽는 동안 타임아웃됐습니다.
ora-06761     tli driver: 순차릴리스의 송신오류
ora-06762     tli driver: 순차릴리스의 읽기오류
ora-06763     tli driver: 분리 송신오류
ora-06764     tli driver: 분리 읽기오류
ora-06765     tli driver: 순차 릴리즈의 대기오류
ora-06766     tli driver: 릴리스시 닫기실패
ora-06767     tli driver: 릴리즈시 할당실패
ora-06770     tli driver: 버전 송신오류
ora-06771     tli driver: 버전 읽기오류
ora-06772     tli driver: 명령 송신오류
ora-06773     tli driver: 명령 읽기오류
ora-06774     tli driver: 브레이크 모드 송신오류
ora-06775     tli driver: 브레이크 모드 읽기오류
ora-06776     tli driver: 파라미터 송신오류
ora-06777     tli driver: 파라미터 읽기오류
ora-06778     tli driver: ccode 송신오류
Posted by 1010
02.Oracle/DataBase2008. 11. 17. 14:33
반응형

ora-00257
: archiver error

위 오류는 해당 디스크에 더이상 아카이브 로그가 쌓일 공간이 없을 때 발생할 가능성이 매우 높다
Posted by 1010
02.Oracle/DataBase2008. 11. 10. 13:18
반응형
DB LINK의 사용은 다른 인스턴스의 객체를 사용하기 위함이다.




위에서 보면 ORCL USER는 PROD의 TEST SCHEMA가 가진 객체를 조회하고 싶은 상황이다.

일반적으로 자신이 가지고 있지 않은 객체를 조회하고 싶을때는 TNS 서비스를 통해
해당 객체를 소유한 USER로 접속하지 않으면 안된다.

DB LINK는 ORCL이 TEST를 소유한 것 같이 조회를 가능하게 한다.
DB LINK를 만들기 위해서는 CREATE SESSION ( 이 권한이 없으면 세션을 만들지도 못한다; ) 과
CREATE DATABSE LINK / CREATE PUBLIC DATABASE LINK 둘중에 하나를 가져야 한다.

Privilege Database Required For

CREATE DATABASE LINK

Local

Creation of a private database link.

CREATE PUBLIC DATABASE LINK

Local

Creation of a public database link.

CREATE SESSION

Remote

Creation

해당 권한의 조회는 role_sys_privs 의 privilege 의 조회로 확인 가능하다.

사용조건으로는 두 인스턴스 모두 네트워크가 연결이 되어야 하며 서로 패킷을
주고 받을 수 있어야 한다. (ping을 사용해 확인)

PROD 인스턴스는 LISTENER를 실행해야하며 ORCL에서는 TNSNAMES.ORA에
접속할 서비스를 등록해야 한다. (직접 파일 수정하거나 NETMGR 사용)

필자는 직접 수정하는 방법으로 진행해 보겠다.


PROD 에서 리스너를 실행하였다.
RH3@PROD : /home/oracle>lsnrctl start


ORCL 에서 TNSNAMES.ORA를 수정한다.

RH3@ORCL : /home/oracle>cd $ORACLE_HOME/network/admin
RH3@ORCL : /oracle/ora92/network/admin>vi tnsnames.ora

다음의 내용을 추가하였다.

PROD_LINK =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.100.100)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = PROD)
        (SERVER = DEDICATED)
    )
  )



tnsping 명령어로 접근이 가능한지 확인해 본다.

RH3@RESP : /home/oracle>tnsping prod_link

TNS Ping Utility for Linux: Version 9.2.0.4.0 - Production on 09-NOV-2008 13:25:
13

Copyright (c) 1997 Oracle Corporation.  All rights reserved.

Used parameter files:
/oracle/ora92/network/admin/sqlnet.ora


Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = 192.168.100.100)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = PROD) (S
ERVER = DEDICATED)))
OK (10 msec)
RH3@RESP : /home/oracle>

단순히 sqlplus로 접근해 확인해봐도 괜찮다

RH3@RESP : /home/oracle>sqlplus "test/test@prod_link"


접근해 볼 샘플 USER를 만들어 진행해 보겠다.

SQL> get te
  1  create user dblink identified by dblink
  2  default tablespace users
  3  temporary tablespace temp
  4* quota unlimited on users


dblink라는 user를 생성하였다.

SQL> /

User created.

dblink user에게 create session 과 create database link를 할당했다.

SQL> grant create session ,create database link to dblink;

Grant succeeded.

SQL> conn dblink/dblink
Connected.
SQL> select * from tab;

no rows selected

SQL> @dblink

Database link created.

아래는 dblink 생성할 때 사용한 구문이다.

SQL> get dblink
  1  create database link dblink
  2  connect to test identified by test
  3* using 'prod_link'

SQL> select * from tab;

no rows selected

객체명 뒤에 DATA BASE LINK 이름을 붙여 사용한다. 형태는 TNS를 통해 접근하는 모양새와 같다.

SQL> select * from tab@dblink;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
CHAINED                        TABLE
PLAN_TABLE                     TABLE
TEST                           TABLE

SQL> select count(*) from test@dblink
  2  ;

  COUNT(*)
----------
    500000

SQL>

/*+ OTN 문서에 아직 많은 내용이 남아있다. UPDATE 요망 */


출처 : http://h391106.tistory.com/category

Posted by 1010
02.Oracle/DataBase2008. 10. 23. 17:31
반응형

우리가 오라클데이터베이스에 접속을해서 DML이나 DDL등의 명령어로 작업을 수행하면,
모든 작업의 기록이 리두로그 파일에 저장이 됩니다.
 
작업의 양이 많아지면 리두로그파일에 기록하는 내용도 굉장히 많아지게 되겠죠.
그렇게 되면 데이터를 기록하기 위해서 리두로그파일을 늘려야 하는 일이 발생을 합니다.
 
그런데 오라클 리두로그파일은 계속 증가하는 것이 아니라 몇 개의 리두로그 파일을 만들어 놓고
번갈아 가면서 기록하는 구조로 되어 있습니다
.
 
이렇게 번갈아 가면서 기록을 하게 되면 새로운작업의 내용이 예전의 작업내용을 덮어쓰므로
예전의 작업한 내용을 잃게 된다는 단점이 있습니다.
 
 
그래서 예전의 작업한 내용에 데이터 손실이 발생하면 복구하기 어렵다는 단점이 있습니다.
 
이런 단점을 해결하기 위한 방법이 리두로그파일의 내용을 다른 디렉토리에 자동으로 복사해서 저장하도록 운영하는 방법입니다.  

이렇게 운영하는 방법을 아카이브 로그 모드(Archive Log Mode)라고 합니다.
 
 
오라클데이터베이스는 기본적으로 No Archive Log Mode고요.. Archive Log Mode로 운영하기 위해서는 따로 설정을 해주어야 합니다.
 


PFILE을 수정하여 데이타베이스를 archivelog mode로 설정하기


NO ARCHIVE LOG 상태의 데이터베이스를 ARCHIVE LOG 모드 상태로 변경하기 위해서는 다음과 같은 순서로 작업해야 합니다.
 
1) INIT<SID>.ORA 파라미터 파일을 수정한다.

2) 데이터베이스 인스턴스를 종료(SHUTDOWN)한다.

3) 데이터베이스 인스턴스를  MOUNT한다.(OPEN하지 않습니다)

4) 데이터베이스를 ARCHIVE LOG 모드로 변경한다.

5) 데이터베이스 인스턴스를 OPEN한다.
 
 
 
1) INIT<SID>.ORA파일의 parameter 수정  
 
INIT<SID>.ORA 파일에서 아래 부분을 수정하고, 주석(#)을 제거하고 저장합니다.
 
# 아카이브 프로세스를 오라클 시작과 함께 실행하도록 설정
# log switch 발생시 자동으로 archive를 수행 합니다
LOG_ARCHIVE_START = TRUE
 
# 아카이브 로그 파일을 저장할 디렉토리 설정
LOG_ARCHIVE_DEST = "C:\oracle\ora92\database\archive"  
 
# 아카이브 로그 파일의 이름 설정
LOG_ARCHIVE_FORMAT = %S.ARC
 
※ LOG_ARCHIVE_FORMAT 옵션
 - %S : redo 로그 시퀀스 번호를 표시하여 자동으로 왼쪽이 0으로 채워져 파일 이름 길이를 일정하게 만든다.
 - %s : redo 로그 시퀀스 번호를 표시하고, 파일 이름 길이를 일정하게 맞추지 않는다.
 - %T : redo 스레드 넘버를 표시하며, 자동으로 왼쪽이 0으로 채워져 파일 이름 길이를 일정하게 만든다.
 - %t : redo 스레드 넘버를 표시하며, 파일 이름 길이를 일정하게 맞추지 않는다.
 
     
 
2) 데이터베이스 인스턴스를 종료
 
-- SQLPLUS 실행
SQLPLUS /nolog
 
-- SYSDBA 권한으로 접속 합니다.
SQL>CONN SYS/MANAGER AS SYSDBA
 
 
SQL> SHUTDOWN IMMEDIATE
데이터베이스가 닫혔습니다.
데이터베이스가 마운트 해제되었습니다.
ORACLE 인스턴스가 종료되었습니다.
 
 
3) 데이터베이스 인스턴스를  MOUNT
SQL> STARTUP MOUNT pfile=C:\oracle\ora92\database\INITORA9I.ORA
데이터베이스가 마운트되었습니다.
 
 
4) DATABASE를  ARCHIVE LOG MODE로 전환.
SQL> ALTER DATABASE ARCHIVELOG;
데이타베이스가 변경되었습니다.
 
 
5) DATABASE OPEN
SQL> ALTER DATABASE OPEN;
 
 
 
6) ARCHIVE LOG MODE가 정상적으로 설정되어 있는지 확인한다.
 
SQL> ARCHIVE LOG LIST
데이터베이스 로그 모드              아카이브 모드
자동 아카이브             사용
아카이브 대상            C:\oracle\ora92\database\archive
가장 오래된 온라인 로그 순서     16
아카이브할 다음 로그   18
현재 로그 순서           18
 
 
7) 강제로 로그 스위치를 발생시켜서 아카이브 로그 파일이 저장되는지 확인 합니다.
SQL> ALTER SYSTEM SWITCH LOGFILE;
시스템이 변경되었습니다.
 
C:\oracle\ora92\database\archive 디렉토리에 파일이 생성되었는지 확인 합니다.
 



ARCHIVELOG MODE에서 NO ARCHIVELOG MODE로 전환하기


먼저, 위에서 setting 했던 INIT<SID>.ORA 파일에서 설정했던 부분을 (#)으로 주석처리 합니다.
 
 
#LOG_ARCHIVE_START = TRUE
#LOG_ARCHIVE_DEST = "C:\oracle\ora92\database\archive"  
#LOG_ARCHIVE_FORMAT = %S.ARC
 

-- 데이터베이스 종료
SQL> SHUTDOWN IMMEDIATE
 
 
-- 데이터베이스 인스턴스를  mount
SQL> STARTUP MOUNT pfile=C:\oracle\ora92\database\INITORA9I.ORA
 
 
-- 데이터베이스를  no archive log mode로 전환.
SQL> ALTER DATABASE NOARCHIVELOG;
 
 
--  database open
SQL> ALTER DATABASE OPEN;
 
 
-- 아카이브 로그 모드 상태 확인
SQL> ARCHIVE LOG LIST
데이터베이스 로그 모드              아카이브 모드가 아님
자동 아카이브             사용 안함
아카이브 대상            C:\oracle\ora92\RDBMS
가장 오래된 온라인 로그 순서     17
현재 로그 순서           19
   


SPFILE(서버 파라미터 파일)을 수정하여 데이타베이스를 archivelog mode로 설정하기


 Oracle9i 이상의 경우 서버 파라미터 파일을 사용 할 경우 아래와 같은 과정을 거쳐서 아카이브 로그모드로 변경해야 합니다.
 
 
1) 파라미터 설정
 
-- sqlplus 실행
SQLPLUS /nolog
 
-- SYSDBA 권한으로 접속 합니다.
SQL>CONN / AS SYSDBA
 
-- LOG_ARCHIVE_START 파라미터 변경
SQL>ALTER SYSTEM SET LOG_ARCHIVE_START=TRUE SCOPE=SPFILE;
 
-- LOG_ARCHIVE_DEST 파라미터 변경
SQL>ALTER SYSTEM SET LOG_ARCHIVE_DEST='C:\oracle\ora92\database\archive' SCOPE=SPFILE;
 
-- LOG_ARCHIVE_FORMAT 파라미터 변경
SQL>ALTER SYSTEM SET LOG_ARCHIVE_FORMAT='%S.ARC' SCOPE=SPFILE;
 
 
2) DB Shutdown
SQL>SHUTDOWN IMMEDIATE
 
 
3) Mount 상태로 Startup
SQL> startup mount
 
 
4) 아카이브 로그 모드 활성화
SQL>ALTER DATABASE ARCHIVELOG;
 
 
5) 데이타베이스 오픈
SQL> ALTER DATABASE OPEN;
 
 
6) 아카이브 로그 모드가 정상적으로 설정되어 있는지 확인한다.
SQL> archive log list;
데이터베이스 로그 모드              아카이브 모드
자동 아카이브             사용
아카이브 대상            C:\oracle\ora92\database\archive
가장 오래된 온라인 로그 순서     17
아카이브할 다음 로그   19
현재 로그 순서           19
 

Posted by 1010
02.Oracle/DataBase2008. 10. 23. 16:10
반응형



Installing and Upgrading

Installation guides for Oracle Database 11g and accompanying products on various platforms are collected here.

  • Full Installation Guides describe a wider variety of scenarios with more detail.
  • Client Installation Guides describe installing Oracle database client software on hosts where the database server is not installed.
  • Supplementary Installation Guides describe installing products that are included with the database but installed separately.

Essentials

Licensing Information HTML PDF
Readme HTML PDF
Universal Installer and OPatch User's Guide for Windows and UNIX HTML PDF
Upgrade Guide HTML PDF

Linux Installation Guides

Release Notes for Linux HTML PDF
Quick Installation Guide for Linux x86 HTML PDF
Quick Installation Guide for Linux x86-64 HTML PDF
Installation Guide for Linux HTML PDF
Client Quick Installation Guide for Linux x86 HTML PDF
Client Quick Installation Guide for Linux x86-64 HTML PDF
Client Installation Guide for Linux HTML PDF
Clusterware Installation Guide for Linux HTML PDF
Real Application Clusters Installation Guide for Linux and UNIX HTML PDF

Microsoft Windows Installation Guides

Release Notes for Microsoft Windows HTML PDF
Quick Installation Guide for Microsoft Windows (32-Bit) HTML PDF
Quick Installation Guide for Microsoft Windows x64 HTML PDF
Installation Guide for Microsoft Windows HTML PDF
Client Quick Installation Guide for Microsoft Windows (32-Bit) HTML PDF
Client Quick Installation Guide for Microsoft Windows x64 HTML PDF
Client Installation Guide for Microsoft Windows HTML PDF
Clusterware Installation Guide for Microsoft Windows HTML PDF
Real Application Clusters Installation Guide for Microsoft Windows HTML PDF

Solaris Installation Guides

Release Notes for Solaris Operating System HTML PDF
Quick Installation Guide for Solaris Operating System (SPARC) HTML PDF
Installation Guide for Solaris Operating System HTML PDF
Client Quick Installation Guide for Solaris Operating System (SPARC) HTML PDF
Client Installation Guide for Solaris Operating System HTML PDF
Clusterware Installation Guide for Solaris Operating System HTML PDF
Real Application Clusters Installation Guide for Linux and UNIX HTML PDF

HP-UX Installation Guides

Release Notes for HP-UX HTML PDF
Quick Installation Guide for HP-UX Itanium HTML PDF
Quick Installation Guide for HP-UX PA-RISC (64-Bit) HTML PDF
Installation Guide for HP-UX HTML PDF
Client Quick Installation Guide for HP-UX Itanium HTML PDF
Client Quick Installation Guide for HP-UX PA-RISC (64-Bit) HTML PDF
Client Installation Guide for HP-UX HTML PDF
Clusterware Installation Guide for HP-UX HTML PDF
Real Application Clusters Installation Guide for Linux and UNIX HTML PDF

AIX Installation Guides

Release Notes for AIX 5L Based Systems (64-Bit) HTML PDF
Quick Installation Guide for AIX 5L Based Systems (64-Bit) HTML PDF
Installation Guide for AIX 5L Based Systems (64-Bit) HTML PDF
Client Quick Installation Guide for AIX 5L Based Systems (64-Bit) HTML PDF
Client Installation Guide for AIX 5L Based Systems (64-Bit) HTML PDF
Clusterware Installation Guide for AIX Based Systems HTML PDF
Real Application Clusters Installation Guide for Linux and UNIX HTML PDF

Supplementary Installation Guides

Products installed separately from the database.

Examples Installation Guide HTML PDF
Gateway for APPC Installation and Configuration Guide for AIX 5L Based Systems (64-Bit), HP-UX PA-RISC (64-Bit), Solaris Operating System (SPARC 64-Bit), and Linux x86 HTML PDF
Gateway for APPC Installation and Configuration Guide for Microsoft Windows HTML PDF
Gateway for IMS, VSAM, and Adabas Installation and Configuration Guide for AIX 5L Based Systems (64-Bit), HP-UX PA-RISC (64-Bit), Solaris Operating System (SPARC 64-Bit), Linux x86, and Linux x86-64 HTML PDF
Gateway for IMS, VSAM, and Adabas Installation and Configuration Guide for Microsoft Windows HTML PDF
Gateway Installation and Configuration Guide for AIX 5L Based Systems (64-Bit), HP-UX PA-RISC (64-Bit), HP-UX Itanium, Solaris Operating System (SPARC 64-Bit), Linux x86, and Linux x86-64 HTML PDF
Gateway Installation and Configuration Guide for Microsoft Windows HTML PDF
Warehouse Builder Installation and Administration Guide for Windows and UNIX HTML PDF
Posted by 1010
02.Oracle/DataBase2008. 10. 23. 15:46
반응형

12. 데이터베이스 관리

12.1 데이터베이스 기동과 종료

데이터베이스의 기동

  • SHUTDOWN
  • NOMOUNT - 1단계 : 데이터베이스 인스턴스 기동
  • MOUNT - 2단계 : 인스턴스를 위한 컨트롤 파일 열림(OPEN)
  • OPEN - 3단계 : 컨트롤 파일에 기술된 모든 파일 열림(OPEN)

(1) 1단계 : 데이터베이스 NOMOUNT 단계

  • 데이터베이스의 파라미터 파일을 읽는다.
  • TRACE 파일 및 ALERT 파일을 연다. 생성 정보를 alert(SID).log 파일에 기록한다.
  • 오라클 데이터베이스에서 이용되는 공유 메모리 구조인 SGA(System Global Area)를
    할당한다.
  • 백그라운드 프로세스를 생성한다.
  • 데이터베이스는 생성된 메모리 구조화 프로세스들과 아직 연결되어 있지 않다.

(2) 2단계 : 데이터베이스 MOUNT 단계

  • 데이터베이스를 구성하는 정보가 모두 있는 컨트롤 파일의 정보를 읽어서 디스크에
    데이터파일이나 리두로그 파일 등이 올바로 존재하는지 또한 각 파일이 현재
    사용가능한지를 점검한다.
  • 데이터베이스의 백업이나 복구 시점에 많이 이용된다. 만약 데이터파일이나
    로그 파일에 문제가 발생하여 데이터베이스가 시작되지 않는다면 이 단게에서
    복구 작업을 수행한 이후에 데이터베이스를 기동한다.
  • 데이터 파일명 변경, 리두로그 파일 추가,삭제,이름변경, 아카이브 모드 옵션의
    변경, 전체 데이터베이스의 복구, 백업하여 데이터베이스 재생성, 불완전 데이터베이스
    복구 등이 가능하다.
  • MOUNT 단계에서는 일반 사용자가 데이터베이스에 접속할수 없다.

(3) 3단계:데이터베이스 OPEN 단계

  • 컨트롤 파일에 기술된 모든 데이터 파일 및 리두로그 파일 등을 연다.
  • 일반 사용자가 데이터베이스를 이용할 수 있는 상태다.
  • 만약 종료 시점에 테이블 스페이스가 오프라인이었다면 데이터베이스를 기동하여도
    해당 테이블스페이스는 오프라인 상태다.
  • 인스턴스가 데이터베이스를 연 이후에 하나 이상의 롤백 세그먼트를 확보한다.

윈도우 NT 기반에서 데이터베이스 기동 방법

  • 제어판의 서비스를 이용하여 오라클 서비스를 기동

유닉스 기반에서 데이터베이스 기동방법

1) 먼저 유닉스에서 오라클을 기동할 수 있는 구너한이 있는 사용자 ID 로 로그인한다.
대개 oracle User
2) 현재 오라클 SID 를 확인 한다.
env |grep ORACLE_SID
ORACLE_SID=ARTDOM
3) SVRMGRL 를 실행하여 오라클을 기동시킨다.
[ 9i 이후엔 svrmgrl ( oracle server manager) 가 지원되지 않는다. ]

sqlplus ' /as sysdba'
    SQL*Plus: Release 10.1.0.4.0 - Production on Tue Jun 24 16:22:44 2008
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.

    Connected to an idle instance.

    SQL>startup
    ORACLE instance started.

    Total System Global Area 1174405120 bytes
    Fixed Size                  1329584 bytes
    Variable Size             316913232 bytes
    Database Buffers          855638016 bytes
    Redo Buffers                 524288 bytes
    Database mounted.
    Database opened.
    SQL>

4) sqlplus 를 통한 접속 테스트

sqlplus scott/manager

    SQL*Plus: Release 10.1.0.4.0 - Production on Tue Jun 24 16:24:36 2008
    
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    
    Connected to:
    Oracle Database 10g Enterprise Edition Release 10.1.0.4.0 - 64bit Production
    With the Partitioning, OLAP and Data Mining options
    
    scott@ARTDOM>select * from tab ;
    
    TNAME                          TABTYPE  CLUSTERID
    ------------------------------ ------- ----------
    DEPT                           TABLE
    EMP                            TABLE
    BONUS                          TABLE
    SALGRADE                       TABLE
    PLAN_TABLE                     TABLE
    CHAINED_ROWS                   TABLE
    CHECK_NEXT                     TABLE
    BIG_TABLE                      TABLE
    CHECK_PART                     TABLE
    CHECK_TRAN                     TABLE
    C_1                            TABLE
    CHECK_RENAME_FILES             TABLE
    CHECK_PART2                    TABLE
    CHECK_PART3                    TABLE
    DEPT_SAL                       TABLE
    MV_DEPT                        TABLE
    CHECK_DDL                      TABLE
    SCOTT_DBA_SEGMENTS             TABLE
    SCOTT_TABLES                   TABLE
    CHECK_VAR                      TABLE
    CHECK_ORANGE                   TABLE
    BIGEMP                         TABLE
    
    22 rows selected.

5) 오라클 필수 백그라운드 프로세스 확인을 통한 확인 [ smon ]
ps -ef|grep ora_ |grep sm
oracle 442430 1 0 16:22:46 - 0:00 ora_smon_ARTDOM

데이터베이스 종료

(1) SHUTDOWN NORMAL

  • 정상적으로 데이터베이스를 종료하는 방법으로 데이터베이스에 연결된
    모든 사용자의 세션이 종료될 때까지 기다린다.
    [ 사용자 세션이 하나라도 존재하면 Down 이 진행 되지 않는다. ]
  • 새로운 사용자의 연결은 허용하지 않는다.
  • 다음 데이터베이스를 기동할 때 별도의 복구 작업이 필요하지 않다.

(2) SHUTDOWN IMMEDIATE

  • 데이터베이스를 관리할 때 가장 많이 사용하는 정지 옵션이다.
  • 현재 커밋되지 않은 SQL 문장을 롤백시킨다.
  • 현재 데이터베이스에 접속한 사용자가 접속을 해제하기를 기다리지 않는다.
  • 만약 데이터베이스 롤백 정보가 많다면 데이버테이스를 정지하는 데 시간이
    많이 소요된다.
  • 잘못된 애플리케이션에 의해 부득이 데이터베이스를 정지시켜야 하는 경우에
    사용된다.
  • 다음 데이버테이스를 기동할 때 별도의 복구 작업이 필요하지 않다.
    다만 해당 시점에 작업하였던 부분이 롤백되었으면 다시 실행하도록 해야 한다.

(3) SHUTDOWN TRANSACTION

  • 데이터베이스를 종료하려면 현재 작업중인 모든 트랜잭션이 정상적으로 수행되어
    종료될때까지 기다린다. [ 접속 세션의 commit/rollback 까지 대기 후 Down ]
  • 모든 작업이 정상적으로 수행되었으므로 별도로 작업해야 할 부분이 필요하지 않다.
  • 다음 데이터베시으를 기동할 때 별도의 복구 작업이 필요하지 않다.

(4) SHUTDOWN ABORT

  • 트랜잭션에 대해 정리되지않으므로 일반적으로 이용하지 않는다.
  • 현재 연결되 모든 세션을 강제로 종료시킨다.
  • 커밋되지 않은 트랜잭션은 롤백되지 않는다.
  • 백업과 복구 작업이 필요한 경우에 사용한다.
  • 다음 데이터베이스를 기동할 때 별도의 복구 작업이 필요하다.

12.2 유용한 데이터베이스 모니터링 스크립트

12.3 데이타베이스 운영 시 정기적으로 점검해야 할 사항

매일 점검해야 할 항목

(1) 모든 데이터베이스 인스턴스가 기동되었는지 확인 한다.
(2) alert Log 를 확인 한다.
(3) 데이터베이스가 성공적으로 백업되었는지 확인 한다.
(4) 데이터베이스의 아카이브 로그 파일이 성공적으로 백업되었는지 확인한다.
(5) 데이터베이스 성능을 위해 충분한 리소스가 존재하는지 확인 한다.

1) 테이블 스페이스에 충분한 공간이 있는지 확인한다.

현실에 맞지 않다 - 책 내용

more "space.sql"
  select tablespace_name,
         sum(blocks) as free_blk, trunc(sum(bytes)/(1024*1024)) AS FREE_M,
         max(bytes)/(1024) as big_chunk_k, count(*) as num_chunks
  from dba_free_space
  group by tablespace_name  ;

Tablespace Free 공간 체크 Script

방법1. MAXBYTES - BYTES + FREE

select AA.*, (AA."Allocation" - AA."Used" + BB."Free" ) "Free Size", BB."Free"
  from
  (select a.tablespace_name "TABLESPACE_NAME",  sum(a.maxbytes)/1024/1024 "Allocation", sum(a.bytes)/1024/1024 "Used"
  from dba_data_Files a
  group by a.tablespace_name ) AA,
  (select b.tablespace_name, sum(b.bytes)/1024/1024 "Free"
  from dba_free_space b
  group by b.tablespace_name ) BB
  where AA.TABLESPACE_NAME = BB.TABLESPACE_NAME(+) ;

방법2. MAXBYTES - SEGMENT SIZE

select a.tablespace_name , a.bytes - b.bytes "FREE(M)"
  from
  ( select tablespace_name,   sum(maxbytes)/1024/1024 bytes from dba_data_files group by tablespace_name ) a,
  ( select tablespace_name,   sum(bytes)/1024/1024 bytes from dba_segments group by tablespace_name) b
  where a.tablespace_name = b.tablespace_name;

방법3. MAXBYTES - EXTENT SIZE

select a.tablespace_name , a.bytes - b.bytes "FREE(M)"
   from
   ( select tablespace_name,   sum(maxbytes)/1024/1024 bytes from dba_data_files group by tablespace_name ) a,
   ( select tablespace_name,   sum(bytes)/1024/1024 bytes from dba_extents group by tablespace_name) b
   where a.tablespace_name = b.tablespace_name;

2) 롤백 세그먼트를 확인한다.

more "rbs_usage.sql"
col today format a20 new_value curr_time
col today noprint
select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') today from dual ;

prompt =========================================================
prompt == rollback segment storage and status                 ==
prompt => DAte : [ &CURR_TIME ]
prompt =========================================================

set linesize 120
col rb_seg for a10
col status for a10
col tbs_nm for a10
col ini_kb for 9,999,999
col nxt_kb for 9,999,999
col tot_kb for 9,999,999

col ext for 999
col xt  for 99

select a.segment_name as rb_seg,
       a.status, c.xacts as xt,
       b.initial_extent/1024 as ini_kb,
       b.next_extent/1024 as nxt_kb,
       b.extents as ext,
       b.bytes/1024 as tot_kb,
       a.tablespace_name as tbs_nm
from dba_rollback_segs a, dba_segments b, v$rollstat c
where a.owner = b.owner
and   a.segment_name = b.segment_name
and   a.segment_id = c.usn
order by a.segment_name ;

3) 과도하게 증가한 세그먼트가 존재하는지 확인 한다.

3_1)우선 ananlyze 진행 한다.

sys@ARTDOM>begin
    dbms_utility.analyze_schema('SCOTT','ESTIMATE',NULL,5);
    end ;
    /
  PL/SQL procedure successfully completed.

3_2) 실행 안됨

select e.owner, e.segment_type, e.segment_name, count(*) as nr_extents,
          s.max_extents, to_char(sum(e.bytes)/(1024*1024),'999,999.90') AS MB
    from dba_extents e, dba_segments
    where e.segment_name = s.segment_name
    group by e.owner, e.segment_type, e.segment_name, s.max_extents
    having  count(*) > 10  or ( s.max_extents - COUNT(*) ) < 20 )
    order by count(*) desc ;

4) 스페이스-바운드 오브젝트를 식별한다. [ 의미 없음 ]

SELECT A.TABLE_NAME, A.NEXT_EXTENT, A.TABLESPACE_NAME
FROM ALL_TABLES A,
( SELECT TABLESPACE_NAME, MAX(BYTES) AS BIG_CHUNK
  FROM DBA_FREE_SPACE
  GROUP BY TABLESPACE_NAME ) F
WHERE F.TABLESPACE_NAME = A.TABLESPACE_NAME
AND   A.NEXT_EXTENT > F.BIG_CHUNK ;

ALTER TABLE <owner>.table STORAGE ( MAXEXTENTS UNLIMITED);

5) CPU, 메모리, 디스크 리소스가 충분한지 확인한다.

6) 데이터베이스 메뉴얼을 하루에 한 시간씩 탐독한다.

주 단위로 점검해야 할 항복

(1) 잘못된 규칙에 의해 오브젝트가 존재하는지 확인 한다.

more "check_next.sql"
  select segment_name, segment_type, dt.tablespace_name, ds.next_extent
  from dba_tablespaces dt, dba_segments ds
  where dt.tablespace_name = ds.tablespace_name
  and dt.next_extent != ds.next_extent
  and ds.owner ='&OWNER';

PK 가 존재 하지 않는 테이블 체크

more "check_pk_exist.sql"
  select table_name from all_tables where owner='&OWNER'
  minus
  select table_name from all_constraints where owner='&&OWNER'
  and constraint_type ='P';

(2) 보완관리가 잘 유지되고 있는지 확인 한다.

(3) Net8에 관련된 로그는 에러나 이슈 사항이 없는지 확인한다.

(4) 모든 alert 로그 파일을 보관한다.

월 단위로 점검해야 할 항목

(1) 데이터베이스의 비정상적인 현상이 발생하는지 확인한다.
(2) 튜닝해야할 부분이 있는지 확인한다.
(3) I/O 경합이 존재하는지 확인
(4) 단편화(Fragmentation)이 존재하는지 확인

12.3 데이터베이스 문제 발생 및 해결 방법

롤백 세그먼트 EXTENT 에러

RBS 사용 현황 체크 - User 별

select s.username, s.sid, s.serial#, rn.name,     rs.curext
           ,rs.curblk,  t.used_ublk, t.used_urec
    from    v$transaction   t
           ,v$session       s
           ,v$rollname      rn
           ,v$rollstat      rs
    where  t.addr     = s.taddr
    and    t.xidusn   = rn.usn
    and    rn.usn     = rs.usn  ;

SHAPSHOT TOO OLD 에러(ORA-1555)

발생 원인

  • 데이터베이스에 롤백 세그먼트 크기나 개수가 적당하게 설정되어 있어도
    OLTP 업무에 배치작업이 기동되어 과도하게 롤백 세크먼트를 사용할 경우 발생한다.
  • 데이터베이스에 변경을 가하는 트랜잭션은 많고 롤백 세그먼트는 크기도 작고,
    개수도 적은 경우에 발생한다.
    해결 방법
    1) 큰 롤백 세그먼트 생성
    CREATE ROLLBACK SEGMENT vldb_rbs 
             STORAGE( INITIAL 100M NEXT 5M )
             TABLESPACE VLDB_RBS ;

    2) 평상시에 OFFLINE 상태 유지

    ALTER ROLLBACK SEGMENT Vldb_rbs OFFLINE ;

    3) 배치작업 수행 시 ONLINE 상태로 변경

    ALTER ROLLBACK SEGMENT vldb_rbs ONLINE ;

    4) 각 작업문장이나 세션에서 롤백 세그먼트 지정

    SET TRANSACTION USE ROLLBACK SEGMENT vldb_rbs ;

    5) 작업 후 OFFLINE 으로 변경함

    ALTER ROLLBACK SEGMENT vldb_rbs OFFLINE ;

문서에 대하여

Posted by 1010
02.Oracle/DataBase2008. 10. 23. 15:32
반응형

그리드 컴퓨팅 데이터베이스의 약진 Oracle Database 10g Release 2


Oracle Database 10g Release 2의 비전
Oracle Database 10g Release 2의 해부
Oracle Database 10g Release 2의 첫인상

ORACLE DATABASE 10g Release 2의 첫 인상


장희정│한국오라클 TSC본부 DB팀


Oracle Database 10g Release 2를 처음 접한 이후 6개월여가 지났다. 그간 Oracle Database 10g Release 2에 대한 자료 및 테스트 등을 통해 생각했던 주목할 만한 몇 가지 기능을 OTN의 고정 필자인 Tom Kyte의‘My First Day with the New Release’ 글을 참고하여 소개하고자 한다.


Conditional Compilation


Oracle Database 10g Release 2에서는 PL/SQL 부문으로 여러 새로운 기능들을 제공하고 있다. 그 중 필자가 처음 주목한 것은 Conditional Compilation이다.


Conditional Compilation은 컴파일러가 의도에 따라 코드의 실행 여부를 결정할 수 있도록 하는 기능이다. 언뜻 들어서는 그저 그런 기능 같지만, 사실은 매우 유용한 기능이다.


Conditional Compilation을 이용하면,


• 현재 애플리케이션의 디버그 코드를 그대로 둘 수 있고, 이 코드를 원하는 대로 동작하게 하거나 동작하지 않도록 할 수 있다.


• C에서 하는 것처럼 Assertion을 프로그래밍할 수 있다. 예를 들어, 각 서브프로그램은 인풋 값을 테스트할 수 있고, 그 값이 특정 조건을 만족하는지 검증할 수 있다. 이런 테스트들이 전체 개발 기간 동안은 Active 상태이고, 프로덕 션 단계에서는 Inactive 상태일 수 있는 것이다. 그러나, 코드가 남아 있으므로 프로덕션 환경에서의 버그를 디버깅할 때 간단하게 활성화시킬 수 있다.


. 버전에 구애 받지 않는 코드를 작성할 수 있다. 버전 X용 코드 세트와 버전 Y용의 다른 코드 세트를 컴파일하면 되 므로, 두 세트의 코드를 가지지 않아도 된다. 새로운 DBMS_DB_VERSION 패키지를 살펴보라.


<리스트1>은 Conditional Compilation이 어떻게 구현될 수 있는지를 간략하게 보여 준다.


<리스트 1> Conditional PL/SQL Compilation 예


SQL> create or replace procedure p
2 as
3 begin
4 $IF $$debug_code $THEN
5 dbms_output.put_line‘( Our debug code’);
6 dbms_output.put_line‘( Would go here’);
7 $END
8 dbms_output.put_line‘( And our real code here’);
9 end;
10 /
Procedure created.

여기서 어떻게‘debug’코드가 프린트 되지 않고, $$debug_code 값이 정의되지 않은 채 코드가 컴파일되는지 주목하기 바란다.


SQL> exec p
And our real code here
PL/SQL procedure successfully completed.

간단하게 debug_code 값을 변경함으로써 디버그 코드를 활성화시킬 수 있다.


SQL> alter procedure P compile“
2 plsql_ccflags =‘ debug_code:true’reuse settings;
Procedure altered.
SQL> exec p
Our debug code
Would go here
And our real code here
PL/SQL procedure successfully completed.

Database Transport


Oracle Database 10g Release 1에서 서로 다른 플랫폼간의Transportable Tablespace를소개한다음, 이번 Oracle Database 10g Release 2에서 이를 한 단계 더 발전시켰다. Oracle Database 10g Release 2 부터는 동일한 Endian(바이트 순서)을 갖는 전 플랫폼에서 전체 데이터베이스를 트랜스포트할 수 있다. 예를 들어, Apple Macintosh에서 HP-UX로, 또는 Solaris x86에서 Open VMS로 단지 개개의 테이블스페이스를 트랜스포트하는 것이 아니라 전체 데이터베이스를 통째로 트랜스포트할 수 있다.


Native XQuery 지원


Oracle Database 10g Release 2는 W3C가 지정한 XML 질의용 표준인 XQuery를 지원한다. 이 기능은 XMLQuery와 XMLTable의 두 가지 기능으로 구현되어 있다. XMLQuery는 SQL 클라이언트에서 XQuery 언어를 사용해 해당 데이터와 관련된 XML 뷰를 질의하거나 Oracle XML DB 리파지토리 문서를 질의할 수 있도록 해준다. XMLTable은 XQuery의 결과를 관련 로우와 칼럼으로 매핑해 주므로, SQL을 사용해 그 매핑 결과에 대해 질의할 수 있다.


Direct SGA Access


데이터베이스가 응답이 없거나 혹은 시스템 성능이 너무 느린 경우, DBA가 가장 먼저 하고자 하는 일은 데이터베이스에 SYSDBA로 접속하여 Wait Event를 체크하는 일일 것이다. 그러나, 인스턴스가 행(hang) 상태라면 로그인도 못하는 지경일 수 있고, 로그인에 성공했다 하더라도 문제 해결을 위한 질의가 제대로 수행되지 못하는 경우가 상당하다.


Oracle Database 10g Release 2의 OEM Grid Control은 사용자의 요청에 따라 Direct SGA Attach 가 가능하므로 프로세스로부터 데이터를 수집할 수 있다. 이러한 메모리 액세스 모드는 SQL이 불가능할 정도로 인스턴스가 심각한 상태라 하더라도 성능 데이터 등을 모니터링할 수 있도록 한다. 이러한 Direct SGA Access 기능은Oracle Enterprise Manager를통해<화면1>과 같이 활용할 수 있다.


<화면 1> Direct SGA Access 기능의 활용



Asynchronous Commit


일반적으로 Java, C, Visual Basic 애플리케이션에서 COMMIT을 실행하면, Wait, 특히, Log File Sync Wait이 발생하게 된다. 이 Wait은 Transaction Permanence를 위해 Log Writer Process가 디스크에 리두를 플러시시킬 때까지 클라이언트가 기다리기 때문이다. 그리고 이것은 일반적인 것으로 커밋을 수행하면, 그 데이터는‘Permanent’해야 하기 때문이다.


그러나 모든 법칙에는 예외가 있기 마련이다. 센서나 네트워크를 통해서 들어오는 기록들을 가능한 빨리 처리해야 하는 시스템이라면, 얘기가 달라진다. 이런 프로그램의 목표는 여러 레코드들을 일괄로 묶은 뒤 INSERT하고 Commit 한 뒤, 계속해서 이런 작업을 반복하는 것이다. 커밋이 완벽하게 수행될 때까지 기다린다면, 기대만큼 빠 르게 실행될 수 없을 것이므로, 이런 프로그램은 그런 방식을 원하지 않을 것이다.


이 제 Oracle Database 10g Release 2에서 Asynchronous Commit을 이용해 보자.‘ commitbut- don’t wait’이나‘commit, and please do wait’ 을지정할수있다. 그러나, commit-but-don’t wait을 사용한다면, 드물게나마‘Commited’데이터가 분실될 수 있음을 예상해야 한다. commit-but-don’t wait을 이용하는 중에 시스템이 중단되면, 그 데이터는 커밋되지 않았을 수 있다. 그렇기 때문에, 사용자가 업무 성격에 따라 판단하여 commit-but-don’t wait을 사용하는 것이 필요하다. 참고로, 쏟아져 들어오는 데이터를 데이터베이스에 신속하게 기록하는 것이 애플리케이션의 최대 목적인 경우가 있다면, 이런 애플리케이션에서는 commitbut- don’t wait을 사용하는 것이 적합할 뿐 아니라 성능 측면에서 절대적으로 필요할 수 있다. <리스트 2>는 이런 예를 보여주는 Java 루틴이다.


<리스트 2> commit-but-don’t wait - Asynchronous Commit


public class instest
{
static public void main(String args[]) throws Exception
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection
conn = DriverManager.getConnection
“( jdbc:oracle:thin:@desktop:1521:ora10gr2”,
“scott”,”tiger”);
conn.setAutoCommit( false )
Statement sql_trace =
conn.createStatement();
sql_trace.execute
“( truncate table t”);
System.out.println“( Table truncated”);
sql_trace.execute
“( begin“ +
“ dbms_monitor.session_trace_enable( WAITS=>TRUE );”+
“end;”);
// create table t(x char(2000))
// create index t_idx on t(x)
PreparedStatement pstmt =
conn.prepareStatement
“( insert into t(x) values(?)”);
pstmt.setString( 1“, x”);
PreparedStatement commit =
conn.prepareStatement
“( commit work write batch nowait”);
//“ ( commit work write immediate wait”);
for( int i = 0; i < 1000; i++ )
{
pstmt.executeUpdate();
commit.executeUpdate();
}
conn.close();
}
}

<리스트2>에서 COMMIT WORK WRITE BATCH NOWAIT나 COMMIT WORK WRITE IMMEDIATE WAIT이 어떻게 사용되고 있는지 보자. 전자가 새로운 기능으로, 커밋이 끝날 때까지 기다리지 않고 커밋하는 방법을 보여 주고 후자는 이전에 수행되던 형태이다. 필자가 <리스트 2>에서 (CREATE TABLE은 INSERT 문 앞에서 참조를 위한 커멘트이다) 테스트 프로그램을 실행 했을 때, WAIT 옵션에서는 로그 파일 동기화를 위한 wait 으로 오랜 시간이 걸렸지만, NOWAIT 옵션에서는 wait time이 전혀 없었다. 그 결과는 <리스트 3>와 같다.


<리스트 3> WAIT와 NOWAIT 결과 비교


Event Waited On          Times Waited    Max. Wait Total Waited
----------------------- --------------- ---------- ------------
log file sync (nowait)             19       0.02         0.04
log file sync (wait)             1017       0.04         1.43

<리스트 3>의 결과를 보면, 로드 중간에 주기적으로 커밋을 필요로 하는 고속의 데이터 로드 프로그램에서는 상당한 차이가 나타날 수 있음을 예상할 수 있다.


Transport AWR Data


데이터베이스의 성능 문제를 분석하기 위해 AWR 데이터는 매우 중요하다. 하지만 운영 중인 데이터베이스에서 AWR 데이터를 분석하는 것이 불가능할 수 있는데, 이러한 경우 AWR 데이터를 별도의 저장소에 로드하고 성능 분석을할수있도록하는기능을Oracle Database 10g Release 2에서 제공하고 있다


Oracle Database 10g Release 2에 새로 추가된 DBMS_SWRF_INTERNAL 패키지가 바로 이기능을 가능하게 하는데, AWR_EXTRACT 프로시저를 이용하면 AWR 데이터를 Data Pump dmp 파일로 다운로드 할수있다.


s1 begin
2 DBMS_SWRF_INTERNAL.AWR_EXTRACT (
3 dmpfile =>‘ awr.dmp’,   // data pump export 파일 명
4 dmpdir =>‘ AWR_DIR’,    // dmp 파일이 기록되는
디렉토리 오브젝트
5 bid => 302,            // 시작 snapshot ID
6 eid => 305             // 끝 snapshot ID
7 );
8* end;

이제 awr.dmp 파일을 새로운 위치로 이동하고, DBMS_SWRF_INTERNAL 패키지의AWR_LOAD 프로시저를 이용하여 로드할 수 있다.


1 begin
2 DBMS_SWRF_INTERNAL.AWR_LOAD (
3    SCHNAME =>‘ AWRUSER’,
4    dmpfile =>‘ awr’,
5    dmpdir =>‘ AWR_DIR’
6 );
7* end;

AWRDIR 디렉토리 오브젝트에 정의된 디렉토리로 부터 awr.dmp 파일을 이용하여 AWR 데이터를 로드하는데, 이때 로드는 직접 SYS 스키마로 바로 로드되지 않고 중간에 스테이징용 스키마에 로드된다. 이후 스테이징 작업이 완료되면, 최종적으로 SYS 스키마로 데이터를 이동시키는 작업이 필요하다.


1 begin
2 DBMS_SWRF_INTERNAL.MOVE_TO_AWR (
3 SCHNAME =>‘ AWRUSER’
4 );
5* end;

이와 같은 방법으로 AWRUSER 스키마에서 SYS 스키마로 AWR 데이터를 이동한 후 성능 분석 작업을 하 면 되는 것이다.


AWR 데이타를 다른 데이터베이스로 이동하여 분석하는 것이 갖는 가장 큰 장점은 운영 데이터베이스에 영향 을 주지 않고 분석 작업을 수행할 수 있다는 것이다. 또한, 여러 데이터베이스로부터 수집된 AWR 데이터를 중앙집중적으로 관리할 수 있다는 장점도 있다


Transparent Data Encryption


이제Oracle Database 10g Release 2의 혁신적인 기능인 Transparent Data Encryption에 대해 살펴보자. 이것은 데이타를 쉽게 암호화할 수 있는 기능으로, 이 기능 덕분에 애플리케이션에서 더 이상 암호화 키를 다루지 않아도 된다. Transparent Data Encryption 기능은 데 이터베이스 레벨에서 칼럼 등에 대한 암호화 설정으로 자동 암호화 및 복호화를 지원한다. 데이터는 디스크에 저장될 때 암호화되어 저장되므로, 누군가가 데이터베이스를 훔치는 경우에 데이타는 보호될 수 있다. 아직 Transparent Data Encryption을 완전히 경험해 본 것은 아니지만, 잠깐 살펴본 결과 그 특징과 사용법을 소개하면 다음과 같다.


제일 먼저 해야 할 일은‘Wallet’을 설정하는 것이었다. 이 Wallet에 암호화 키가 저장될 것이고, 그 다음 이 파일은 패스워드로 보호될 것이다.


간단한 예제를 살펴보자. Oracle 홈에서‘wallet’이라는 디렉토리를 만들고, 다음 사항을 sqlnet.ora 파일에 기술한다.


WALLET_LOCATION=
(SOURCE=(METHOD=FILE)
(METHOD_DATA=
(DIRECTORY=/home/ora10gr2/wallet)
)
)

그 다음에는 Wallet을 열기만 하면 된다.


SQL> alter system
2 set encryption wallet open
3 identified by foobar;
System altered.

위작업은Transparent Data Encryption 기능을 사용하려면, 데이터베이스 오픈 후 반드시 해야 하는 작업이다.


이제 암호화 키를 셋업하도록 하자.


SQL> alter system
2 set encryption key
3 identified by foobar;
System altered.

여기서는 시스템이 키를 만들도록 했지만, 고유의 키를 만들 수도 있다. 이렇게 하면 이 시스템에서 또 다른 시스템으로 쉽게 데이터를 옮길 수 있다.


이상으로 간단한 셋업이 끝났고 이제 데이터를 암호화를 위한 작업을 시작해보자.


SQL> create table t
2 ( c1 varchar2(80),
3 c2 varchar2(80) encrypt )
4 tablespace test;
Table created.
SQL> insert into t values
2 ‘( this_is_unencrypted’,
3 ‘this_is_encrypted’);
1 row created.

이제 데이터는 암호화되어 디스크상에 저장되고, 권한 있는 사용자는 데이터 질의 시 데이터의 암호가 해제되어 리얼 데이터를 확인할 수 있게 된다.


SQL> select *
2 from t;
C1                            C2
--------------------------- -----------------------
this_is_unencrypted           this_is_encrypted

그렇다면, 데이터가 암호화되었다는 건 어떻게 확인 할 수 있을까? 오라클 데이터파일에서 특정 문자열과 grep을 사용해 그 문자열을 찾을 수 있는지 없는지 알아 보았다. 먼저, 암호화된 데이터가 들어 있는 블록이 디스 크에 저장되어 있는지부터 확인해 보았다.


SQL> alter system checkpoint;
System altered.

그 다음에 문자열들을 찾아보았다.‘ this_is’를 포함 하고 있는 암호화된 dbf 데이터파일에서 문자열을 찾아보 았다.


$ strings -a encrypt.dbf|grep this_is
this_is_unencrypted

보다시피,‘ this_is_unencrypted’문자열만 나타났다. 다른 문자열은 저장되기 전에 이미 암호화 되었기 때문에 볼 수가 없는 것이다.


이 간단한 예제는 새로운 암호화 기능의 빙산의 일각 에 불과하다. Transparent Data Encryption은 외부의 테이블 언로드, 데이터 펌프 등과도 잘 작동하며, Oracle Wallet Manager 같은 GUI 툴을 통해 Wallet과 Passwrd를관리할수있다. 또, 키 손상된 것 같으면, 명령어를 이용해 데이터를 리키 할(re-key) 수있다. 개인적으로 Transparent Data Encryption은 Oracle Database 10g Release 2에서 가장 훌륭한 기능 중 하나라고 생각한다.


Autotrace


Oracle Database 10g Release 2의 Autotrace 기능은 DBMS_XPLAN 패키지를 사용해 Explain Plan을 디스플레이 한다. 그래서, 이전 릴리즈에 비하여 더욱 상세한 Explain Plan을 제공한다. Oracle9i Database Release 2 이상부터는 DBMS_XPLAN 패키지를 사용 해 이러한 플랜을 구할 수 있었으나, Autotrace가 DBMS_XPLAN을 사용함으로써 작업이 한결 쉬워졌다. 이DBMS_XPLAN 아웃풋에서특징적인부분은플랜의 하단에 Predicate Information(where절 부분)이 추 가된 것으로, 오라클 데이터베이스가 where 절 구문을 어느 단계에서 어떻게 사용할 것인지 정확하게 보여주는 것으로, 상당히 훌륭한 기능이라고 생각한다<리스트 4>.


<리스트 4> Autotrace with DBMS_XPLAN


SQL> set autotrace traceonly explain
SQL> select *
2 from emp, dept
3 where emp.deptno = dept.deptno
4 and emp.job =‘ CLERK’;
Execution Plan
-------------------------------------------------------------
Plan hash value: 877088642
----------------------------------------------------------------
| Id | Operation | Name| Rows| Bytes | Cost (%CPU) | Time |
----------------------------------------------------------------
|0 |SELECT STATEMENT        | | 4 | 468 | 7 (15) | 00:00:01 |
|* 1 | HASH JOIN            | | 4 | 468 | 7 (15) | 00:00:01 |
|* 2 | TABLE ACCESS FULL| EMP | 4 | 348 | 3 (0)  | 00:00:01 |
| 3 | TABLE ACCESS FULL| DEPT | 4 | 120 | 3 (0)  | 00:00:01 |
-----------------------------------------------------------------
Predicate Information (identified by operation id):
-----------------------------------------------------------------
1 - access“( EMP”.”DEPTNO”=”DEPT”.”DEPTNO”)
2 - filte“r( EMP”.”JOB”=’CLERK’)
Note
--------
  - dynamic sampling used for this statement

DBMS_OUTPUT


DBMS_OUTPUT이 Oracle Database 10g Release 2에서 업그레이드되었다. 버퍼 사이즈를 무제한으로(100 만 바이트까지!) 정의할 수 있을 뿐 아니라 255 Character 이상의 라인도 프린트할 수 있다. 현재 최대 라인 길이는 32K이다. 다음은 DBMS_OUTPUT의 실제 활용 예 이다.


SQL> set serveroutput on -
> size unlimited
SQL> begin
2 dbms_output.put_line
3 ( rpad‘( *’,2000,’*’) );
4 end;
5 /
************************
...
************************
PL/SQL procedure successfully completed.

Oracle DataGuard Fast-Start Failover


Oracle Database 10g Release 2의 또 다른 신기능은 관리자가 일련의 명령어를 실행하거나 버튼을 누르지 않 아도 되는 스탠드바이 데이터베이스의 자동 페일오버이 다. Oracle Data Guard가 Production(Active) Server와 스토리지, 네트워크의 장애 발생시 스탠드바이 데이터베이스를 자동으로 페일오버하는 것이다.


Data Pump 압축


Oracle Database 10g Release 1이처음나왔을때희 소식은 완전히 새로 만들어진 Export (EXP), Import (IMP) 유틸리티와 EXPDP, IMPDP의 새로운 Oracle Data Pump 유틸리티였다. 하지만, EXPDP와 IMPDP 툴은 엑스포트 중에 DMP 파일들을 압축할 수 없다는 한 가지 단점이 있었다. EXPDP의 경우, 먼저 DMP 파일을 만든 후 이를 압축해야 했다. 예전의 EXP 툴에서는 지정된 파이프에 데이터를 기록하고, 그 파이프 에 기록된 데이터를 압축하도록 명령할 수 있었던 것에 비 하면, 이것은 분명 원하지 않던 단점이었다. 그러나, 이제 그런 번거로움이 없어졌다.


다행히도Oracle Database 10g Release 2에서는 이전 툴과 비교해 훨씬 쉽게 DMP 파일을 만들면서 부분 압축할 수 있게 되었다. EXPDP 스스로 덤프 파일에 씌 어진 모든 메타 데이터를 압축할 것이고, IMPDP는 자동 으로 압축 해제할 것이다. 또한, Oracle Database 10g Release 2에서처음으로Windows 플랫폼에서의DMP 파일 부분 압축이 가능하게 되었다.


LOG ERRORS


Log Errors는 Oracle Database 10g Release 2의 Delete, Insert, Merge 및 Update 문에서 볼 수 있는 새로운 구문이다. Log Errors는 많은 로우의 벌크 처리 시 실행에 실패한 로우들을 저장할 수 있도록 해준다. 이 전에는 문장 전체를 에러 처리함으로써 성공한 로우 데이 터에 대해서 재작업을 해줘야 하는 비효율성이 있었다.


예를들어, Insert Into T Select A,B,C From T2 Log Errors Into Errlog(‘ Bad_Rows_For_T’) Reject Limit Unlimited 같은 문장을 만들 수 있다.


이 문장은 조건에 위배되는 로우도 Bad_Rows_For _T 테이블에 로깅할 수 있도록 해준다. 이를테면, 너무 긴 칼럼 값 때문에 생긴 에러, Constraint Violation(Not Null, unique, referential, check constraint), 트리거실행중발생한에러, Type Conversion 에러, 파티 션 매핑 에러 등을 로깅할 수 있다. 에러가 발생하면, 이 에 러를 야기한 로우는 오라클 에러 번호, 에러 메시지 텍스트, 작업 유형(Insert, Update 또는 Delete) 그리고 Update 및 Delete 작업 중 실패한 로우의 RowID와 함께‘bad’테이블에 로그된다.


필자는 Oracle Database 10g Release 2의 여러 새 기능들 중 이 기능을 특히 좋아하게 될 것 같다. 각각의 로우를 일일이 처리하는 대신 벌크 작업을 수행하면 속도 와 자원 활용 면에서 큰 혜택을 볼 수 있을 것이다. 그리고, 실패한 로우의 에러 로깅은 이전부터 늘 요구되는 기능이 었는데, 이제 Log Errors로 완전히 해결되었다.


Restore Points


Oracle Database 10g Release 2에는Restore Point 를 설정할 수 있는 기능이 있다. Oracle Database 10g Release 1에서 데이터베이스를 플래시백할 수 있는 기능이 처음 소개되었지만, SCN(System Change Number) 과 플래시백할 시점을 알아내야 했다. 그러나, Oracle Database 10g Release 2에서는 먼저 Restore Point‘ X’를 생성하고, 손상을 입힐 만한 일, 예를 들어 애플리케이션의 업그레이드 같은 일을 수행 한 뒤, 업그레이드가 실패한 경우 간단하게Flashback Database To Restore Point‘ X’를 실행하면 작업 전의 상태로 돌아가는 것이다. 이제 더 이상 플래시백을 위한 SCN을 찾기 위 해 Select문을 실행하거나 플래시백 시점을 추정할 필요가 없게 된 것이다.


요약


이상은 Oracle Database 10g Release 2의 새 기능들 중 일부를 간략하게 훑어본 것이다. 위의 기능들과 언급하 지 못한 심도 깊고 다양한 Oracle Database 10g Release 2의 신기능들을 독자 여러분들이 직접 체험할 수 있기를 바란다.


제공 : DB포탈사이트 DBguide.net

출처명: 한국오라클'

Posted by 1010
02.Oracle/DataBase2008. 10. 23. 15:29
반응형

Oracle Database 11g:
DBA와 개발자가 알고 있어야 하는 새로운 기능

저자 - Arup Nanda Oracle ACE Director

Data Guard

Active Data Guard가 어떻게 실시간 쿼리를 통해 스탠바이 환경에 대한 투자를 가치 있게 만들면서, 물리적 스탠바이 데이터베이스를 스냅샷 스탠바이로 변환해, 아카이브 로그 및 많은 새로운 향상된 기능을 인프라에 적용하는지 자세한 정보를 알아 보겠습니다.

Download Oracle Database 11g 다운로드

Oracle Database 11g에는 책 한 권을 채울 수 있을 만큼 많은 Data Guard의 향상된 기능이 있습니다. 따라서 모든 향상된 기능을 자세히 밝히기는 불가능합니다. 대신 가장 흥미롭다고 생각되는 것을 중심으로 설명하도록 하겠습니다.

보다 간편하진 스탠바이 데이터베이스 생성

이제 시작합니다. 먼저 물리적 스탠바이 데이터베이스의 생성입니다. Oracle Database 11g에서, 이 프로세스는 RMAN 커맨드 하나면 족할 정도로 무척 간편해졌습니다. 이전에는, 2대의 머신 사이에 Data Guard를 설정하려면, Grid Control 마법사 인터페이스를 사용했습니다. 이 글을 작성하고 있는 시점 에서는, Oracle Enterprise Manager Grid Control 11g는 아직 사용할 수 없고, Database Control도 Data Guard를 위한 마법사를 가지고 있지 않습니다. 그러나 SQL 커맨드 사용 경험의 유무에 상관없이, Oracle Database 11g에, Data Guard 환경을 설정하는 것은 어렵지 않습니다. 이는 너무 단순해 여기서 모든 단계를 설명할 수 있습니다.

prolin11로 명명된 기본 데이터베이스가 prolin1이라는 서버에서 운영되고 있다고 가정합니다. 스탠바이 데이터베이스는 prolin2라는 서버에 설정하려고 합니다. 스탠바이 데이터베이스 인스턴스의 명칭은 pro11sb입니다. 단계는 다음과 같습니다:

  1. 이미 가지고 있는 경우가 아니라면, 우선, prolin1에 spfile을 생성합니다.
    SQL> create spfile from pfile;
    
    이 단계는 필수적인 것은 아니지만, 프로세스를 쉽게 해주는 이점이 있습니다. 데이터베이스 생성 후, spfile을 사용하기 위하여 prolin11 데이터베이스를 다시 시작합니다

  2. 스탠바이 재실행 로그 생성은 필수적인 것은 아니지만, 그렇게 하는 것이 좋습니다. 스탠바이 재실행 로그는 기본 데이터베이스에 발생하는 변화를 거의 실시간으로 스탠바이에 반영되도록 하는데, 이것이 Real Time Apply (RTA)라는 개념입니다. 따라서, 우리는 여기서 기본 데이터베이스에 스탠바이 재실행 로그를 생성할 것입니다 (스탠바이 재실행 로그는 기본 데이터베이스에 생성된다는 것을 잊지 마십시오. RMAN이 이 일을 할 것입니다):
    SQL> alter database add standby redo logfile group 4 
      2> (‘+DG1/sby_redo01.rdo') size 50M;
    SQL> alter database add standby redo logfile group 5 
      2> (‘+DG1/sby_redo02.rdo') size 50M;
    SQL> alter database add standby redo logfile group 6 
      2> (‘+DG1/sby_redo03.rdo') size 50M;
    SQL> alter database add standby redo logfile group 7 
      2> (‘+DG1/sby_redo04.rdo') size 50M;
    
    이를 통해 4개의 스탠바이 재실행 로그 그룹이 생성됩니다.

  3. prolin2 서버의 listener.ora 파일에 pro11sb를 위한 입력을 합니다:
    SID_LIST_LISTENER =
      (SID_LIST =
        (SID_DESC =
          (GLOBAL_DBNAME = pro11sb) 
          (ORACLE_HOME = /opt/oracle/product/11g/db1)
          (SID_NAME = pro11sb) 
        )
      )
     
    LISTENER =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = prolin2)(PORT = 1521))
      )
    
  4. 리스너를 실행하려면 재로딩합니다
  5. prolin1에서, $ORACLE_HOME/network/admin: 하부의 tnsnames.ora 파일에 pro11sb 데이터베이스를 위한 입력을 합니다 :
    PRO11SB =
      (DESCRIPTION =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = prolin2)(PORT = 1521))
        )
        (CONNECT_DATA =
          (SID = pro11sb)
        )
      )
    
  6. prolin2에서, Oracle Home/dbs 디렉토리에 1 라인을 포함하는 initodba11sb.ora 파일을 생성합니다:
    db_name=prolin11
    
    이는 스탠바이 인스턴스를 위한 초기화 파일로 기능할 것입니다; 파라미터의 나머지는 우리가 나중에 보게 될 RMAN 커맨드에 의해 자동 입력됩니다.

  7. prolin2에서, $ORACLE_BASE/admin 디렉토리 갑니다. 여기에 pro11sb라는 이름의 디렉토리를 생성한 다음, 스탠바이 인스턴스에 대한 감사 파일을 보유하기 위하여 pro11sb 내에 adump라는 이름의 디렉토리를 생성합니다.

  8. prolin1의 $ORACLE_HOME/dbs 디렉토리 하부에서, 흔히 orapworadba11로 명명되는 인스턴스 패스워드 파일을 볼 수 있습니다. 이 파일을 볼 수 없다면 (가능성은 희박하지만), 이를 생성합니다. 다음 그 파일을 prolin2의 $ORACLE_HOME/윤 하부로 복사합니다. 이를 orapwodba11sb 파일로 복사합니다. 이렇게 하면 기본 데이터베이스의 sysdba 연결 패스워드를 스탠바이에도 적용할 수 있습니다.

  9. prolin2에서, NOMOUNT 상태의 인스턴스 pro11sb를 실행합니다:
    $ sqlplus / as sysdba
    SQL> startup nomount
    
    이는 인스턴스를 실행하지만 아무것도 마운팅하지 않습니다.

  10. 이제 모든 초기화 준비가 완료되었으므로, 스탠바이 데이터베이스를 생성할 강력한 RMAN 스크립트를 호출합니다. prolin1에서, RMAN을 가동해 다음 스크립트를 실행합니다. 이를 파일에 저장하고 RMAN 프롬프트에서 스크립트를 실행하는 것은 매우 쉽습니다.
    connect target sys/oracle123@prolin11
    connect auxiliary sys/oracle123@pro11sb
     
    run {
       allocate channel c1 type disk;
       allocate auxiliary channel s1 type disk;
     
       duplicate target database
            for standby
            from active database
            dorecover
            spfile
            parameter_value_convert 'prolin11','pro11sb'
            set db_unique_name='pro11sb'
            set db_file_name_convert='/prolin11/','/pro11sb/'
            set log_file_name_convert='/prolin11/','/pro11sb/'
            set control_files='/oradata/pro11sb/control01.ctl'
            set fal_client='pro11sb'
            set fal_server='prolin11'
            set standby_file_management='AUTO'
            set log_archive_config='dg_config=(prolin11,pro11sb)'
            set log_archive_dest_2='service=prolin11 LGWR ASYNC valid_for=(ONLINE_LOGFILES,PRIMARY_ROLE) db_unique_name=pro11sb'
            set log_archive_dest_state_2='enable'
            set log_archive_format='pro11sb_%t_%s_%r.arc'
       ;
      sql channel c1 "alter system archive log current";
      sql channel s1 "alter database recover managed standby database using current logfile disconnect";
    }
    
    이 스크립트는 스탠바이 데이터베이스를 생성하고, 적절한 파라미터를 스탠바이 데이터베이스를 위한 spfile에 배치하고, 스탠바이 데이터베이스를 위한 진단 데스티네이션을 생성하고, 스탠바이를 다시 시작합니다. 이 작업의 정확한 구조를 이해하려면, 여기서 RMAN 커맨드의 아웃풋을 볼 필요가 있습니다.

    아래의 2 라인은 기본 및 스탠바이 인스턴스에 연결됩니다:

    connect target sys/oracle123@prolin11;
    connect auxiliary sys/oracle123@pro11sb;
    
    패스워드 파일을 스탠바이 호스트에 복사했기 때문에, SYS 패스워드는 동일하게 남아 있으며 따라서 스탠바이 인스턴스에 연결은 (마운팅 데이터베이스가 없지만) 성공적입니다. 다음으로, 다음과 같은 라인들이 실행됩니다:
    duplicate target database for standby from active database
         spfile
            parameter_value_convert 'prolin11','pro11sb'
            set 'db_unique_name'='pro11sb'
            set 'db_file_name_convert'='/prolin11/','/pro11sb/'
            ... and so on ...
    
    duplicate target database 커맨드는 우선 원격 서버에 있는 SQL*Net를 통해 기본 데이터베이스의 이미지를 복사함으로써 기본 데이터베이스로부터 스탠바이를 생성합니다. 복사가 완료되면, 내부적으로 커맨드를 발령하여 (switch clone datafile all;), 스탠바이 데이터베이스를 클론으로 만듭니다. 스크립트의 세트 커맨드가 스탠바이 인스턴스를 위한 SPFILE의 파라미터를 설정하며, 이 데이터베이스가 스탠바이 데이터베이스가 됩니다. 다시 말하지만, RMAN 아웃풋은 배후 활동에 대한 모든 정보를 제공합니다.
물리적 스탠바이 데이터베이스를 구축하는 것이 매우 쉽다는 것을 알아 두십시오. 이는 스크립트를 실행하는 것만큼이나 간단합니다!

Active Data Guard

물리적 스탠바이 데이터베이스를 사용하여 Data Guard 환경을 구현할 때 오랫동안 장애로 남아 있던 것 중의 하나는 스탠바이 데이터베이스의 수동성이었습니다. Oracle Database 10g 및 그 이전에는, 물리적 스탠바이 데이터베이스를 복구 프로세스를 멈춘 후에만, 읽기 전용 (말하자면, 리포팅 부담을 줄이기 위해)으로 개방했습니다. 이들 제품에서, Data Guard가 DR 솔루션의 일부이었다면, 뒤처지는 것이 두려워 오랫동안 복구 프로세스를 멈출 수 없었을 것이며, 따라서 물리적 스탠바이 데이터베이스는 읽기 전용을 위한 것이 아니라면, 당연히 무용지물이었을 것입니다

Oracle Database 11g로, 이제 상황이 변했습니다: 물리적 스탠바이 데이터베이스를 읽기 전용 모드로 개방하고 복구 프로세스를 다시 시작할 수 있습니다. 이는 기본 데이터베이스를 지속적으로 사용하면서 리포팅을 위해 스탠바이를 사용할 수 있다는 것을 의미합니다. (이전 버전의 경우와 마찬가지로, 스탠바이에서 백업도 할 수 있습니다.) 이것이 어떻게 이루어지는지 살펴 보겠습니다.

우선, 스탠바이 복구 관리를 취소합니다:

SQL> alter database recover managed standby database cancel;

Database altered.
다음, 데이터베이스를 읽기 전용으로 개방합니다:
SQL> alter database open read only;
 
Database altered.
여기까지는, 프로세스가 11g 이전 버전과 동일합니다. 이제, 11g의 정점을 살펴 보도록 하겠습니다: 스탠바이 데이터베이스가 읽기 전용으로 개방되어 있는 동안, 복구 프로세스 관리를 다시 시작할 수 있습니다.
SQL> alter database recover managed standby database disconnect;
 
Database altered.
이제 스탠바이 데이터베이스는 복구 관리 모드로 배치되어, 개방되어 있는 동안, 로그 파일을 적용합니다. 어떻게 이를 확인할 수 있을까요? 간단합니다; 단지 기본 데이터베이스의 최장 시퀀스 번호를 스탠바이의 그 것과 비교하면 됩니다. 기본 데이터베이스에서, 로그 변환을 하여 최장 시퀀스 번호를 확인합니다:
SQL> alter system switch logfile;
 
System altered.

SQL> select max(Sequence#) from v$log;
 
MAX(SEQUENCE#)
--------------
            79
로그 변환은 스탠바이가 읽기 전용 모드로 개방되어 있는 동안 진행됩니다. 스탠바이의 최장 시퀀스를 확인합니다:
SQL> select max(Sequence#) from v$log;
 
MAX(SEQUENCE#)
--------------
            79
이것 역시 79로 기본과 같습니다. 이는 로그 애플리케이션이 여전히 작업 중이라는 것을 보여줍니다. 여기서 이는 단순히 로그가 적용되고 있다는 것만을 보여주는 것이 아니냐는 의문이 생길 수 있습니다. 기본에서 진행되는 변화가 이 모드에서 보일까요? 확인해 보겠습니다. 기본에서, 테이블을 생성합니다:
SQL> create table test2 (col1 number);
 
Table created.
...그리고 나서 몇 개의 로그 변환을 하고 이들 로그가 스탠바이에 적용될 때까지 기다립니다. 다음으로 스탠바이 데이터베이스를 확인합니다:
SQL> desc test2
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------------------------
 COL1                                               NUMBER
Presto! 테이블이 스탠바이에 생성되고, 쿼리가 가능해졌습니다.

이 경우, 기본에서 생긴 변화를, 네트워크가 사용 가능하다면, 스탠바이에 즉각 나타나게 해주는 Real Time Apply를 사용할 수 있었다는 것을 기억하십니까? RTA는 ADG에 필수적인 것은 아니지만, 기본에 생긴 최근의 변화를 보고자 할 때, ADG가 보다 유용한 것이 되도록 해줍니다

보안과 관련해선, 걱정할 것이 없습니다. 데이터베이스는 읽기 전용 모드에 있기 때문에, 아무것도 여기에 쓸 수 없습니다. 만약 audit_trail 파라미터가 기본에서 DB로 설정되어 있다면 (Oracle Database 11g에서의 디폴트), 스탠바이에서도 동일하지만, 일기 전용이기 때문에, 감사 추적을 쓸 수는 없습니다

알림 로그에 나타난 라인을 보십시오:

AUDIT_TRAIL initialization parameter is changed to OS, as DB is NOT compatible for database opened with read-only access
아하! 감사 추적은 멈추지 않습니다; 오히려, 데이터베이스가 개방되었을 때, OS 파일로 자동 전환됩니다. 스탠바이 데이터베이스를 활성화하면, audit_trail은 DB로 자동 재설정됩니다.

스냅샷 스탠바이

일반적 시나리오를 생각해 보겠습니다: 새로운 애플리케이션을 데이터베이스에 배치 중이고, 데이터베이스 성능의 영향에 대해 알고 싶다고 합시다. Oracle Database 11g에는, SQL 구문을 캡처하고 이를 재생하는 완벽한 툴이 있지만 (Database Replay), 그 영향력을 직접 실행해 보고 확인해 볼 필요가 있습니다. 테스트 시스템을 캡처하더라도, 프로덕션 시스템에서 재생하는 것은 불가능합니다. 우선, 배치가 되지 않습니다, 또한, 배치된다고 하더라도, 애플리케이션으로 다른 테이블을 변경할 수 없습니다. 그러면 애플리케이션의 영향력을 확인하려면 어떻게 해야 할까요?

완벽한 답은 물리적 스탠바이 데이터베이스를 업데이트가 가능한 스냅샷 스탠바이 데이터베이스로 임시 변환할 수 있는 Oracle Database 11g입니다. 이 모드에서, 애플리케이션을 운영할 수 있고—많은 테이블 변경 가능—그 영향력을 평가할 수 있습니다. 영향력을 평가한 후, 데이터베이스를 정상적 복구가 진행되고 있는 스탠바이로 변환할 수 있습니다. 이는 정해진 지점으로 플래시백하여 모든 변화를 원상 복구하는 플래시백 데이터베이스 기능을 사용하여 데이터베이스 복구 지점을 생성함으로써 가능합니다. 이 작업이 어떻게 진행되는지 알아보겠습니다:

우선, 이미 진행되고 있는 경우가 아니라면, 스탠바이에서 복구를 시작합니다:

SQL> alter database recover managed standby database disconnect;

Database altered.
복구가 몇 개의 로그 파일을 선정할 때까지 기다립니다. 그리고 복구를 중단합니다.
SQL> alter database recover managed standby database cancel;
 
Database altered.
여기서, 스냅샷 스탠바이 데이터베이스를 생성할 수 있습니다. 이것은 플래시백 로깅을 가능하게 하기 때문에, 플래시 복구 영역을 구성하지 않으면, 다음과 같은 메시지를 받게 됩니다:
ORA-38784: Cannot create restore point 'SNAPSHOT_STANDBY_REQUIRED_01/12/2008
00:23:14'.
ORA-38786: Flash recovery area is not enabled.
이를 피하기 위해서는, 미리 플래시 복구 영역을 생성해야 합니다. 이미 그렇게 하지 않았다 하더라도, 걱정할 필요는 없습니다. 지금 생성하면 되기 때문입니다:
SQL> alter system set db_recovery_file_dest_size = 2G;
 
System altered.
 
SQL> alter system set db_recovery_file_dest= '/db_recov';
 
System altered.
이제 절차를 마쳤으므로, 다음과 같은 간단한 커맨드를 사용해 스탠바이 데이터베이스를 스냅샷 스탠바이로 변환할 수 있습니다:
SQL> alter database convert to snapshot standby;

Database altered.
이제 데이터베이스를 리사이클링합니다:
SQL> shutdown immediate
ORA-01507: database not mounted
...
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
이제 데이터베이스가 읽기/쓰기 작업을 위해 개방되었습니다:
SQL> select open_mode, database_role
  2  from v$database;
 
OPEN_MODE  DATABASE_ROLE
---------- ----------------
READ WRITE SNAPSHOT STANDBY
이제 데이터베이스를 변경할 수 있습니다. 여기가 Database Replay를 사용하여 캡처한 작업을 재생할 최적의 지점입니다. 이제 데이터베이스에서 시스템을 변경하고 변화의 영향력을 보기 위하여 몇 차례 재생할 수 있습니다. 이것은 프로덕션 데이터베이스의 복사본이므로, 재생은 해당 작업을 정확하게 재현합니다.

테스트가 완료되면, 스냅샷 스탠바이 데이터베이스를 정상적인 물리적 스탠바이 데이터베이스로 변환합니다. 다음과 같은 단계를 거칩니다:

SQL> connect / as sysdba
Connected.	
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
 
...
Database mounted.
SQL> alter database convert to physical standby; 
 
Database altered.
이제 끄고, 데이터베이스를 마운팅하고 복구 관리를 시작합니다.
SQL> shutdown
ORA-01507: database not mounted
 
 
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
...
Database mounted.
Start the managed recovery process:
SQL> alter database recover managed standby database disconnect;
이제 스탠바이 데이터베이스가 복구 관리 모드로 복귀했습니다. 당연히, 데이터베이스가 스냅샷 스탠바이 모드에 있으면, 기본의 아카이브 로그가 적용되지 않습니다. 이것은 지금 적용되며 작업 완료까지 몇 분 걸립니다.

스냅샷 스탠바이 데이터베이스는 스탠바이 데이터베이스를 사용하여 프로덕션 데이터베이스의 변화를 사전에 정확히 예상할 수 있습니다. 그러나 이게 전부가 아닙니다. 또 다른 장점이 있습니다. 기본에서 생긴 변화를, 네트워크가 사용 가능하다면, 스탠바이에 즉각 나타나게 해주는 Real Time Apply를 사용할 수 있었다는 것을 기억하십니까? 누군가 기본 데이터베이스에서 대규모 업데이트를 하거나 일부 코드를 변경하는 등 실수를 한다면 어떻게 될까요? 이전 버전에서, 이 같은 실수가 스탠바이로 확산되는 것을 방지하기 위하여, 신중하게 스탠바이 데이터베이스에서 딜레이를 사용합니다. 그러나 딜레이로 인해, 스탠바이가 올바로 작동하지 않거나 프로덕션의 활성 카피로 사용될 수 없을 수 있습니다.

더 이상은 필요 없습니다. 스탠바이 데이터베이스를 플래시백할 수 있기 때문에, 딜레이를 유지하고 있을 필요가 없습니다. 문제가 있다면, 언제든지 이전 상태로 플래시백할 수 있습니다.

물리적 스탠바이에서 논리적 스탠바이로의 변환

이제 물리적 스탠바이 데이터베이스를 논리적인 것으로 쉽게 변환할 수 있습니다. 다음 단계를 거칩니다:

  1. 스탠바이 데이터베이스는 어딘가로부터 데이터 딕셔너리 정보를 가져올 필요가 있습니다. 딕셔너리 정보는 기본의 재실행 스트림에 배치되어야 합니다. 따라서, 기본 데이터베이스에서, 다음과 같이 하여 딕셔너리를 위한 LogMiner 테이블을 만듭니다:
    SQL> begin 
      2    dbms_logstdby.build;
      3  end;
      4  /
     
    PL/SQL procedure successfully completed.
    
  2. 스탠바이에서, 복구 관리 프로세스를 멈춥니다
    SQL> alter database recover managed standby database cancel;
    
    Database altered.
    
  3. 이제, 스탠바이에 커맨드를 입력해 이를 논리적인 것으로 변환합니다:
    SQL> alter database recover to logical standby pro11sb;
     
    Database altered.
    
    1 단계를 실행하지 않았다면, 위의 커맨드는 딕셔너리 정보가 없기 때문에, 멈춰 있을 것입니다. 이 경우 여기서 1 단계를 실행하면 됩니다. RTA를 실행했다면, 정보는 스탠바이 데이터베이스에 즉각 정보가 나타날 것입니다.
  4. 기본의 몇 가지 로그 변환을 통해 아카이브 로그를 생성해 스탠바이로 보내야 합니다:
    SQL> alter system switch logfile;
     
    System altered.
    
  5. 잠시 후, 스탠바이에서, 데이터베이스 변경 커맨드가 완료되는 것을 볼 수 있습니다. 이제 스탠바이가 논리적인 것으로 변했습니다. 알림 로그에서 다음과 같은 것이 나타납니다:
    RFS[12]: Identified database type as 'logical standby'
    
  6. Recycle the database:
    SQL> shutdown
    ORA-01507: database not mounted
    ORACLE instance shut down.
    SQL> startup mount
    ORACLE instance started.
     
    Total System Global Area 1071333376 bytes
    ...
    Database mounted.
    SQL> alter database open resetlogs;
     
    Database altered.
    
  7. 이제 논리적 스탠바이로 되었으므로, SQL Apply 프로세스를 시작해야 합니다
    SQL> alter database start logical standby apply immediate;
    
SQL> alter database start logical standby apply immediate; 논리적 스탠바이 데이터베이스가 이제 완전 작동합니다! 일단 물리적 스탠바이를 논리적인 것으로 변환하면, 다음에서 설명할 특수 구문 ("keep identity")을 사용하지 않는 한 ,이를 다시 물리적인 것으로 변환할 수 없습니다.

롤링 업데이트

DBA의 업무에서 어려운 점은 업그레이드를 위해 꽤 오랜 시간 데이터베이스를 내려야 하는 정당성을 밝히는 것입니다. Oracle Database 11g에서는, 롤링 업데이트를 통해 어떠한 유형의 스탠바이 데이터베이스라도 가지고 있다면, 이 일은 매우 쉬어집니다:

  1. 스탠바이를 업그레이드합니다.
  2. 애플리케이션을 스탠바이로 옮깁니다.
  3. 기본을 업그레이드합니다.
  4. 애플리케이션을 다시 본래의 기본으로 옮깁니다.
이것이 논리적 스탠바이라면, 스탠바이가 단지 기본의 SQL을 적용하면 되기 때문에, 프로세스가 매우 간편합니다. SQL이 적용되면, 업그레이드는 해당 데이터베이스에서 쉽게 이루어집니다. 복구를 멈추고, 스탠바이를 업그레이드하고, 복구를 진행한 후, 스탠바이를 기본으로 변환할 수 있습니다. 나중에, 본래의 기본을 업그레이드 할 스탠바이로 만들 수 있습니다. 마지막으로, 역할을 바꿔, 본래의 기본을 새로운 기본으로 만들 수 있습니다.

그러나, 많은 스탠바이 데이터베이스는 사용 및 관리의 간편성을 위해 본질적으로 물리적입니다. 스탠바이가 논리적이 아니라 물리적이라면, 단계는 거의 흡사합니다. 스탠바이를 임시로 논리적으로 변환한 후 다시 물리적으로 변환하는 것입니다. 여기서 중요한 것은 영구적이 아니라 임시로라는 것입니다. 따라서, 다음과 같이 "keep identity"구문을 가진 변환 커맨드를 입력합니다:

SQL> alter database recover to logical standby keep identity;
 
Database altered.
보다 자세한 내용은 문서에서 확인할 수 있습니다.

기타 개선 사항

Data Guard 프로세스 자체에 몇 가지 중요한 개선 내용이 있습니다:

재실행 압축

Data Guard는 기본의 아카이브 로그를 스탠바이 데이터베이스 서버로 옮겨 이를 해당 데이터베이스에 적용한다는 전제를 가지고 있습니다. 기본과 스탠바이 사이의 시간 지체의 핵심 요소의 하나는 아카이브 로그를 옮기는 시간입니다. 이는 재실행 스트림을 압축하면 어느 정도 줄일 수 있습니다.

Oracle Database 11g에서는 TRUE로 설정된 파라미터 압축을 사용하여 SQL*Net를 통해 스탠바이 서버 전체를 경유하는 재실행 스트림을 압축할 수 있습니다. 이는 오로지 갭 해소 중에 옮겨지는 로그를 위한 것입니다. 이 문서의 앞부분에 제시된 사례에서 압축을 할 때 사용할 수 있는 커맨드는 다음과 같습니다.

alter system set log_archive_dest_2 = 'service=pro11sb LGWR ASYNC 
valid_for=(ONLINE_LOGFILES,PRIMARY_ROLE) db_unique_name=pro11sb compression=enable'

네트 타임 아웃

Data Guard 환경은 데이터베이스 인스턴스 연결을 통해 재실행 데이터를 스탠바이 서버로 보내 작동시킨다. 인스턴스가 시간 내 응답하지 않으면, 로그 전송 서비스는 지정된 타임 아웃 값을 기다린 후 중단합니다. 이 타임 아웃 값은 Oracle Database에 net_timeout이라는 파라미터를 사용해 설정할 수 있습니다. 최대 보호 모드에서, 로그 전송 서비스는 중단 전 20회의 재시도를 합니다.

그러나 우선 로그 전송에서 얼마만큼의 딜레이가 존재하는지 알아야 합니다. 새로운 뷰 v$redo_dest_resp_histogram에 막대 그래프 모양으로 시간이 나타납니다:

SQL> desc v$redo_dest_resp_histogram
 Name                   Null?    Type
 ---------------------- -------  --------------
 DEST_ID                         NUMBER
 TIME                            VARCHAR2(20)
 DURATION                        NUMBER
 FREQUENCY                       NUMBER
 
뷰는 해당 버킷에서 전송 시간 측정 결과를 보여줍니다. 작동 후 며칠 후 뷰를 조사해 보면, 타임 아웃에 설정에 대한 구상을 할 수 있을 것입니다. 다음과 같이 하여 타임 아웃 값을 설정할 수 있습니다:
alter system set log_archive_dest_2 = 'service=pro11sb LGWR ASYNC 
valid_for=(ONLINE_LOGFILES,PRIMARY_ROLE) db_unique_name=pro11sb compression=enable net_timeout=20'
다시 한 번 말하지만, 이는 앞에서 제시한 사례와 관련된 것입니다. 파라미터 값의 "net_timeout=20" 구문을 기억해 두십시오.

동적 변경 가능 파라미터

논리적 스탠바이 데이터베이스 환경 운영 프로세스에서, 프로세스를 튜닝하고 일부 파라미터 값을 조정할 필요가 있습니다. Oracle Database 11g에서, 이들 대부분의 파라미터는 온라인에서 업데이트할 수 있습니다. 뷰 dba_logstdby_parameters를 쿼리하면 이를 알 수 있습니다.

col name format a30
col value format a10
col unit format a10
col setting a6
col setting format a6
col dynamic format a7
select *
from dba_logstdby_parameters
order by name
/

NAME                           VALUE      UNIT       SETTIN DYNAMIC
------------------------------ ---------- ---------- ------ -------
APPLY_SERVERS                  5                     SYSTEM YES
EVENT_LOG_DEST                 DEST_EVENT            SYSTEM YES
                               S_TABLE
LOG_AUTO_DELETE                TRUE                  SYSTEM YES
LOG_AUTO_DEL_RETENTION_TARGET  1440       MINUTE     SYSTEM YES
MAX_EVENTS_RECORDED            10000                 SYSTEM YES
MAX_SERVERS                    9                     SYSTEM YES
MAX_SGA                        30         MEGABYTE   SYSTEM YES
PREPARE_SERVERS                1                     SYSTEM YES
PRESERVE_COMMIT_ORDER          TRUE                  SYSTEM NO
RECORD_APPLIED_DDL             FALSE                 SYSTEM YES
RECORD_SKIP_DDL                TRUE                  SYSTEM YES
RECORD_SKIP_ERRORS             TRUE                  SYSTEM YES
RECORD_UNSUPPORTED_OPERATIONS  FALSE                 SYSTEM YES
칼럼 DYNAMIC이 값을 동적으로 변경 가능한지를 보여 준다는 사실을 기억해 두십시오. 거의 모든 파라미터는 동적입니다. 예를 들어, 스탠바이를 멈추지 않고 파라미터 APPLY_SERVERS를 변경하려면, 다음과 같이 합니다.
SQL> begin
  2     dbms_logstdby.apply_set('APPLY_SERVERS',2);
  3  end;
  4  /
이는 apply_servers 값을 2로 설정하는데, 이는 스탠바이를 멈추지 않고 할 수 있습니다.

SQL Apply 이벤트 테이블

Oracle Database 10g에서, SQL Apply와 관련된 이벤트는 알림 로그에 작성되는데, 알림 혹은 리포팅 확인을 위하여 스크립트를 작성하는 편이 좋기 때문에, 그다지 유용한 것이 못됩니다. Oracle Database 11g에서, 이벤트는 디폴트로 SYSTEM 스키마의 새로운 테이블 LOGSTDBY$EVENTS에 작성되도록 되어 있습니다. 다음은 샘플 쿼리입니다:

select event_time, error
from system.logstdby$events
order by 1;
The output:
EVENT_TIME                    ERROR
----------------------------- -------------------------------------------------
13-JAN-08 11.24.14.296807 PM  ORA-16111: log mining and apply setting up
13-JAN-08 11.24.14.320487 PM  Apply LWM 2677727, HWM 2677727, SCN 2677727
14-JAN-08 07.22.10.057673 PM  APPLY_SET: APPLY_SERVERS changed to 2
14-JAN-08 07.22.11.034029 PM  APPLY_SERVERS changed to 2
14-JAN-08 07.45.15.579761 PM  APPLY_SET: EVENT_LOG_DEST changed to DEST_ALL
14-JAN-08 07.45.16.430027 PM  EVENT_LOG_DEST changed to DEST_ALL
여러 가지 이유로, 이 이벤트를 테이블에 가지고 있는 것이 좋습니다. 예를 들면, 조작 및 리포팅이 간편해집니다. 그러나 때로는, 특히 오류 및 메시지 알림 로그를 스캐닝하기 위한 모니터링 툴을 구현했다면, 이를 알림 로그에서 보는 것도 괜찮습니다. 이는 논리적 스탠바이 데이터베이스 적용 파라미터 "event_log_dest"를 "DEST_ALL"로 설정하면 가능해집니다:
begin
   dbms_logstdby.apply_set('EVENT_LOG_DEST','DEST_ALL');
end;
이는 동적으로 이루어지며, 이벤트는 테이블과 알림 로그 모두에 전달됩니다. 이 커맨드를 입력한 후, 알림 로그를 확인할 수 있습니다. 많은 SQL Apply 이벤트와 더불어 최소한 다음의 2 라인이 보일 것입니다:
LOGSTDBY: APPLY_SET: EVENT_LOG_DEST changed to DEST_ALL
LOGSTDBY status: EVENT_LOG_DEST changed to DEST_ALL

결론

우선, 우리는 활성 기본 데이터베이스로부터 물리적 스탠바이 데이터베이스를 구현하는 것이 별 것 아니라는 것을 알게 되었습니다. 또한, 물리적 스탠바이를 논리적으로 변환하는 것이 매우 간단하다는 것도 알게 되었습니다. 이 사실로부터 누릴 수 있는 최대의 장점은 스탠바이 데이터베이스를 어떤 방식으로든 비즈니스 지원을 위해 사용할 수 있다는 것입니다. Active Data Guard 기능은 스탠바이 데이터베이스를 개방해 아카이브 로그가 적용되는 동안 쿼리를 허용합니다. 스냅샷 스탠바이 데이터베이스는 데이터베이스에서 프로덕션 데이터베이스 로딩을 허용한 후 정상적 복구 관리 프로세스를 다시 시작하도록 처음 시작했던 지점으로 플래시백합니다. 이들 2가지 기능은 스탠바이 서버의 프로세싱 기능을 활용할 수 있도록 허용하기 때문에 11g로의 업그레이드를 위한 강력한 촉매 역할을 할 것입니다.

"Oracle Database 11g: DBA와 개발자가 알고 있어야 하는 새로운 기능" 홈페이지로 돌아가기


Arup Nanda Arup Nanda (arup@proligence.com)는 Starwood Hotel and Resorts의 데이터베이스 시스템 매니저로 12년이 넘는 기간 동안 오라클 DBA로 활동해 왔으며 2003년 오라클 매거진에 의해 "올해의 DBA"로 선정되었습니다. Arup은 오라클 관련 이벤트 및 저널의 발표자, 기고자로서 적극적으로 활동하고 있으며 뉴욕 오라클 사용자 그룹 실행 위원회 회원이자 Oracle ACE 디렉터입니다. 그는<RMAN Recipes for Oracle Database 11g: A Problem Solution Approach>를 포함하는 4권의 책을 공저하였습니다.
Posted by 1010
02.Oracle/DataBase2008. 10. 23. 13:55
반응형

10gR2 em 을 사용해서
archivelog 모드로 전환하려고 할 때,
호스트 인증서에 OS의 사용자 이름과 암호를 정확히 입력했는데도
아래 오류 메세지가 발생해서 진행이 안되네요...

RemoteOperationException: ERROR: Wrong password for user

해결 방법을 찾았네요...

관리도구 -> 로컬보안정책 메뉴에 들어가서

보안설정>로컬정책>사용자 권한 할당까지 들어가서

일괄작업으로 로그온 정책에 사용하는 계정을 추가하니깐 되네요...

Posted by 1010
02.Oracle/DataBase2008. 10. 23. 12:01
반응형

Oracle Secure Backup

파일 시스템과 오라클 데이터베이스를 위한 고성능 테이프 백업 관리를 이용하여 데이터 보호 환경의 비용과 복잡성을 절감할 수 있습니다.

보도 자료

Oracle Secure Backup은 분산 UNIX, Linux, Windows, NAS(Network Attached Storage) 환경의 오라클 데이터베이스 및 파일 시스템을 위한 테이프 데이터 보호 기능을 제공합니다. 데이터 보호 및 백업 도메인 액세스 기능을 제공하는 Oracle Secure Backup은 SSL(Secure Socket Layer), 데이터 암호화 등의 검증된 보안 테크놀로지를 기반으로 구현되었습니다. Oracle Secure Backup은 Oracle Enterprise Manager(EM)과 통합되어 있으며, 테이프를 이용하여 전체 오라클 환경을 보호하고자 하는 오라클 고객에게 이상적인 솔루션입니다:

  • 테이프 드라이브 당 비용이 저렴하므로 다른 테이프 백업 제품과 비교하여 혁신적인 비용 절감 효과를 제공합니다.
  • 오라클 데이터베이스의 Recovery Manager(RMAN)과 통합된 기능을 제공합니다 (Oracle 9i 이상 지원).
  • 최적화된 데이터베이스 백업 기능을 제공하므로 성능 개선, 테이프 사용량 절감이 가능합니다.
  • 오라클 데이터베이스의 테이프 백업을 위한 데이터 암호화 기능을 제공합니다.
  • 이기종 환경의 파일 시스템 데이터 보호 기능:
    • Oracle Home, 바이너리
    • 오라클 애플리케이션 제품의 설정 파일
  • Data Guard, Real Application Clusters (RAC), Automatic Storage Management (ASM) 환경의 최적화된 지원 제공

Oracle Secure Backup은 엔터프라이즈 테이프 백업 소프트웨어의 비용과 복잡성을 절감하고 오라클 고객의 ROI를 보장합니다. 단일 벤더 제품을 이용하여 오라클 데이터베이스의 디스크/테이프 백업 환경을 구현함으로써, 멀티 벤더 솔루션에 수반되는 복잡성을 제거하고 문제 해결 과정의 오류와 번거로운 절차를 피할 수 있게 합니다. Oracle Secure Backup은 전체 오라클 환경을 위한 안정적인 테이프 데이터 보호 환경을 제공합니다.


튜토리얼
오라클이 권장하는 전략
Bullet 테이프 백업의 암호화
Bullet 파일 시스템 백업의 스케줄링
Bullet Backup and restoring file system data
Bullet Managing media and devices using EM
Bullet User-level Access Control
Bullet

Installation on Windows

Oracle Secure Backup Express
bullet

Oracle Database, Oracle Application 제품군과 함께 무료 제공되는 Oracle Secure Backup Express는 하나의 테이프 드라이브를 장착한 단일 서버 보호를 위한 솔루션입니다. 두 개 이상의 테이프 드라이브가 필요한 경우 Oracle Secure Backup 정식 버전 라이센스를 구매하고 간단하게 업그레이드할 수 있습니다.

bullet 데이터 시트
 

뛰어난 확장성의 클라이언트/서버 아키텍처를 기반으로 하는 Oracle Secure Backup은 관리 포인트를 단일화함으로써 네트워크 서버의 테이프 백업 관리를 중앙집중화하는 효과를 제공합니다.

중앙 관리 서버는 Oracle Secure Backup의 카탈로그, 작업 스케줄러, 작업 설정을 유지하며 서버 인증을 위한 CA(Certificate Authority) 역할을 수행합니다. 관리 서버에 의해 관리되는 모든 호스트와 테이프 디바이스는 관리 도메인의 일부로 포함됩니다. 도메인 내의 호스트는 백업 요구사항과 테이프 드라이브 액세스를 기준으로 하나 또는 그 이상의 역할(role)에 할당됩니다.

백업해야 할 데이터가 위치한 각 호스트에는 클라이언트 역할이 할당되며, 서버에 테이프 드라이브가 직접 연결되어 있는 경우에는 미디어 서버 역할도 함께 수행합니다. 테이프 디바이스는 다수의 서버에 의해 분산, 공유되거나 전용으로 할당될 수 있습니다. 공유 테이프 환경에서, Oracle Secure Backup은 테이프 리소스 사용률의 극대화를 위한 다이내믹 테이프 드라이브 공유 기능을 제공합니다.

관리 도메인은 한 대의 서버 또는 수 TB의 데이터를 저장한 수백 대의 이기종 서버로 구성될 수 있습니다.

Posted by 1010
02.Oracle2008. 10. 23. 11:59
반응형

Oracle Secure Backup

파일 시스템과 오라클 데이터베이스를 위한 고성능 테이프 백업 관리를 이용하여 데이터 보호 환경의 비용과 복잡성을 절감할 수 있습니다.

보도 자료

Oracle Secure Backup은 분산 UNIX, Linux, Windows, NAS(Network Attached Storage) 환경의 오라클 데이터베이스 및 파일 시스템을 위한 테이프 데이터 보호 기능을 제공합니다. 데이터 보호 및 백업 도메인 액세스 기능을 제공하는 Oracle Secure Backup은 SSL(Secure Socket Layer), 데이터 암호화 등의 검증된 보안 테크놀로지를 기반으로 구현되었습니다. Oracle Secure Backup은 Oracle Enterprise Manager(EM)과 통합되어 있으며, 테이프를 이용하여 전체 오라클 환경을 보호하고자 하는 오라클 고객에게 이상적인 솔루션입니다:

  • 테이프 드라이브 당 비용이 저렴하므로 다른 테이프 백업 제품과 비교하여 혁신적인 비용 절감 효과를 제공합니다.
  • 오라클 데이터베이스의 Recovery Manager(RMAN)과 통합된 기능을 제공합니다 (Oracle 9i 이상 지원).
  • 최적화된 데이터베이스 백업 기능을 제공하므로 성능 개선, 테이프 사용량 절감이 가능합니다.
  • 오라클 데이터베이스의 테이프 백업을 위한 데이터 암호화 기능을 제공합니다.
  • 이기종 환경의 파일 시스템 데이터 보호 기능:
    • Oracle Home, 바이너리
    • 오라클 애플리케이션 제품의 설정 파일
  • Data Guard, Real Application Clusters (RAC), Automatic Storage Management (ASM) 환경의 최적화된 지원 제공

Oracle Secure Backup은 엔터프라이즈 테이프 백업 소프트웨어의 비용과 복잡성을 절감하고 오라클 고객의 ROI를 보장합니다. 단일 벤더 제품을 이용하여 오라클 데이터베이스의 디스크/테이프 백업 환경을 구현함으로써, 멀티 벤더 솔루션에 수반되는 복잡성을 제거하고 문제 해결 과정의 오류와 번거로운 절차를 피할 수 있게 합니다. Oracle Secure Backup은 전체 오라클 환경을 위한 안정적인 테이프 데이터 보호 환경을 제공합니다.


튜토리얼
오라클이 권장하는 전략
Bullet 테이프 백업의 암호화
Bullet 파일 시스템 백업의 스케줄링
Bullet Backup and restoring file system data
Bullet Managing media and devices using EM
Bullet User-level Access Control
Bullet

Installation on Windows

Oracle Secure Backup Express
bullet

Oracle Database, Oracle Application 제품군과 함께 무료 제공되는 Oracle Secure Backup Express는 하나의 테이프 드라이브를 장착한 단일 서버 보호를 위한 솔루션입니다. 두 개 이상의 테이프 드라이브가 필요한 경우 Oracle Secure Backup 정식 버전 라이센스를 구매하고 간단하게 업그레이드할 수 있습니다.

bullet 데이터 시트
 

뛰어난 확장성의 클라이언트/서버 아키텍처를 기반으로 하는 Oracle Secure Backup은 관리 포인트를 단일화함으로써 네트워크 서버의 테이프 백업 관리를 중앙집중화하는 효과를 제공합니다.

중앙 관리 서버는 Oracle Secure Backup의 카탈로그, 작업 스케줄러, 작업 설정을 유지하며 서버 인증을 위한 CA(Certificate Authority) 역할을 수행합니다. 관리 서버에 의해 관리되는 모든 호스트와 테이프 디바이스는 관리 도메인의 일부로 포함됩니다. 도메인 내의 호스트는 백업 요구사항과 테이프 드라이브 액세스를 기준으로 하나 또는 그 이상의 역할(role)에 할당됩니다.

백업해야 할 데이터가 위치한 각 호스트에는 클라이언트 역할이 할당되며, 서버에 테이프 드라이브가 직접 연결되어 있는 경우에는 미디어 서버 역할도 함께 수행합니다. 테이프 디바이스는 다수의 서버에 의해 분산, 공유되거나 전용으로 할당될 수 있습니다. 공유 테이프 환경에서, Oracle Secure Backup은 테이프 리소스 사용률의 극대화를 위한 다이내믹 테이프 드라이브 공유 기능을 제공합니다.

관리 도메인은 한 대의 서버 또는 수 TB의 데이터를 저장한 수백 대의 이기종 서버로 구성될 수 있습니다.

Posted by 1010
02.Oracle2008. 10. 23. 11:58
반응형
http://www.netapp.com/kr/products/management-software/snapmanager-oracle-ko.html


SnapManager® 소프트웨어로 Oracle® 데이터베이스의 백업, 복원, 복구, 복제 등에 수반되었던 오래 걸리고 복잡한 수작업들을 자동으로 손쉽게 처리할 수 있습니다.

Oracle 기반의 어플리케이션은 비즈니스 지원에 필수적이며 하루 24시간 내내 가용성이 보장되어야 합니다. 관리자는 중요 Oracle 기반 비즈니스 프로세스를 지원하기 위해 효율성을 극대화할 수 있는 툴을 필요로 합니다.

Oracle 어플리케이션 제품군용 SnapManager의 백업, 복원, 복구, 복제 기능으로 Oracle 데이터베이스를 자동으로 손쉽게 관리할 수 있습니다. NetApp의 축적된 기술을 활용하여 공간 낭비를 최대한 줄이면서 즉각적으로 Snapshot™ 복사본과 Oracle 데이터베이스의 복제본을 만들 수 있습니다.

여러 Oracle 데이터베이스를 통합하고 Oracle 데이터 관리를 완전 자동화합니다.

성능 저하 없이 백업 빈도를 증가시켜 데이터와 비즈니스를 확실히 보호하십시오. 데이터베이스 크기에 관계 없이 오류가 발생한 데이터베이스를 분 단위로 완전한 운영 상태로 복원합니다.

QA, 개발, 테스트 및 기타 필요에 따라 완전한 데이터베이스 복제본을 몇 초 내에 생성합니다.

SnapManager 소프트웨어로 Oracle 데이터베이스 관리를 자동화하고 단순화하는 방법을 자세히 알아보십시오 (PDF).

Posted by 1010
02.Oracle2008. 10. 23. 11:54
반응형
http://www.bakbone.co.kr/products/application_data_protection/oracle/

오라클 온라인 APM™
 
오라클 DB가 증가함에 따라 이 중요한 비즈니스 자산들을 보호해야 할 필요가 대두되었습니다.  특정 DB의 온라인 백업/복구 솔루션은 사용자 데이터의 보호와 유지가 관건입니다.  오라클 APM은 오라클 DB의 빠른 온라인 백업을 통하여 어플리케이션의 가용성을 증가시킵니다. 오라클 APM은 핫 백업, 단일 시스템에서의 다중 DB서버 지원, 사용하기 쉬운 사용자 인터페이스, 로 테이블 백업 지원 등 광범위하고 다양한 기능들이 포함되어 있습니다. 
 
핫 백업
넷볼트의 오라클 온라인 APM 사용으로 데이터베이스는 백업이 진행되는 동안이라도 온라인 상태로서 엑세 스가 가능하며 다운타임, 제로를 보장합니다. 
 
다중 DB서버 지원
넷볼트의 오라클 온라인 APM은 사용 가능한 서버들 모두 디스플레이합니다.  APM은 오라클서버 일부 또는 전부에 대해 백업 및 복구를 허용합니다. 
 
선택가능한 DB 백업작업
오라클 온라인 APM에만 필요로 하는 백업. 사용의 편리함, 포인트 앤드 클릭의 사용자 인터페이스는 개별 테이블 스페이스, 트랜젝션 로그 및 컨트롤 과 초기화 파라메터 파일 백업 및 복구의 정확한 튜닝을 제공합니다. 
 
로 테이블스페이스(Raw Tablespace) 지원
UNIX환경에서, 오라클 온라인 APM은 사용자 개입없이 로 및 테이블스페이스의 백업이 가능합니다. 
Posted by 1010
02.Oracle/DataBase2008. 10. 22. 15:33
반응형
원인:
관리도구의 서비스에서 OracleServiceORCL 이 정지가 되어있는 상태에서 오라클에 접속하게 되면 아래의 현상이 발생한다
 
C:\>sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.1.0 - Production on Mon Dec 13 16:33:47 2004
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
ERROR:
ORA-12560: TNS:protocol adapter error

Enter user-name:
 
 
해결 방법:
1. 관리도구의 서비스에서 OracleServiceORCL을 시작한다.
2. 명령어로 시작한다
 
1번의 경우 서비스에서 OracleServiceORCL을 선택하고 위에 있는  ▶ 버튼을 클릭하면 시작된다.
 
2번의 경우는 아래와 같이 할 수 있다.
C:\>oradim -startup -sid ORCL -usrpwd oracle -starttype srvc -pfile c:\oracle\ora92\database\initORCL.ora
 
-sid ORCL  (오라클 SID를 입력)
-usrpwd oracle  (password)
-pfile c:\oracle\ora92\database\initORCL.ora (pfile의 경로를 쓰시면 됩니다.)


출처 : http://nanamix.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-ORA-12560-%EC%97%90%EB%9F%AC-%EB%8C%80%EC%B2%98%EB%B2%95
Posted by 1010
02.Oracle/DataBase2008. 10. 22. 15:16
반응형
DBMS를 기동

sqlplus '/ as sysdba'
sql>startup



만약 DB가 클라이언트랑 다른 머신에서 동작한다면...
listener기동해야합니다.
lsnrctl start
Posted by 1010
02.Oracle/DataBase2008. 10. 22. 14:48
반응형
오라클 테이블스페이스 만들기
① TABLESPACE의 종류 (SYSTEM, UNDO, TEMPORARY ,DATA, SYSAUX 등 5가지)
② 데이터파일의 사이즈 변경
  ALTER DATABASE
  DATAFILE 'C:\ORACLE\DATA\NEOSS_FM01.DBF' RESIZE 300M
③ 데이터파일 추가  
  ALTER TABLESPACE TS_DATA
  ADD DATAFILE 'C:\ORACLE\DATA\NEOSS_FM02.DBF' SIZE 200M ;
④ 기본테이블스페이스 지정 (10g)
  ALTER DATABASE DEFAULT TABLESPACE TS_DATA; -- 데이터베이스에 대한 기본 테이블스페이스 지정
  ALTER USER SCOTT DEFAULT TABLESPACE TS_DATA; -- USER별 기본 테이블스페이스 지정
  주의) 기본 테이블 스페이스를 변경할 경우 기존에 명시적으로 지정된(개별 유저에 대하여)
      기본 테이블 스페이스도 변한다...
⑤ SYSAUX라는 테이블 스페이스 도입 (10G)
⑥ 테이블 스페이스 이름 변경
  ALTER TABLESPACE RENAME TO ;
⑦ 테이블스페이스별로 블록크기를 다르게 지정 가능 (9i 이상)
⑧ 테이블스페이스 옮기기
   ALTER TABLE TB_EMP MOVE TABLESPACE TS_DATA2;
⑨ 테이블스페이스에 대한 권한 부여
   ALTER USER SCOTT QUOTA UNLIMITED ON TS_DATA;

------------------------------------------------------------------
▣ DATA 테이블 스페이스 만들기
------------------------------------------------------------------
CREATE TABLESPACE TS_DATA
DATAFILE 'C:\ORACLE\DATA\NEOSS_FM01.DBF'
SIZE 100M
AUTOEXTEND ON
NEXT 10M
MAXSIZE 1000M
EXTENT MANAGEMENT LOCAL
UNIFORM SIZE 1M
-- STORAGE 절을 구성할 필요 없다.(INITIAL, NEXT, PCTINCREASE, MINEXTENTS,
-- MAXEXTENTS 를 자동관리)
-- 최초 생성시에는 INITIAL, NEXT, MINEXTENTS 에 대하여 효력이 있다.
-- Autoallocate방식과 Uniform 방식중 EXTENT MANAGEMENT 가 명시되지 않으면 Autoallocate로 설정
SEGMENT SPACE MANAGEMENT AUTO;
-- PCTUSED, FREE LIST, FREE LIST GROUP 설정을 자동으로 한다.
/


------------------------------------------------------------------
▣ TEMP 테이블 스페이스 만들기
   ① locally managed tablespace uniform size 만 생성가능
     autoallocate ,extent management dictionary option 을 사용하면 ora-25319 error 가 발생
   ② rename 이 불가능
------------------------------------------------------------------
CREATE TEMPORARY TABLESPACE TS_TEMP
TEMPFILE 'C:\ORACLE\TEMPDATA\NEOSS_TEMP01.DBF'  
-->DATAFILE이 아니라 TEMPFILE 이다..
SIZE 10M
EXTENT MANAGEMENT LOCAL
UNIFORM SIZE 512K
/

------------------------------------------------------------------
▣ UNDO 테이블 스페이스 만들기
  ① UNDO_MANAGEMENT 와 UNDO_TABLESPACE, UNDO_RETENTION PARAMETER를 제공
  ② 지역적으로 관리되는 익스텐트만 사용가능
  ③ 시스템에 의해 관리되는 익스텐트 할당만 사용가능하다.
   (UNIFORMSIZE를 할당 할 수 없고 AUTOALLOCATE만 가능)
------------------------------------------------------------------
CREATE UNDO TABLESPACE TS_UNDO
DATAFILE 'C:\ORACLE\TEMPDATA\NEOSS_UNDO01.DBF'
SIZE 1M
AUTOEXTEND ON
NEXT 1M
MAXSIZE 1024M
/
Posted by 1010
02.Oracle/DataBase2008. 10. 20. 23:47
반응형

오라클 유용한 함수(안쓰면 까먹어서 또 찾아봐야하는 그런...) 정리

/*---------------------------
1. 문자 함수
------------------------------*/
①LOWER( column|expression!!! )

LOWER('String') --> string : 소문자로 변환

②UPPER( column|expression!!! )

UPPER('String') --> STRING : 대문자로 변환

③INITCAP( column|expression!!! )

INITCAP('string') --> String : 첫글자만 대문자이고 나머지글자는 소문자로 변환

④CONCAT( column1|expression!!ŋ ,column2|expression!!Ō )

CONCAT('Good','String') --> GoodString : ||와 같은 역할을 한다.

⑤SUBSTR(column|expression!!!, m [,n]) : m값이 음수면 문자값의 끝부터..)

SUBSTR('String',1,3) --> Str : 1번째부터 3개의 문자를 리턴한다.

⑥LENGTH( column|expression!!! )

LENGTH('String') --> 6 : 문자열의 길이를 리턴한다.

⑦INSTR( column|expression!!!, )

INSTR('String','r') --> 3 : 문자열에 'r'이 몇번째 위치하고 있나를 리턴한다.

⑧LPAD( column|expression!!!,n,'string' ) : n 은 전체 길이

LPAD('String',10,'*') --> ****String

: 10자리수중에 모자란 자리수를 '*'로 왼쪽에 채운다.(문자,숫자 가능!!!)

⑨ RPAD('String',10,'*') --> String****

: 10자리수중에 모자란 자리수를 '*'로 오른쪽에 채운다.(문자,숫자 가능!!!)

⑩ LTRIM(' String') --> 'String' : 문자열의 왼쪽 공백을 버린다.
 - LTRIM('****AAA***','*')  --> 왼쪽에 특정 문자를 지운다.

⑪ RTRIM('String ') --> 'String' : 문자령의 오른쪽 공백을 버린다.

* TRIM(leading/tailing/both, trim_character FROM trim_source )

TRIM( 'S' FROM 'SSMITH') --> MITH

12. TRANSLATE      REPLACE와 똑 같지만 이것은  스트링 단위가 아닌 문자  단위로 작동한다.
 TRANSLATE('AABBA','B','C') -->AACCA
-- 숫자는 모두 9로 문자는 모두 X로 변환하기
SELECT
       TRANSLATE('2KRW229','0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ','9999999999XXXXXXXXXXXXXXXXXXXXXXXXXX')
 FROM DUAL
 -------------------
 9XXX999


13. REPLACE        어떤 스트링이 나타나는 곳마다 다른 스트링으로 바꾼다.

-- TRANSLATE와 확실한 구별 법

 SELECT
       TRANSLATE('2KRW229','229','0')
 FROM DUAL
-------------------------------
0KRW00

  SELECT
       replace('2KRW229','229','0')
 FROM DUAL
 -------------------------------
2KRW0


--특정Character의 아스키값 구하기
SELECT CHR(65) "CHR", ASCII('A') "ASCII" FROM DUAL;
SELECT ASCII( CHR(65) ) FROM DUAL;

SELECT LOWER('My name is LKM') "LOWER", UPPER('My name is LKM') "UPPER" FROM DUAL;

SELECT LPAD('LKM', 10, '*') "LPAD", RPAD('LKM', 10, '*') "RPAD" FROM DUAL;
SELECT LPAD('1234567890', 20, '+') || RPAD('1234567890', 20, '^') "12345678901234567890"
FROM DUAL;
SELECT LPAD('1,234,567', 30, ' ') "LPAD사용으로 30자리 맞춤",
'1,234,567' "단순문자 사용",
1234567 "단순숫자 사용"
FROM DUAL;

SELECT LTRIM(' AAA ') "LTRIM", RTRIM(' AAA ') "RTRIM" FROM DUAL;
SELECT LTRIM( RTRIM( ' A A A ' ) ) "TRIM" FROM DUAL;

SELECT REPLACE('ORACLE', 'A', 'BBB') "REPLACE" FROM DUAL;
SELECT EMP_NAME, REPLACE(EMP_NAME, '이', '박') "이->박"
FROM PERSONNEL
WHERE EMP_NAME LIKE '이%';

SELECT SUBSTR('ORACLE PROJECT', 1, 3) SUBSTR1,
SUBSTR('ORACLE PROJECT', 4, 5) SUBSTR2,
SUBSTR('ORACLE PROJECT', 10) SUBSTR3 FROM DUAL ;
SELECT SUBSTRB('ORACLE PROJECT', 1, 3) SUBSTRB1,
SUBSTRB('ORACLE PROJECT', 4, 5) SUBSTRB2,
SUBSTRB('ORACLE PROJECT', 10) SUBSTRB3 FROM DUAL ;
SELECT SUBSTR('오라클 PROJECT', 1, 3) SUBSTR1,
SUBSTR('오라클 PROJECT', 4, 5) SUBSTR2,
SUBSTR('오라클 PROJECT', 10) SUBSTR3 FROM DUAL ;
SELECT SUBSTRB('오라클 PROJECT', 1, 3) SUBSTRB1,
SUBSTRB('오라클 PROJECT', 4, 5) SUBSTRB2,
SUBSTRB('오라클 PROJECT', 10) SUBSTRB3 FROM DUAL ;

SELECT LENGTH ('ORACLE PROJECT') "LENGTH",
LENGTHB('ORACLE PROJECT') "LENGTHB",
FROM DUAL;
SELECT EMPNO, LENGTH(EMPNO), LENGTHB(EMPNO),
EMP_NAME, LENGTH(EMP_NAME), LENGTHB(EMP_NAME)
FROM PERSONNEL
WHERE EMPNO > '98102';
SELECT HOBBY, LENGTH(HOBBY), LENGTHB(HOBBY)
FROM PERSONNEL
WHERE EMPNO > '98102';

SELECT INSTR ('ORACLE PROJECT', 'R', 1, 1) INSTR1,
INSTR ('ORACLE PROJECT', 'R', 1, 2) INSTR2,
INSTR ('ORACLE PROJECT', 'R', 1, 3) INSTR3
FROM DUAL;
SELECT INSTR ('CORPORATE FLOOR','OR', 3, 2) INSTR,
INSTRB ('CORPORATE FLOOR','OR', 3, 2) INSTRB
FROM DUAL;
SELECT HOBBY,
INSTR (HOBBY, ')', 1, 1) INSTR,
INSTRB(HOBBY, ')', 1, 1) INSTRB
FROM PERSONNEL
WHERE EMPNO > '98102';


/*------------------------------
2. 숫자 함수
-----------------------------------*/
① ROUND(45.926, 2) --> 45.93 : 소수점 두자리수까지 보여주면서 반올림한다.

② TRUNC(45.926, 2) --> 45.92 : 소수점 두자리까지만 보여주고 나머지는 버린다.

③ MOD(1600,300) --> 100 : 1600을 300으로 나누고 나머지를 리턴한다.

* ROUND예제(WHOLE NUMBER:정수)

SELECT ROUND(45.923,2), ROUND(45.923,0), ROUND(45.923,-1) FROM DUAL

==> 45.92 46 50

* TRUNC예제

SELECT TRUNC(45.923,2), TRUNC(45.923), TRUNC(45.923,-1) FROM DUAL

==> 45.92 45(n이 생략된면 일의 자리까지 남기고 버린다.) 40

* SYSTEM 날짜를 갖고 오는 방법.

SELECT sysdate FROM dual


--무조건 올림
SELECT CEIL(13.11) FROM DUAL;
SELECT CEIL(13.001) FROM DUAL;

--나머지 구함
SELECT MOD(23, 5) FROM DUAL;
SELECT MOD(57, 145) FROM DUAL;

-- 제곱승
SELECT POWER(3, 2), POWER(3, -2) FROM DUAL;
SELECT POWER(2, 10) FROM DUAL;

--자릿수 지정
SELECT ROUND(345.123, 0) FROM DUAL;
SELECT ROUND(345.123, 2), ROUND(345.123, -1) FROM DUAL;

--지정된 자리까지 잘라내기
SELECT TRUNC(345.123, 1), TRUNC(345.123, 0), TRUNC(345.123, -1) FROM DUAL;
SELECT TRUNC( 345.123 + 0.09, 1 ) FROM DUAL;
SELECT TRUNC( 345.123 + 0.9, 0 ) FROM DUAL;
SELECT TRUNC( 345.123 + 9, -1 ) FROM DUAL;

SELECT SIGN(5.989), SIGN(0), SIGN(-999.098) FROM DUAL;



/*------------------------------------
3. 날짜 계산( 날짜를 숫자로 저장)
-----------------------------------------*/
date + number : date에 number만큼 후의 날자를 보여준다.

date - number : date에 number만큼 전의 날자를 보여준다.

date1 - date2 : date1에서 date2 까지의 총 일수를 보여준다.( date1+date2는 X )

date1 + 숫자/24 : date1에서 시간을 더해 날짜를 보여준다.

4. Date Functions

MONTHS_BETWEEN('01-SEP-95','11-JAN-94') --> 19.6774194

; 두날짜 사이의 달수를 보여준다.

ADD_MONTHS('11-JAN-94', 6) --> 11-JUL-94

; 날짜에 6개월을 더한 날자를 보여준다.

NEXT_DAY('01-SEP-95','FRIDAY') --> '08-SEP-95'

; 해당일 다음에 오는 FRIDAY의 일자를 보여준다.

('SUNDAY'는 1, 'MONDAY'는 2...이런식으로 숫자를 써줘도 된다.)

LAST_DAY('01-SEP-95') --> '30-SEP-95'

; 해당월의 마지막날자를 보여준다.

ROUND('25-JUL-95','MONTH')--> 01-AUG-95 ROUND('25-JUL-95','YEAR')--> 01-JAN-96

TRUNC('25-JUL-95','MONTH') --> 01-JUL-95 TRUNC('25-JUL-95','YEAR') --> 01-JAN-95


/*--------------------------------
5. 타입 변환 함수
----------------------------------*/
nlsparams : 십진수, 그룹구분자, 지역 통화 기호, 국제 통화 기호

TO_CHAR(date,['format'],[nlsparams]) : date를 format에 맞게 문자열로 변환한다.

- Date Format Elements

YYYY --> 1999 (년출력) , YEAR --> nineteen ninety-nine (년출력)

MM --> 12 (월출력) , MONTH --> DECEMBER (월출력), MON --> DEC

D --> 요일을 숫자로 리턴한다.(일요일은 1, 월요일은 2...)

DD --> 07 (달의 일출력)

DDD --> 200 (연의 일출력)그 해의 총 몇 일째인가를 리턴한다.

DAY --> MONDAY (요일출력) DY-->MON

CC --> 20 (몇 세기인지를 보여준다.)

WW --> 그 해의 몇 번째 주인가를 리턴한다.

W --> 그 달의 몇 번째 주인가를 리턴한다.


* Element들을 소문자로 쓰면 소문자로 나오고 대문자로 쓰면 대문자로 출력된다.

HH or HH12 or HH24 / MI(0-59분) / SS(0-59초)


* 문자열은 " " 묶어 추가한다 DD " of " MONTH --> 12 of DECEMBER

*숫자 접미어는 숫자를 문자로 표기. TH(4->4TH)/ SP(4->FOUR)/ SPTH or THSP(4->FOURTH)

ddspth : 14-> fothteenth

* / . , : 구두점은 결과에 그대로 출력한다. * 공백, 선행제로를 제거하는 fm요소가 있다.

TO_CHAR(number,'format',[nlsparams]) : number를 format에 맞게 문자열로 변환한다.

- Number Format Elements

9 : 999,999 --> 1,234 $: 부동 달러 기호 $99999 -> $1234

0 : 099999 --> 001234 99.999EEEE -> 1.234E+03 B: 0값을 공백으로

L : L99,999 --> FF1,234 (NLS_CURRENCY에 설정되어있는 값이 L로 보여진다.)


TO_NUMBER(char,['format'],[nlsparams]) : 숫자형태의 문자열을 숫자로 변한한다.

TO_DATE(char,['format'],[nlsparams]):날자형태의 문자열을 format에 맞게 날자형식으로 변환 한다.


/*--------------------------------------------------------
6. NVL Funcion : 값이 null일 때 설정값을 보여준다.
----------------------------------------------------------*/
NVL(number_column, 0) : null일 때 0을 보여준다.

NVL(date_column, '01-JAN-95') : null일 때 '01-JAN-95'를 보여준다.

NVL(character_column, 'Empty') : null일 때 'Empty'를 보여준다.

* column Type과 표현식의 type이 반드시 일치해야 한다.


/*-------------------------------------------------------------------------
7. DECODE Function : CASE or IF-THEN-ELSE 형식과 비슷하다.
---------------------------------------------------------------------------*/
*DECODE(col/expression!!!, search1, result1 [,search2,result2,…] [,default])

F1 (F2 (F3 (col,arg1),arg2),arg3)



이중 Decode나 Nvl 그리고, To_데이터형은 너무나도 많이 쓰여서 잘 안 까먹지만....

숫자나 문자관련 함수 잘 안쓰면 찾기가 너무 힘들다는..... '그 뭐시기냐 문자열의 위치 찾아내는거

그 함수 뭐냐?' 라면 '그게 뭔데?'라는 반문이-_- 차라리 instr이 뭐하는거지가 더 쉬운 질문이다-_-

대전 있을때 자료전환건이 있어서... 처리를 하려고 보니 특정칼럼 하나에 잘 쓰이지 않는

두개의 필드값을 탭구분자로 나눠서 때려넣어논 꼴을 본적이 있다. instr, chr, replace로 간단히

해결가능할걸 instr과 chr를 잘 몰라 통째로 엑셀로 받아 수작업을 했다라는....

그것도 1만3천건의 자료를 ㅠ.ㅠ


다음은 예전 공부할때 예제들.. 참고삼아






/*--------------------------------
* 함수 - Date Function *
--------------------------------*/


SELECT SYSDATE FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') "SYSDATE" FROM DUAL;

SELECT LAST_DAY(SYSDATE) FROM DUAL;
SELECT TO_CHAR(LAST_DAY(SYSDATE), 'YYYY-MM-DD HH24:MI:SS') "LAST_DAY" FROM DUAL;

SELECT MONTHS_BETWEEN( '2002/01/13', '2002/05/13' ) "MONTHS_BETWEEN (-)",
MONTHS_BETWEEN( '2002/01/13', '2001/11/13' ) "MONTHS_BETWEEN (+)"
FROM DUAL ;
SELECT MONTHS_BETWEEN( '2002/01/13', '2002/01/30' ) "MONTHS_BETWEEN (-)",
MONTHS_BETWEEN( '2002/01/13', '2002/01/01' ) "MONTHS_BETWEEN (+)"
FROM DUAL ;

SELECT ADD_MONTHS(SYSDATE, 1) "ADD_MONTHS (+)",
ADD_MONTHS(SYSDATE, -1) "ADD_MONTHS (-)"
FROM DUAL ;

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
SELECT ADD_MONTHS( '2002/02/28', 12 ) "1년후",
ADD_MONTHS( '2002/02/28', 24 ) "2년후",
ADD_MONTHS( '2002/02/28', 36 ) "3년후"
FROM DUAL ;

SELECT SYSDATE,
NEXT_DAY(SYSDATE, '일요일') "NEXT_DAY 1",
NEXT_DAY(SYSDATE, 1 ) "NEXT_DAY 2"
FROM DUAL;
SELECT SYSDATE,
NEXT_DAY(SYSDATE, '수요일') "NEXT_DAY 1",
NEXT_DAY(SYSDATE, 4 ) "NEXT_DAY 2"
FROM DUAL;


/*------------------------------------------
* 함수 - Conversion Function *
-------------------------------------*/


SELECT TO_CHAR(1234567.891) "TO_CHAR1",
TO_CHAR(1234567.891, '999') "TO_CHAR2",
TO_CHAR(1234567.891, '9,999,999') "TO_CHAR3",
TO_CHAR(1234567.891, '0.0000') "TO_CHAR5",
TO_CHAR(1234567.891, '9,999,999.0000') "TO_CHAR6",
TO_CHAR(123, '9,999.00') "TO_CHAR7",
TO_CHAR(123, '9,999.99') "TO_CHAR8"
FROM DUAL ;
SELECT TO_CHAR(1234567.891, '9G999G999') "TO_CHAR3",
TO_CHAR(1234567.891, '0D0000') "TO_CHAR5",
TO_CHAR(1234567.891, '9G999G999D0000') "TO_CHAR6",
TO_CHAR(123, '9G999D00') "TO_CHAR7",
TO_CHAR(123, '9G999D99') "TO_CHAR8"
FROM DUAL ;

SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD') "TO_CHAR1",
TO_CHAR(SYSDATE, 'YYYY/MM') "TO_CHAR2",
TO_CHAR(SYSDATE, 'YYYY') "TO_CHAR3",
TO_CHAR(SYSDATE, 'DD') "TO_CHAR4",
TO_CHAR(SYSDATE, 'DAY') "TO_CHAR5",
TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') "TO_CHAR6",
TO_CHAR(TO_DATE('20020101','YYYYMMDD'), 'YYYY-MM-DD') "TO_CHAR7",
TO_CHAR(TO_DATE('20020101','YYYYMMDD'), 'YYYYMMDD HHMISS') "TO_CHAR8"
FROM DUAL ;

SELECT TO_NUMBER('123456.9') "TO_NUMBER1",
TO_NUMBER('1234567') "TO_NUMBER2"
FROM DUAL ;
SELECT TO_NUMBER('123,456.9', '999,999.9') "TO_NUMBER1",
TO_NUMBER('1,234,567', '9G999G999') "TO_NUMBER2"
FROM DUAL ;

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
SELECT TO_DATE('20020824') "TO_DATE1",
TO_DATE('2002-08-24') "TO_DATE2",
TO_DATE('200208') "TO_DATE3"
FROM DUAL ;
SELECT TO_DATE('20020824', 'YYYYMMDD') "TO_DATE1",
TO_DATE('2002-08-24', 'YYYY-MM-DD') "TO_DATE2",
TO_DATE('200208', 'YYYYMM') "TO_DATE3"
FROM DUAL ;
SELECT TO_DATE('2002/08/24 08:14:06', 'YYYY/MM/DD HH24:MI:SS') "TO_DATE1",
TO_DATE('2002/08/24 08:14:06 오후', 'YYYY/MM/DD HH:MI:SS AM') "TO_DATE2"
FROM DUAL ;


/*------------------------------------
* 함수 - Group Function *
-------------------------------------*/


SELECT AVG(HEIGHT), AVG(WEIGHT) FROM PERSONNEL;

SELECT MAX(EMPNO), MAX(EMP_NAME), MIN(EMPNO), MIN(EMP_NAME) FROM PERSONNEL;
SELECT MAX(HEIGHT), MIN(HEIGHT) FROM PERSONNEL;

SELECT SUM(WEIGHT) FROM PERSONNEL;

SELECT COUNT(*), COUNT(EMPNO), COUNT(JIKCH_CODE) FROM PERSONNEL;


/*----------------------------
* 함수 - ETC *
----------------------------*/


SELECT EMPNO, EMP_NAME, HOBBY 취미, WELL 특기
FROM PERSONNEL
WHERE EMPNO BETWEEN '98001' AND '98005';
SELECT EMPNO, EMP_NAME, HOBBY 취미, NVL(WELL, '(없다)') 특기
FROM PERSONNEL
WHERE EMPNO BETWEEN '98001' AND '98005';

SELECT DECODE( '나', '나', '맞다', '아니다' ) "나가 나면 맞다, 아니면 아니다"
FROM DUAL ;
SELECT DECODE( '나', '대명', '아니다',
'너' , '아니다',
'그' , '아니다',
'나' , '맞다',
'모르겠다' ) FROM DUAL ;
SELECT EMPNO,
EMP_NAME,
DECODE (HT_CODE, '1', '현재원', '2', '휴직', '퇴사') HT_CODE
FROM PERSONNEL
WHERE EMPNO BETWEEN '98071' AND '98080';

SELECT GREATEST (132, 33, 45, 90, 60.77) GREATEST,
LEAST (132, 33, 45, 90, 60.77) LEAST
FROM DUAL;
SELECT GREATEST ('이공명', '이대명', '최수미') GREATEST,
LEAST ('이공명', '이대명', '최수미') LEAST
FROM DUAL;

SELECT USERENV('LANGUAGE') "LANGUAGE",
USERENV('TERMINAL') "TERMINAL",
USERENV('SESSIONID') "SESSIONID"
FROM DUAL;

SELECT UID, USER FROM DUAL;

---------------------------------------------------------------------------------------------------
오라클 내장함수


Error 관련 내장함수
---------------------------------------------------------------------
SQLCODE        현재 발생한 오류에 따른 오류 코드를 반환한다.
SQLERRM        오라클 오류 코드와 연결된 오류 메시지를 반환한다.

Number 관련 내장함수
---------------------------------------------------------------------
ABS            어떤 수의 절대값을 반환한다.
ACOS         어떤 수의 아크코사인을 라디안 단위로 반환한다.
ASIN           어떤 수의 아크사인을 라디안 단위로 반환한다.
ATAN          어떤 수(x)의 아크탄젠트를 라디안 단위로 반환한다.
ATAN2        어떤 수(y/x)의 아크탄젠트를 라디안 단위로 반환한다.
CEIL           지정된 수보다 크거나 같은 최소 정수 값을 반환한다.
COS            어떤 수의 코사인을 라디안 단위로 반환한다.
COSH         어떤 수의 쌍곡선 코사인을 라디안 단위로 반환한다.
EXP            어떤 수의 지수 값을 반환한다. E=2.7182818
FLOOR        지정된 수보다 크거나 같은 최대 정수 값을 반환한다.
LN             어떤 수 x의 대수 값을 반환한다.
LOG            어떤 수 y에서 x를 밑으로 한 대수 값을 반환한다.
MOD            어떤 수 x를 y로 나눈 나머지를 반환한다.
POWER          어떤 수 x에 y 제곱한 값을 반환한다.
ROUND          x를 y자리에서 반올림한 값을 반환한다.
SIGN           숫자 x의 부호에 따라 양수이면 +1, 음수이면 -1, 0이면 0을 반환한다.
SIN            어떤 수의 사인을 라디안 단위로 반환한다.
SINH           어떤 수의 쌍곡선 사인을 라디안 단위로 반환한다.
SQRT           어떤 수 x의 제곱근을 반환한다. X는 반드시 양의 실수이다.
TAN            어떤 수의 탄젠트를 라디안 단위로 반환한다.
TANH           어떤 수의 쌍곡선 탄젠트를 라디안 단위로 반환한다.
TRUNC          어떤 수 x를 y 위치에서 잘라낸다.

Character 관련 내장함수
---------------------------------------------------------------------
ASCII          문자의 ASCII 코드를 반환한다.
CHR            주어진 ASCII 값에 해당하는 문자를 반환한다.
CONCAT         두 개의 스트링을 서로 연결한다. (|| 연산자를 사용한 것과 같다)
INITCAP        각 단어의 첫 글자를 대문자로 나머지는 소문자로 변환한 스트링을 반환한
                다(문자가 아닌 값에는 영향이 없다)
INSTR          어떤 스트링에서 특정 스트링의 위치를 반환한다.
INSTRB         어떤 스트링에서 특정 스트링의 위치를 반환하는데,  값을 싱글 바이트 문
                자 시스템에 대한 바이트 단위로 반환한다.
LENGTH         뒤에 따라오는 공백을 포함하여 문자 스트링의 길이를 반환한다. 값이 null
                이면 null을 반환한다.
LENGTHB        문자 스트링의 길이를 반환하는데, 이것은 값을 싱글 바이트 문자 셋에 대
                한 바이트 단위로 반환한다.
LOWER          전체 문자 스트링을 소문자로 바꾼다. 문자가 아닌 값에는 영향이 없다
LPAD           스트링의 왼쪽에 지정한 어떤 스트링을 덧붙인다.
LTRIM          왼쪽에 있는 문자 스트링을 잘라낸다.
NLS_INITCAP    NLSSORT에 의해 지정된 다른 정렬방법을 사용할 수 있다는 것을 제외하
                고는 INITCAP 함수와 같다.
NLS_LOWER      NLSSORT에 의해 지정된 다른 정렬방법을 사용할 수 있다는 것을 제외하
                고는 LOWER 함수와 같다.
NLS_UPPER      NLSSORT에 의해 지정된 다른 정렬 방법을 사용할 수 있다는  것을 제외
                하고는 UPPER 함수와 같다.
NLSSORT        문자를 정렬하는 방법을 바꾼다. 이것은 NLS 함수를  사용하기 전에 지정
                해야 한다. 그렇지 않으면 기본 정렬이 사용된다.
REPLACE        어떤 스트링이 나타나는 곳마다 다른 스트링으로 바꾼다.
RPAD           스트링의 오른쪽에 지정된 어떤 스트링을 덧붙인다.
RTRIM          오른쪽에 있는 문자 스트링을 잘라낸다.
SOUNDEX        스트링의 음향을 반환한다. 철자는 다르지만 소리는 비슷한 단어에 유용하
                다.
SUBSTR         어떤 스트링에서 스트링의 일부를 반환한다.
SUBSTRB        싱글 바이트 문자 시스템을 처리하기 위해 파라미터가 문자가 아닌 바이트
                단위로 표현된다는 것을 제외하고는 SUBSTR 함수와 같다.
TRIM           LTRIM과 RTRIM 함수의 기능을 조합한  것이다. 스트링에서 앞 뒤 문자
                를 잘라낸다.
TRANSLATE      REPLACE와 똑 같지만 이것은  스트링 단위가 아닌 문자  단위로 작동한
                다.

UPPER          전체 문자 스트링을 대문자로 바꾼다. 문자가 아닌 값에는 영향이 없다.

Conversion 관련 내장함수
---------------------------------------------------------------------
CHARTOROWID    오라클이 제공하는 외부형식으로  된 CHAR이나 VARCHAR2를  그 내부
                바이너리 형식으로 변환한다.
CONVERT        한 문자 셋을 다른 문자 셋으로 변환한다.
HEXTORAW       16진 스트링 값을 내부 원시 값으로 변환한다.
RAWTOHEX       내부 원시 값을 외부 16진 스트링으로 변환한다.
ROWIDTOCHAR    ROWID를 외부적인 18 문자 스트링 표현으로 변환한다.
TO_CHAR        DATES, MLSLABELS, NUMBERS를 VARCHAR2 스트링으로 변환한다.
TO_DATE        CHAR이나 VARCHAR2 스트링을 DATE 값으로 변환한다.
TO_LABEL       CHAR이나 VARCHAR2 스트링을 MLSLABEL 값으로 변환한다.
TO_MULTI_BYTE  싱글 바이트 스트링으로 된 문자를 멀티 바이트 스트링으로 변환한다.
TO_NUMBER      CHAR이나 VARCHAR2 스트링을 NUMBER 값으로 변환한다.
TO_SINGLE_BYTE 멀티 바이트 스트링으로 된 문자를 싱글 바이트 스트링으로 변환한다.

Date 관련 내장함수
---------------------------------------------------------------------
ADD_MONTHS     지정된 날짜에 1달을 더한다.  만일 결과로 나온 달이  현재일수보다 작은
                일수를 갖고 있는 달로 변경되면 그 달의 마지막 날을 반환한다.
LAST_DAY       주어진 달의 마지막 날을 반환한다.
MONTHS_BETWEEN 두 날짜 사이의 개월 수를 계산한다. 만일 두 날짜가 그 달의 마지막 날이
                라면 정수를 반환하고 그렇지 않으면 한 달을 31일로 계산한 분수 값을 반
                환한다.
NEW_TIME       사용자가 지정한 시간대에 대한 시간/날짜 값을 반환한다.
NEXT_DAY       시작 날짜 다음에 지정된 요일이 처음으로 나오는 날짜를 반환한다.
ROUND          월, 연도, 세기 등과 같이 선택한 날짜 파라미터를 반올림한다.
SYSDATE        시스템 날짜와 시간을 DATE 형식으로 반환한다.
TRUNC          일, 월 등과 같이 지정된 날짜 파라미터를 잘라낸다.

집합함수
---------------------------------------------------------------------
AVG            지정된 컬럼 값의 평균을 구한다.
COUNT          쿼리에서 반환되는 행의 개수를 구한다.
GLC            MLSLABEL의 최대 아래쪽 한계를 구한다.
LUB            MLSLABEL의 최대 위쪽 한계를 구한다.
MAX            쿼리에서 지정된 컬럼의 값 중 가장 큰 값을 반환한다.
MIN            쿼리에서 지정된 컬럼의 값 중 가장 작은 값을 반환한다.
STDDEV         쿼리에서 선택된 컬럼의 표준 편차를 반환한다.
SUM            쿼리에서 선택된 컬럼의 합계를 구한다.
VARIANCE       쿼리에서 선택된 컬럼의 분산을 구한다.
DISTINCT       쿼리의 유일값만 구한다.

【예제】
SQL> select COUNT(DISTINCT job) from emp;
SQL> select COUNT(job) from emp;
SQL> select COUNT(*) from emp;


기타 내장함수
---------------------------------------------------------------------
BFILENAME      파일이 저장되어 있는 물리적 LOB  바이너리 파일과 연결되어 있는 포인
                터를 반환한다. 오라클에서는 포인터를 locator라고 부른다.
DECODE         값 목록 중에서 IF-THEN-ELSE 문과 같이 작동한다.
DUMP           VARCHAR2 스트링으로 된 덤프 값을 제공한다. 스트링을 여러 가지 다른
                형식으로 된 표현으로 보여주기 위해서이다.
EMPTY_BLOB     데이터를 갖고 있지 않는 컬럼이나 BLOB 변수를 초기화하는데 사용한다.
EMPTY_CLOB     데이터를 갖고 있지 않는 컬럼이나 CLOB 변수를 초기화하는데 사용한다.
GREATEST       값이나 식의 목록에서 가장 큰 값을 반환한다.
GREATEST_LB    MLSLABELS 목록에서 최대 아래쪽 한계를 반환한다.
LEAST          값이나 식의 목록에서 가장 작은 값을 반환한다.
LEAST_LB       MLSLABELS 목록에서 최소 아래쪽 한계를 반환한다.
NLS_CHARSET_ID  NLS 문자셋 이름과 연결된 NLS 문자셋 ID 번호를 반환한다.
NLS_CHARSET_NAME 함수에 전달된 ID와 연결된 NLS 문자셋 이름을 반환한다.
NVL            값이나 식의 목록에서 처음으로 NULL이 아닌 값을 선택한다.
UID            오라클 사용자에게 할당된 사용자 ID를 반환한다.
USER           현재 사용자 이름을 VARCHAR2 스트링으로 반환한다.
USERENV        현재 작업환경에 관한 정보를 반환한다.
VSIZE          어떤 값의 바이트 수를 반환한다.

【예제】
$ sqlplus scott/tiger
SQL> select * from emp;
SQL> select uid from dual;
SQL> select user from dual;
SQL> select count(user) from emp;
SQL> select avg(sal) from emp;
SQL> select max(sal) from emp;
SQL> select min(sal) from emp;
SQL> select stddev(sal) from emp;
SQL> select sysdate from dual;
SQL> select last_day(sysdate) from dual;
SQL> select to_char(sysdate) from dual;
SQL> select to_char(next_day(sysdate,'Monday'),'MM/DD/yyyy')
    2  from dual;



출처 : http://chunter.tistory.com/20

Posted by 1010
02.Oracle/DataBase2008. 9. 25. 14:38
반응형

접속

접속명령

conn 아이디/비밀번호 as 접속권한

conn 아이디 as 접속권한

conn / as 접속권한 (익명 접속도 가능)

 

접속 해제 명령

disconn

 

오라클 서버에 접속시 관리자 계정(system)으로 접속하려면 'as sysdba' 사용

 

접속포트 바꾸기

exec dbms_xdb.sethttpport(9090);

 

 

시스템 기본 테이블 스페이스 조회

msSQL과는 달리 DB의 개념이 없고 비슷하게 테이블 스페이스라는 것이 있다.

select tablespace_name, status

from dba_tablespaces

order by tablespace_name

 

 

오라클 사용자 계정 만들기

  1. 테이블 스페이스 생성
    [이름] => TS_lazy
    [경로] => D:\java\TS_lazy.dbf
    create tablespace TS_lazy
    datafile 'D:\java\TS_lazy.dbf' size 10M
    default storage
    (initial 128k next 64k pctincrease 10);
  2. 사용자 계정 생성에 테이블 스페이스 지정
    [아이디] => lazy
    [비밀번호] => 302
    create user [아이디] identified by [비밀번호]
    default tablespace TS_lazy
    temporary tablespace temp
    사용자 보기 : select username, user_id from dba_users;
  3. 사용자 권한 부여
    grant connect, resource to [아이디]

 

데이터베이스와 일반 데이터의 차이

  1. 데이터에 보안을 적용하기가 쉽다.
  2. 데이터의 중복을 막을 수 있고 자료의 일관성을 유지할 수 있다.

 

 

데이터베이스 종류

  1. 관계형(R) 데이터 베이스 : MySQL, MS-SQL, Oracle9i, 10g

 

 

테이블 구조

2차원 배열의 형태로 구성

테이블을 구성하는 최소 단위 - item

item이 어러개 모이면 - 필드

필드가 어러개 모이면 - 레코드

레코드가 여러개 모이면 - 테이블

 

 

SQL 명령문 종류

  1. DDL : 데이터 정의 ( create, drop, alter )
  2. DML : 데이터 조작 ( select, update, insert, delete )
  3. DCL : 데이터 제어 ( grant, revoke, rollback, commit )

 

 

 

ORACLE 자료형

-- char : 문자형 (고정길이) max : 2000 byte
-- nchar : 문자형 (고정길이), 유니코드 지원,  max : 2000 byte
-- varchar2 : 문자형 (가변길이) max : 2000 byte
-- nvarchar2 : 문자형 (가변길이) 유니코드 지원, max : 2000 byte
-- date : 날짜형, 형식 지정자로 변환가능, max : 7 byte
-- number : 숫자(정수, 실수)형, max : 37자리까지 정수, 실수 표현가능
-- number(n) : 최대 n byte 정수
-- number(n, m) : n - 소수점 제외자릿수, m - 소수점 이하 자릿수

-- 대용량 데이터 저장용 자료형
-- long : 문자/바이너리 저장용, max : 2 byte
-- 테이블에 단 한번만 사용 가능
-- clob : 문자 저장용, max : 4 Gbyte
-- blob : 바이너리 저장용,  max : 4 Gbyte
-- 데이터 저장 / 출력시 특수한 변환과정 필요 

 

 

저장 프로시저 ( store procedure )

  1. 기본문법
  2. create procedure [저장프로시져 이름] (
  3. -- create or replace procedure [저장프로시져 이름] : 저장과 수정을 동시에 함.
  4. < 매개변수 목록 >

  5. ) is
  6. begin
  7. <프로시져 본문>

  8. end [저장프로시져 이름]

< 매개변수 목록 > : 프로그램 실행시 필요한 데이터를 받을 경우 사용

변수명   in/out   <자료형>

 

< 프로시져 지역변수 > : 프로시져 안에서만 사용

변수명   <자료형>

 

< 프로시져 수식 >

문자연결 연산자 : ||

대입 연산자 :       :=

 

  1. CREATE OR REPLACE PROCEDURE savesungjuk2(
  2.      iname IN sungjuk.names%TYPE, -- 매개변수
  3.   ikor IN sungjuk.kor%TYPE,
  4.   ieng IN sungjuk.eng%TYPE,
  5.   imat IN sungjuk.mat%TYPE
  6. ) IS
  7.   itot sungjuk.tot%TYPE;   -- 지역변수
  8.   iavg sungjuk.avgs%TYPE;
  9.   igrd sungjuk.grd%TYPE;
  10. BEGIN
  11.   itot := ikor + ieng + imat;
  12.   iavg := itot/3;
  13.   IF(iavg > 89) THEN
  14.     igrd := 'A';
  15.   ELSIF(iavg > 79) THEN
  16.      igrd := 'B';
  17.    ELSIF(iavg > 69) THEN
  18.         igrd := 'C';
  19.    ELSIF(iavg > 59) THEN
  20.        igrd := 'D';
  21.    ELSE
  22.        igrd := 'F';
  23.   END IF;
  24.  

     

  25.   INSERT INTO sungjuk VALUES(sjseq.NEXTVAL, iname, ikor, ieng, imat, itot, iavg, igrd, SYSDATE);
  26. END savesungjuk2;
  27. EXECUTE savesungjuk2 ('lazy5', 50, 60, 99);
  28. SELECT * FROM SUNGJUK

 

  1. CREATE OR REPLACE PROCEDURE listBoard(
  2.            rs OUT       SYS_REFCURSOR      -- 결과값 저장 변수
  3. ) IS
  4. BEGIN
  5.          OPEN rs FOR
  6.                   SELECT bno, subject, id, rdate, reads FROM BOARD;
  7. END listBoard;

 

  1. CREATE OR REPLACE PROCEDURE viewBoard(
  2.            ibno         IN              board.bno%TYPE,
  3.            rs           OUT     sys_refcursor
  4. ) IS
  5. BEGIN
  6.          OPEN rs FOR
  7.          SELECT * FROM board WHERE bno = ibno;
  8. END;
Posted by 1010
02.Oracle/DataBase2008. 9. 25. 14:26
반응형

 
사용자 삽입 이미지

MS-SQL 에는 Management Studio 라는 GUI 툴킷이 있습니다.
오라클도 SQL Developer 라는게 있더군요.
기본적으로 설치되지않고 오라클 사이트에서 옵션으로 제공하고 있습니다.

사용자 삽입 이미지

http://www.oracle.com/technology/software/products/sql/index.html

그냥 다운받으면 zip 파일 형태로 제공되는데, 압축을 풀고 sqldeveloper.exe 파일을 실행하면 됩니다.
설치과정이 없더군요.

실행후에 연결 Connection 을 만들어야 합니다.
아래와 같이 하시면 될듯 하네요.
저는 로컬 연결과 학교 데이터베이스 수업에서 쓸 연결, 이렇게 2 개를 만들었습니다.

사용자 삽입 이미지

사용자 삽입 이미지

참고로, 위 스샷은 MS-SQL Management Studio 입니다.
저는 MS-SQL 이 더 편한듯 ;;
Posted by 1010
02.Oracle/DataBase2008. 9. 25. 14:22
반응형
Posted by 1010
02.Oracle/DataBase2008. 9. 1. 17:45
반응형
Posted by 1010
02.Oracle/DataBase2008. 8. 7. 15:16
반응형

All_all_tables      : user가 access할수있는 모든 Table
All_catalog        : user가 access할수있는 모든 Table, Views, synonyms, sequence
All_clusters        : user가 access할수있는 모든 clusters
All_col_comments : user가 access할수있는 모든 Table,Views에 대한 칼럼comments
All_col_privs      : user에게 또는 Public에게 허용된 모든 칼럼에 대한 권한.
All_col_privs_made : user가 부여한 칼럼에 대한 권한.
All_col_privs_recd : user에게 또는 Public에게 허용된 모든 칼럼에 대한 권한.
All_coll_types     : user가 access 할수 있는 모든 collection type
All_cons_columns : 제약조건에 관련된 칼럼, access할수 있는 대한 정보
All_constraints    : access할수 있는 테이블에 대한 제약조건.
All_db_links       : user가 access 할수 있는 데이터베이스 link
All_def_audit_opts : 오브젝트가 생성될때 적용될수있는 default오브젝트감사내용.
All_dependencies  : user가 access할수있는 오브젝트간의 dependencies(참조,link)
All_directories     : user가 access할 수 있는 모든 directories (owner 는 항상 sys)
All_errors        : user가 access할수있는 모든 objects(view,procedure,package, function,
                    packagebody) 에 대한 에러.
All_ind_columns  : user가 access할수있는 테이블에 대한 인덱스의 칼럼.
All_ind_partitions : user가 access할수있는 인덱스partition, partition에 대한
            storage매개변수, Analyze명령에 의해 결정된 partition통계.
All_indexes       : user가 access할수있는 테이블의 인덱스.    
             이 view의 통계를 수집하기위해, Analyze명령을 사용한다.
             병렬partition인텍스탐색을 지원한다.
All_labels         : system labels 에 대한 Oracle server view.
All_libraries       : user가 access할 수 있는 모든 libraries.
All_lobs           : user가 access할 수 있는 모든테이블에 포함된 LOBs.
All_method_params : user가 access할 수 있는 method와 그method의 parameter.
All_method_results :
All_nested_tables  : user가 access할수있는테이블내의 Nested Table
All_object_tables  : user가 access할수있는테이블의모든정보.
All_objects : user가 access할수있는objects(index partition,table partition,package,
             package body, trigger)
All_part_col_statistics : user가 access할 수 있는 테이블partition에 대한 칼럼통계와
             막대그래프화된 정보.
All_part_histograms   : user가 access할수있는 테이블partition의 histograms에 대한
             histogram정보.
All_part_indexes      : user가 access할수있는 모든partition된 index의 partition정보.
All_part_key_columns :user가 access할수있는 partition된 objects의 partition key
             칼럼에 대한정보
All_part_tables        : user가 access할수있는partition된 Table에 대한 partition정보.
All_refresh            : user가 access할수있는모든 refresh groups.
All_refresh_children   : user가 access할 수 있는 refresh groups 안의 모든objects
All_refs                : user가 access할 수 있는 칼럼중 REF칼럼과, REF속성.
All_registered_snapshots : 모든 등록된 snapshots.
All_sequences          : user가 access할수있는 sequences.
All_snapshot_logs      : 모든 snapshot logs.
All_snapshot_refresh_times : 모든 snapshot refresh times.
All_snapshots           : user가 acces할수있는 모든 snapshots.
All_source              : user가 access할수있는 모든 stored objects의 text source.                 
All_synonyms          : user가 access할수있는 모든 synonyms.
All_tab_col_statistics   : 'User_tab_columns' view안의 정보에대한 칼럼통계와 그래프정보
All_tab_columns        : user가 access할수있는모든 table, views, clusters에 대한 칼럼.
             이view를 활용하기위해서는 Analyze명령어를 사용한다.
All_tab_comments      : user가 access할 수 있는 모든 table, views에 대한 comments.
All_tab_histograms     : user가 access할수있는table, views에 대한 histograms.
All_tab_partitions : user가 access할수 있는 각각의 테이블partition에 대한    
      partition정보, storage parameter, Analyze명령에 의한 통계정보등을 서술한다.
All_tab_privs           : user혹은 PUBLIC가 부여받은 오브젝트권한.
All_tab_privs_made    : user가 부여한 user권한과 오브젝트권한.
All_tab_privs_recd     : user 또는 PUBLIC이 부여받은 오브젝트권한.
All_tables            : user가 access할 수 있는 모든 테이블.
                        Analyze명령으로 이 view의 통계를 얻을 수 있다.
All_triggers : user소유의 trigger, user소유테이블의 trigger, 또는 user가
         CREATE ANY TRIGGER 권한을 갖고있다면, 모든 트리거에 대한 정보.
All_trigger_cols : user소유의 trigger, user소유테이블의 trigger, 또는 user가
         CREATE ANY TRIGGER 권한을 갖고있다면, 모든 트리거에 대한 칼럼정보.
All_type_attrs : user가 access할 수 있는 type의 attributes.
All_type_methods : user가 access할수있는type의 methods.
All_types       : user가 access할 수 있는 type.
All_updatable_columns : join view에서 update가능한 칼럼에 대한 정보.
All_users       : 데이터베이스의 모든 user에 대한 정보.
All_views      : user가 access할수있는view의 텍스트.
Audit_actions  : 감사추적type코드 정보.
catalog         : Oracle 5.0 version과의 호환정보를 포함한다.
                이view의 사용은 추천할만하지 못하다.
cat             : user_catalog 에 대한 synonym.
chained_rows  : ANALYZE LIST CHAINED ROWS 명령에 대한 default table.
clu             : user_clusters 테이블의 synonym.
code_pieces    : dba_object_size 와 user_object_size view를 create 시에 사용됨.


code_size      : dba_object_size 와 user_object_size view를 create 시에 사용됨.
col             : Oracle 5.0version 호환정보를 포함하고 있다.
cols            : user_tab_columns view 의 synonym.
column_privileges : user가 부여한권한,부여받은권한, owner인권한,
             또는 PUBLIC에게 부여받은 권한에 대한 칼럼정보.
Dba_2pc_neighbors : 진행중인 트랜잭션에 대한 연결 및 종료에 대한 정보.
Dba_2pc_pending   : recovery를 기다리는 분산된트랜잭션에 대한 정보.
Dba_all_tables      : 데이터베이스내의 모든테이블(object table, relational table).
Dba_audit_exists   : "AUDIT NOT EXISTS" and "AUDIT EXISTS"에 의해 생성된
                    감사추적요소.
Dba_audit_object   : 시스템내의 모든 object에 대한 감사추적기록.
Dba_audit_session  : 세션연결과 종료에 관련된 모든 감사 추적기록.
Dba_audit_statement : GRANT, REVOKE, AUDIT, NOAUDIT, ALTER SYSTEM
                 관련된 감사추적기록.
Dba_audit_trail  : 모든 감사추적요소.
Dba_blockers   : 누군가가 스스로 걸지않은 lock이 해제되기를 기다리는 session정보.
Dba_catalog    : 모든 데이터베이스 table, views, synonyms 과 sequence에 대한 정보.
Dba_clu_columns : cluster칼럼과 table칼럼의 mapping정보.
Dba_clusters   : 데이터베이스내에 있는 모든 cluster.
Dba_col_comments : 데이터베이스내의 모든 table, views의 칼럼에대한 comments.
Dba_col_privs : 데이터베이스내의 칼럼에 대한 모든권한.
Dba_coll_types : 데이터베이스내의 모든 collection type, VARRAYs, nested tables,
                object tables 등에 대한 정보.
Dba_constraints    : 모든테이블에 대한 constraint(primary, check, unique,
        referential integrity, with check option on a view, with read only on a view) 정보.
Dba_cons_columns : constraint 정의안에 있는 access가능한 칼럼에 대한 정보.
Dba_data_files      : 데이터베이스파일에 관한 정보.
Dba_db_links       : 데이터베이스내의 모든 Link.
Dba_Ddl_locks     : 데이터베이스내의 모든 DDL lock과 DDL lock이 현저하게
                       요구되는 사항에 관한정보.
Dba_dependencies  : object 에 대한 Dependence.(REF, HARD)
Dba_directories     : 데이터베이스내의 모든 directory objects.
Dba_Dml_locks     : 데이터베이스내에 구성된모든 DML lock과 DML lock이
             현저하게 요구되는사항에 관한정보.
Dba_errors      : 데이터베이스내의 저장된 object에 대해 가장최근에 발생된 error.
Dba_exp_files   : export파일에 대한 정보.
Dba_exp_objects : 점진적으로 export 되고있는 object에 대한 정보.
Dba_exp_version : 가장최근에 export된 session에 대한 version 정보.

Dba_extents      : 데이터베이스내의 모든 세그먼트를 이루는 extents에 대한 정보.
Dba_free_space  : 모든 테이블스페이스내의 free extents의 정보.
Dba_free_space_coalesced : 테이블스페이스내의 합쳐진 공간에 대한 통계정보.

Dba_indexes   : 데이터베이스내의 모든 index. 통계정보를 얻기위해 Analyze를 사용.
Dba_ind_columns : 모든테이블과 클러스터에서 인덱스를 구성하는 칼럼에 대한정보.
Dba_ind_partitions : 각각의 index파티션에 대해서, 파티션정보, 파티션에대한
            storage 매개변수, Analyze에 결정된 파티션통계자료.
Dba_jobs   :  데이터베이스에 있는 모든 Jobs.
Dba_jobs_running  : 데이터베이스내에 현재 실행중인 모든 Jobs.
Dba_libraries       : 데이터베이스내의 모든 libraries.
Dba_lobs           : 모든 테이블에 포함된 LOBs.
Dba_locks          : 데이터베이스내에 생성된 모든 lock, latch과 lock,latch가
                      현저하게 요구되는 사항에 대한 정보.
Dba_method_params  : 데이터베이스내에 type에 대한 method 매개변수.
Dba_method_results  : 데이터베이스내에 type에 대한 method results.
Dba_nested_tables    : 모든테이블내에 포함된 nested table에 대한 정보.
Dba_object_size      : PL/SQL object에 대한 size, bytes.
Dba_object_tables : 데이터베이스내에 모든 object tables.
Dba_objects       : 데이터베이스내에 모든 objects.(index partition, table partition,
            package,package_body,trigger)
Dba_obj_audit_opts     : 모든 table, view에 대한 감사 option.
Dba_part_col_statistics  : 모든 table 파티션에 대한 칼럼통계와 그래프정보.
Dba_part_histograms    : 모든 table 파티션의 histogram에 대한 데이터(endpoint).
Dba_part_indexes       : 모든 partition index에 대한 정보.
Dba_part_key_columns : 모든 partition된 object에 대한 분할키칼럼정보.
Dba_part_tables        : 모든 partition된 table에 대한 정보.
Dba_priv_audit_opts   : 시스템과 user에 의해 감사를 받고있는 시스템 privileges.
Dba_profiles           : 모든 profiles과 해당 profile의 limit을 나타냄.
Dba_queue_schedules  : 메시지를 전달하는 schedule.
Dba_queue_tables      : 데이터베이스내에 생성된 모든 queue테이블의
                          queue type의 name과 type. 
Dba_Queus             : 데이터베이스내의 모든 queue에 대한 동작특성.
Dba_rchild              : refresh group 안의 모든 children object.
Dba_refresh             : 모든 refresh  group 에 대한 정보.
Dba_refresh_children    : refresh group 안의 모든 object에 대한 정보.
Dba_refs   :  데이터베이스내의 모든 테이블의 REF칼럼과, REF 속성을 가진 칼럼.
Dba_refistered_snapshot_groups : 모든 snapshot 사본 그룹.


Dba_registered_snapshots   : 지역테이블의 원격snapshot 에 대한 정보.
Dba_rgroup                 : 모든 refresh group.
Dba_roles                   : 모든 데이터베이스내에 존재하는 roles.
Dba_role_privs              : user와 role에 부여된 role에 대한 정보.
Dba_rollback_segs           : rollback segments 에 대한 정보.
Dba_segments   : 모든 데이터베이스 segment에 대한 할당된 storage에 대한 정보.
Dba_sequences  : 모든 데이터베이스내의 sequences 에 대한 정보.
Dba_snapshot_logs          : 모든 데이터베이스내의 snapshot_logs.
Dba_snapshot_refresh_times : snapshot refresh 한 시간.
Dba_snapshots               : 모든 데이터베이스내의 snapshots.
Dba_source                  : 모든 데이터베이스내의 저장object 의 source를포함.
Dba_stmt_audit_opts         : system, user에 의한 현재의 감사option에 대한 정보.
Dba_synonyms               : 데이터베이스내의 모든 synonyms
Dba_sys_privs         : user에게 부여된 system privilege와 role.
Dba_tab_col_statistics : Dba_tab_columns view에 있는정보에 대한 칼럼통계와
                         그래프정보
Dba_tab_columns    : 모든 table, view, cluster에 대한 칼럼정보. Analyze명령어사용.
Dba_tab_comments  : 데이터베이스내의 모든 table, view에 대한 주석.
Dba_tab_histograms  : 모든 table의 칼럼에 대한 histogram.
Dba_tab_partitions    : 각각의 table partition에 대해서, partition level의 partition정보와,
          partition의 storage매개변수 ,Analyze 에의해 결정된 여러 partition통계정보.
Dba_tab_privs   : 모든 데이터베이스내의 object에 부여된 권한.
Dba_tables      : 모든 데이터베이스내의 관계형테이블에 관한정보.Analyze로
                   통계정보를  얻을수 있다.
Dba_tablespaces : 모든 테이블스페이스에 관한정보.
Dba_triggers     : 모든 데이터베이스내의 trigger 정보.
Dba_trigger_cols : 모든 trigger에서 사용된 칼럼정보.
Dba_ts_quotas   : 모든 user에게 할당된 tablespace.
Dba_type_attrs   : 데이터베이스내의 type에 대한 속성.
Dba_type_methods : 데이터베이스내의 모든 type에 대한 methods.
Dba_types          : 데이터베이스내의 모든 추상적데이터type.
Dba_updatable_columns : join view에서 데이터베이스관리자가
                           update할수있는칼럼정보.
Dba_users  : 데이터베이스내의 모든 user정보.
Dba_views  : 모든 데이터베이스내의 view의 text.
Dbms_alert_info      : 등록된 alert정보.
Dbms_lock_allocated : 사용자에게 할당된 lock정보.
Deptree     :  utldtree.sql 에의해 생성되며, object의 dependency tree정보를 포함함.
          'Sys' user인 경우. 이 object에 관련된 공유커서를 나타내고,
          다른 user인 경우공유커서이외의 object를 나타낸다.
          다른 user는 공유커서정보를 얻기위해, Sys.deptree를 access할수있다.

Dictionary       :   data dictionary table, view에 대한 정보.
Dict_columns    :   data dictionary table, view에 대한 칼럼.
Error_size       :    Dba_obejct_size 와 user_obejct_size view를 create 할때 사용된다.
Exceptions      :    무결성제약조건에 위배되는 정보를 포함. utlexcpt.sql 로 생성.
File_lock        :   병렬서버view. 초기화파라미터 GC_FILE_TO_LOCKS 에 명시된,
           데이터파일에 PCM lock의 mapping정보.
File_ping : 병렬서버view.각데이타파일에 할당된 block의 수.  
          GC_FILES_TO_LOCKS 최적값을 구하기 위해 현존하는 데이터파일의
          access방법을 결정하는데 이 정보를사용할 수 있다.
FILEXT$  :  DBA_DATA_FILES 와 동일. (DBA_DATA_FILES의 사용을 추천)
GLOBAL_NAME : 현제 데이터베이스의 유일한 이름.
HS_ALL_CAPS   : 모든 비 Oracle Data store (FDS) 와 관련된 특성에 관한정보.
HS_ALL_DD     : 모든 비 Oracle Data store(FDS)에 대한 Data dictionary.
HS_ALL_INITS   : 비 Oracle Data store(FDS)에 대한 초기화 매개변수.
HS_BASE_CAPS  : 비 Oracle Data store(FDS)에 대한 기본특성에 관한정보.
HS_BASE_DD    : 비 Oracle Data store(FDS)에 대한 Data dictionary.
HS_CLASS_CAPS : 비 Oracle Data store(FDS)에 포함된 class-specific 특성정보.
HS_CLASS_DD   : 비 Oracle Data store(FDS) class_specific data dictionary.
HS_CLASS_INIT  :  비 Oracle Data store(FDS) class-specific 초기화 매개변수.
HS_EXTERNAL_OBJECT_PRIVILEGES : user에게 부여된 object권한.
HS_EXTERNAL_OBJECTS : oracle server에서 access가능한 external obejct.
HS_EXTERNAL_USER_PRIVILEGES : 어느 특정object에 국한되지않은 모든
                                           부여된권한
HS_FDS_CLASS  : 비 oracle (FDS) class 에 관한 정보.
HS_FDS_INST    : 비 oracle (FDS) instance에 관한정보.
HS_INST_CAPS   : instance-specific 특성정보.
HS_INST_DD     : 비 oracle (FDS) instance-specific data dictionary 변경정보.
HS_INST_INIT    : 비 oracle (FDS) instance-specific 초기화 매개변수정보.
IDEPTREE  : UTLDTREE.sql 로 생성하고, 관련tree를 나타냄.
               Deptree의 자동정렬버젼.
INDEX_HISTOGRAM  :  Analyze index...validate structure 명령에 대한정보.
INDEX_STATS          : 마지막 Analyze index..validate structure 명령에 대한정보.
NLS_DATABASE_PARAMETERS : 데이터베이스의 NLS 매개변수.
NLS_INSTANCE_PARAMETERS  : instance의 NLS 매개변수.
NLS_SESSION_PARAMETERS     : user session의 NLS 매개변수.

OBJ   :  user_objects 의 synonym.
PARSED_PIECES  :  Dba_object_size, User_object_size view를 생성시에 필요.
PARSED_SIZE     :  Dba_obejct_size, User_object_size view를 생성시에 필요.
Plan_table   :   explain plan의 결과에 대한 table. utlxplan.sql로 생성.
Product_component_version  :  Oracle 제품군의 버전과 상태설명.


Pstubtbl   :   Pstub utility에 의해 생성된 stub에 관한정보.
Publicsyn   :   public synonym 에 관한 정보.
Public_dependency   :   object와 관련된 dependencies.(parent object)
Resource_cost   :  각각의 resource에 대한 cost.
Resource_map   :  각각의 resource에 대한 정보.(resource name, resource number)
Role_role_privs  :  다른 role에 부여된 role정보.(user가 access가능한 role에 한해)
Role_sys_privs  : 다른 role에 부여된 system role정보(user가 access가능한role에 한해)
Role_tab_privs  : 다른 role에 부여된 table privileges정보.
                    (user가 access가능한role에 한해)

SEQ             :  user_sequences 의 synonym.
Session_privs    : 현재 user에게 사용가능한 권한.
Session_roles    : 현재 user에게 사용가능한 roles.
Source_size     :  Dba_object_size, User_object_size view를 생성시 필요.
Stmt_audit_option_map   : 감사 option type code정보.
Syn             : user_synonyms 에 대한 synonym.
Synonyms      : Oracle ver 5.와 호환성을 포함. not recommend
Syscatalog      : Oracle ver 5.와 호환성을 포함. not recommend
Sysfiles         :  Oracle ver 5.와 호환성을 포함. not recommend
Syssegobj       : Oracle ver 5.와 호환성을 포함. not recommend
System_privilege_map  :  system privilege code에 대한 정보.
Sys_objects   : object ID와 object type 그리고 segment data block주소를 매핑하는정보.
Tab             : Oracle ver 5.와 호환성을 포함. not recommend
Table_privileges : user가 부여한, 부여받은, 소유한, 그리고 PUBLIC으로
         부여된 object 권한정보. Oracle ver 6.과 호환성을 포함.    not recommend.
Table_privilege_map  :  access 가능한 권한code/권한명칭 정보.
Tabs                   :  User_tables 의 synonym.
Tabquotas              : Oracle ver 5.와 호환성을 포함. not recommend
Trusted_servers       : 분산환경에서 서버가 신뢰할만한지를 나타냄.
Tp_pitr_check        : catpitr.sql 에 의해 생성. 테이블스페이스의 point-in-time복구를
           방해할지도 모르는 dependencies혹은 restriction에 관한 정보제공.
Ts_pitr_objects_to_be_dropped  : 테이블스페이스의 point-in-time복구수행의 결과
           손실된 object에 대한 정보. (point-in-time recovery의 경우만 해당).
User_all_tables        : user가 사용가능한 테이블(object table, relational table)정보.
User_arguments       : user가 access가능한 object의 매개변수정보.
User_Audit_object    : cataudit.sql로 생성. object에 관련된 감사추적기록.
User_Audit_session   : cataudit.sql로 생성. user의 연결/종료에 관련된 감사추적기록.
User_Audit_statement : cataudit.sql로 생성. user에 의해 실행된 GRANT,REVOKE,
                AUDIT, NOAUDIT, ALTER SYSTEM 명령에 대한 감사추적기록.


User_Audit_trail      : user와 관련된 전반적인 사항의 감사추적기록.
User_catalog          : user 소유의 table, views, synonyms, sequences 의 이름과 type.
User_clusters          : user소유의 cluster.
User_clu_columns     : user table 의 칼럼과 cluster칼럼과의 매핑테이블.
User_col_comments   : user 의 table, view의 칼럼에 대한 주석.
User_col_privs        : user 가 소유한, 부여한, 부여받은 칼럼에 대한 권한.
User_col_privs_made : user 소유 object의 칼럼에 대한 권한.
User_col_privs_recd  : user가 부여받은 칼럼에 대한 권한.
User_coll_types       : user가 명명한 collection type정보.
User_constraints      : user소유 테이블의 제약조건정의.
User_cons_columns  : user소유 제약조건에 정의된 칼럼에 대한정보.
User_db_links        : user소유 데이터베이스링크에 대한정보.
User_dependencies   : user소유 object에 대한 dependencies.
User_errors           : user소유 저장 object에 대한 현재의 에러.
User_extents          : user소유 object에 속하는 세그먼트의 extent 정보.
User_free_space      : user가 access가능한 테이블스페이스내의 free extent 정보.
User_indexes     : user 소유의 indexes. Analyze명령을 사용해야함. 병렬서버를 지원.
User_ind_columns   : user소유 index 또는 user소유 table 의 칼럼정보.
User_ind_partitions  : user소유의 index partition각각에 대한설명과, partition정보,
         partition의 storage 매개변수, Analyze명령으로 결정된 여러partition통계
User_jobs           : user소유의 모든 job.(export/import, execution)
User_libraries       : user소유의 모든 libraries .
User_lobs           : user소유의 table에포함된 LOBs정보.
         internal LOBs( BLOBs, NCLOBs) 만해당, external LOBs(i.e, BFILES)은 아님.
User_method_params  : user type의 method 매개변수.
User_method_results   : user type의 method 의 results.
User_nested_tables     : user소유 테이블에 포함된 nested tables.
User_object_tables      : user가 사용가능한 object table.
User_objects            : user소유의 object.(index partition, table partition, package,
                           packagebody, trigger)
User_object_size         : user소유의 PL/SQL object.
User_obj_audit_opts      : cataudit.sql로 생성. user소유의 table,view에 대한 감사option
User_part_col_statistics : user소유의 tablepartition정보에 대한 칼럼통계와 그래프정보.
User_part_histograms  : user가 access할수있는 table partition의 histogram에 대한
                          그래프데이터(end-pointer).
User_part_key_columns : user소유의 partition object의 partition key칼럼에 대한정보.
User_part_indexes       : 모든 user소유의 partition index의 partition정보.
User_part_tables         : user소유의 partition table에 대한 object 레벨의 partition정보.


User_password_limits   : user에게 적용된 password profile parameter.
User_queue_tables      : user소유 스키마에 생성된 queue table내부의 queues정보.
User_Queues            : user스키마의 모든 queue에 대한 동작 특성을 나타냄.
User_refresh             : 모든 refresh group.
User_refresh_children    : user가 소유한 refresh group 내부의 object에 관한정보.
User_refs                 : user소유테이블의 object type칼럼중 REF칼럼, REF속성.
User_resource_limits     : 현재 user의 resource 한계.
User_role_privs          : user에게 부여된 roles.
User_segments  : user오브젝트에 포함된 데이터베이스 segments의 storage할당정보.
User_sequences  : user 소유의 sequences.
User_snapshots   : user 가 볼수있는 snapshots.
User_snapshot_logs : user 소유의 모든 snapshot logs.
User_source         : user소유 저장 objects 의 모든 text source.
User_snapshot_refresh_times    : snapshot refresh time.
User_synonyms                 : user소유의 synonym.
User_sys_privs                  : user에게 부여된 system 권한.
User_tab_col_statistics        : user_tab_columns view에 대한 칼럼통계와
                               그래프정보를  나타냄.
User_tab_columns   : user소유의 table, view, cluster의 칼럼정보.(Analyze명령사용)
User_tab_comments  : user소유의 table, view에 대한 주석.
User_tab_histograms  : user소유 table의 칼럼에 대한 histogram.
User_tab_partitions   : user소유 table partition에 대한, partition 레벨의 분할정보와,
           partition의 storage매개변수, Analyze에 의해 집계된 여러통계정보.
User_tab_privs       : user가 소유한, 부여한, 부여받은 object에 대한 권한 정보.
User_tab_privs_made : user가 소유한 object에 관한 모든 권한.
User_tab_privs_recd  : user가 부여받은 object 권한정보.
User_tables           : user소유의 relational table에 대한 정보. (Analyze명령사용)
User_tablespaces     : user가 access 가능한 tablespaces에 대한 설명.
User_triggers         : user가 소유한 triggers 정보.
User_trigger_cols    : user가 소유한 또는 user테이블에 있는 trigger안의 column 정보.
User_ts_quotas       : user에게 할당된 tablespace quotas 정보.
User_types           : 테이블안의 user소유의 type.
User_type_attrs      : user type의 속성을 나타냄.
User_type_methods  : user type의 methods를 나타냄.
User_updatable_columns : join view에서 사용자에게 update가 허용된 칼럼정보.
User_users           : 현재 user에 관한 정보.
User_views          : user 소유의 view에 대한 text.




FILEXT$     : 데이터파일의 AUTOEXTEND를 ON으로 변경했을 때 처음 생성.
V$ACCESS  : 현재 데이터베이스내의 lock이걸린 object와  그 object를
                 access 하려는 session id.
V$ACTIVE_INSTANCES : 현재 데이터베이스내의 Mount된
                 모든 인스턴스에대하여 인스턴스 이름과, 번호를 매치.
V$AQ        : 데이터베이스내의 모든 Queue에 대한 통계.
V$ARCHIVE : Archive에 필요한 redo log file에 대한 정보.
       각각의 행은 하나의 thread에 대한 정보이다. V$LOG도 동일한정보.
V$ARCHIVE_DEST : 현재의 instance에서, 모든 archive log destination, 
                 현재값, mode, status.
V$ARCHIVED_LOG : archive log 이름을 포함하는 controlfile에 대한 archive log 정보,
       archive log 기록은 online중 redo log가 성공적으로 저장되었거나,
       clear(log가 clear되면, name칼럼은 null이 된다)된후 insert된다.
V$BACKUP  : 모든 online 데이터파일의 backup 상태를 나타낸다.
V$BACKUP_CORRUPTION : 데이터파일의 backup 중 에러정보를 나타낸다.
       에러들은 control 파일과 achived log backup 에 포함되지 않는다.
V$BACK_DATAFILE : control 파일에서 datafile과 controlfile 의 backup정보를 보여줌.
V$BACK_DEVICE   : 지원되는 backup 디바이스정보.
V$BACK_PIECE     : controlfile에서 backup piece에 대한 정보를 포함.
       각각의 backup set 은 하나 또는 그이상의 backup piece로 구성된다.
V$BACKUP_REDOLOG : controlfile에서 backup set의 저장된 log에 대한 정보.
        Online redo logs는 곧바로 backup 되지 않는다: 먼저 disk에 저장된후 backup
        된다. 저장된 log backup set 은 하나 또는 그이상의 logs들로 구성된다.
V$BACKUP_SET     : controlfile에서 backupset 정보를 보여줌.
       backup set 행은 backup set이 성공적으로 완료되었을 때 insert된다.
V$BGPROCESS       : 백그라운드 프로세스 정보.
V$BH                  : 병렬서버 view이다.
                          SGA내의 모든 버퍼에 대한 ping의 상태와 수를 나타낸다.
V$BUFFER_POOL    : 인스턴스내에서 사용가능한 모든 버퍼풀에 대한정보.
V$CACHE  : 병렬서버 view이다.
               특정데이타베이스object에 관련된 현재의 인스턴스의
               SGA내부의 각각의 block에 대한 block header에 대한 정보.
V$CACHE_LOCK : 병렬서버view. platform-specific lock manager 식별자를 제외하면,
              V$CACHE와 유사하다.
V$CIRCUIT  : 가상 circuit에 관한 정보이며, 가상circuit란 dispatcher와 server를
               통한 데이터베이스와의 user 연결을 말한다.
V$CLASS_PING : 각각blockclass마다 ping된 블록의 수를나타낸다.
               다른class블록의 충돌을 비교하기위해 사용.
V$COMPATIBILITY : 이전버전으로 downgrade를 방지하기위해
         데이터베이스인스턴스에 의해 사용된특성들을 설명.
         다른 인스턴스가 갖고있는 특성에 영향을 미치지 않으며,
         데이터베이스가 완전히 정지한이후에도 존재하지 않는 일시적인
         비호환성들을 포함할수도 있다.
V$COMPATSEG   : 이전버전으로 되돌아가는 것을 막기위한 데이터베이스에서
                      사용되는 영구적인 특성들.
V$CONTROLFILE  : 컨트롤파일의 이름과 상태.
V$CONTROLFILE_RECORD_SECTION  : 컨트롤파일의 record에 대한 정보.
V$COPY_CORRUPTION  : 컨트롤파일로부터 데이터파일의 복사불량에 대한 정보.
V$CURRENT_BUCKET   : 캐쉬내의 버퍼의 수가 감소할때 발생할 수 있는
                        캐쉬손실의 경우수를 예상하는데 유용.
V$DATABASE         :    control file 로부터 데이터베이스정보를 포함.
V$DATAFILE    : 컨트롤파일로부터데이타파일에대한 정보를 포함.
V$DATAFILE_COPY    :컨트롤파일로부터 데이터파일의 복사에 대한 정보를포함.
V$DATAFILE_HEADER : 데이터파일헤더에 대한 정보.

V$DBFILE : 데이터베이스를 구성하는 모든 데이터파일.
              대신에 V$DATAFILE 추천한다.
V$DBLINK : 세션에 의해 open된 데이터베이스링크에 대한 설명.
         이 데이터베이스링크들은 닫히기전에 commit되거나 rollback되어야만 한다.

V$DB_OBJECT_CACHE : library cache에 cach된 데이터베이스오브젝트를 나타냄.
V$DB_PIPES             : 데이터베이스내에 현재 운영중인 pipe에 대한 설명.
V$DELETED_OBJECT  : 삭제된 archived 로그, 데이터파일 copy,
         컨트롤파일에서 백업piece 에 대한 정보. 이뷰의 목적은 복구목록의
         재동조작업을 최적화하는 것이다. archived 로그나, 데이터파일 copy,
         백업piece 등이 삭제될때는 해당하는 행이삭제되었음이 표시된다.
V$DISPATCHER         : dispatcher 프로세스에 관한 정보.
V$DISPATCHER_RATE  : dispatcher 프로세서에 관련된 확률통계.
V$DLM_CONVERT_LOCAL   : lock 변환작업에 대한 경과시간.
V$DLM_CONVERT_REMOTE  : 원격 lock변환작업에 대한 경과시간.
V$DLM_LATCH              : DLM 잠금에 대한 통계.
          각각의 잠금에 대한 통계보다는, 각 타입에 대한 총계를 포함.
          개념적으로 IMM_GETS/TTL_GETS 값은 1에 가깝게 된다.
V$DLM_LOCKS : 병렬서버 view이다. 블록화되었거나, 다른 것을
            블록화하고있는 lock manager에 알려진 모든  lock에 대한 정보.
V$DML_MISC         : 잡다한 DLM 통계에 대한 정보.
V$ENABLEDPRIVS:사용가능한 권한에 대한정보, 이들권한은
             SYS.SYSTEM_PRIVILEGES_MAP테이블에 존재해야만 한다.
V$ENQUEUE_LOCK : 큐에 대기상태인 오브젝트에의해 소유된 모든 lock이
          view의 칼럼은 V$LOCK의 칼럼과 동일하다.
          자세한 것은 V$LOCK을 참고.
V$EVENT_NAME :  wait event 에 대한 정보.
V$EXECUTION   :  병렬 질의 실행에 대한 정보.
V$EXECUTION_LOCATION : 병렬 질의 실행 트리의 위치에 대한 자세한 정보.
V$FALSE_PING   : 병렬서버view. ping에 실패지도 모르는 버퍼에 대한 정보.
                      즉, 10회이상ping된 다른 버퍼와
       동일한 lock으로 잠겨있는 버퍼를 말한다.
       ping이 실패로 판명된 버퍼는 lock충돌을 감소시키기위해
       1-44페이지의 "GC_FILES_TO_LOCK"에 다시 매핑된다.
V$FILE_PING  : 데이터파일마다 ping된 블록수를 보여줌. 이정보는 현존하는
        데이터파일에 대한 access패턴을 결정하는데 and,
        데이터파일블록을 PCM lock에 새로 매핑하는것을 결정하는데 사용된다.
V$FILESTAT    : 파일 read/write 통계.
V$FIXED_TABLE : 데이터베이스내의 모든 동적실행테이블, views, 유도테이블.
       실제테이블을 참조하는 약간의 V$테이블은 리스트에 없다.
V$FIXED_VIEW_DEFINITION : (V$로 시작하는)고정view에 대한 설명.
       유의해서 사용해야한다.
V$GLOBAL_TRANSACTION    : 현재 활동중인 트랜잭션에 대한 설명.
V$INDEXED_FIXED_COLUMN : index된 동적실행테이블(X$ table)의 칼럼에
      대한 설명.  X$ table은 경고없이 변경할수있다.
      이view는 보다 효과적으로 고정뷰(V$view)에 대한
V$INSTANCE : 현재의 인스턴스의 상태를 나타냄.
        V$INSTANCE의 버전은 V$INSTANCE의 초기버전과 호환성이 없다.
V$LATCH     : 하위 잠금에 대한 통계와 상위 잠금에 대한 요약통계.
       즉, 상위잠금에 대한 통계는 그 하위잠금에 대한 각각의 통계를 포함한다.
V$LATCHHOLDER : 현재잠금에 대한 정보.
V$LATCHNAME   :  V$LATCH 에 있는 잠금에 대한 디코드된 잠금이름에 대한
       정보. V$LATCHNAME의 행들은 V$LATCH의 행들과 1:1로 대응된다.

V$LATCH_CHILDREN : 하위잠금에 대한 통계를 포함. 
       V$LATCH의 칼럼에 child#  칼럼이추가되었다.  LATCH#칼럼이 서로
       동일하다면, 하위잠금이 동일한 상위잠금을 갖는 것이다.
V$LATCH_MISSES  : 잠금을 획득하는데 실패한 시도에 대한 통계.
V$LATCH_PARENT : 상위잠금에 대한 통계.
                        V$LATCH_PARENT 칼럼은 V$LATCH칼럼과 동일하다.
V$LIBRARYCACHE : library cache의 실행과 활동통계.       
V$LICENSE          : license 한계에 대한 정보.
V$LOADCSTAT      : 직접적재하는동안 컴파일된 SQL*loader 통계정보.
       이테이블에대한 어떤 Select 문도 "no rows returned" 결과가 나오는데,
       왜냐면, 동일한 시간에 데이터를 적재하면서, 쿼리를 날릴수 없기 때문이다.

V$LOCK       : 현재 Oracle 서버에 의해 확립된 잠금에 대한 정보나 lock또는
                   latch에 대한 두드러진요청
V$LOCK_ACTIVITY : 병렬서버view이다. V$LOCK_ACTIVITY는 현재의
             인스턴스의 DLM잠금동작을 나타낸다.
             각각의 행은 잠금동작의 타입과 일치된다.
V$LOCK_ELEMENT : 병렬서버view이다. 버퍼캐쉬에 의해사용된 각각의
       PCM잠금에 대해 v$LOCK_ELEMENT 에 한행이다.
       잠금요소에 대응되는 PCM잠금의 이름은 'BL',indx,class등이다.
V$LOCKED_OBJECT : 시스템안의 모든 트랜잭션에 걸린 잠금을 나타낸다.
V$LOCKED_WITH_COLLISIONS : 병렬서버view이다.
       여러버퍼를 보호하는 lock을 찾는데 사용되며, 그 버퍼들은 최소한
       10회이상 각각 강제로 쓰여지거나, 강제로 읽혀진 버퍼들이다.
V$LOG       : 컨트롤파일로부터 log 파일정보를 포함한다.
V$LOGFILE  :  redo log 파일정보. redo log 그룹과 멤버 파일명.
V$LOGHIST  : 컨트롤파일로부터 log history정보를 포함. 지속적인 호환성을
                 포함하고 있다. 대신에 V$LOG_HISTORY의 사용을 권장한다.
V$LOG_HISTORY      : 컨트롤파일로부터 log history 정보를 포함한다.
V$MLS_PARAMETERS : Oracle Server의 확정된 초기화파라미터를 나타냄.
V$MTS                  : multi-threaded server의 성능향상을위한 정보를 포함.
V$MYSTAT             : 현재 세션에 대한 통계값포함.
V$NLS_PARAMETERS   : 현재의 NLS 매개변수의 값들을 포함.
V$NLS_VALID_VALUES  : 유효한 NLS 매개변수값.
V$OBJECT_DEPENDENCY : 현재 공유풀에 적재되어있는 package, procedure,
       cursor등에 관련되어있는 object를 결정하는데 사용된다.
       예를들면, V$SESSION, V$SQL등과 조인하면, 현재 어떤 user가
       실행중인 SQL문에서 어떤 테이블이 사용되었는지를 알아낼수가 있다.
V$OFFLINE_RANGE : 컨트롤파일로부터 offline된 datafile을 보여준다.
       DATAFILE행에 저장되어있는 각각의 데이터파일의 최종offline 간격을
       보여줌. offline 간격은 테이블스페이스가 처음 offline normal,
       또는 Read Only로 변경되고난이후 다시 online 또는 read-write로
       변경된다음에 확정된다.
       데이터파일이 스스로 Offline로 변경되거나 테이블스페이스가
        OFFLINE IMMEDIATE로 변경되면, offline간격은 확정되지 않는다.

V$OPEN_CURSOR : 각각 user 세션이 열렸있거나, 정지되어있는 cursor를 보여준다.
V$OPTION        : Oracle Server와 같이 설치된 선택사항들.
V$PARAMETER  : 초기화 파라미터에 대한 설명이다.
V$PING     : 병렬서버view이다.
      최소한 1번이상 ping된 블록만을 보여준다는 것을 제외하고 V$CACHE view와
      동일하다.특정 데이터베이스 object와 관련된 현재의 인스턴스내의 SGA에
      있는 각각의 블록에대한 block header정보를 포함하고 있다.
V$PQ_SESSTAT  : 병렬쿼리에 대한 session 통계를 포함.
V$PQ_SLAVE    : 인스턴스내에 실행중인 parallel 쿼리서버에 대한 통계.
V$PQ_SYSSTAT  : 병렬쿼리에 대한 시스템통계.


V$PQ_TQSTAT  : 병렬쿼리 동작의 통계를 포함. 통계는 질의가 완료된후에
           컴파일되며 세션이 살아있는동안  계속 남아있는다.
V$PROCESS    : 현재 작업중인 프로세스에 대한 정보.
       LATCHWAIT 칼럼은 프로세스잠금이 무엇을 기다려야하는가를 나타내며,
       LATCHSPIN 칼럼은 프로세스잠금이 동작되는 것을 나타낸다.
       멀티프로세서의 경우 Oracle 프로세스는 잠금을 기다리기전에 실시한다.
V$PWFILE_USERS  :  password 파일로부터 유도해낸
                   SYSDBA, SYSOPER 권한을 부여받은 user.
V$QUEUE  :  멀티쓰레드 메시지큐에 대한 정보.
V$RECENT_BUCKET  :  대용량 캐쉬실행을 평가하기에 유용한 정보.
V$RECOVER_FILE     :  media 복구에필요한 파일의 상태를 나타냄.
V$RECOVERY_FILE_STATUS : 각각의 RECOVER명령에 대한 각 데이터파일에
     대한 정보를 한행씩 포함.
      Oracle프로세스가 복구를 수행하는데 유용한 정보임.
      recover manager는 서버프로세스에 직접 복구를수행하도록 했을 때,
      recovery manager가 이 view에서 관련된정보를 참고할 수 있다.
      다른user들에게는 유용하지 않다.
V$RECOVERY_LOG : 완벽한 media복구에 필요한 archived logs에 관한 정보.
      이정보는 log history view인 V$LOG_HISTORY에서 유도된 것이다.
V$RECOVERY_PROGRESS : 데이터베이스복구작업이 중간에 멈추지않도록하는데
     사용되며, 복구작업을 완료하는데 요구되는 시간을 측정하는데 사용된다.
V$RECOVERY_STATUS : 현재의 복구진행상태를 나타낸다. 단지 복구를 수행하는
      Process 에대한 정보만이유용하다. 복구관리자가 서버프로세스에게 복구를
      수행하라고 지시할때에, 복구관리자는 이view에서
      관련정보를 참조할 수 있다. 다른 user에게는 불필요하다.
V$REQDIST  :  MTS dispatcher의 응답시간에 대한 그래프통계를 나타내며,
             time range는 버킷 number의 지수함수로 증가한다.
V$RESOURCE  : 자원(resource)의 이름과 주소정보를 포함.
V$RESOURCE_LIMIT : System 자원의 부분적인 사용에 대한 정보. 자원의
         소비를 모니터링함으로서 낭비를 방지하는데 사용된다.

V$ROLLNAME : 모든 online중인 rollback segments의 이름.
                   데이터베이스가 open시에만 조회가능.
V$ROLLSTAT   : 롤백세그먼트통계정보.
V$ROWCACHE : 자료사전활동에 대한 통계.
                   각각의 행은 하나의 자료사전cache 통계를 포함.
V$SESSION     : 현재 open된 세션에 대한 정보.
V$SESSION_CONNECT_INFO  : 현재의 세션에 대한 network 연결에 대한 정보.
V$SESSION_CURSOR_CACHE  : 현재의 세션에 대한 cursor 사용에 대한 정보.
      SESSION_CACHED_CURSORS 초기화파라미터에 대한 효율을 측정하지는
      않는다.
V$SESSION_EVENT    : 세션의 event 대기에 관한정보.
V$SESSION_LONGOPS : 장시간실행되는 작업에 대한 상태. SOFAR,
      TOTALWORK칼럼은 진행상태를 제공한다. 예를들어 
      다음요소(hach cluster creations, backup, recovery) 에 대한
      작동상태를 모니터링할 수 있다.
V$SESSION_OBJECT_CACHE : 로칼서버의 현재사용중인
                                    user세션의 object, cache통계정보.
V$SESSION_WAIT  : 활동중인 세션이 대기하고있는 자원또는 이벤트이다.
V$SESSTAT         : user세션 통계이다. 통계number(statistic#)에 해당하는
      통계name을 찾으려면, V$STATNAME를 참고하면 된다.
V$SESS_IO         : 각각의 user세션에 대한 I/O 통계이다.
V$SGA             : System Global Area 에대한 간략한 정보.(name, size)
V$SGASTAT       : System Global Area에 대한 자세한 정보.(name, bytes, pool)

V$SHARED_POOL_RESERVED : Shared Pool내에 예약풀과 공간을
                       바꾸고자할 때 도움이 되는통계.
V$SHARED_SERVER  :  Shared Server processes 에 대한 정보를 포함.
V$SORT_SEGMENT   : 주어진 인스턴스내의 각 sort세그먼트에 대한 정보.
       테이블스페이스가 Temporary 타입일때만 update된다.

V$SORT_USAGE  :  sort 사용에 대해 기술한다.
V$SQL  :  Group by절이없는 공유sql영역에대한 통계이며 입력된
             원래 sql문장의 각 child의 row를 포함.
V$SQL_BIND_DATA : 데이터가 이 서버에서 추출가능하다면 이 view를
        조회하는 세션에 소유된 각 커서안에 있는 각각의 원격bind변수에 대한
        클라이언트에 의해 보내진 데이터.
V$SQL_BIND_METADATA : 이view를 조회하는 세션에 소유된 각커서안에 있는
       각각의 원격bind변수에 대해 클라이언트에의해 제공되는 bind metadata.

V$SQL_CURSOR : 이 view를 조회하는 세션과 관련된 각 cursor에 대한 디버깅정보.
V$SQL_SHARED_MEMORY : 메모리 스냅샷에 공유된 커서에 대한 정보.
       공유풀에 저장된 각SQL문은 관련된 하나또는 그이상의 하위object를
       가지고 있다.
V$SQLAREA : 공유SQL영역에 대한 통계를 가지고있으며, Sql 문자열마다
       한행을 포함한다. 메모리내에 존재하는, parse된, 실행을 대기하고있는
       SQL문장에 대한 통계를 제공한다.
V$SQLTEXT : SGA내부의 공유SQL 커서에 속해있는 SQL문장을 포함.
V$SQLTEXT_WITH_NEWLINES : 가독성이 증가되고, 공백을 포함한 SQL문장안에
       newline과 tabs을 대체하지 않는다는 것을 제외하고는 V$SQLTEXT view와
       동일하다.
V$STATNAME : V$SESSTAT와 V$SYSSTAT테이블에서 나타난 statistics에 대한 이름.
V$SUBCACHE : 현재 라이브러리 캐쉬메모리에 적재된 하위 캐쉬에 대한 정보.
      모든 라이브러리캐쉬에 대해 언급하고있으며, 각 라이브러리 캐쉬object마다
      각 적재된 하위 캐쉬에 대해 한행을 나타낸다.
V$SYSSTAT : 시스템 통계이다. 각 statistic number(statistic#)와 관련된 statistic의
      이름을 찾기위해서는,  "V$STATNAME"를 보시오.
V$SYSTEM_CURSOR_CACHE : 시스템  전반적인정보라는 것을 제외하고,
            V$SESSION_CURSOR_CACHE와 유사한 정보를 나타낸다.
V$SYSTEM_EVENT : 이벤트에 대한 총 wait정보. TIME_WAITED,
       AVERAGE_WAIT칼럼은 급속메커니즘을 지원하지 않는 플랫폼에서
       0값을 포함할 것이다. 이런 플랫폼에서 DB를 운영중이고,
       이칼럼이 wait time을 줄여주기를 원한다면, 파라미터파일의
       TIMED_STATISTICS를 TRUE로 세팅하면된다.
       단지 이렇게 하면, 시스템 성능에 약간의 마이너스효과를 가져올 것이다.
V$SYSTEM_PARAMETER  :  System parameter에 대한 정보.
V$TABLESPACE            : 컨트롤파일로부터 테이블스페이스 정보를 나타내준다.
V$THREAD                : 컨트롤파일로부터 thread 정보를 가져온다.
V$TIMER     :    1/100 초로 나타낸 경과시간. 시간은 epoch가 시작된이후부터
       측정되며, epoch는 OS의 특성이며, 값이 4bytes(약 497일)를 넘을때마다
       0근처의 값이 된다.
V$TRANSACTION  :  시스템내의 활동중인 트랜잭션.
V$TRANSACTION_ENQUEUE : 트랜잭션 오브젝트에 의해 소유된 lock를 나타냄.
V$TYPE_SIZE : 데이터블록용량을 측정하는데 사용되는 여러
                  데이터베이스컴포넌트들의 SiZe.
V$VERSION  :  Oracle Server의 core 라이브러리 컴포넌트의 Version수이다.
                  각 컴포넌트에 한 row가 있다.
V$WAITSTAT : 블록점유에 대한 통계. 통계가 사용가능한 시간에만 갱신된다.

 

출처 : http://www.oracleclub.com

Posted by 1010
02.Oracle/DataBase2008. 8. 6. 17:07
반응형

# vi /etc/rc.d/rc.local


su - oracle -c /oracle/9i/bin/"dbstart"

su - oracle -c /oracle/9i/bin/"lsnrctl start"


추가 해준다


# vi /etc/oratab

DB02:/oracle/9i:Y


추가


# reboot


$ lsnrctl status (리스너 확인)

SQL> select status from v$instance; (DB 확인)

Posted by 1010