Utiliser Oracle Direct NFS avec la sauvegarde et la reprise après sinistre

Pour utiliser Oracle Direct NFS (dNFS) avec un appareil de sauvegarde/restauration, les conditions suivantes doivent être remplies:

  • Bande passante réseau suffisante entre le serveur de base de données et l'appareil de sauvegarde/restauration

  • Appliquez tous les correctifs Oracle requis ou recommandés. Oracle gère une liste de correctifs obligatoires ou recommandés dans la documentation d'assistance Oracle.

Configurer la console de gestion pour protéger et monter des bases de données Oracle virtuelles via dNFS

Pour effectuer une sauvegarde basée sur dNFS, vous devez définir le format de disque de préproduction (préférence de disque) de l'appliance de sauvegarde/restauration sur NFS.

Suivez ces instructions pour définir le format de disque de préproduction (préférence de disque) sur NFS:

  1. Accédez à Gérer > Hôtes.

  2. Effectuez un clic droit sur l'hôte, puis sélectionnez Modifier.

  3. Dans le champ "Format de disque d'escalade", sélectionnez NFS, puis cliquez sur Enregistrer.

Actions à effectuer sur l'hôte cible pour que dNFS fonctionne

Effectuez les actions suivantes pour vous assurer que dNFS est correctement configuré:

  1. Recherchez le message suivant sous DB Alert.log pour vérifier que dNFS est activé:

    Oracle instance running with ODM: Oracle Direct NFS ODM Library Version 3.01.
    

    Si dNFS n'est pas activé, activez-le:

    • Les paquets client NFS doivent exister sur l'hôte de la base de données pour les tâches de protection, ainsi que sur tout hôte Oracle sur lequel vous pouvez installer une base de données Oracle capturée à l'aide de dNFS. Par exemple, pour Linux, le package nfs-util doit exister sur l'hôte. Vérifiez les points suivants:

      rpm -qa |grep nfs-util

    • Activez dNFS sur l'hôte Oracle:

      cd $ORACLE_HOME/rdbms/lib make -f ins_rdbms.mk dnfs_on

    • Redémarrez les bases de données exécutées sur ce ORACLE_HOME, puis recherchez le message suivant sous DB Alert.log pour vérifier que dNFS est activé:

      Instance Oracle exécutée avec ODM: bibliothèque ODM Oracle Direct NFS version 3.0

  2. Pendant la tâche de sauvegarde, exécutez la requête suivante pour vérifier l'utilisation de dNFS:

    select * from gv$dnfs_servers;
    

    Vous pouvez consulter les statistiques de lecture/écriture NFS pour les E/S en cours:

    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;
    

    Nous pouvons voir les informations de traitement du canal 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;
    

Résoudre les problèmes dNFS: problèmes de base de données

Par exemple :

Journal des alertes

La première étape de toute opération de débogage consiste à vérifier le journal des alertes à la recherche de messages liés à dNFS. Un problème courant observé sur les bases de données avec dNFS est la limitation de la taille du tampon de socket. Oracle tente d'ajuster la taille, mais cela peut être limité par l'OS. Dans ce cas, une erreur semblable à celle-ci s'affiche dans le journal des alertes:

    Direct NFS: Failed to set socket buffer size.wtmax=[1048576]\
    rtmax=[1048576], errno=-1

D'autres éléments à rechercher dans le journal des alertes incluent si les cartes réseau appropriées sont utilisées pour communiquer avec le fichier. Pour le savoir, recherchez un message semblable au suivant:

    Direct NFS: channel id [0] path [192.168.56.3] to filer [192.168.56.3] via local [] is UP

Fichiers de suivi de la base de données

En cas de problèmes d'E/S, les événements suivants peuvent être définis dans la base de données pour capturer des informations de journalisation supplémentaires. Définissez ces événements, attendez que l'incident se produise, puis examinez les fichiers de trace.

    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

La base de données ne répond pas

Si une base de données exécutée sur dNFS ne répond pas, connectez-vous en tant que SYSDBA à l'aide de sqlplus et effectuez une analyse de blocage ou un vidage:

    ```oradebug
    oradebug setmypid
    oradebug unlimited
    oradebug hanganalyze 3
    oradebug dump systemstate 266
    ```

