백업/복구 어플라이언스와 함께 Oracle Direct NFS (dNFS)를 사용하려면 다음 요구사항을 충족해야 합니다.
데이터베이스 서버와 백업/복구 어플라이언스 간의 충분한 네트워크 대역폭
Oracle에서 필요하거나 권장하는 모든 패치를 사용합니다. Oracle은 Oracle 지원 문서에 필수 또는 권장 패치 목록을 유지합니다.
dNFS를 통해 가상 Oracle 데이터베이스를 보호하고 마운트하기 위한 관리 콘솔 구성
dNFS 기반 백업을 실행하려면 백업/복구 어플라이언스 스테이징 디스크 형식 (디스크 환경설정)을 NFS로 설정해야 합니다.
다음 안내에 따라 스테이징 디스크 형식 (디스크 환경설정)을 NFS로 설정합니다.
관리 > 호스트로 이동합니다.
호스트를 마우스 오른쪽 버튼으로 클릭하고 수정을 선택합니다.
스테이징 디스크 형식에서 NFS를 선택한 다음 저장을 클릭합니다.
dNFS가 작동하도록 타겟 호스트에서 실행할 작업
dNFS가 올바르게 구성되었는지 확인하려면 다음 작업을 실행하세요.
DB Alert.log에서 다음 메시지를 확인하여 dNFS가 사용 설정되어 있는지 확인합니다.
Oracle instance running with ODM: Oracle Direct NFS ODM Library Version 3.01.
dNFS가 사용 설정되어 있지 않으면 사용 설정합니다.
NFS 클라이언트 패키지는 보호 작업의 데이터베이스 호스트와 dNFS를 사용하여 캡처된 Oracle 데이터베이스를 마운트할 수 있는 모든 Oracle 호스트에 있어야 합니다. 예를 들어 Linux의 경우
nfs-util
패키지가 호스트에 있어야 합니다. 다음과 같이 확인하세요.rpm -qa |grep nfs-util
Oracle 호스트에서 dNFS를 사용 설정합니다.
cd $ORACLE_HOME/rdbms/lib make -f ins_rdbms.mk dnfs_on
해당
ORACLE_HOME
에서 실행되는 데이터베이스를 다시 시작한 다음 DB Alert.log에서 다음 메시지를 확인하여 dNFS가 사용 설정되어 있는지 확인합니다.ODM으로 실행되는 Oracle 인스턴스: Oracle Direct NFS ODM 라이브러리 버전 3.0
백업 작업 중에 다음 쿼리를 실행하여 dNFS 사용량을 확인합니다.
select * from gv$dnfs_servers;
발생한 I/O의 NFS 읽기/쓰기 통계를 확인할 수 있습니다.
select inst_id, PNUM, NFS_READ, NFS_WRITE, NFS_COMMIT, NFS_MOUNT from gv$dnfs_stats where NFS_READ>0 or NFS_WRITE>0 order by inst_id, PNUM;
dnfs 채널 프로세스 정보를 확인할 수 있습니다.
select c.inst_id, program, pid,pname, local, path from gv$process p, gv$dnfs_channels c where p.inst_id = c.inst_id and c.pnum = p.pid;
dNFS 문제 해결: 데이터베이스 문제
여기에는 다음이 포함됩니다.
알림 로그
디버그 작업의 첫 번째 단계는 dNFS 관련 메시지에 대한 알림 로그를 확인하는 것입니다. dNFS가 있는 데이터베이스에서 관찰되는 일반적인 문제는 소켓 버퍼 크기가 제한된다는 것입니다. Oracle은 크기를 조정하려고 하지만 O/S에 의해 제한될 수 있습니다. 이 경우 다음과 같은 오류가 알림 로그에 표시됩니다.
Direct NFS: Failed to set socket buffer size.wtmax=[1048576]\
rtmax=[1048576], errno=-1
경고 로그에서 확인해야 할 다른 항목으로는 올바른 네트워크 카드가 파일러와 통신하는 데 사용되고 있는지 여부가 있습니다. 이는 다음과 유사한 메시지를 찾아 확인할 수 있습니다.
Direct NFS: channel id [0] path [192.168.56.3] to filer [192.168.56.3] via local [] is UP
데이터베이스 추적 파일
I/O 문제가 발생하는 경우 데이터베이스에서 다음 이벤트를 설정하여 추가 로깅 정보를 캡처할 수 있습니다. 이러한 이벤트를 설정하고 인시던트가 발생할 때까지 기다린 다음 검토하여 파일을 추적합니다.
ALTER SYSTEM SET MAX_DUMP_FILE_SIZE =UNLIMITED;
ALTER SYSTEM SET EVENTS '10298 trace name context forever, level 1'; # KSFD I/O tracing
ALTER SYSTEM SET EVENTS '19392 trace name context forever, level 8'; # kgnfs tracing
ALTER SYSTEM SET EVENTS '19394 trace name context forever, level 8'; # skgnfs tracing
ALTER SYSTEM SET EVENTS '19396 trace name context forever, level 6'; # kgodm tracing
ALTER SYSTEM SET EVENTS '19398 trace name context forever, level 128'; # mount tracing errors
데이터베이스가 응답하지 않음
dNFS에서 실행되는 데이터베이스가 응답하지 않으면 sqlplus를 사용하여 SYSDBA로 로그인하고 'hanganalyze' 또는 덤프를 실행합니다.
```oradebug
oradebug setmypid
oradebug unlimited
oradebug hanganalyze 3
oradebug dump systemstate 266
```
데이터베이스가 RAC 데이터베이스인 경우 마지막 두 개의 oradebug 명령어에 -g 옵션을 추가합니다.
dNFS 뷰
dNFS 클라이언트는 실제로 데이터베이스 커널에 있습니다. 따라서 데이터베이스 내에서 dNFS의 상태를 모니터링하고 확인하기 위해 데이터베이스 내에 여러 v$ 뷰가 있습니다. Oracle에서는 dNFS 성능을 빠르게 모니터링하는 데 사용할 수 있는 패키지를 제공합니다. 이 패키지는 Oracle dNFS 모니터 패키지에 있습니다.
배포가 완료되면 DBA는 다음을 실행하여 정보를 가져올 수 있습니다(매개변수: dnfs_monitor(절전 시간), dnfs_itermonitor(절전 시간, 확인할 횟수), 절전 시간은 초 단위).
SQL> set serveroutput on
SQL> set lines 200
SQL> exec dnfs_monitor(60);
Started at 01/18/2017 10:09:46 AM
Finished at 01/18/2017 10:10:46 AM
READ IOPS: 2
WRITE IOPS: 3
TOTAL IOPS: 5
READ Throughput: 0 MB/s
WRITE Throughput: 0 MB/s
TOTAL Throughput: 0 MB/s
SQL> exec dnfs_itermonitor(2,10)
Started at 01/18/2017 10:20:18 AM
TIMESTAMP READ IOPS WRITE IOPS TOTAL IOPS READ(MB/s) WRITE (MB/s) TOTAL (MB/s)
01/18/2017 10:20:20 AM 15 7 22 0 0 0
01/18/2017 10:20:22 AM 2 3 5 0 0 0
01/18/2017 10:20:24 AM 0 3 3 0 0 0
01/18/2017 10:20:26 AM 2 2 4 0 0 0
01/18/2017 10:20:28 AM 0 3 3 0 0 0
01/18/2017 10:20:30 AM 2 3 5 0 0 0
01/18/2017 10:20:32 AM 4 3 7 0 0 0
01/18/2017 10:20:34 AM 0 3 3 0 0 0
01/18/2017 10:20:36 AM 2 3 5 0 0 0
01/18/2017 10:20:38 AM 2 3 5 0 0 0
Finished at 01/18/2017 10:20:38 AM
V$ 뷰는 다음과 같습니다.
V$DNFS_SERVER: 모든 NFS 서버 연결에 관한 정보를 표시합니다 (NFS 서버당 하나). 이 보기는 연결 및 TCP 소켓 설정을 확인하는 데 유용합니다.
V$DNFS_CHANNELS: NFS 서버에 생성된 모든 네트워크 경로의 정보를 표시합니다. 각 dNFS 클라이언트는 네트워크 경로당 프로세스당 하나의 채널을 만듭니다. 경로가 여러 개 있는 경우 (NIC가 여러 개) dNFS 클라이언트는 모든 채널에서 로드 균형을 조정합니다. 데이터는 마지막 선택 이후의 활동을 반영합니다.
V$DNFS_FILES: dNFS 클라이언트를 사용하여 열린 파일을 표시합니다.
V$DNFS_STAT: dNFS 클라이언트의 성능 측정항목입니다.
열 | 설명 |
---|---|
SRVNAME
|
NFS 서버 이름 |
DIRNAME
|
NFS 서버에서 내보낸 볼륨 |
MNTPORT
|
로컬 마운트 포트 |
NFSPORT
|
NFS 서버 포트 |
WTMAX
|
NFS 서버의 최대 쓰기 크기 |
RTMAX
|
NFS 서버의 최대 읽기 크기 |
열 | 설명 |
---|---|
PNUM
|
Oracle 프로세스 번호 (v$process의 PID 링크) |
SVRNAME
|
NFS 서버 이름 |
PATH
|
서버로 연결되는 네트워크 경로 |
CH_ID
|
dNFS 채널 ID |
SVR_ID
|
dNFS 서버 ID |
SENDS
|
마지막 선택 이후 채널을 통해 작업을 전송합니다. |
RECVS
|
마지막 선택 이후 채널을 통해 작업을 수신합니다. |
PINGS
|
마지막 선택 이후 채널을 통해 작업에 핑을 보냅니다. |
열 | 설명 |
---|---|
FILENAME
|
파일 이름입니다. |
FILESIZE
|
파일 크기입니다. |
PNUM
|
프로세스 ID (v$process의 PID에 연결) |
SRV_ID
|
NFS 서버 ID |
열 | 설명 |
---|---|
PNUM
|
Oracle 프로세스 번호 (v$process 의 PID에 연결)
|
NFS_NULL
|
Null operations
|
NFS_GETATTR
|
속성 작업 가져오기 |
NFS_SETATTR
|
속성 설정 작업 |
NFS_LOOKUP
|
조회 작업 |
NFS_ACCESS
|
액세스 작업 |
NFS_READLINK
|
링크 작업 읽기 |
NFS_READ
|
읽기 작업 |
NFS_WRITE
|
쓰기 작업 |
NFS_CREATE
|
만들기 작업 |
NFS_MKDIR
|
디렉터리 만들기 작업 |
NFS_MKNOD
|
노드 작업 실행 |
NFS_SYMLINK
|
심볼릭 링크 작업 |
NFS_REMOVE
|
작업 삭제 |
NFS_RMDIR
|
디렉터리 삭제 작업 |
NFS_RENAME
|
이름 바꾸기 작업 |
NFS_LINK
|
링크 작업 |
NFS_READDIR
|
디렉터리 읽기 작업 |
NFS_READDIRPLUS
|
디렉터리 읽기 플러스 작업 |
NFS_FSSTAT
|
파일 시스템 상태 작업 |
NFS_FSINFO
|
파일 시스템 정보 작업 |
NFS_PATHCONF
|
경로 구성 작업 |
NFS_COMMIT
|
커밋 작업 |
NFS_MOUNT
|
마운트 작업 |
Oracle dNFS 모니터 패키지
CREATE OR REPLACE PROCEDURE dnfs_monitor
(sleepSecs IN NUMBER)
IS
startTime DATE;
startReadIOPS NUMBER;
startWriteIOPS NUMBER;
startReadBytes NUMBER;
startWriteBytes NUMBER;
endTime DATE;
endReadIOPS NUMBER;
endWriteIOPS NUMBER;
endReadBytes NUMBER;
endWriteBytes NUMBER;
readThr NUMBER;
writeThr NUMBER;
readIOPS NUMBER;
writeIOPS NUMBER;
elapsedTime NUMBER;
BEGIN
SELECT sysdate, SUM(stats.nfs_readbytes), SUM(stats.nfs_writebytes),
SUM(stats.nfs_read), SUM(stats.nfs_write)
INTO startTime, startReadBytes, startWriteBytes, startReadIOPS, startWriteIOPS
FROM dual, v$dnfs_stats stats;
DBMS_OUTPUT.PUT_LINE('Started at ' || TO_CHAR(startTime,'MM/DD/YYYY HH:MI:SS AM'));
DBMS_LOCK.SLEEP(sleepSecs);
SELECT sysdate, SUM(stats.nfs_readbytes), SUM(stats.nfs_writebytes), SUM(stats.nfs_read), SUM(stats.nfs_write)
INTO endTime, endReadBytes, endWriteBytes, endReadIOPS, endWriteIOPS
FROM dual, v$dnfs_stats stats;
DBMS_OUTPUT.PUT_LINE('Finished at ' || to_char(endTime,'MM/DD/YYYY HH:MI:SS AM'));
elapsedTime := (endTime - startTime) * 86400;
readThr := (endReadBytes - startReadBytes)/(1024 * 1024 * elapsedTime);
writeThr := (endWriteBytes - startWriteBytes)/(1024 * 1024 * elapsedTime);
readIOPS := (endReadIOPS - startReadIOPS)/elapsedTime;
writeIOPS := (endWriteIOPS - startWriteIOPS)/elapsedTime;
DBMS_OUTPUT.PUT_LINE('READ IOPS: ' || LPAD(TO_CHAR(readIOPS, '999999999'), 10, ' '));
DBMS_OUTPUT.PUT_LINE('WRITE IOPS: ' || LPAD(TO_CHAR(writeIOPS,
'999999999'), 10, ' '));
DBMS_OUTPUT.PUT_LINE('TOTAL IOPS: ' || LPAD(TO_CHAR(readIOPS + writeIOPS, '999999999'), 10, ' '));
DBMS_OUTPUT.PUT_LINE('READ Throughput: ' || LPAD(TO_CHAR(readThr, '999999999'), 10, ' ') || ' MB/s');
DBMS_OUTPUT.PUT_LINE('WRITE Throughput: ' || LPAD(TO_CHAR(writeThr,
'999999999'), 10, ' ') || ' MB/s');
DBMS_OUTPUT.PUT_LINE('TOTAL Throughput: ' || LPAD(TO_CHAR(readThr + writeThr, '999999999'), 10, ' ') || ' MB/s');
END;
/
CREATE OR REPLACE PROCEDURE dnfs_itermonitor
(sleepSecs IN NUMBER,
iter IN NUMBER)
IS
startTime DATE;
startReadIOPS NUMBER;
startWriteIOPS NUMBER;
startReadBytes NUMBER;
startWriteBytes NUMBER;
endTime DATE;
endReadIOPS NUMBER;
endWriteIOPS NUMBER;
endReadBytes NUMBER;
endWriteBytes NUMBER;
readThr NUMBER;
writeThr NUMBER;
readIOPS NUMBER;
writeIOPS NUMBER;
i NUMBER;
elapsedTime NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE('Started at ' || TO_CHAR(SYSDATE, 'MM/DD/YYYY HH:MI:SS AM'));
DBMS_OUTPUT.PUT_LINE(
LPAD('TIMESTAMP', 15, ' ')||
LPAD('READ IOPS', 33, ' ')||
LPAD('WRITE IOPS', 15, ' ')||
LPAD('TOTAL IOPS', 15, ' ')||
LPAD('READ (MB/s)', 15, ' ')||
LPAD('WRITE (MB/s)', 15, ' ')||
LPAD('TOTAL (MB/s)', 15, ' '));
FOR i IN 1..iter
LOOP
SELECT sysdate, SUM(stats.nfs_readbytes), SUM(stats.nfs_writebytes), SUM(stats.nfs_read), SUM(stats.nfs_write)
INTO startTime, startReadBytes, startWriteBytes, startReadIOPS, startWriteIOPS
FROM dual, v$dnfs_stats stats;
DBMS_LOCK.SLEEP(sleepSecs);
SELECT sysdate, SUM(stats.nfs_readbytes), SUM(stats.nfs_writebytes), SUM(stats.nfs_read), SUM(stats.nfs_write)
INTO endTime, endReadBytes, endWriteBytes, endReadIOPS, endWriteIOPS
FROM dual, v$dnfs_stats stats;
elapsedTime := (endTime - startTime) * 86400;
readThr := (endReadBytes-startReadBytes)/(1024 * 1024 * elapsedTime);
writeThr := (endWriteBytes-startWriteBytes)/(1024 * 1024 * elapsedTime);
readIOPS := (endReadIOPS - startReadIOPS)/elapsedTime;
writeIOPS := (endWriteIOPS - startWriteIOPS)/elapsedTime;
DBMS_OUTPUT.PUT_LINE(
TO_CHAR(endTime, 'MM/DD/YYYY HH:MI:SS AM')||
LPAD(TO_CHAR(readIOPS, '999999999'), 15, '') ||
LPAD(TO_CHAR(writeIOPS, '999999999'), 15,' ') ||
LPAD(TO_CHAR(readIOPS + writeIOPS, '999999999'),15, ' ') ||
LPAD(TO_CHAR(readThr, '999999999'), 15, '') ||LPAD(TO_CHAR(writeThr, '999999999'), 15, '
') ||
LPAD(TO_CHAR(readThr + writeThr, '999999999'), 15, ' '));
END LOOP;
DBMS_OUTPUT.PUT_LINE('Finished at ' || to_char(endTime, 'MM/DD/YYYY HH:MI:SS AM'));
END;
Oracle DBA 가이드
- Oracle 데이터베이스용 백업 및 DR
- Oracle 데이터베이스 보호를 위한 기본 요건
- Oracle 패치 및 알려진 문제
- 보호를 위해 Oracle 데이터베이스 준비
- Oracle 데이터베이스 검색 및 보호
- Oracle 데이터베이스 세부정보 및 설정
- 백업 및 DR과 함께 dNFS 사용
- 탐색된 Oracle 데이터베이스 보호
- Oracle 데이터베이스를 표준 마운트로 마운트
- Oracle 데이터베이스의 즉각적인 가상 사본 만들기
- Oracle 데이터베이스 복원 및 복구
- 마운트 및 마이그레이션을 사용하여 Oracle 데이터베이스 즉시 복구
- 백업 및 DR 워크플로를 사용하여 환경 프로비저닝