当前位置:首页 > 开发 > 数据库 > 正文

SCN之delayed block cleanout

发表于: 2014-06-07   作者:czmmiao   来源:转载   浏览次数:
摘要:  Block的cache header部分,记录着一个block scn,它是当前块最后一次变更的时间戳(确切说,这个更新并不是指itl上的scn的最新更新,在接下来delayed block cleanout下的slot重用情况下,可以看到block scn并不等于itl上的最后一次更新的scn)。可以通过dump获得block scn/last itl scn 和发布ora_rows

 Block的cache header部分,记录着一个block scn,它是当前块最后一次变更的时间戳(确切说,这个更新并不是指itl上的scn的最新更新,在接下来delayed block cleanout下的slot重用情况下,可以看到block scn并不等于itl上的最后一次更新的scn)。可以通过dump获得block scn/last itl scn 和发布ora_rowscn语句获得last itl scn。

1. SQL> select distinct ora_rowscn,dbms_rowid.rowid_block_number(rowid) from test_ind where dbms_rowid.rowid_block_number(rowid)=31501;
ORA_ROWSCN DBMS_ROWID.ROWID_BLOCK_NUMBER(
———- ——————————
617405 31501

2. SQL> alter system dump datafile 4 block 31501;
Start dump data blocks tsn: 4 file#: 4 minblk 31501 maxblk 31501
buffer tsn: 4 rdba: 0x01007b0d (4/31501)
scn: 0×0000.00096bbd seq: 0×01 flg: 0×02 tail: 0x6bbd0601
frmt: 0×02 chkval: 0×0000 type: 0×06=trans data
――――――――――――――――――――――――――――――――――――――
Itl Xid Uba Flag Lck Scn/Fsc
0×01 0x000a.001.00000089 0x008033be.0046.14 C— 0 scn 0×0000.00065b9e
0×02 0×0008.02b.000000ac 0x00802fea.004a.28 –U- 1 fsc 0×0000.00096bbd

    发布transaction后,未提交之前,block scn是不会改变的,对应的itl中也并不做scn记录。Block scn的改变,确切的说不是在发布commit之时(因为有delayed block cleanout的情况存在),而是在transaction对应的itl获得commit scn之时。

    当发生fast commit cleanout,系统将transaction提交时刻的scn作为commit scn,更新block上 itl和undo segment header的Transaction table的slot上的 scn,并修改block scn,三者是一致的。发生delayed block cleanout的时候,之前的transaction commit更新的只是Transaction table,而并未做block上的处理,等待下次使用此block的时候,更新block scn和itl状态。block scn和itl的更新又分2种情况:
    (1)当不产生undo slot重用的时候, delayed block cleanout时,结合Transaction table里面和undo slot的信息,更新block scn和itl上的Scn/Fsc为transaction曾经提交时候的scn。
    (2)当产生undo slot重用的时候,更新对应itl上scn为control scn,而block scn 为delayed block cleanout发生时刻的scn。

    简单看一下这个测试过程。

(一)fast commit cleanout

1.建表/插入数据

SQL> create table test_scn(see char(500)) pctfree 90 tablespace test_a ;
Table created
SQL> insert into test_scn values(‘see1′);
1 row inserted
SQL> insert into test_scn values(‘see2′);
1 row inserted
SQL> commit;
Commit complete
SQL> select dbms_rowid.rowid_block_number(rowid),ora_rowscn from test_scn;
DBMS_ROWID.ROWID_BLOCK_NUMBER( ORA_ROWSCN
—————————— ———-
25617 622604
25618 622604

2.发布事务更新

SQL> update test_scn set see=’kao’ where see=’see1′;
SQL> select dbms_rowid.rowid_block_number(rowid),ora_rowscn from test_scn;
DBMS_ROWID.ROWID_BLOCK_NUMBER( ORA_ROWSCN
—————————— ———-
25617 622604
25618 622604 ――发现block scn并未改变
SQL>commit;

SQL> select dbms_rowid.rowid_block_number(rowid),ora_rowscn from test_scn;

DBMS_ROWID.ROWID_BLOCK_NUMBER( ORA_ROWSCN
—————————— ———-
25617 622604
25618 622683 ――已经更新

(二) delayed block cleanout

1.创建一个小undo表空间.

SQL> create undo tablespace undo datafile ‘E:\ORACLE\PRODUCT\10.2.0\ORADATA\DEMO\undo.dbf’ size 2M;
Tablespace created
SQL> alter system set undo_tablespace=’undo’;
System altered

2 .发布更新后,清空buffer_cache,创造延时块清除条件,然后提交

SQL> select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid), ora_rowscn,t.* from test_scn t;
DBMS_ROWID.ROWID_BLOCK_NUMBER( DBMS_ROWID.ROWID_RELATIVE_FNO( ORA_ROWSCN SEE
—————————— —————————— ———- ——————–
25617 6 625000 kao1
25618 6 693298 see2
SQL> update test_scn set see=’kao2′ where see=’see2′;
1 row updated
SQL> select XIDUSN,XIDSLOT,XIDSQN from v$transaction;
XIDUSN XIDSLOT XIDSQN
———- ————- —————- —————- —————-
20 33 21 ――得到XIDUSN,XIDSLOT的使用情况,后续发布重用脚本
SQL> alter system flush buffer_cache;
System altered
SQL> commit;
Commit complete
SQL> select timestamp_to_scn(systimestamp) from dual;
TIMESTAMP_TO_SCN(SYSTIMESTAMP)
——————————
693323 —–大概的commit scn

3.发布脚本,使XIDUSN 20 XIDLOT 33 重用。

SQL>exec proc_go_break_reuse(20,33,21);

代码如下:

CREATE TABLE goon
AS
   SELECT *
     FROMdba_objects
    WHERE 1 = 2;

create or replace PROCEDURE proc_go_break_reuse (v_XIDUSN     NUMBER,
                                                v_XIDSLOT    NUMBER,
                                                v_XIDSQN     NUMBER)
/* ————————————————–
Description:It’s used to maketransaction slot reused
—————————————————*/
AS
   nsid                 NUMBER;
   TYPE transaction_record_type IS RECORD
   (
      XIDUSN    NUMBER,
      XIDSLOT   NUMBER,
      XIDSQN    NUMBER
   );
  transaction_record  transaction_record_type;
BEGIN
   SELECT SYS_CONTEXT ('userenv', 'sid') INTO nsid FROM DUAL;
   LOOP
      INSERT INTO goon
         SELECT *
           FROM dba_objects
          WHERE ROWNUM < 100;
      SELECT XIDUSN,XIDSLOT,XIDSQN
        INTO transaction_record
        FROM v$transaction a,v$session b
       WHERE a.ADDR = b.TADDR AND b.SID = nsid;
      IF (    transaction_record.XIDUSN=v_XIDUSN
          AND transaction_record.XIDSLOT =v_XIDSLOT
          AND transaction_record.XIDSQN >v_XIDSQN)
      THEN
         GOTO resue_end;
      END IF;
      COMMIT;
      DELETE FROM goon;
      SELECT XIDUSN,XIDSLOT,XIDSQN
        INTO transaction_record
        FROM v$transaction a, v$session b
       WHERE a.ADDR = b.TADDR AND b.SID = nsid;
      IF (    transaction_record.XIDUSN=v_XIDUSN
          AND transaction_record.XIDSLOT=v_XIDSLOT
          AND transaction_record.XIDSQN >v_XIDSQN)
      THEN
         GOTO resue_end;
      END IF;
      COMMIT;
   END LOOP;
  <<resue_end>>
   COMMIT;
END;

4.产生延时块清除,记录相应scn号

SQL> select * from test_scn;
SEE
——————————————————————————–
kao1
kao2
SQL> select timestamp_to_scn(systimestamp) from dual;

TIMESTAMP_TO_SCN(SYSTIMESTAMP)
——————————
703860 ―――发生延时块清除时候的大概scn

SQL> select dbms_rowid.rowid_block_number(rowid), ora_rowscn from test_scn t where see=’kao2′;

DBMS_ROWID.ROWID_BLOCK_NUMBER( ORA_ROWSCN
—————————— ———-
25618 701061 —最后一次itl 上的 commit scn

5.dump undo header和block 25618

SQL> alter system dump undo header ‘_SYSSMU15$’;

System altered
TRN CTL:: seq: 0×0340 chd: 0x002b ctl: 0×0021 inc: 0×00000000 nfb: 0×0001
mgc: 0×8201 xts: 0×0068 flg: 0×0001 opt: 2147483646 (0x7ffffffe)
uba: 0x0200009b.0336.0a scn: 0×0000.000ab285 -这是control scn
―――――――――――――――――――――――――――――――――――――
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
————————————————————————————————
0×00 9 0×00 0×0018 0×0001 0×0000.000ab2f0 0x0200009b 0×0000.000.00000000 0×00000001 0×00000000 1210262128
―――――――――――――――――――――――――――――――――――――――――――――
0×21 9 0×00 0×0018 0xffff 0×0000.000abd20 0×02000084 0×0000.000.00000000 0×00000052 0×00000000 1210262179 --该slot已经被重用,重用的提交scn为000abd20
―――――――――――――――――――――――――――――――――――――――――――――
0x2f 9 0×00 0×0017 0x002e 0×0000.000ab387 0x0200009b 0×0000.000.00000000
0×000000

SQL> alter system dump datafile 6 block 25618;

Start dump data blocks tsn: 6 file#: 6 minblk 25618 maxblk 25618
buffer tsn: 6 rdba: 0×01806412 (6/25618)
scn: 0×0000.000abd72 seq: 0×01 flg: 0×00 tail: 0xbd720601 ―――这个scn 就是block scn,scn号为703858,可见应该是延时块清除的时候的scn
frmt: 0×02 chkval: 0×0000 type: 0×06=trans data

Hex dump of block: st=0, typ_found=1
Dump of memory from 0x074C8400 to 0x074CA400
……………………………………………………………………..
Block header dump: 0×01806412
Object id on Block? Y
seg/obj: 0×2966 csc: 0×00.abd72 itc: 2 flg: E typ: 1 – DATA
brn: 0 bdba: 0x180640e ver: 0×01 opc: 0
inc: 0 exflg: 0

Itl Xid Uba Flag Lck Scn/Fsc
0×01 0×0014.021.00000015 0x0200009f.02c5.0e C-U- 0 scn 0×0000.000ab285 --这个scn就是control scn,在TRN CTL有记录,对应为701061
0×02 0×0010.016.00000014 0×02000074.0294.0d C— 0 scn 0×0000.000a9432

关于SCN,也可参阅

http://czmmiao.iteye.com/blog/2077044

 

参考至:http://www.easyora.net/blog/scn_block_scn.html

如有错误,欢迎指正

邮箱:czmcj@163.com

SCN之delayed block cleanout

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
【iOS之Block笔记】   1、Block如果定义在函数中,则生成在栈上,当离开作用域后,block就被释放
1、定义 (1) Block是OC中的一种数据类型,在iOS开发中被广泛使用 (2) ^是Block的特有标记 (3) Block
3 Block
一、前言 block是iOS4.0+和Mac oxX 10.6以后引进的对C语言的拓展,用来实现匿名函数的特性。所谓匿
SCN是什么?The System Change Number system change number (SCN)是一个非常重要的标记,Oracle使
软件工程pair project之Block++ By Chen Xue, Li Keqian 概述:我们做的是一个弹球程序。通过对现有
Delayed_job plugin是一个健壮的稳定的用于在后台运行任务的解决方案。 下面的例子中,使用一个邮件
继上次升级hadoop完毕后,集群启动正常,但是在访问Namenode的50070的界面上,发现了如下截图的警告
继上次升级hadoop完毕后,集群启动正常,但是在访问Namenode的50070的界面上,发现了如下截图的警告
继上次升级hadoop完毕后,集群启动正常,但是在访问Namenode的50070的界面上,发现了如下截图的警告
继上次升级hadoop完毕后,集群启动正常,但是在访问Namenode的50070的界面上,发现了如下截图的警告
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号