Вы находитесь на странице: 1из 5

Yousef Rifai REDO REDUCTION

dba@shineout.com USING
NOLOGGING

Introduction
This paper covers the subject of reducing redo generation (LOGGING) using
NOLOGGING. It is a follow up to the Redo reduction with maximum Recoverability
paper. The first paper covers some useful subjects about redo generation which are not
mentioned in this paper.

Important points about NOLOGGING


Oracle gave the user the ability to limit LOGGING (redo generation) on tables and
indexes by setting them in NOLOGGING mode but before going into how to limit the
redo generation it is important to note the following points about LOGGING:
• NOLOGGING is designed to handle bulk inserts for data which can be re-
produced.
• LOGGING should not be disabled on a primary database if it has one or more
standby databases. For this reason oracle introduced the ALTER DATABASE
FORCE LOGGING command in Oracle 9iR2. If this command is run then logging
is not disabled on any database object regardless of this object logging mode.
• Any change to the database dictionary will cause redo generation.
• Data which are not logged can not be recovered. The data should be backed up after
the modification.
• NOLOGGING does not apply to UPDATE, DELETE or normal INSERT.
• Tables and indexes should be set back to LOGGING mode when the
NOLOGGING is no longer needed.
• NOLOGGING is not needed for Direct Path Insert if the database is in
NOArchivelog mode.

Disabling Logging
Logging can be disabled at the table level or the tablespace level. If it is done at the
tablespace level then every newly created index or table in this tablespace will be in
NOLOGGING mode. A table or an index can be create with NOLOGGING mode or it
can be altered using ALTER TABLE/INDEX NOLOGGING;. It is important to note that
just because an index or a table was created with NOLOGGING does not mean that redo
generation has been stopped for this table or index. NOLOGGING is active in the
following situations and while running one of the following commands but not after
that. This is not a full list:
o direct load (SQL*Loader)
o direct load INSERT (using APPEND hint)
o CREATE TABLE ... AS SELECT
o CREATE INDEX
o ALTER TABLE MOVE
o ALTER TABLE ... MOVE PARTITION
o ALTER TABLE ... SPLIT PARTITION

Page 1 of 5
Yousef Rifai REDO REDUCTION
dba@shineout.com USING
NOLOGGING

o ALTER TABLE MERGE PARTITION


o ALTER TABLE MODIFY PARTITION ADD SUBPARTITON
o ALTER TABLE MODIFY PARTITION COALESCE SUBPARTITON
o ALTER INDEX ... SPLIT PARTITION
o ALTER INDEX ... REBUILD
o ALTER INDEX ... REBUILD PARTITION

Logging is stopped only while one of the commands above is running so if a user runs:
ALTER INDEX foo_idx NOLOGGING ;
The actual rebuild of the index does not generate redo (all data dictionary changes
associated with the rebuild do) but after that any DML on the index will generate redo
this includes direct load insert on the table which the index belongs to.
Here is another example to make the point clear:
Create table tab_nolog NOLOGGING(….);
All the following statements will generate redo despite the fact the table is in
NOLOGGING mode:
Insert into tab_nolog .., Update tab_nolog set …, delete from tab_nolog ..
The following WILL NOT generate redo (apart from dictionary changes and indexes):
Insert /*+ APPNED +/ ..
Alter table tab_nolog move ..
Alter table tab_nolog move partition …

Using NOLOGGING
To activate the NOLOGGING for one of the ALTER commands above add the
NOLOGGIN clause after the end of the ALTER command. For example :
Alter table foo move partition part1 tablespace ts1 NOLOGGING;
The same applies for CREATE INDEX but for CREATE TABLE the NOLOGGING
should come after the table name. Example:
Create table tab_with_nologging NOLOGGING as select * from big_tab;
It is a common mistake to add the NOLOGGING at the end because oracle will consider
it an alias and the table creation will generate a lot of logging.

To user Direct Path Load in SQL * Loader you must run the
$ORACLE_HOME/rdbms/admin/catldr.sql script before your first sqlldr is run in direct
path mode. To run sqlldr in direct path mode use direct=true. For further information
refer to Conventional and Direct Path Loads
Direct Path Insert is discussed bellow.

DIRECT PATH INSERT


To use Direct Path Insert use the /*+ APPEND */ hint as follow:
INSERT /*+ APPEND */ into … SELECT …
When direct path insert is used oracle does the following:
 Format the data to be inserted as oracle blocks.

Page 2 of 5
Yousef Rifai REDO REDUCTION
dba@shineout.com USING
NOLOGGING

 Insert the blocks above the High Water Mark (HWM)


 When commit takes place the HWM is moved to the new place. The process is
