第3章 补充日志(Supplemental Logging)
补充日志不是一种独立的日志,而是对重做记录中变更矢量的补充信息。LogMiner、闪回事务查询、闪回事务等功能要求启用补充日志。
补充日志是为update服务的,高度真实还原update命令
功能介绍
对于insert命令,重做记录会记录新增记录的所有字段。
对于delete命令,撤销段会记录删除前的所有字段,该信息由重做记录生成,也就是undo信息的重做记录。
不管是insert还是delete命令,重做记录中都记录了整行的所有信息,而update命令,重做记录只记录被修改字段的旧值(undo中)和新值(redo中),没有被修改的字段值不会被记录。以如下update命令为例
update hr.employees set salary=28000 where employee_id=100;
没有启用补充日志时重做记录为:5号数据块207号块中的第1行的第8个字段的值被修改为28000,不会出现employee_id=100这个信息。
启用补充日志后重做记录为:5号数据块207号块中的第1行的第8个字段的值被修改为28000,被修改前第1个字段(employee_id)的值时100,第8个字段的值时24000。
数据库级补充日志
索引组织表中,又是update命令会导致整行被转移到另一个索引块中,这叫行移动。
堆栈表中,如果update命令导致行变长,原来的数据块不能存放下时,行的部分(不包括行头)会迁移到另一个数据块中,行头仍保存在原来的数据块中,这叫行迁移。
- 最小补充日志
- 不会对重做记录产生明显的额外开销,支持LogMiner、闪回事务查询
- 主键补充日志(无条件)
- 重做记录中增加被修改行的主键字段的旧值,不管是否被修改都会记录
- 如果表没有主键,则由长度最小的非空唯一索引字段代替
- 如果上面两个都没有,则由所有字段(LOB和LONG除外)代替(每个表最好都有主键或者非空唯一索引字段)
- 唯一索引补充日志(有条件)
- 为复合字段唯一索引服务
- 假如在first_name和last_name上创建了一个唯一索引,只修改first_name时,会将first_name和last_name的值都记录下来
- 外键补充日志(有条件)
- 为复合字段外键服务
- 全体字段补充日志(无条件)
- 相当于启用逐渐补充日志的情况下既没有主键,也没有非空唯一索引字段。对LGWR和磁盘空间开销非常大,慎用。
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;
#启用最小补充日志
alter database add supplemental log data;
#启用主键补充日志 (会自动开启最小补充日志,并且不允许关闭最小补充日志)
alter database add supplemental log data (primary key) columns;
#启用唯一索引补充日志 (会自动开启最小补充日志,并且不允许关闭最小补充日志)
alter database add supplemental log data (unique) columns;
#启用外键补充日志 (会自动开启最小补充日志,并且不允许关闭最小补充日志)
alter database add supplemental log data (foreign key) columns;
#启用全体字段补充日志 (会自动开启最小补充日志,并且不允许关闭最小补充日志)
alter database add supplemental log data (all) columns;
#关闭最小补充日志
alter database drop supplemental log data;
表库级补充日志
启用标记补充日志前提:必须启用数据库级最小补充日志,分为主键、唯一索引、外键、全字段和自定义字段5种类型,前4中与数据库级的特性相同,只是在特定表上启用。
#启用表级主键补充日志
alter table hr.employees add supplemental log data (primary key) columns;
#启用表级唯一索引补充日志
alter table hr.employees add supplemental log data (unique) columns;
#启用表级外键补充日志
alter table hr.employees add supplemental log data (foreign key) columns;
#启用表级全体字段补充日志
alter table hr.employees add supplemental log data (all) columns;
#启用表级自定义字段补充日志(有条件) 仅当first_name或last_name被修改,重做记录才记录这两个字段的旧值
alter table hr.employees add supplemental log group emp_info (first_name,last_name);
#启用表级自定义字段补充日志(无条件) 表的任意字段被修改,重做记录都会记录这两个字段的旧值
alter table hr.employees add supplemental log group emp_info (first_name,last_name) always;