Oracle补充日志及日志记录规则


这篇文章是在《构建最高可用Oracle数据库系统:Oracle 11gR2 RAC管理、维护与性能优化》11.4.2小节的基础上进一步修改而成的,并感谢老谭的提醒和帮助。

Supplemental Log是一种补充类型的日志,主要用于逻辑Standby数据库的同步、LogMiner、Streams和Flashback等技术。对于逻辑Standby数据库来说,不能通过ROWID来标识某一行,Oracle推荐使用主键、约束和索引唯一标识行数据,但如果某部分表由于某种原因没有主键、唯一约束和唯一索引,不能有效的标识行数据,那么必须通过Supplemental Log记录多个字段甚至所有字段值来唯一标识表行。Supplemental Log也是记录在在线Redo日志中,所以启用Supplemental Log会加快在线Redo日志的填充。

Supplemental Log可以在数据库级别启动,在数据库级别启动Minimal Logging会记录操作的足够信息,通常在主数据库创建Minimal Logging已经足够使用。数据库级别Supplemental Log补充日志还能针对所有字段、主键字段、唯一字段和外键字段创建。另外也可以在表级别设置Supplemental Log,这叫做Identification Key Logging,不同类型的Supplemental Log会产生不同大小的日志记录。

执行以下的SQL启用或禁用数据库级别Minimal Logging:
ALTER DATABASE ADD|DROP SUPPLEMENTAL LOG DATA;

针对逻辑Standby数据库记录的日志信息有以下规则:
1).如果一个表有主键被定义,那么主键被记录作为UPDATE语句的一部分去标识修改的行。
2).如果主键不存在,最短的非空唯一约束、唯一索引被记录作为UPDATE语句的一部分标识修改的行。
3).在主键和非空唯一约束/索引都没有的情况下,所有的列被记录,作为UPDATE语句的一部分标识修改的行。换句话说,除了LONG、LOB、LONG RAW、对象类型和集合类型的字段,所有字段都将被记录。
4).一个函数索引,即使它是被定义为唯一的,也不能用于唯一标识修改的行。然而,只要修改的行能被唯一标识,逻辑Standby数据库支持函数索引表的同步。

Oracle推荐在主数据库尽可能的给表添加主键或者非空唯一索引,确保SQL Apply能有效的应用Redo数据更新逻辑Standby数据库。

下面通过实验来讨论Oracle补充日志的语法及类型:

C:\Users\LIUBINGLIN>sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on 星期六 3月 15 20:27:28 2014

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> col supplemental_log_data_fk format a30
SQL> col supplemental_log_data_all format a30
SQL> col supplemental_log_data_min format a30
SQL> set linesize 200
SQL> select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            NO

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

数据库已更改。

SQL>  select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            YES

SQL> ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;

数据库已更改。

SQL>  select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            NO

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (FOREIGN KEY) COLUMNS;

数据库已更改。

SQL>  select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
YES                            NO                            IMPLICIT
SUPPLEMENTAL_LOG_DATA_FK=YES表示启动了外键补充日志。

SQL> ALTER DATABASE DROP SUPPLEMENTAL LOG DATA (FOREIGN KEY) COLUMNS;

数据库已更改。

SQL>  select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            NO

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (UNIQUE) COLUMNS;

数据库已更改。

SQL>  select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            IMPLICIT

SQL> ALTER DATABASE DROP SUPPLEMENTAL LOG DATA (UNIQUE) COLUMNS;

数据库已更改。

SQL>  select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            NO

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;

数据库已更改。

SQL>  select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            IMPLICIT

IMPLICIT - Minimal supplemental logging is enabled because all or a combination of primary key, unique key, and foreign key supplemental logging is enabled.
YES - Minimal supplemental logging is enabled through an ALTER DATABASE ADD SUPPLEMENTAL LOG DATA statement.

    SUPPLEMENTAL_LOG_DATA_MIN=YES和IMPLICIT都表示数据库启动了最小化的补充日志。YES表示通过ALTER DATABASE ADD SUPPLEMENTAL LOG DATA语句启动的最小化补充日志;如果启动了对主键、唯一键、外键、ALL的补充日志,默认情况下都会打开最小化的补充日志,IMPLICIT表示的是通过启动对主键、唯一键、外键或者ALL的支持而打开的最小化补充日志。