Si la base de données est une base de données RAC, ajoutez une option -g aux deux dernières commandes oradebug.

Vues dNFS

Le client dNFS se trouve dans le noyau de la base de données. Par conséquent, plusieurs vues v$ existent dans la base de données pour surveiller et vérifier l'état des dNFS à partir de la base de données. Oracle fournit un package qui peut être utilisé pour surveiller rapidement les performances de dNFS. Ce package se trouve dans le package de surveillance dNFS d'Oracle.

Une fois déployé, un administrateur de base de données peut effectuer les opérations suivantes pour obtenir des informations (paramètres: dnfs_monitor(sleep time), dnfs_itermonitor (sleep time,number of times to check), le temps de veille est en secondes):

    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

Les vues V$ sont les suivantes:

  • V$DNFS_SERVER: affiche des informations sur toutes les connexions au serveur NFS (une pour chaque serveur NFS). La vue est utile pour vérifier la connectivité et les paramètres de socket TCP.

  • V$DNFS_CHANNELS: affiche des informations sur tous les chemins réseau créés vers les serveurs NFS. Chaque client dNFS crée un canal par processus et par chemin réseau. Si plusieurs chemins existent (plusieurs NIC), le client dNFS équilibre la charge sur tous les canaux. Les données reflètent l'activité depuis la dernière sélection.

  • V$DNFS_FILES: affiche les fichiers ouverts à l'aide du client dNFS.

  • V$DNFS_STAT: métriques de performances pour le client dNFS.

V$DNFS_SERVER
Colonne Description
SRVNAME Nom du serveur NFS
DIRNAME Volume exporté par le serveur NFS
MNTPORT Port d'installation local
NFSPORT Port du serveur NFS
WTMAX Taille d'écriture maximale pour le serveur NFS
RTMAX Taille de lecture maximale pour le serveur NFS
V$DNFS_CHANNELS
Colonne Description
PNUM Numéro de processus Oracle (lien vers le PID dans v$process)
SVRNAME Nom du serveur NFS
PATH Chemin réseau vers le serveur
CH_ID ID de la chaîne dNFS
SVR_ID ID du serveur dNFS
SENDS Envoyez des opérations via le canal depuis la dernière sélection.
RECVS Recevoir les opérations sur le canal depuis la dernière sélection.
PINGS Opérations de ping sur le canal depuis la dernière sélection.
V$DNFS_FILES
Colonne Description
FILENAME Nom du fichier.
FILESIZE Taille du fichier.
PNUM ID de processus (lien vers le PID dans v$process)
SRV_ID ID du serveur NFS
V$DNFS_STAT
Colonne Description
PNUM Numéro de processus Oracle (lien vers le PID dans v$process)
NFS_NULL Null operations
NFS_GETATTR Opérations Get d'attribut
NFS_SETATTR Opérations d'attributs Set
NFS_LOOKUP Opérations de recherche
NFS_ACCESS Opérations d'accès
NFS_READLINK Opérations de lecture des liens
NFS_READ Opérations de lecture
NFS_WRITE Opérations d'écriture
NFS_CREATE Opérations Create
NFS_MKDIR Effectuer des opérations de répertoire
NFS_MKNOD Effectuer des opérations de nœud
NFS_SYMLINK Opérations de lien symbolique
NFS_REMOVE Supprimer des opérations
NFS_RMDIR Supprimer des opérations de répertoire
NFS_RENAME Renommer des opérations
NFS_LINK Opérations de liaison
NFS_READDIR Opérations de lecture d'annuaire
NFS_READDIRPLUS Opérations de lecture du répertoire plus
NFS_FSSTAT Opération d'état du système de fichiers
NFS_FSINFO Opérations d'informations sur le système de fichiers
NFS_PATHCONF Opérations de configuration des chemins d'accès
NFS_COMMIT Opérations de validation
NFS_MOUNT Opérations d'installation

Le package de surveillance dNFS Oracle

    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;

Guide de l'administrateur de base de données Oracle