一句DML操作对数据表的修改看似很简单:把老的记录值替换成新的记录值,插入或者删除一条记录,这个看似简单的操作但在buffer cache里却有着不一般的经历,为实现读一致性,一个block在buffer cache里可能有多个版本,在DML的过程中,buffer cache里的block经历了一系列的变化。本文以update、insert、delete操作为例揭示了buffer cache里data block状态是如何变化的,有助于我们进一步了解事务的本质及buffer cache的运作机制
###创建测试表
create table scott.t1118_1 tablespace ts1116 as select * from all_users;
Table created
select data_object_id from dba_objects where object_name='T1118_1';
DATA_OBJECT_ID
----------------
41231
col segment_name format a15
col owner format a15
set linesize 100
select owner,segment_name,header_file,header_block from dba_segments where segment_name='T1118_1';
OWNER SEGMENT_NAME HEADER_FILE HEADER_BLOCK
--------------- --------------- ----------- ------------
SCOTT T1118_1 5 60682
###create table后,x$bh里有了三条记录
SYS@tstdb1-SQL> select obj,addr,hladdr,flag,lru_flag,class,state,dbarfil,dbablk,ba,tch from x$bh where obj=41231;
OBJ ADDR HLADDR FLAG LRU_FLAG CLASS STATE DBARFIL DBABLK BA TCH
---------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------
41231 00000001109968B8 07000001B6B503D8 33554433 0 4 1 5 60682 070000014A920000 1
41231 00000001109968B8 07000001B6C811F8 33554433 0 9 1 5 60681 07000000F4010000 1
41231 00000001109968B8 07000001B6DB20E0 33554433 0 8 1 5 60680 0700000102904000 1
这三条记录分别对应3个block
block 5/60680:1st level bitmap block
FLAG:33554433 换算成16进制后:0x2000001=0x2000000(Redo Generated since block read)+0x00001(buffer dirty)
CLASS: 8, 表示1st level bmb
STATE:1,表示Execlusive current
TCH: 1,表示Touch count
block 5/60681:2st level bitmap block
FLAG:33554433 换算成16进制后:0x2000001=0x2000000(Redo Generated since block read)+0x00001(buffer dirty)
CLASS: 9, 表示2nd level bmb
STATE:1,表示Execlusive current
TCH: 1,表示Touch count
block 5/60682:segment header
FLAG:33554433 换算成16进制后:0x2000001=0x2000000(Redo Generated since block read)+0x00001(buffer dirty)
CLASS: 4, 表示segment header
STATE:1,表示Execlusive current
TCH: 1,表示Touch count