block cleanout分析(二)

继续上一篇文章,delayed block cleanout存在一些问题,下面列出问题,通过测试来分析delayed block cleanout过程中的一些变化会对delayed block cleanout有什么影响?并且redo,undo是如何变化的?

问题1、当出现事务递交前modified block就被flush回硬盘,此时没有提交事务,但是undo表空间被删除,紧接着做了回滚操作,此时modified block的原始数据从哪里获取?

问题2、假设在modified blockflush回硬盘之前,undo tablespace中的datablock的原始值的信息被覆盖,此时modified blockflush写回硬盘能够成功吗?

问题3 undo$系统表是专门用来记录什么信息的表?是记录数据块的信息还是记录块头信息?

 

实验1、理解undo$系统表,针对问题3

--删除表

 drop table test;

--建表

create table test

 pctfree 99

  pctused 1

 as

 select rownum n1, rpad(rownum,200) v1

 from all_objects

 where rownum <= 1000 ;

 --查询下信息

 SQL>  select dbms_rowid.ROWID_RELATIVE_FNO(rowid), dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from test where rownum=1;

DBMS_ROWID.ROWID_RELATIVE_FNO( DBMS_ROWID.ROWID_BLOCK_NUMBER(

------------------------------ ------------------------------

                             2                          15730

--更新表,但先不提交

update test set n1=n1+1;

 

--强制将缓存中的数据块写进磁盘中去

ALTER SESSION SET EVENTS 'immediate trace name flush_cache';

--查看undo表空间信息

SQL> show parameter undo_tablespace

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

undo_tablespace                      string      UNDOTS2

--提交事务

commit;

--切换undo tablespace

alter system set undo_tablespace=UNDO_SMALL;

 

--删除旧的undo tablespace

 DROP TABLESPACE UNDOTS2  INCLUDING CONTENTS AND DATAFILES;

 --DUMPdata block的头信息,此时是在cleanout以前

alter system dump datafile 2 block 15730;

 

--cleanout

select count(*) from test;

 

--DUMPdata block的头信息,此时是在cleanout之后

alter system dump datafile 2 block 15730;

(注:介绍下Xid参数保存的信息

 Xid是一个指向回滚段上的事务表上的槽的指针(undoseg#.slot#.wrap)。undoseg# 参数

 表示回滚段,slot#表示事务表上的一个槽,并且wrap参数表示在一个事务中这个槽被使用

 的次数。)

 

--比较cleanout前后DUMP出来的信息

 --发生cleanout以前

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0xffff.000.00000000  0x0000 0000.0000.00   C---    0  scn 0x 0000.002562f 2

0x02   0x 0013.01a .00000025  0x018000bd.0027.01  ----    1  fsc 0x0000.00000000

0x03   0x0000.000.00000000  0x0000 0000.0000.00   ----    0  fsc 0x0000.00000000

 

tl: 207 fb: --H-FL-- lb: 0x2  cc: 2

 

--发生cleanout之后:尽管原来的UNDO表空间已经被删除,但是经过延迟块清除之后,仍能够得到一个SCN,这个SCN表示什么意思呢?又是从哪里得来的?下面解释

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0xffff.000.00000000  0x0000 0000.0000.00   C---    0  scn 0x 0000.002562f 2

0x02   0x 0013.01a .00000025  0x018000bd. 0027.01   C -U-    0  scn 0x 0000.002567a 6 --2451366

0x03   0x0000.000.00000000  0x0000 0000.0000.00   ----    0  fsc 0x0000.00000000

 

tl: 207 fb: --H-FL-- lb: 0x0  cc: 2

 

在系统中有一个系统基表记录了系统中回滚段中的部分信息,这个表是undo$,可以在路径C:/oracle/product/ 10.2.0 /db_1/RDBMS/ADMIN下的sql.bsq文件中查找该undo$系统基表的定义以及表中每个字段的注释,定义如下:

create table undo$                                     /* undo segment table */

( us#           number not null,                      /* undo segment number */

  name          varchar2("M_IDEN") not null,    /* name of this undo segment */

  user#         number not null,      /* owner: 0 = SYS(PRIVATE), 1 = PUBLIC */

  file#         number not null,               /* segment header file number */

  block#        number not null,              /* segment header block number */

  scnbas        number,           /* highest commit time in rollback segment */

  scnwrp        number,              /* scnbas - scn base, scnwrp - scn wrap */

  xactsqn       number,               /* highest transaction sequence number */

  undosqn       number,                /* highest undo block sequence number */

  inst#         number,    /* parallel server instance that owns the segment */

  status$       number not null,              /* segment status (see KTS.H): */

  /* 1 = INVALID, 2 = AVAILABLE, 3 = IN USE, 4 = OFFLINE, 5 = NEED RECOVERY,

   * 6 = PARTLY AVAILABLE (contains in-doubt txs)

   */

  ts#           number,                                 /* tablespace number */

  ugrp#         number,                      /* The undo group it belongs to */

  keep          number,

  optimal       number,

  flags         number,

  spare1        number,

  spare2        number,

  spare3        number,

  spare4        varchar2(1000),

  spare5        varchar2(1000),

  spare6        date

)

有兴趣的战友可以继续研究系统表,这个UNDO$表就介绍到此。

 

经过分析上面的ITL列表,可以看出ITL=0X02是当前的活动事务,其Xid0x 0013.01a .00000025,其中0x0013表示回滚段的段头,通过这个编号在undo$表中查询相关的回滚段的信息,如下:

SQL> select name,SCNBAS,file#,block# from undo$ where name='_SYSSMU19$';   --2451366

 

NAME                               SCNBAS      FILE#     BLOCK#

------------------------------ ---------- ---------- ----------

_SYSSMU19$                        2451366          6        137

 

SQL> alter system dump datafile 6 block 137;--DUMP这个系统基表所在数据块中的信息

System altered

*** 2008-05-04 20:37:58.500

alter system dump datafile/tempfile: file 6 not readable 但是具体的信息oracle是不允许访问的,没有DUMP出来详细的信息

 

SQL>  SELECT * FROM test

  2   as of SCN 2451366 ; --使用回闪查询来查询在SCN=2451366点上的表信息,查询出来得到的结果是更新之后的信息,也就是说在更新之前的信息已经被覆盖掉

        N1 V1

---------- --------------------------------------------------------------------------------

         2 1

         3 2

         4 3

         5 4

         6 5

         7 6

         8 7

         9 8

     。。。

      999 998

      1000 999

      1001 1000

1000 rows selected

 

 SQL>  SELECT * FROM test  

2         as of SCN 2451365 ;(<2451366--SCN缩小到小于2451366,则出现ORA-01555快照过旧的错误,说明已经在回滚段中已经不存表在更新之前的表信息,更新之前的表信息已经被覆盖,此时可以确定SCN=2451366为当前的upper bound scn,当前回滚段中没有比这个SCN再小的SCN了,这个SCN已经是数据库能够恢复的最早的SCN

SELECT * FROM test

 as of SCN 2451365

ORA-01555: 快照过旧: 回退段号 19 (名称为 "_SYSSMU19$") 过小

 

对上面的实验产生一个问题:就是回闪查询得到的数据是如何得到的?是从哪里得到的?是undo$系统表中的吗?是不是在系统更新的时候会将UNDO项同时插入到回滚段和系统表undo$中吗?还是原来的回滚段中的信息转移到undo$系统表中的呢?

实验2、针对产生的问题测试如下:

--查看跟踪文件可以看到这个alter操作内部都做了什么,来确定这些DDL语句做了什么?

步骤如下:

SQL> alter session set events '10046 trace name context forever,level 14';

会话已更改。

SQL>  alter system set undo_tablespace=UNDO_SMALL;--alter system set remote_login_passwordfile=none scope=spfile;

系统已更改。

SQL> alter session set events '10046 trace name context off';

会话已更改。

--查看DUMP文件如下:

*** 2008-05-04 22:28:10.328

=====================

PARSING IN CURSOR #14 len=70 dep=0 uid=65 oct=42 lid=65 tim=6482826468 hv=1349202016 ad='259e5160'

 alter session set events '10046 trace name context forever,level 14'

END OF STMT

EXEC #14:c=0,e=54,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=6482826465

WAIT #14: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=54517 tim=6482826551

WAIT #14: nam='SQL*Net message from client' ela= 27729 driver id=1413697536 #bytes=1 p3=0 obj#=54517 tim=6482854305

=====================

.....

=====================

PARSING IN CURSOR #11 len=44 dep=0 uid=65 oct=49 lid=65 tim=6486442627 hv=2472468311 ad=' 2569a 588'

alter system set undo_tablespace=UNDO_SMALL

END OF STMT

PARSE #11:c=0,e=309,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=6486442624

BINDS #11:

XCTEND rlbk=0, rd_only=1 -- XCTEND rlbk=0, rd_only=1:表示commit

                        -- XCTEND rlbk=1, rd_only=1: 表示rollback.

=====================

......

=====================

PARSING IN CURSOR #13 len=148 dep=1 uid=0 oct=6 lid=0 tim=6486492876 hv=3540833987 ad='33ec8e30'

update undo$ set name=:2,file#=:3,block#=:4,status$=:5,user#=:6,undosqn=:7,xactsqn=:8,scnbas=:9,scnwrp=:10,inst#=:11,ts#=:12,spare1=:13 where us#=:1 –更新了undo$系统基表的信息

END OF STMT

PARSE #13:c=31250,e=49926,p=12,cr=68,cu=0,mis=1,r=0,dep=1,og=4,tim=6486492873

BINDS #13:

kkscoacd

 Bind#0

  oacdty=01 mxl=32(09) mxlc=00 mal=00 scl=00 pre=00

  oacflg=18 fl2=0001 frm=01 csi=852 siz=32 off=0

  kxsbbbfp=33ed4cb2  bln=32  avl=09  flg=09

  value="_SYSSMU1$"

 Bind#1

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 2328c 4  bln=24  avl=02  flg=05

  value=7

 Bind#2

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 2328a 0  bln=24  avl=02  flg=05

  value=9

 Bind#3

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 23287c   bln=24  avl=02  flg=05

  value=2

 Bind#4

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 232858  bln=24  avl=02  flg=05

  value=1

 Bind#5

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 232834  bln=24  avl=03  flg=05

  value=519

 Bind#6

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 232810  bln=24  avl=03  flg=05

  value=1041

 Bind#7

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 2327ec  bln=24  avl=05  flg=05

  value=2465980

 Bind#8

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 2327c 8  bln=24  avl=01  flg=05

  value=0

 Bind#9

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 2327a 4  bln=24  avl=01  flg=05

  value=0

 Bind#10

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 232780  bln=24  avl=02  flg=05

  value=10

 Bind#11

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 23275c   bln=24  avl=02  flg=05

  value=1

 Bind#12

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp= 0c 2328e8  bln=22  avl=02  flg=05

  value=1

WAIT #13: nam='db file sequential read' ela= 233 file#=1 block#=202 blocks=1 obj#=54517 tim=6486494597

WAIT #13: nam='db file sequential read' ela= 2483 file#=1 block#=106 blocks=1 obj#=54517 tim=6486497143

WAIT #13: nam='db file sequential read' ela= 7947 file#=1 block#=9 blocks=1 obj#=54517 tim=6486505167

WAIT #13: nam='db file sequential read' ela= 1614 file#=1 block#=403 blocks=1 obj#=54517 tim=6486506833

EXEC #13:c=15625,e=13965,p=4,cr=1,cu=3,mis=1,r=1,dep=1,og=4,tim=6486506933

STAT #13 id=1 cnt=1 pid=0 pos=1 obj=0 op='UPDATE  UNDO$ (cr=1 pr=4 pw=0 time=12597 us)'

STAT #13 id=2 cnt=1 pid=1 pos=1 obj=34 op='INDEX UNIQUE SCAN I_UNDO1 (cr=1 pr=1 pw=0 time=308 us)'

WAIT #11: nam='db file sequential read' ela= 14410 file#=7 block#=9 blocks=1 obj#=0 tim=6486560235

=====================

....

=====================

PARSING IN CURSOR #10 len=56 dep=0 uid=65 oct=42 lid=65 tim=6489733238 hv=3193596740 ad='259e4e40'

alter session set events '10046 trace name context off'

END OF STMT

PARSE #10:c=0,e=242,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=6489733236

BINDS #10:

EXEC #10:c=0,e=58,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=6489733338

分析:发现在DUMP出来的文件中有20个对undo$表中记录的更新信息,说明在做alter system set undo_tablespace=UNDO_SMALLDDL语句时,实质上做了隐式的提交工作,并且也及时更新了数据字典中一些系统基表中的信息,如:对undo$表做了更新操作。此时猜测是在做UNDO表空间切换时,oracle将原来的回滚段上的信息及时地更新到undo$系统表中去。不是原先想的对原回滚段和undo$系统表都插入undo项。

 

实验3、针对问题1的实验

 --删除表

 drop table test;

 

--建表

create table test

 pctfree 99

  pctused 1

 as

 select rownum n1, rpad(rownum,200) v1

 from all_objects

 where rownum <= 1000 ;

 

--查询下信息

SQL>  select dbms_rowid.ROWID_RELATIVE_FNO(rowid), dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from test where rownum=1;

DBMS_ROWID.ROWID_RELATIVE_FNO( DBMS_ROWID.ROWID_BLOCK_NUMBER(

------------------------------ ------------------------------

                             2                            994

--查看undo表空间信息

SQL> show parameter undo_tablespace

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

undo_tablespace                      string      UNDO_SMALL

 

--更新表,但先不提交

update test set n1=n1+1;

 

--强制将缓存中的数据块写进磁盘中去

ALTER SESSION SET EVENTS 'immediate trace name flush_cache';

 

--下面一语句在另一个会话中完成,否则会提交之前的更新事务

SQL>    alter system set undo_tablespace=undots3;

System altered

 

--查看undo表空间信息

SQL> show parameter undo_tablespace

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

undo_tablespace                      string      UNDOTS3

 

--删除UNDO表空间

SQL>  DROP TABLESPACE UNDO_SMALL  INCLUDING CONTENTS AND DATAFILES;

 

DROP TABLESPACE UNDO_SMALL  INCLUDING CONTENTS AND DATAFILES

ORA-30013: 还原表空间 'UNDO_SMALL' 当前正在使用中

 

 此时报错:ORA-30013: 还原表空间 'UNDO_SMALL' 当前正在使用中

 表示在事务还没有提交之前,删除UNDO表空间是不允许的,因为此时更新事务仍然占用着UNDO表空间中一部分空间资源,

 但是此时想删除UNDO表空间需要等待更新事务释放所占用的UNDO表空间中的资源。

 

--下面就无法完成回滚原来更新的数据的工作

  rollback;

实验4、针对问题2

明天继续:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值