undo相关实验

一、先建一个会话,以scott用户登录

connect scott/tiger


select * from emp; 
update emp set sal=4000 where empno=7788; 


先不提交这个事务,在另外窗口新开session,使用SYS用户查询相关信息,进行进一步的分析研究


SQL> select xidusn,xidslot,xidsqn,ubablk,ubafil,ubarec FROM v$transaction;


    XIDUSN    XIDSLOT     XIDSQN     UBABLK     UBAFIL     UBAREC
---------- ---------- ---------- ---------- ---------- ----------
          8         32       1895       4917          2         45


SQL>  select usn,writes,rssize,xacts,hwmsize,shrinks,wraps from v$rollstat;


       USN     WRITES     RSSIZE      XACTS    HWMSIZE    SHRINKS      WRAPS
---------- ---------- ---------- ---------- ---------- ---------- ----------
         0       5160     385024          0     385024          0          0
         1        156    1171456          0    1171456          0          0
         2        296    1171456          0    1171456          0          0
         3        478    1171456          0    1171456          0          0
         4        472    1171456          0    1171456          0          0
         5        264    1171456          0    1171456          0          0
         6       1528     253952          0     253952          0          0
         7        284    1171456          0    1171456          0          0
         8        462    1171456          1    1171456          0          0
         9        308    1171456          0    1171456          0          0
        10        574     188416          0     188416          0          0



  TRN TBL::,也就是这个回滚段中记录的事务列表




  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
   0x00    9    0x00  0x0768  0xffff  0x0000.002030ff  0x00000000  0x0000.000.00000000  0x00000000   0x00000000  1390029178


 0x20   10    0x80  0x0767  0x0002  0x0000.0020312a  0x00801335  0x0000.000.00000000  0x00000001   0x00000000  0


state状态9为非活动事务.state为10为活动事物

index字段就是事务表中的slot号,dba 包含这个活动事务的block地址

在这个例子中index为0x20,转换为10进制2*16=32,刚好与  XIDSLOT   相等

再来看dba,0x00801335 转换为二进制位d0000 0000 1000 0000 0001 0011 0011 0101,

DBA代表数据块的存储地址,由10位文件号+22位数据块(BLOCK)组成。这个是ORACLE内部决定的

前十位0000 0000 10转10进制为2,后面20位转十进制为4917 ,刚好与v$transaction中的结果匹配。


二、scoott不提交update的动作,继续执行下面的命令

SQL> update emp set sal=4000 where empno=7900;

SQL> update emp set sal=4000 where empno=7902;

SQL> select xidusn,xidslot,xidsqn,ubablk,ubafil,ubarec FROM v$transaction;


    XIDUSN    XIDSLOT     XIDSQN     UBABLK     UBAFIL     UBAREC                 


---------- ---------- ---------- ---------- ---------- ----------
         8         32       1895       4917          2         47


可以发现XID与一中XID相同,说明他们在同一个事物中。

 UBA------该事务的最后一个UNDO RECORD的地址(一个事务的UNDO,由多个UNDO RECORD组成,                                                                                                                                                                      一个UNDO BLOCK里面包含多个UNDO RECORD)

SQL> alter system dump undo header '_SYSSMU8$'; 


System altered.


SQL> alter system dump datafile 2 block 4917;


在trc文件中找到

UNDO BLK:
xid: 0x0008.020.00000767  seq: 0x16d cnt: 0x2f  irb: 0x2f  icl: 0x0   flg: 0x0000
其中的xid = Undo segment no.Slotno.sequence no

 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset

0x01 0x1f8c     0x02 0x1ee8     0x03 0x1e8c     0x04 0x1de8     0x05 0x1d8c
0x06 0x1ce8     0x07 0x1c8c     0x08 0x1be8     0x09 0x1b8c     0x0a 0x1ae8
0x0b 0x1a8c     0x0c 0x19e8     0x0d 0x198c     0x0e 0x18e8     0x0f 0x188c
0x10 0x17e8     0x11 0x178c     0x12 0x16e8     0x13 0x168c     0x14 0x15e8
0x15 0x158c     0x16 0x14e8     0x17 0x148c     0x18 0x13e8     0x19 0x138c
0x1a 0x12e8     0x1b 0x128c     0x1c 0x11e8     0x1d 0x118c     0x1e 0x10e8
0x1f 0x108c     0x20 0x0fe8     0x21 0x0f8c     0x22 0x0ee8     0x23 0x0e8c
0x24 0x0de8     0x25 0x0d8c     0x26 0x0ce8     0x27 0x0c8c     0x28 0x0be8
0x29 0x0b8c     0x2a 0x0ae8     0x2b 0x0a8c     0x2c 0x09ac     0x2d 0x0910
0x2e 0x08a4     0x2f 0x084c

irb: 0x2f 指的是回滚段中记录的最近未提交变更开始之处,如果开始回滚,这是起始的搜索点


* Rec #0x2f  slt: 0x20  objn: 51148(0x0000c7cc)  objd: 51148  tblspc: 4(0x00000004)
*       Layer:  11 (Row)   opc: 1   rci 0x2e --------偏移量
Undo type:  Regular undo   Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02  ver: 0x01
op: C  uba: 0x00801335.016d.2e
KDO Op code: URP row dependencies Disabled
  xtype: XAxtype KDO_KDOM2 flags: 0x00000080  bdba: 0x01000020  hdba: 0x0100001b
itli: 1  ispac: 0  maxfr: 4858
tabn: 0 slot: 12(0xc) flag: 0x2c lock: 0 ckix: 191
ncol: 8 nnew: 1 size: 0
vector content: -----------前镜像的值
col  5: [ 2]  c2 1f


因为update的是数值的,所以可以用下面的过程计算出该值

SQL> set   serveroutput   on ; -- -----使用set   serveroutput   on   命令设置环境变量serveroutput为打开状态,从而使得pl/sql程序能够在SQL*plus中输出结果 ,使用函数                                                                                                                                dbms_output.put_line()可以输出参数的值。
SQL> declare n number;
  2  begin
  3     dbms_stats.convert_raw_value('c21f',n);
  4     dbms_output.put_line(n);
  5  end;
  6  /
3000

上面这个过程能把dump出来的东西还原回去

同时我们也可以认证:

SQL> select dump(3000,16) from dual;  16表示16进制


DUMP(3000,16)
------------------
Typ=2 Len=2: c2,1f  结果与上面是一致的



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

huangliang0703

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值