supplemental log补充日志不是独立的日志,而是对重做日志的少量补充。
LogMiner、闪回事务、闪回事务查询、逻辑standby、streams、GoldenGate等功能或工具需要开启补充日志才能正常工作。
补充日志分为:数据库级补充日志、 表级补充日志,可在【数据库】和【表】两种级别进行设置。
■■数据库级设置,分两类
■最小附加日志(minimal supplemental logging)
使用DATA选项,启用最小附加日志,语法如下
alter database {add|drop} supplemental log data;
启用最小日志可以确保LogMiner(或其他任何基于LogMiner的产品)可以支持行链接、簇表、索引组织表等。
■标识键日志(identification key logging)
使用DATA(all,primary key,unique,foreign key) columns选项,启用最小日志及列数据日志,语法如下:
alter database {add|drop} supplemental log {data(all,primary key,unique,foreign key) columns};
如:alter database add supplemental log data (foreign key) columns;
在源库日志为变化来源同步其他数据库的情况下,比如逻辑备用数据库,受影响的数据行必须以列数据标识(而不是rowid),必须启用此种附加日志。
■查询当前设置
缺省情况下,Oracle不启用以上任何附加日志。当使用ALL,PRIMARY,UNIQUE或FOREIGN附加日志时,最小补全日志默认开启(即检查结果为IMPLICIT)。 在删除所有导致IMPLICIT最小化附加日志的附加日志后,最小化附加日志变为NO。
SELECT supplemental_log_data_min min, supplemental_log_data_pk pk, supplemental_log_data_ui ui, supplemental_log_data_fk fk, supplemental_log_data_all allc FROM v$database; MIN PK UI FK ALL -------- --- --- --- --- NO NO NO NO NO
■■表级设置,分两类
■通过以下语句设置命名日志组
alter table table_name
add supplemental log group group_a(column_a [no log],column_b,...) [always];
NO LOG选项用于指定在日志中排除哪些列。
在命名日志组中,至少存在一个无“NO LOG”的定长列。比如,对LONG列使用no log选项,可以在更改LONG列时,记录其他列的内容(LONG列本身不能存在日志里)。
ALWAYS选项, 在更新时,日志组中的所有列都会记录在日志中。
这就是所谓的“无条件”日志组,有时也叫“always log group”。如果不指定该选项,只有在日志组中的任何列被修改时,所有列才会出现在日志中。这就是所谓的“有条件”日志组。
说明:同一列可以在多个日志组中存在,但日志中只记录一次;同一列在“无条件”与“有条件”日志组中存在时,该列将“无条件”记录。
■通过以下语句设置所有列或主键/外键/唯一键组合日志组
alter table table_name
add supplemental log data(all,primary key,unique,foreign key) columns;
Oracle将生成无条件或有条件日志组。对于无条件日志组,日志中将记录该日志组中的所有列;对于有条件日志组,只有日志组中的列有变化时,才会记录日志组中的所有列。
如果指定“ALL”列,日志中将包含所有最大大小固定长度的列。这种日志是系统创建的无条件日志组。
如果指定“PRIMARY KEY”列,只要有更新,组成主键的所有列都会记录在日志中。这种日志是系统创建的无条件日志组。
Oracle使用如下顺序确定附加记录哪些列:
*组成主键的列(主键有效,或rely且非DISABLED or INITIALLY DEFERRED状态)
*最小的、至少有一个非空列的唯一索引
*记录所有标量列
如果指定“UNIQUE”列,如果任何组成唯一键或位图索引的列被修改,组成该唯一键或位图索引的其他列都会记录在日志中。这种日志是系统创建的有条件日志组。
如果指定“FOREIGN KEY”列,如果任何组成外键的列被修改,组成该外键的其他列都会记录在日志中。这种日志是系统创建的有条件日志组。
■表级测试
drop table test; create table test(x int,y int); --增加附加日志 alter table test add supplemental log data(all,primary key,unique,foreign key) columns; select * from dba_log_groups; OWNER LOG_GROUP_NAME TABLE_NAME LOG_GROUP_TYPE ALWAYS GENERATED ------- ---------------- ----------- --------------------- ----------- -------------- SYS SYS_C0098739 TEST ALL COLUMN LOGGING ALWAYS GENERATED NAME SYS SYS_C0098740 TEST PRIMARY KEY LOGGING ALWAYS GENERATED NAME SYS SYS_C0098741 TEST UNIQUE KEY LOGGING CONDITIONAL GENERATED NAME SYS SYS_C0098742 TEST FOREIGN KEY LOGGING CONDITIONAL GENERATED NAME select * from dba_log_group_columns; no row selected --删除附加日志 alter table test drop supplemental log data(all,primary key,unique,foreign key) columns; select * from dba_log_groups; no row selected select * from dba_log_group_columns; no row selected --增加命名附加日志 alter table test add supplemental log group group_a(x,y); select * from dba_log_groups; OWNER LOG_GROUP_NAME TABLE_NAME LOG_GROUP_TYPE ALWAYS GENERATED ------- ---------------- ----------- ---------------------- ----------- -------------- SYS GROUP_A TEST USER LOG GROUP CONDITIONAL USER NAME select * from dba_log_group_columns; OWNER LOG_GROUP_NAME TABLE_NAME COLUMN_NAME POSITION LOGGIN ------- ---------------- ----------- -------------------- --------------- ------ SYS GROUP_A TEST X 1 LOG SYS GROUP_A TEST Y 2 LOG alter table test drop supplemental log group group_a;
■■性能影响评估
在启动数据库补充日志的时候,会使得所有缓存的游标变得无效,突如其来的大量硬解析将对数据库的性能带来影响。启动数据库补充日志将等待当前所有的事务结束,使得该操作之后记录的所有Redo数据都有补充日志的属性,如果数据库有长事务或事务过于频繁将导致该操作出现Hang住的情况,由此可见启动数据库的补充日志应尽量避开数据库高峰期。
也就是说,只有在业务高峰期执行开启补充日志操作时,会短时间/暂时影响数据库性能,开启操作完成后,数据库会逐渐恢复正常性能。如果只是开启数据库级别最小补充日志模式【本次方案】,后续的补充日志对生产的影响更是微乎其微。
由于启动/关闭supplemental log,不需重启数据库,因此可以密切监控数据库性能,万一有其他影响,可立即关闭补充日志。
文章评论
■主键补充日志的作用是在update命令的重做记录中添加被修改行的主键字段的旧值,这是无条件式的补充日志,所谓无条件即无论主键字段本身是否被update命令修改,其旧值都会被记录。但是,不能保证每张表一定有主键。如果存在没有主键的表,则主键字段由长度最小的非空唯一索引字段代替。如果表结构中一个非空索引字段都没有,那么oracle将:将被修改行的所有字段(除了lob和long类型)的旧值都记录下来,这将导致重做记录的数据量暴涨,所以如果要启用主键补充日志,又为了维护lgwr和重做日志,每张表最好具有主键或至少一个非空唯一字段。
■需要注意的是,凡是启用或者关闭数据库级补充日志(包括最小补充日志和另外几种日志)都会导致共享池中所有SQL命令游标非法,也就是短期之内应解析会显著上升。特定表上的表级补充日志的启用与关闭会导致所有引用该表的SQL游标非法,也会引起一段时间的硬分析增加。
■补充日志主要为update服务,额外记录指定字段的旧值,使得有能力分析重做日志的工具可以高度还原update命令,由于额外记录了字段的旧值,也能将其看成一种特殊的备份。
■表级补充日志,只是针对某个表,没有必要在整个数据库范围启用补充日志功能,在启用表级补充日志之前,应该先启用数据库级最小补充日志。