Usa Oracle Direct NFS con Backup and DR

Para usar Oracle Direct NFS (dNFS) con un dispositivo de copia de seguridad o recuperación, se deben cumplir los siguientes requisitos:

  • Ancho de banda de red suficiente entre el servidor de bases de datos y el dispositivo de copia de seguridad o recuperación

  • Usa todos los parches obligatorios o recomendados de Oracle. Oracle mantiene una lista de parches obligatorios o recomendados en la documentación de Oracle Support.

Configura la consola de administración para proteger y activar bases de datos virtuales de Oracle a través de dNFS

Para realizar una copia de seguridad basada en dNFS, debes configurar el formato de disco de preparación (preferencia de disco) del dispositivo de copia de seguridad o recuperación en NFS.

Sigue estas instrucciones para configurar el formato de disco de preparación (preferencia de disco) en NFS:

  1. Ve a Administrar > Hosts.

  2. Haz clic con el botón derecho en el host y selecciona Editar.

  3. En el formato de disco de preparación, selecciona NFS y, luego, haz clic en Guardar.

Acciones que se deben realizar en el host de destino para que funcione dNFS

Realiza estas acciones para asegurarte de que dNFS esté configurado correctamente:

  1. Busca el siguiente mensaje en DB Alert.log para confirmar que dNFS está habilitado:

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

    Si dNFS no está habilitado, haz lo siguiente:

    • Los paquetes de cliente NFS deben existir en el host de la base de datos para los trabajos de protección y en cualquier host de Oracle en el que puedas activar una base de datos de Oracle capturada con dNFS. Por ejemplo, en Linux, el paquete nfs-util debe existir en el host. Verifica lo siguiente:

      rpm -qa |grep nfs-util

    • Habilita dNFS en el host de Oracle:

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

    • Reinicia las bases de datos que se ejecutan en ese ORACLE_HOME y, luego, busca el siguiente mensaje en DB Alert.log para confirmar que dNFS esté habilitado:

      Instancia de Oracle que se ejecuta con ODM: Biblioteca de ODM de NFS directo de Oracle versión 3.0

  2. Durante el trabajo de copia de seguridad, ejecuta la siguiente consulta para verificar el uso de dNFS:

    select * from gv$dnfs_servers;
    

    Puedes ver las estadísticas de lectura/escritura de NFS para las operaciones de E/S en curso:

    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;
    

    Podemos ver la información del proceso del canal de 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;
    

Soluciona problemas de dNFS: Problemas con la base de datos

Esto incluye lo siguiente:

Registro de alertas

El primer paso para cualquier operación de depuración es verificar el registro de alertas en busca de mensajes relacionados con dNFS. Un problema habitual que se observa en las bases de datos con dNFS es que el tamaño del búfer del socket es limitado. Oracle intenta ajustar el tamaño, pero el SO puede limitar este proceso. En este caso, se encuentra un error como este en el registro de alertas:

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

Otros elementos que debes buscar en el registro de alertas incluyen si se usan las tarjetas de red correctas para comunicarse con el archivo. Para determinarlo, busca un mensaje similar al siguiente:

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

Archivos de registro de la base de datos

Si se producen problemas de E/S, se pueden configurar los siguientes eventos en la base de datos para capturar información de registro adicional. Establece estos eventos, espera a que se produzca el incidente y, luego, revisa los archivos de seguimiento.

    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 datos no responde

Si una base de datos que se ejecuta en dNFS no responde, accede como SYSDBA con sqlplus y realiza un "hanganalyze" o un volcado:

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

Si la base de datos es una base de datos de RAC, agrega una opción -g a los últimos dos comandos oradebug.

Vistas de dNFS

El cliente de dNFS se encuentra en el kernel de la base de datos. Por lo tanto, existen varias vistas v$ dentro de la base de datos para supervisar y verificar el estado de dNFS desde la base de datos. Oracle proporciona un paquete que se puede usar para supervisar rápidamente el rendimiento de dNFS. Este paquete se encuentra en el paquete de supervisión de dNFS de Oracle.

Una vez que se implementa, un DBA puede realizar lo siguiente para obtener información (parámetros: dnfs_monitor(tiempo de inactividad), dnfs_itermonitor (tiempo de inactividad,cantidad de veces que se debe verificar), el tiempo de inactividad se mide en segundos):

    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

Las vistas de V$ son las siguientes:

  • V$DNFS_SERVER: Muestra información de todas las conexiones del servidor NFS (una para cada servidor NFS). La vista es útil para verificar la conectividad y la configuración del socket TCP.

  • V$DNFS_CHANNELS: Muestra información de todas las rutas de red creadas en los servidores NFS. Cada cliente de dNFS crea un canal por proceso por ruta de red. Si existen varias rutas (varios NIC), el cliente de dNFS realiza el balanceo de cargas en todos los canales. Los datos reflejan la actividad desde la última selección.

  • V$DNFS_FILES: Muestra los archivos que están abiertos con el cliente de dNFS.

  • V$DNFS_STAT: Métricas de rendimiento del cliente de dNFS.

V$DNFS_SERVER
Columna Descripción
SRVNAME Nombre del servidor NFS
DIRNAME Volumen exportado por el servidor NFS
MNTPORT Puerto de activación local
NFSPORT Puerto del servidor NFS
WTMAX Tamaño máximo de escritura para el servidor NFS
RTMAX Tamaño máximo de lectura para el servidor NFS
V$DNFS_CHANNELS
Columna Descripción
PNUM Número de proceso de Oracle (vínculo al PID en v$process)
SVRNAME Nombre del servidor NFS
PATH Ruta de red al servidor
CH_ID ID del canal de dNFS
SVR_ID ID del servidor dNFS
SENDS Envía operaciones a través del canal desde la última selección.
RECVS Operaciones de recepción en el canal desde la última selección
PINGS Operaciones de ping en el canal desde la última selección
V$DNFS_FILES
Columna Descripción
FILENAME Es el nombre del archivo.
FILESIZE Es el tamaño del archivo.
PNUM ID de proceso (vínculo al PID en v$process)
SRV_ID ID del servidor NFS
V$DNFS_STAT
Columna Descripción
PNUM Número de proceso de Oracle (vínculo al PID en v$process)
NFS_NULL Null operations
NFS_GETATTR Cómo obtener operaciones de atributos
NFS_SETATTR Operaciones de configuración de atributos
NFS_LOOKUP Operaciones de búsqueda
NFS_ACCESS Operaciones de acceso
NFS_READLINK Operaciones de vínculo de lectura
NFS_READ Operaciones de lectura
NFS_WRITE Operaciones de escritura
NFS_CREATE Operaciones de creación
NFS_MKDIR Cómo realizar operaciones de directorio
NFS_MKNOD Cómo realizar operaciones de nodo
NFS_SYMLINK Operaciones de vínculos simbólicos
NFS_REMOVE Operaciones de eliminación
NFS_RMDIR Cómo quitar operaciones de directorio
NFS_RENAME Operaciones de cambio de nombre
NFS_LINK Operaciones de vínculo
NFS_READDIR Operaciones de lectura de directorios
NFS_READDIRPLUS Operaciones de lectura del directorio más
NFS_FSSTAT Operación de estado del sistema de archivos
NFS_FSINFO Operaciones de información del sistema de archivos
NFS_PATHCONF Operaciones de configuración de rutas
NFS_COMMIT Operaciones de confirmación
NFS_MOUNT Operaciones de activación

El paquete de supervisión de dNFS de 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;

Guía del administrador de bases de datos de Oracle