oracle undo的原理

本文详细解析了Oracle数据库如何利用独立Undo机制实现未提交数据的可见性,通过具体实例展示了Oracle如何在不提交更新的情况下让其他会话看到原始数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

独立Undo是oracle数据库战胜其他数据库的关键原因,下面来看看oracle是如何利用undo:

1,先创建一个表,并插入数据,然后更新数据,但并不提交;

SQL> createtable t(id int,name varchar2(10));

表已创建。

SQL> insertinto t values(1,'a');

已创建 1 行。

SQL> insertinto t values(2,'b');

已创建 1 行。

SQL> commit;

提交完成。

SQL> update tset name='c

  2  'where id=1;

已更新 1 行。

    2,新开一个窗口查询表t的数据,这里最多有三种情况:1,原数据;2,新数据;3,阻塞;其他数据库跟新后都看不到原来的数据,而oracle则让用户看到原数据,这便是oracle的强大之处之一。下面我们通过dump文件来导出数据查看

SQL> select id,name,rowid from t;

        ID NAME                 ROWID

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

         1 hl                   AAANYgAAFAABkpFAAA

--通过oracle提供的包查询表t所在的文件号及块号

SQL> select id,name,dbms_rowid.rowid_relative_fno(rowid)fno,dbms_rowid.rowid_bl

ock_number(rowid) bno from t;

 

        ID       NAME          FNO        BNO

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

         1        c              5        412229

         2        b               5        412229

注:dump出来的文件可以通过以下的sql语言查询出来:

执行必须在当前session下执行;

selectdecode(instr(c.VALUE,'/',1),1,c.VALUE||'/',c.VALUE||'\')||d.INSTANCE_NAME||'_ora_'||a.SPID||'.trc'

  from v$process a,v$sessionb,v$parameter c,v$instance d

    where a.ADDR=b.PADDR andc.NAME='user_dump_dest' and b.AUDSID=userenv('sessionid');

执行必须在当前session下执行;

 

Itl           Xid                  Uba         Flag Lck        Scn/Fsc

0x01  0x0002.01b.00000444 0x008000ac.0269.0e  C---    0 scn 0x0000.095ec11b

0x02   0x0008.002.00000401  0x00800a2d.01d0.04  ----   1  fsc0x0000.00000000

 

data_block_dump,data header at 0x7cb2264

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

tsiz: 0x1f98

hsiz: 0x16

pbl: 0x07cb2264

bdba: 0x01464a45

     76543210

flag=--------

ntab=1

nrow=2

frre=-1

fsbo=0x16

fseo=0x1f7f

avsp=0x1f70

tosp=0x1f70

0xe:pti[0] nrow=2    offs=0

0x12:pri[0]        offs=0x1f7f

0x14:pri[1]        offs=0x1f88

block_row_dump:

tab 0, row 0, @0x1f7f

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

col  0: [ 2]  c1 02

col  1: [ 2] 63

tab 0, row 1, @0x1f88

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

col  0: [ 2]  c1 03

col  1: [ 1]  62

end_of_block_dump

End dump data blocks tsn: 6 file#: 5 minblk 412229 maxblk 412229

从dump出的文件们可以发现数据的值已经改变,a对应的ascii码为61,而dump出的为63。

为什么另一个session中读到的确是61(a)呢?

因为oracle在这一列上添加了一个锁如图:lb:0x2(lb:lock bytes),在读取数据时oracle会去读0x02对应的uba(undo block address)flag 为---- 对应的这一行;

--获取数据文件号

SQL> select dbms_utility.data_block_address_file(8391213) fromdual;

DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(8391213)

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

               2

--获取块号

SQL> select dbms_utility.data_block_address_block(8391213) fromdual;

DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(8391213)

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

              2605

将这个块dump出来和上面的对比。

uba: 0x00800a2d.01d0.03 ctl max scn: 0x0000.095ebbc6 prv tx scn: 0x0000.095ebbde
txn start scn: scn: 0x0000.095ec11b logon user: 57
 prev brb: 8391209 prev bcl: 0
KDO undo record:
KTB Redo 
op: 0x03  ver: 0x01  
op: Z
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x01464a45  hdba: 0x01464a43
itli: 2  ispac: 0  maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 8
ncol: 2 nnew: 1 size: -1
col  1: [ 1]  61
 
End dump data blocks tsn: 1 file#: 2 minblk 2605 maxblk 2605

Col 1:[1]  61及对应的就是a。

查询数据文件号为2的正是undo数据文件。

SQL> select df.file_name,df.file_id,df.tablespace_name,sp.contents
  2  from dba_data_files df,dba_tablespaces sp where df.tablespace_name=sp.tab
space_name;


FILE_NAME                                                                                                      FILE_ID TABLESPACE_NAME          CONTENTS
------------------------------                                                                                     ---------- ---------------                           - -----------------
F:\ORACLE\PRODUCT\10.2.0\ORADATA\ZXNTAGL\USERS01.DBF          4        USERS                                  PERMANENT

F:\ORACLE\PRODUCT\10.2.0\ORADATA\ZXNTAGL\SYSAUX01.DBF          3       SYSAUX                                PERMANENT
 
F:\ORACLE\PRODUCT\10.2.0\ORADATA\ZXNTAGL\UNDOTBS01.DBF       2      UNDOTBS1                         UNDO

F:\ORACLE\PRODUCT\10.2.0\ORADATA\ZXNTAGL\SYSTEM01.DBF          1       SYSTEM                               PERMANENT

F:\ORACLE\PRODUCT\10.2.0\DATAFILE\ZXNTAGL_TS_DATA_TAGL.DAT  5    ZXNTAGL_TS_DATA_TAGL PERMANENT
              
F:\ORACLE\PRODUCT\10.2.0\ORADATA\ZXNTAGL\TEST.DBF                      6     TEST                                        PERMANENT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值