oracle scn跳变是什么意思,Oracle block scn什么时候发生变化

我们知道block scn存在 block头中,其具体位置在block offset 8-13中,即占用6个字节。

用bbed查看,可以看到scn处于kcbh结构体中,其中offset 8-11属于scn的低8位,offfset 12-13属于scn的高4位。

struct kcbh, 20 bytes                      @0

ub1 type_kcbh                           @0

ub1 frmt_kcbh                           @1

ub1 spare1_kcbh                         @2

ub1 spare2_kcbh                         @3

ub4 rdba_kcbh                           @4

ub4 bas_kcbh                            @8           ub2 wrp_kcbh                            @12         ub1 seq_kcbh                            @14          ub1 flg_kcbh                            @15          ub2 chkval_kcbh                         @16          ub2 spare3_kcbh                         @18 那我们不禁有个疑问?此scn是什么时候产生的呢?是该block发生变化时,还是该block从buffer_cache刷到数据文件时产生的呢? 我们先做简要分析 假设会话开始于scn 1000,block scn记录的是block变化时scn (1)不论引起该block变化的事务提交与否,当block scn大于1000时,那么会话将读取该block后,为保证事务一致性会话将读取undo block(即consistent read)。 (2)不论引起该block变化的事务提交与否,当block scn小于1000时,那么会话将读取该block后,如果事务已提交,将直接读取结果。如果事务未提交,那再次读取undo block,构造一致性block。 采用此方法,当有多并发事务时,原理相似,并不会导致事务不一致。 如果block scn记录的是内存刷到数据文件时的current scn,那会有什么样的后果? 假设block变化scn为1500。block scn记录的是从block从buffer_cache刷到数据文件时产生,其scn为2000并已记录在block head中,且此block已不在内存中。 假设会话开始于scn 1600,当已引起该block变化的事务已提交,从事务一致性角度来讲,将直接读取block(即current read),但由于block head记录为scn 2000, 1600<2000,又满足consistent read条件(一直读到scn<1600,且事务已提交的scn为止),这样又会引起事务不一致。 经过以上分析,我们得出以下结论,block head记录的是该引起该block变化时的scn。 下面通过实验来解答上述结论。以下测试来自测试环境,数据库极少事务变化量。 首先查看表格zhoul在数据库的存放位置,由以下查询可知zhoul表格数据存放在7号文件block号为15511的数据块中。 SQL> col file# for 999 SQL> col block# for 99999 SQL> set linesize 300 SQL> select  dbms_rowid.ROWID_RELATIVE_FNO(rowid) file#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#,i,name from zhoul; FILE# BLOCK#          I NAME ----- ------ ---------- --------------------     7  15511          1 aaa     7  15511          2 bbb     7  15511          3 ccc 为了获得比较干净的测试环境,首先切换一个归档日志,这样可以将其他事务的变化条目排除在这个online redolog之外。 SQL> alter system switch logfile; System altered. SQL> select * from zhoul;          I NAME ---------- --------------------          1 uuu          2 bbb          3 ccc 在内存中修改表格zhoul数据,注意将字段i=1修改成系统最新的scn值,并进行提交。这样该数据文件头在buffer_cache存储的scn将会比10995251185389略大 但应该会比10995251185563小。 SQL>  update zhoul set i=(select current_scn scn from v$database) where i=1; 1 row updated. SQL> commit; Commit complete. SQL> col i for 999999999999999999 SQL> select * from zhoul;                   I NAME ------------------- --------------------      10995251185389 uuu                   2 bbb                   3 ccc SQL> select current_scn i from v$database;                   I -------------------      10995251185563 打开statistic跟踪,可以看到全部为8个consistent gets,也就意味着15511号还在buffer_cache中。 SQL> set autot traceonly stat SQL> select * from zhoul; Statistics ----------------------------------------------------------           0  recursive calls           0  db block gets           8  consistent gets           0  physical reads           0  redo size         523  bytes sent via SQL*Net to client         400  bytes received via SQL*Net from client           2  SQL*Net roundtrips to/from client           0  sorts (memory)           0  sorts (disk)           3  rows processed 现在将buffer_cache中数据块刷出至数据文件中。 SQL> alter system flush buffer_cache; System altered. 获得包含此事务的online redolog SQL> set autot off      SQL> select member from v$log a,v$logfile b where a.group#=b.group# and a.status='CURRENT'; MEMBER -------------------------------------------------------------------------------- /oradata/mcstar/redo01.log 将redo01.log dump出来,由于本文只研究数据块写出操作,固只需dump layer为23,opcode为1的change。 SQL> alter system dump logfile '/oradata/mcstar/redo01.log' layer 23 opcode 1; System altered. 打开跟踪文件可以看到,其scn为 0x0a00.080a86ef,此值和bbed结果一致。 CHANGE #1 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ:  0 OP:23.1 Block Written - afn: 7 rdba: 0x01c03c97 BFT:(1024,29375639) non-BFT:(7,15511)                    scn: 0x0a00.080a86ef seq: 0x03 flg:0x06                                       BBED> dump block 15511 offset 0 count 20 File: /oradata/mcstar/zhoul01.dbf (0) Block: 15511            Offsets:    0 to   19           Dba:0x00000000 ------------------------------------------------------------------------ 06a20000 973cc001 ef860a08 000a0306 3f130000 进一步将0x0a00.080a86ef转换成10进制之后为10995251185391,此值比10995251185389略大,但小于10995251185563,也就证明了我们的猜想: block head的scn记录的是该block改变时的scn,并非从buffer_cache时刷出的scn。 SQL> col scn for 999999999999999 SQL> select to_number('0a00080a86ef','xxxxxxxxxxxx') scn from dual;              SCN ----------------   10995251185391

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值