NOLOGGING & APPEND (Direct-path INSERT) | ExpoDBA

NOLOGGING & APPEND (Direct-path INSERT)

NOLOGGING & APPEND (Direct-path INSERT)

Estas opciones son utilizadas generalmente para mejorar la performance en algunas tareas de mantenimiento.
Pero ¿Qué es lo que realmente hacen? ¿Cómo afectan al recovery de la base de datos?

Antes de arrancar, debemos tener unos conceptos importantes.

 

Por defecto, las tablas e indices se crean en logging, a menos que se aclare la clausula en la creación de la tabla o el tablespace en el que se crea tenga la opción nologging.

Este parametro es completamente ignorado si la base de datos está configurada con FORCE LOGGING.


LOGGING:
Cada vez que la base ejecuta un DML o un DDL o un COMMIT, Oracle escribe este cambio como un nuevo registro en el redo log buffer, que luego es pasado a los redo log files, y luego  a los archive log files (si la base esta en archivelog mode).

Cada DML o DDL puede utilizar un nuevo bloque o modificar uno o más bloques en la base de datos (los que contienen la información), y lo que se escribe en el registro del redolog buffer es un registro que contiene un vector de cambios, de manera tal que con esa información se pueda volver a generar el cambio, con solo la información reducida almacenada en este registro.

Cuando la transacción es consolidada con un COMMIT, se crea un nuevo registro en el redolog buffer y asigna un nuevo SCN  al cambio.

Este es el mecanismo de defensa que tiene la base para que en caso de tener que hacer un recover, tiene toda la información aplicada a los datafiles almacenada en los redolog o archive log.

NOLOGGING:

Solo afecta a los direct-path load que se hagan a la base de datos. No afecta a los DML convencionales como INSERT, UPDATE, DELETE.

Los comandos DDL que son afectados por esta clausula son:

 

    alter table ... move partition
    alter table ... split partition
    alter table ... add partition (if hash partition)
    alter table ... merge partition
    alter table ... modify partition
        add subpartition
        coalesce subpartition
        rebuild unusable indexes
    alter index ... split partition
    alter index ... rebuild
    alter index ... rebuild partition
    create table ... as select
    create index 

 

 

De todos modos el NOLOGGING solo reduce la creación de redo, pero no lo elimina porque siguen modificandose otros bloques en la base como los del diccionario, de undo, etc.

De esta manera por cada bloque que se modifica en el segmento, no se registra la modificación en los redologs, por lo tanto, en caso de fallo, no se pueden recuperar los datos cargados y es nuestro deber volver a cargarlos o tomar las medidas necesariar para recuperar la base hasta un punto posterior al Direct-Path INSERT



UNDO RECORDS:
Cada vez que se modifica un bloque, este bloque es copiado y almacenado en un segmento del tablespace de UNDO.
Este bloque se mantiene en el undo hasta que no se haga commit o rollback de la transacción, de manera tal que cualquier persona que consulte los datos de ese bloque, antes de que se haga rollback y commit, pueda acceder a la última versión no modificada que se encuentra en el Undo. Realizando así una lectura consistente.

Direct-Path INSERT (APPEND Hint):
Cada vez que se hace un insert, lo que hace Oracle es buscar un bloque donde entre ese registro, dentro de los bloques existentes (revisa free list). También chequea que se mantenga las referential integrity constraints.

Al poner el HINT de APPEND lo que logramos es que evite esa busqueda de bloques con espacio y directamente ejecute un direct-path insert, insertando los datos después de los datos existentes en el segmento (Después de la HWM). Además los datos no pasan por el buffer cache, sino que se escriben directamente en los datafiles y no chequea las referential integrity constraints.

Si el insert se realiza con la clausula PARALLEL, automáticamente Oracle utiliza Direct-Path INSERT por lo tanto no es necesario poner el HINT.

El APPEND solo es válido para cargas masivas, no para inserts normales.

 

Si el insert se realiza en PARALLEL, entonces sí o sí se hace con Direct-Path INSERT a menos que se aclare la clausula NOAPPEND.

 

 


 

Con todos estos conceptos claros ahora es más sencillo poder notar que combinación se puede hacer y que tener en cuenta en cada caso.

Ante un insert as select (por elegir una de las opciones donde se dan todas las combinaciones) Oracle realiza los siguientes pasos:

 

LOGGING - NOAPPEND

  1. Busca un bloque con espacio para meter el registro (En freelist)
  2. Si lo encuentra copia el bloque con espacio al UNDO (porque modifica un bloque ya existente con datos)
  3. Modifica el bloque agregando el registro
  4. Registra el cambio en el Redolog Buffer (Porque está en LOGGING)

 

LOGGING - APPEND

  1. NO busca bloque con espacio en freelist (Porque esta en APPEND, escribe sobre HWM)
  2. NO copia ningún bloque con espacio al UNDO (porque el bloque que selecciona es nuevo)
  3. Escribe el registro en el nuevo bloque
  4. Registra el cambio en el Redolog Buffer (Porque está en LOGGING)

 

NOLOGGING - NOAPPEND

  1. Busca un bloque con espacio para meter el registro (En freelist)
  2. Si lo encuentra copia el bloque con espacio al UNDO (porque modifica un bloque ya existente con datos)
  3. Modifica el bloque agregando el registro
  4. NO registra el cambio en el Redolog Buffer (Porque está en NOLOGGING)

 

NOLOGGING - APPEND

  1. NO busca bloque con espacio en freelist (Porque esta en APPEND, escribe sobre HWM)
  2. NO copia ningún bloque con espacio al UNDO (porque el bloque que selecciona es nuevo)
  3. Escribe el registro en el nuevo bloque
  4. NO registra el cambio en el Redolog Buffer (Porque está en NOLOGGING)

 

Para mejorar la performance de la inserción queda claro que lo más rápido es utilizar NOLOGGING - APPEND, ya que en cada insert que realiza, solo escribe el nuevo bloque y nos ahorramos de escribir el buffer, el undo por cada bloque, se reducen las escrituras del LGWR, Los switchs de Log files, etc.

 

NOTA:  Se aclara que cuando decimos que no escribe ningún bloque en el undo o en el redolog buffer, nos referimos a lo aplicado a la tabla en particular, pero no hay que olvidarse que el insert también modifica datos en el diccionario, o indices que SI O SI deben ser reflejados y entrar dentro del mecanismo de seguridad, generando tanto redo como undo.

 

Es importante tener en cuenta que al utilizar NOLOGGING, comprometemos el recovery de la base en caso de fallos y que debemos hacer un  backup luego de aplicar los cambios, o tener en cuenta que luego de recuperar la base después de un fallo con un restore previo al insert, el recover no tendrá la información necesaria para recuperar estos datos y será necesario volver a aplicar el insert.

 

Ejemplos:

Insert en serial mode con direct-path y nologging

insert /*+ append */ into TABLA_DESTINO select * from TABLA_ORIGEN nologging;

 

Insert en parallel mode con direct-path y nologging

insert into TABLA_DESTINO select * from TABLA_ORIGEN PARALLEL nologging ;
insert /*+ PARALLEL 4*/ into TABLA_DESTINO select * from TABLA_ORIGEN nologging ; 

 

Bueno, y está claro que para que no sea en parallel o append, simplemente hay que sacar el HINT y para evitar el nologging, solo cambiarlo por logging o sacarlo.