ORACLE update 操作内部原理

发表于:2013-10-11来源:IT博客大学习作者:惜分飞点击数: 标签:oracle
对于oracle的update操作,在数据块中具体是如何出来,是直接更新原来值,还是通过插入新值修改指针的方法实现.下面通过证明:

  对于oracle的update操作,在数据块中具体是如何出来,是直接更新原来值,还是通过插入新值修改指针的方法实现.下面通过证明:

  模拟表插入数据

  SQL> create table t_xifenfei(id number,name varchar2(10));

  Table created.

  SQL> insert into t_xifenfei values(1,'XFF');

  1 row created.

  SQL> insert into t_xifenfei values(2,'CHF');

  1 row created.

  SQL> commit;

  Commit complete.

  SQL> alter system checkpoint;

  System altered.

  SQL> select id,rowid,

  2 dbms_rowid.rowid_relative_fno(rowid)rel_fno,

  3 dbms_rowid.rowid_block_number(rowid)blockno,

  4 dbms_rowid.rowid_row_number(rowid) rowno

  5 from t_xifenfei;

  ID ROWID REL_FNO BLOCKNO ROWNO

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

  1 AAASc+AAEAAAACvAAA 4 175 0

  2 AAASc+AAEAAAACvAAB 4 175 1

  SQL> alter system dump datafile 4 block 175;

  System altered.

  SQL> select value from v$diag_info where name='Default Trace File';

  VALUE

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

  /u01/oracle/diag/rdbms/ora11g/ora11g/trace/ora11g_ora_24625.trc

  数据存储对应16进制值

  SQL> select dump(1,'16') from dual;

  DUMP(1,'16')

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

  Typ=2 Len=2: c1,2

  SQL> select dump(2,'16') from dual;

  DUMP(2,'16')

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

  Typ=2 Len=2: c1,3

  SQL> select dump('XFF','16') FROM DUAL;

  DUMP('XFF','16')

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

  Typ=96 Len=3: 58,46,46

  SQL> SELECT DUMP('CHF','16') FROM DUAL;

  DUMP('CHF','16')

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

  Typ=96 Len=3: 43,48,46

  得出第一条记录对应值为:02c10203584646;第二条记录对应值为:02c10303434846

  dump 数据块得到记录

  bdba: 0x010000af

  data_block_dump,data header at 0xb683c064

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

  tsiz: 0x1f98

  hsiz: 0x16

  pbl: 0xb683c064

  76543210

  flag=--------

  ntab=1

  nrow=2

  frre=-1

  fsbo=0x16

  fseo=0x1f84

  avsp=0x1f6e

  tosp=0x1f6e

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

  0x12:pri[0] offs=0x1f8e ---->8078

  0x14:pri[1] offs=0x1f84 ---->8068

  block_row_dump:

  tab 0, row 0, @0x1f8e

  tl: 10 fb: --H-FL-- lb: 0x1 cc: 2

  col 0: [ 2] c1 02

  col 1: [ 3] 58 46 46

  tab 0, row 1, @0x1f84

  tl: 10 fb: --H-FL-- lb: 0x1 cc: 2

  col 0: [ 2] c1 03

  col 1: [ 3] 43 48 46

  end_of_block_dump

  End dump data blocks tsn: 4 file#: 4 minblk 175 maxblk 175

  bbed查看相关记录

  BBED> p kdbr

  sb2 kdbr[0] @118 8078 <--第一条row directory指针位置

  sb2 kdbr[1] @120 8068 <--第二条row directory指针位置

  BBED> p *kdbr[0]

  rowdata[10]

  -----------

  ub1 rowdata[10] @8178 0x2c

  BBED> x /rnc

  rowdata[10] @8178

  -----------

  flag@8178: 0x2c (KDRHFL, KDRHFF, KDRHFH)

  lock@8179: 0x01

  cols@8180: 2

  col 0[2] @8181: 1

  col 1[3] @8184: XFF

  BBED> p *kdbr[1]

  rowdata[0]

  ----------

  ub1 rowdata[0] @8168 0x2c

  BBED> x /rnc

  rowdata[0] @8168

  ----------

  flag@8168: 0x2c (KDRHFL, KDRHFF, KDRHFH)

  lock@8169: 0x01

  cols@8170: 2

  col 0[2] @8171: 2

  col 1[3] @8174: CHF

  BBED> d

  File: /u01/oracle/oradata/ora11g/users01.dbf (4)

  Block: 175 Offsets: 8168 to 8191 Dba:0x010000af

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

  2c010202 c1030343 48462c01 0202c102 03584646 010650e5

  <32 bytes per line>

  这里可以得到结论如下:

  1.数据是从块的底部开始往上存储

  2.在每一条记录的头部分别有flag/lock/cols对应这里的2c0102

  3.这里的偏移量和dump出来的数据可以看出来两条记录是连续在一起(偏移量分别为:8168和8178)

  更新一条记录

  SQL> update t_xifenfei set name='XIFENFEI' where id=1;

  1 row updated.

原文转自:http://blogread.cn/it/article/5666