done bypassing the buffer cache.

It is clear that direct load is useful for bulk inserts. Using it to insert few hundred records
at a time can have bad effect on space and performance.
It is very important to understand how Direct Path Inserts affects redo generation. As
mentioned above it does not affect indexes but it is affected by the following factors:
• The database Archivelog mode.
• Using the /*+ APPEND */ hint.
• The LOGGING mode of the table.
• The FORCE LOGGING mode of the database (from 9i R2).

If the database is in FORCE LOGGING mode then Oracle will treat the table as if it was
in LOGGING mode regardless of its mode. To find out if the database is in FORCED
LOGGING or not run:
select FORCE_LOGGING from v$database ;
If the /*+ APPEND */ Hint is not used then the insertion will generate the normal amount
of redo regardless of the other factors.
This table will show the relation between ARCHIVELOG mode and having the table in
LOGGING mode when the /*+ APPEND */ hint is used. This does not include index
redo nor does it include data dictionary changes redo

LOGGING MODE ARCHIVELOG NOARCHIVELOG


LOGGING Redo No Redo
NOLOGGING No Redo No Redo

Reducing Logging For Bulk DML


Bulk Inserts
To load bulk data using Direct Path.
o set table in nologging mode. Alter table table_name nologging;
o alter index index_name unusable ;
o alter session set skip_unusable_indexes=true ;(*)
o Insert /*+ APPEND */ into table_name select …
o Alter index index_name rebuild nologging;
o Alter table table_name logging ;
o Alter index index_name logging ;
o Backup the data.

(*)skip_unusable_indexes is an instance initialization parameter in 10g and it default to


true. Before 10g, skip_unusable_indexes needs to be set in a session or the user will get
an error. It is a good practice to set it in a session, regardless of the database version,
when the above is done.

Page 3 of 5
Yousef Rifai REDO REDUCTION
dba@shineout.com USING
NOLOGGING

There is no direct way (at the time of writing this document) of reducing redo generation
for bulk update and delete. The user needs to reduce the workload on the database.

Bulk Delete:
1. Create a new_table with no logging, CREATE TABLE table_name
NOLOGGING (….); THE NOLOGGING COMES AFTER THE
TABLE_NAME NOT AT THE END OF THE STATEMENT.
2. Insert /*+ Append */ into new_table select the records you want to keep from
current_table.
3. Create the indexes on the new table with NOLOGGING (*)
4. Create constraints, grants etc.
5. Drop current_table.
6. Rename new_table to current.
7. Alter new_table and indexes logging.
8. Backup the data.

(*) If the data left is so small or there are a lot of dependencies on the table (views,
procedures, functions) the following steps can be used instead of 3-6 above
3. Disable constrains on current_table;
4. Truncate current_table;
5. make indexes unusable;
6. alter current table NOLOGGING ;
7. Insert /*+ APPEND */ into current_table select * from new_table ;
8. commit;
9. rebuild indexes with NOLOGGING;
10. enable constraints
11. Put current table and indexes in LOGGING mode
12. backup the data
13. drop table new_table;

Bulk Update:
Follow the steps for bulk Delete but integrate the update within the select statement. Lets
say that you want to update the value column in the goods table by increasing it by 10%
the statement will be like:
1. Create a new_table with no logging, CREATE TABLE table_name
NOLOGGING (….); THE NOLOGGING COMES AFTER THE
TABLE_NAME NOT AT THE END OF THE STATEMENT.
2. Insert /*+ Append */ into new_table select (update statement eg: col1, col2*
1.1,…)
3. Create the indexes on the new table with NOLOGGING (*)
4. Create constraints, grants etc.
5. Drop current_table.

Page 4 of 5
Yousef Rifai REDO REDUCTION
dba@shineout.com USING
NOLOGGING

6. Rename new_table to current.


7. Alter new_table and indexes logging.
8. Backup the data.

Backup And Nologging


It is important that the data loaded using NOLOGGING can be loaded again if you need
to. If the database crashed before backing up the new data then this data can not be
recovered.
Here are the two scenarios of backing up:
Export (exp or expdp)
This method will allow you to recover the loaded data up to the point the export was
taken but not later.

Hot Backup
In order to recover any additional data or modification to the table you bulk inserted into
using NOLOGGIN the least you need to do is a hot backup of that tablespace. Remember
you still generate redo for DML on the table when it is in NOLOGGING mode but you
are strongly advised to put it in LOGGING mode in case you run one of the operations
mentioned in the Disabling Logging section.

Page 5 of 5