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

Pour utiliser Oracle Direct NFS (dNFS) avec un dispositif de sauvegarde/récupération, vous devez remplir les conditions suivantes :

  • Bande passante réseau suffisante entre le serveur de base de données et l'appliance de sauvegarde/récupération

  • Utilisez tous les correctifs Oracle requis ou recommandés. Oracle tient à jour une liste des correctifs requis ou recommandés dans la documentation de l'assistance Oracle.

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

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

Suivez ces instructions pour définir le format du disque intermédiaire (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 "Format du disque de préparation", 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 confirmer 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 :

    • Des packages client NFS doivent exister sur l'hôte de la base de données pour les jobs de protection, et sur tout hôte Oracle sur lequel vous pourriez 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 éléments 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 confirmer que dNFS est activé :

      Instance Oracle exécutée avec ODM : Oracle Direct NFS ODM Library 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 sur le processus 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 liés à 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 pour les messages liés à dNFS. Un problème courant observé sur les bases de données avec dNFS concerne la taille limitée du tampon de socket. Oracle essaie d'ajuster la taille, mais cela peut être limité par l'OS. Dans ce cas, une erreur semblable à celle-ci est détectée dans le journal d'alertes :

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

Parmi les autres éléments à rechercher dans le journal des alertes, vérifiez si les bonnes cartes réseau sont utilisées pour communiquer avec le filer. Pour le savoir, recherchez un message semblable à celui-ci :

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

Fichiers de trace de 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 ou un vidage de blocage :

    ```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 en fait 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 de dNFS depuis la base de données. Oracle fournit un package qui peut être utilisé pour surveiller rapidement les performances d'dNFS. Ce package se trouve dans le package de surveillance Oracle dNFS.

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), sleep time 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 pour toutes les connexions au serveur NFS (une pour chaque serveur NFS). L'affichage est utile pour vérifier la connectivité et les paramètres des sockets TCP.

  • V$DNFS_CHANNELS : affiche des informations pour tous les chemins réseau créés sur les serveurs NFS. Chaque client dNFS crée un canal par processus et par chemin réseau. S'il existe plusieurs chemins (plusieurs cartes d'interface réseau), 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 de montage 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 canal dNFS
SVR_ID ID du serveur dNFS
SENDS Envoyez des opérations sur le canal depuis la dernière sélection.
RECVS Recevez les opérations sur le canal depuis la dernière sélection.
PINGS Effectue un ping des opérations sur le canal depuis la dernière sélection.
V$DNFS_FILES
Colonne Description
FILENAME Nom du fichier.
FILESIZE Taille du fichier.
PNUM ID du processus (lien vers 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 Obtenir les opérations d'attribut
NFS_SETATTR Définir les opérations d'attribut
NFS_LOOKUP Opérations de recherche
NFS_ACCESS Opérations d'accès
NFS_READLINK Lire les opérations de lien
NFS_READ Opérations de lecture
NFS_WRITE Opérations d'écriture
NFS_CREATE Opérations Create
NFS_MKDIR Effectuer des opérations sur les répertoires
NFS_MKNOD Effectuer des opérations sur les nœuds
NFS_SYMLINK Opérations sur les liens symboliques
NFS_REMOVE Supprimer des opérations
NFS_RMDIR Supprimer les opérations de répertoire
NFS_RENAME Opérations de renommage
NFS_LINK Opérations sur les liens
NFS_READDIR Opérations de lecture de l'annuaire
NFS_READDIRPLUS Opérations de lecture et d'ajout de répertoires
NFS_FSSTAT Opération d'état du système de fichiers
NFS_FSINFO Opérations d'information 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

Package de surveillance 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;

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