SQL> select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            NO

下面是ALTER DATABASE ADD SUPPLEMENTAL LOG DATA的语法:


SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE,FOREIGN KEY) COLUMNS;

数据库已更改。

多种类型的补充日志可以一起设置。

SQL> select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
YES                            NO                            IMPLICIT

SQL> ALTER DATABASE DROP SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE,FOREIGN KEY) COLUMNS;

数据库已更改。

SQL> select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            NO                            NO

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;

数据库已更改。

SQL> select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
NO                            YES                            IMPLICIT

打开ALL类型的补充日志不包含外键补充日志,ALL表示的是ALL COLUMN。

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (FOREIGN KEY) COLUMNS;

数据库已更改。

SQL> select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
YES                            YES                            IMPLICIT

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

数据库已更改。

SQL> select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUPPLEMENTAL_LOG_DATA_FK      SUPPLEMENTAL_LOG_DATA_ALL      SUPPLEMENTAL_LOG_DATA_MIN
------------------------------ ------------------------------ ------------------------------
YES                            YES                            YES

以上的查询结果表示打开了所有类型的补充日志。

由此实验我们可以得出,Oracle数据库补充日志分为:最小化补充日志,主键补充日志,外键补充日志,唯一键补充日志,ALL类型的补充日志。

执行ALTER DATABASE SQL语句打开数据库补充日志后,告警日志会显示补充日志打开的情况:
SUPLOG: Commencing to rollback failed DDL at scn = 13732025618576
SUPLOG:  minimal = ON, primary key = OFF
SUPLOG:  unique = OFF, foreign key = OFF, all column = OFF

参考文章:
http://www.askmaclean.com/archives/oracle-supplemental-%E8%A1%A5%E5%85%A8%E6%97%A5%E5%BF%97%E4%BB%8B%E7%BB%8D.html

另外,还需要说明一点的是如果对非常繁忙的数据库启动补充日志可能会带来性能问题和出现Hang住的情况,下面通过一篇metalink文章来说明该问题:

Alter Database Add Supplemental Log Data Hangs (文档 ID 406498.1)
修改时间:2013-2-6    类型:PROBLEM


In this Document

 Symptoms 
 Changes 
 Cause 
 Solution 
 References 

--------------------------------------------------------------------------------

 


APPLIES TO:
Oracle Database - Enterprise Edition - Version 10.2.0.1 and later
Information in this document applies to any platform.

SYMPTOMS
As part of the Streams setup you can specify supplemental logging at the database level.

It can be done manually:

 

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;
 

 or implicitly running procedures like DBMS_STREAMS_ADM.ADD_SCHEMA_RULES

or if you setup Streams using Grid Control it is automatically executed by SrcSchemaRule1 Stage Step 12.

In some cases, this step hangs and the statement ALTER DATABASE ADD SUPPLEMENTAL LOG DATA remains waiting for TX lock in shared mode.

CHANGES

CAUSE
The statement ALTER DATABASE ADD SUPPLEMENTAL LOG DATA  is waiting for TX lock in shared mode when there is any uncommitted transaction. This is the expected behavior.

You can issue ALTER DATABASE ADD SUPPLEMENTAL LOG DATA when the database is open. However, OracleDatabase will invalidate all DML cursors in the cursor cache, which will have an effect on performance until the cache is repopulated. Besides,we also need to wait for the completion of all the in-flight transaction so that any redo generated after this DDL would have the right supplemental logging attributes. 

SOLUTION
You need to wait for the completion of all the in-flight transaction.

In those databases with high activity where there are always active transactions the supplemental logging can be enabled by bouncing the database and running the statement manually:

STARTUP MOUNT
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
ALTER DATABASE OPEN;
  在启动数据库补充日志的时候,会使得所有缓存的游标变得无效,突如其来的大量硬解析将对数据库的性能带来影响。启动数据库补充日志将等待当前所有的事务结束,使得该操作之后记录的所有Redo数据都有补充日志的属性,如果数据库有长事务或事务过于频繁将导致该操作出现Hang住的情况,由此可见启动数据库的补充日志应尽量避开数据库高峰期。

--end--

国内企业级Linux系统市场调查CentOS
Fedora
Debian
Ubuntu
SUSE Linux
RedHat Enterprise Linux
   

相关内容