关于Oracle中supplemental log的补充说明

在上一篇关于Oracle补全日志的介绍中漏写了关于最小补全日志(minimal supplemental log)与表级补全日志的关系;表级补全日志需要在最小补全日志打开的情况下才起作用,即若一个数据库没有开最小补全日志或之前drop supplemental log data操作则即便指定了表级补全日志,实际在重做日志输出的过程中描述的记录仍只记录rowid和相关列值。

打开最小补全日志的命令如下:

在上一篇关于Oracle补全日志的介绍中漏写了关于最小补全日志(minimal supplemental log)与表级补全日志的关系;表级补全日志需要在最小补全日志打开的情况下才起作用,即若一个数据库没有开最小补全日志或之前drop supplemental log data操作则即便指定了表级补全日志,实际在重做日志输出的过程中描述的记录仍只记录rowid和相关列值。

打开最小补全日志的命令如下:

Alter database add supplemental log data;

其次若如之前叙述的因表上的列数过多(超过200个),则应检查视图 dba_logstdby_not_unique, 该视图记录了在数据库中没有主键或没有唯一索引并且列非空的索引(tables in the primary database that do not have a primary key or unique index with NOT NULL columns)的表。如使用以下SQL:

select owner, table_name, bad_column

from dba_logstdby_not_unique

where table_name not in

(select table_name from dba_logstdby_unsupported);

TSMSYS    SRS$    Y
HTEST    TEST    N
HGET    GETMAXID    N
HGET    HUSER    N
SCOTT    BONUS    N
SCOTT    SALGRADE    N

其中bad_column列较为关键。若该字段为 Y,表示一个表列被使用大数据类型定义,例如CLOB或BLOB。sql apply尝试维护这些表,但是你必须要保证表中除这列外的其他列的单值性。就是说,注意,如果一个表中有两行除了LOB列外,其他的值完全相同,这样表 的改动就不能被逻辑备用数据库应用,sql apply会停止。N,表示表中包含足够的列信息,需要用来在逻辑备用数据库中维护表的。

针对前文叙述的在表上列较多的情况下(超过200个列),且不能添加主键和唯一非空索引的表,我们需要特别关注。但实际如果我们想了解一个段在一定段内产生的重做量却十分困难。(method :check  how much redo generated by one segment)

已知的研究方法例如logmnr工具,和dump redologs以及oradebug都无法提供足够的信息帮助统计。

仅有的方法是通过logmnr估算,v$logmnr_contents视图中记录的rbablk与rbabyte,为重做日志中的块偏移量(redo log中512byte为一个快)与字节偏移量,通过计算差值结合data_obj#列,可以大致估算某个段上一定时间内的重做量:

create table redo_analysis nologging as

select data_obj#,  oper, rbablk*512 + rbabyte curpos,

lead(rbablk*512+rbabyte,1,0) over (order by  rbasqn, rbablk, rbabyte)

nextpos

from

( select distinct data_obj#,  operation oper,

rbasqn, rbablk, rbabyte from v$logmnr_contents

order by rbasqn, rbablk, rbabyte );

select data_obj#, oper, obj_name, sum(redosize) total_redo

from

(

select data_obj#, oper, obj.name obj_name , nextpos-curpos-1 redosize

from redo_analysis redo1, sys.obj$ obj

where (redo1.data_obj# = obj.obj# or  redo1.data_obj# = obj.dataobj#)

and  nextpos !=0 — For the boundary condition

union all

select data_obj#, oper, ‘internal ‘ , nextpos-curpos  redosize

from redo_analysis redo1

where  redo1.data_obj#=0 and  redo1.data_obj# = 0

and nextpos!=0

)

group by data_obj#, oper, obj_name

order by 4

以上估算并不准确,在有手动切换(switch logfile)日志及其他特殊情况时误差较大。

Comments

  1. 手工切换时不准确,可以举个例子吗?

    谢谢

    • maclean says

      因为以上脚本是通过 计算重做日志中的块偏移量的差值来估算 redo量的, 如果发生过日志是手工切换的,那么这个日志里的内容可能很少或者几乎没有,但是仍会以整个redo log的size 来估算redo量。

Comment

*

沪ICP备14014813号-2

沪公网安备 31010802001379号