dbi services Blog
Welcome to the dbi services Blog! This blog focuses on database infrastructure and middleware topics. It covers technologies such as Oracle, Microsoft SQL Server, MySQL, Sybase, Linux, or Documentum (etc.). The dbi services blog represents the view of our consultants, not necessarily that of dbi services. Feel free to comment on the postings!
Certaines requêtes DDL offrent la possibilité de ne pas générer des enregistrements dans les redo log via la clause NOLOGGING. Le mode nologging permet donc dans certains cas d'accélérer des traitements, ceux-ci pouvant facilement être récupérables à travers des mécanismes externes à la base de données. Ce mode peut cependant avoir des conséquences fâcheuses comme nous allons le constater et ce pas uniquement dans le contexte de configurations comme Oracle DataGuard.
Dans le cadre de mon activité de consultant, je rencontre fréquemment des bases de données qui sont en mode NOLOGGING. Quelle en est la signification et quelles peuvent être les implications d'une telle configuration ?
Pour répondre à cette question nous allons nous intéresser au comportement d'une instance de base de données en mode NOLOGGING.
SQL> select force_logging from v$database; FORCE_LOGGING
---NO
Les tablespaces de l'instance sont eux par contre en mode LOGGING :
SQL> select tablespace_name , logging from dba_tablespaces;
TABLESPACE_NAME LOGGING
------------------------------ ---------
SYSTEM LOGGING
SYSAUX LOGGING
UNDOTBS1 LOGGING
TEMP NOLOGGING
USERS LOGGING
REPO_RMAN LOGGING
REPO_RMAN2 LOGGING
Nous créons une table test_redo et nous la plaçons en mode NOLOGGING:
SQL> create table test_redo as select * from all_objects where 1=2;
Table created.
SQL> alter table test_redo nologging;
Table altered.
En insérant des données dans la table redo_test, on visualise une activité des redologs :
SQL> set autotrace on statistics;SQL> insert into test_redo select * from all_objects;71890 rows created.Statistics----------------------------------------------------------1527 recursive calls9938 db block gets50166 consistent gets859 physical reads8430816 redo size674 bytes sent via SQL*Net to client619 bytes received via SQL*Net from client3 SQL*Net roundtrips to/from client1523 sorts (memory)0 sorts (disk)71890 rows processed
Si on réalise une insertion en direct load via le hint APPEND, l'activité des redologs est moins importante, il y a eu beaucoup moins d'écriture dans les redologs :
SQL> insert /*+ APPEND */ into test_redo select * from all_objects;71890 rows created.Statistics----------------------------------------------------------225 recursive calls1380 db block gets47267 consistent gets0 physical reads28304 redo size663 bytes sent via SQL*Net to client633 bytes received via SQL*Net from client3 SQL*Net roundtrips to/from client1501 sorts (memory)0 sorts (disk)71890 rows processed
Si nous interrogeons la vue v$datafile, nous pouvons visualiser qu'il y a eu une activité qui n'a pas été écrite dans les redologs :
SQL> SELECT NAME, UNRECOVERABLE_CHANGE#,
2 TO_CHAR (UNRECOVERABLE_TIME,'DD-MON-YYYY HH:MI:SS')
3 FROM V$DATAFILE;
NAME UNRECOVERABLE_CHANGE# TO_CHAR(UNRECOVERABLE_TIME
/u01/database/DB112/system01.dbf 0
/u01/database/DB112/sysaux01.dbf 0
/u01/database/DB112/undotbs01.dbf 0
/u01/database/DB112/users01.dbf 2048947 18-APR-2011 05:07:10
A présent, restaurons l'instance de base de données à un instant t postérieur à l'insertion en direct load, ces données ne seront pas restaurées un message de bloc corrompu apparaitra :
SQL> select count(*) from redo_test; select count(*) from redo_test * ERROR at line 1: ORA-01578: ORACLE data block corrupted (file # 4, block # 1410) ORA-01110: data file 4: '/u01/database/DB112/users01.dbf' ORA-26040: Data block was loaded using the NOLOGGING option
Les opérations en nologging sont plus rapides puisqu'il n'y a pas d'écriture dans les redologs :
SQL> set timing on SQL> create table redo_test as select * from all_objects where 1=2; Table created. Elapsed: 00:00:01.29 SQL> create table redo_test_nolog nologging as select * from all_objects where 1=2; Table created. Elapsed: 00:00:00.56 SQL> insert into redo_test select * from all_objects; 71892 rows created. Elapsed: 00:00:05.58 SQL> insert /* +APPEND */ into redo_test_nolog select * from all_objects; 71892 rows created. Elapsed: 00:00:03.62
Regardons maintenant si une table créée en mode NOLOGGING a des conséquences sur toutes les opérations DML. Nous allons détruire toutes les lignes de la table redo_test_nolog et effectuer un rollback :
SQL> create table redo_test_nolog nologging as select * from all_objects; Table created. SQL> delete from redo_test_nolog; 71892 rows deleted. SQL> rollback; Rollback complete. SQL> select count(*) from redo_test_nolog; COUNT(*) 71892
Comme précisé dans la documentation Oracle :
"The NOLOGGING clause also specifies that subsequent direct loads using SQL*Loader and direct load INSERT operations are not logged. Subsequent DML statements (UPDATE, DELETE, and conventional path insert) are unaffected by the NOLOGGING attribute of the table and generate redo."
En résumé les opérations en nologging peuvent faire gagner du temps, mais il faut être conscient du risque pris lors de telles opérations. Toute opération effectuée en direct load insert implique nécessairement un backup de l'instance.
Related Post
- A test database in one click - with Oracle Data Guard 11g Perhaps you know this situation: A developper or application owner quickly needs a test database to test new code or to validate changed code before i...
- Database world - high availability: SQL Server vs Oracle Last week, I attended the Microsoft TechDays for the first time. The Swiss 2011 "edition" took place in Bern. For me this is really a n...



Hello Pierre,
Sympathique rappel ;-) il y a une jolie note Oracle sur le sujet :
The Gains and Pains of Nologging Operations [ID 290161.1]
Pierre