バックアップと DR で Oracle Direct NFS を使用する

バックアップ/リカバリ アプライアンスで Oracle Direct NFS(dNFS)を使用するには、次の要件を満たす必要があります。

  • データベース サーバーとバックアップ/リカバリ アプライアンスの間の十分なネットワーク帯域幅

  • Oracle の必須パッチまたは推奨パッチをすべて使用します。Oracle は、Oracle サポートのドキュメントで、必須または推奨のパッチのリストを維持しています。

dNFS を介した仮想 Oracle データベースの保護とマウントを構成する管理コンソールを構成する

dNFS ベースのバックアップを実行するには、バックアップ/リカバリ アプライアンスのステージング ディスク形式(ディスク設定)を NFS に設定する必要があります。

次の手順で、ステージング ディスクの形式(ディスク設定)を NFS に設定します。

  1. [管理] > [ホスト] に移動します。

  2. ホストを右クリックして [編集] を選択します。

  3. ステージング ディスク形式で [NFS] を選択し、[保存] をクリックします。

dNFS が機能するためにターゲット ホストで実行するアクション

次の操作を行い、dNFS が正しく構成されていることを確認します。

  1. 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

  2. バックアップ ジョブ中に、次のクエリを実行して 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 データベースの場合は、最後の 2 つの 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 サーバーごとに 1 つ)の情報が表示されます。ビューは、接続と TCP ソケットの設定を確認する場合に便利です。

  • V$DNFS_CHANNELS: NFS サーバーに作成されたすべてのネットワーク パスの情報が表示されます。各 dNFS クライアントは、ネットワーク パスごとにプロセスごとに 1 つのチャネルを作成します。複数のパスが存在する場合(複数の NIC の場合)、dNFS クライアントはすべてのチャネルでロード バランシングを行います。データは、前回選択してからのアクティビティを反映しています。

  • V$DNFS_FILES: dNFS クライアントを使用して開いているファイルを表示します。

  • V$DNFS_STAT: dNFS クライアントのパフォーマンス指標。

V$DNFS_SERVER
説明
SRVNAME NFS サーバー名
DIRNAME NFS サーバーによってエクスポートされたボリューム
MNTPORT ローカル マウント ポート
NFSPORT NFS サーバー ポート
WTMAX NFS サーバーの最大書き込みサイズ
RTMAX NFS サーバーの最大読み取りサイズ
V$DNFS_CHANNELS
説明
PNUM Oracle プロセス番号(v$process の PID へのリンク)
SVRNAME NFS サーバー名
PATH サーバーへのネットワーク パス
CH_ID dNFS チャネル ID
SVR_ID dNFS サーバー ID
SENDS チャンネルを介して前回選択してからオペレーションを送信します。
RECVS チャンネル経由で前回選択してからのオペレーションを受信します。
PINGS チャンネルを介した前回選択以降の ping オペレーション。
V$DNFS_FILES
説明
FILENAME ファイルの名前。
FILESIZE ファイルのサイズ。
PNUM プロセス ID(v$process の PID へのリンク)
SRV_ID NFS サーバー ID
V$DNFS_STAT
説明
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 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 ガイド