Oracle中的补充日志(supplemental log)
Posted 太古丶凶兽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle中的补充日志(supplemental log)相关的知识,希望对你有一定的参考价值。
原网址:http://sugarlovecxq.blog.51cto.com/6707742/1693092
在配置DG的时候,有涉及到补充日志的知识,故做以整理。
补充日志不是独立的一种日志,是对重做记录中变更矢量的补充信息,增加了变更矢量记载的记录量,Oracle数据库某些功能要求启用补充日志才能正常地或更好的工作,如logminer、DG、闪回事务查询、闪回事务。
Oracle中insert、delete命令在默认情况下产生的重做记录足以表明被修改的行的每个字段在被修改前后的值是什么,insert,变更前行不存在,产生的重做记录会记载新行的每个字段的值,delete,变更后不存在,但是由于重做记录也要负责产生撤销数据块的变更,所以行被删除之前的各字段的值也记录在撤销数据块的变更矢量中,也就是insert和delete命令的重做记录中,能找到整行的所有信息。
但是update不同于insert和delete一定会涉及一行的所有字段,常常只是更改一个或几个字段,处于对性能的考虑,Oracle没必要把修改的字段的值也保存在变更矢量中,事实上是在撤销块的比昂矢量中只记载被修改的字段的更改前的值,而在数据块的变更矢量中则记载了被修改的字段的新值,同一行中其他没有被修改的字段,不会记载其修改前的值,因为没有被修改。
如:update scott.emp set sal=12000 where empno=7369 ;
为了支持实例恢复和介质恢复,其重做记录只需要记载sal字段的值为12000即可,在常规的重做记录中完全不会出现empno为7369的信息
Insert、delete、update的常规重做记录具体记载何种信息是以保证实例恢复与介质恢复能够正常进行为标准的,不相关的信息不会记录在重做日志中。正是因为有撤销数据块的变更矢量,所以保证实例恢复与介质恢复也简介地保证了回滚操作可以被执行。
如果启用了补充日志,数据块的变更矢量的记载可以变为; sal字段的值为12000,并且再额外的记录该行被修改之前第一个字段empno的值是7369以及sal为800(修改之前的值),更多的信息意味着update命令被等价还原的可能性提高了,数据的恢复性提高
补充日志主要就是为update服务,补充的目的就是要高度还原真实的update命令。
补充日志可以在数据库级别和表级别上启用
supplemental log可以在数据库级别启动,在数据库级别启动minimal logging会记录操作的足够信息,通常逻辑standby数据库创建minimal logging已经足够使用。数据库supplemental log补充日志还能针对所有字段、主键字段、唯一字段和外键字段创建。也可以设置表级别设置supplemental log,称为identification key logging,不同类型的supplemental log会产生不同大小的日志记录。
针对逻辑standby数据库记录的日志信息有以下规则:
如果一个表有主键被定义,那么主键被记录作为update语句的一部分来标识修改的行
如果主键不存在,最短的非空约束、唯一索引被记录作为update语句的一部分来标识修改的行在主键和非空约束/索引都没有的情况下,所有的列被记录,作为update语句的一部分来标识修改的行,也就是除了long,lob,longg raw,对象类型和集合类型的字段,所有字段都将被记录一个函数索引,即使它被定义为唯一的,也不能用于唯一标识修改的行,只要修改的行能被唯一标识,逻辑standby数据库支持函数索引表的同步
推荐主数据库尽可能给表添加主键或者非空唯一索引,确保sql apply能有效应用redo数据来更新逻辑standby数据库。
查找数据库中没有唯一逻辑标识的表
1
2
3
4
5
|
select owner, table_name from dba_logstdby_not_unique where (owner, table_name) not in ( select distinct owner, table_name from dba_logstdby_unsupported) and bad_column = ‘Y‘ ; |
添加禁用主键rely的约束
如果能确保应用在表中的行为是唯一的,在表上创建禁用主键rely约束,这能避免维护
主数据库主键的开销在主数据库表上使用alter table语句的relay disable子句创建禁用主键rely约束,表test有两列ID、name,以下sql在test表创建禁用rely约束
alter table test add primary key (id,name) rely disable ;
当明确指定了rely约束,系统将嘉定行能通过指定字段标识唯一性
为了提高sql apply的性能,在表的字段上添加唯一的约束/索引,确保逻辑standby数据库维护的表都能唯一标识行,如果没添加唯一的约束/索引,当通过sql apply在表上执行update或者delete语句期间会全表扫描,会降低性能。
查看当前数据库中补充日志状态:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
SQL> select * from v$version ; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production PL/SQL Release 11.2.0.3.0 - Production CORE 11.2.0.3.0 Production TNS for Linux: Version 11.2.0.3.0 - Production NLSRTL Version 11.2.0.3.0 - Production SQL> 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 "all" from v$ database ; 2 3 4 5 6 MIN PK UI FK all -------- --- --- --- --- NO NO NO NO NO |
可以看到,补充日志的类型有:最小补充日志、标识关键字段补充日志两大类
1.最小补充日志
最小补充日志是最基本的一种数据库级补充日志,
启用最小补充日志
1
2
3
4
5
6
7
8
9
|
SQL> alter database add supplemental log data ; Database altered. SQL> select supplemental_log_data_min min from v$ database ; MIN -------- YES |
关闭最小补充日志
1
2
3
4
5
6
7
8
9
|
SQL> alter database drop supplemental log data ; Database altered. SQL> select supplemental_log_data_min min from v$ database ; MIN -------- NO |
需要注意的是,凡是启用或者关闭数据库级补充日志(包括最小补充日志和另外几种日志)都会导致共享池中所有SQL命令游标非法,也就是短期之内应解析会显著上升。
2.标识关键字段补充日志
标识关键字段补充日志有四种:主键、唯一索引、外键、全体字段补充日志
2.1主键补充日志
主键补充日志的作用是在update命令的重做记录中添加被修改行的主键字段的旧值,这是无条件式的补充日志,所谓无条件即无论主键字段本身是否被update命令修改,其旧值都会被记录。但是,不能保证每张表一定有主键。如果存在没有主键的表,则主键字段由长度最小的非空唯一索引字段代替。如果表结构中一个非空索引字段都没有,那么oracle将:将被修改行的所有字段(除了lob和long类型)的旧值都记录下来,这将导致重做记录的数据量暴涨,所以如果要启用主键补充日志,又为了维护lgwr和重做日志,每张表最好具有主键或至少一个非空唯一字段。
启用主键补充日志:
1
2
3
4
5
6
7
8
9
|
SQL> alter database add supplemental log data ( primary key ) columns ; Database altered. SQL> select supplemental_log_data_pk as pk from v$ database ; PK --- YES |
标识关键字段补充日志(包括主键补充日志)必须建立在最小补充日志的基础上,当其被启用时,若最小补充日志尚未启用,则oracle会隐式开启最小补充日志 状态为IMPLICIT
同样在没有关闭标识关键字段补充日志的时候,不能先关闭最小补充日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
SQL> 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 "all" from v$ database ; 2 3 4 5 6 MIN PK UI FK all -------- --- --- --- --- IMPLICIT YES NO NO NO SQL> alter database drop supplemental log data ; alter database drop supplemental log data * ERROR at line 1: ORA-32589: unable to drop minimal supplemental logging |
2.2唯一索引补充日志
只有当唯一字段被update时,才会记录该字段被修改前的值,因为唯一键索引是能够建立在多个字段上的
如:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
SQL> create unique index name_idx on hr.employees(first_name,last_name); Index created. SQL> alter database add supplemental log data ( unique ) columns ; Database altered. SQL> select supplemental_log_data_ui ui from v$ database ; UI --- YES |
update 命令现在更新first_name,常规日志会只记载first_name字段的旧值,而唯一键索引将会记录first_name和last_name,所以这种补充日志完全可以说是为复合字段唯一索引服务的
2.3外键补充日志
外键补充日志和唯一索引补充日志一样同为有条件式的,只有当外键字段被update命令
修改时,其修改前的旧值才会被记录。所以这种补充日志完全是为复合字段外键服务的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SQL> alter database add supplemental log data ( foreign key ) columns ; Database altered. SQL> 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 "all" from v$ database ; 2 3 4 5 6 MIN PK UI FK all -------- --- --- --- --- IMPLICIT YES YES YES NO |
2.4全体字段补充日志
全体字段补充日志和主键补充日志一样为无条件式的,无论哪个字段被update命令修改,所有字段(除了lob,long类型)的旧值都将被记录,其效果相当于启用了主键补充日志的前提下既没有主键也没有非空唯一索引字段的情况,这样几乎所有的表数据都搬到了重做日志中,不但存在当前的,历史数据也没有丢下。对恢复操作来说比较好,但是对于lgwr和磁盘空间就不是太好,一般很少启用这样的日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SQL> alter database add supplemental log data ( all ) columns; Database altered. SQL> 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 "all" from v$ database ; 2 3 4 5 6 MIN PK UI FK all -------- --- --- --- --- IMPLICIT YES YES YES YES |
数据库级的补充日志,共同点是启用和关闭导致所有SQL游标非法
无论需要启用哪一种标识关键字段补充日志,都需要启用最小补充日志,4种标识关键字段的效果可以累加,不冲突。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
SQL> alter database drop supplemental log data ( primary key , unique , foreign key , all ) columns ; Database altered. SQL> 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 "all" from v$ database ; 2 3 4 5 6 MIN PK UI FK all -------- --- --- --- --- NO NO NO NO NO SQL> alter database add supplemental log data ( primary key , unique , foreign key , all ) columns ; Database altered. SQL> 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 "all" from v$ database ; 2 3 4 5 6 MIN PK UI FK all -------- --- --- --- --- YES YES YES YES YES |
表级补充日志
只是针对某个表,没有必要在整个数据库范围启用补充日志功能,在启用表级补充日志之前,应该先启用数据库级最小补充日志
表级补充日志分为主键、唯一索引、外键、全字段和自定义5种类型,前四种和数据级对应的类型特点一致,只是在特定的表上启用。
如:
alter table scott.emp add supplemental log data (primary key) columns ;
alter table scott.emp add supplemental log data (unique) columns ;
alter table scott.emp add supplemental log data (foreign key) columns ;
alter table scott.emp add supplemental log data (all) columns ;
自定义字段是表级补充日志特有的功能,用户可以任意指定那些字段的旧值需要被补充记录。
alter table hr.employees add supplemental log group emp_info (first_name,last_name,email) ;
以上将first_name,last_name,email字段指派为一个名为empinfo的日志组,意思就是只要update命令修改了这3个字段中的任意一个,重做记录必须记载全部3个字段的旧值这称为有条件式的,无条件式的要加关键字always
alter table hr.employees add supplemental log group emp_info (first_name,last_name,email) always ;
表级补充日志的情况可以查询dba_log_groups和dba_log_grup_columns
1
2
3
4
5
6
7
8
9
10
11
|
select g.log_group_name name , g.owner || ‘.‘ || g.table_name table_name, g.always, g.generated, c.column_name from dba_log_groups g, dba_log_group_columns c where g.log_group_name = c.log_group_name(+) and g.table_name = c.table_name(+) and g.table_name = ‘EMPLOYEES‘ and g.owner = ‘HR‘ order by 1, 2, 3, 4; |
特定表上的表级补充日志的启用与关闭会导致所有引用该表的SQL游标非法,会引起一段时间的硬分析增加。
补充日志主要为update服务,额外记录指定字段的旧值,使得有能力分析重做日志的工具可以高度还原update命令,由于额外记录了字段的旧值,也能将其看成一种特殊的备份。
本文出自 “相守姑娘说” 博客,请务必保留此出处http://sugarlovecxq.blog.51cto.com/6707742/1693092
以上是关于Oracle中的补充日志(supplemental log)的主要内容,如果未能解决你的问题,请参考以下文章