天天看點

一緻性讀(Read Consistency)的深入解析data_block_dump,data header at 0xd85664

一緻性讀(Read Consistency)的深入解析data_block_dump,data header at 0xd85664

gyj@OCM> create table gyj (id int,name varchar2(10));

Table created.

gyj@OCM> insert into gyj values(1,'GGGGGG');

1 row created.

gyj@OCM> commit;

Commit complete.

gyj@OCM> select * from gyj;

ID NAME           
1 GGGGGG           

gyj@OCM> var x refcursor

gyj@OCM> exec open :x for select * from gyj;

PL/SQL procedure successfully completed.

gyj@OCM> update gyj set name='YYYYYY' where id=1;

1 row updated.

gyj@OCM> update gyj set name='JJJJJJ' where id=1;

gyj@OCM> print :x

ID NAME           
1 GGGGGG           

能真正看懂為什麼print所顯示的這個結果是GGGGGG,而并不是JJJJJJ,那就說明你對一緻性讀已了解過了。

再往下分析深入分析:做一系列的dump:

gyj@OCM> select id,name,dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from gyj;

ID NAME       DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)           
1 JJJJJJ                                        6                                  151
           

sys@OCM> alter system dump datafile 6 block 151;

System altered.

Itl Xid Uba Flag Lck Scn/Fsc

0x01 0x0004.010.00000211 0x00c02d8a.0090.20 --U- 1 fsc 0x0000.00100118

0x02 0x0003.00d.000002db 0x00c02d16.00bc.06 C--- 0 scn 0x0000.00100109

bdba: 0x01800097

data_block_dump,data header at 0xd85664

tsiz: 0x1f98

hsiz: 0x14

pbl: 0x00d85664

76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f8b

avsp=0x1f77

tosp=0x1f77

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

0x12:pri[0] offs=0x1f8b

block_row_dump:

tab 0, row 0, @0x1f8b

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

col 0: [ 2] c1 02

col 1: [ 6] 4a 4a 4a 4a 4a 4a

gyj@OCM> select UTL_RAW.CAST_TO_VARCHAR2(replace('4a 4a 4a 4a 4a 4a',' ')) from dual;

UTL_RAW.CAST_TO_VARCHAR2(REPLACE('4A4A4A4A4A4A',''))

JJJJJJ

sys@OCM>alter system dump datafile 3 block 11658;

*-----------------------------

  • Rec #0x20 slt: 0x10 objn: 74580(0x00012354) objd: 74580 tblspc: 7(0x00000007)
  • Layer: 11 (Row) opc: 1 rci 0x00

Undo type: Regular undo Begin trans Last buffer split: No

Temp Object: No

Tablespace Undo: No

rdba: 0x00000000Ext idx: 0

flg2: 0

uba: 0x00c02d8a.0090.1d ctl max scn: 0x0000.000ffd42 prv tx scn: 0x0000.000ffd5a

txn start scn: scn: 0x0000.00100109 logon user: 91

prev brb: 12594569 prev bcl: 0

KDO undo record:

KTB Redo

op: 0x04 ver: 0x01

compat bit: 4 (post-11) padding: 1

op: L itl: xid: 0x0007.003.0000021e uba: 0x00c02c50.00a7.3a

flg: C--- lkc: 0 scn: 0x0000.001000f5

Array Update of 1 rows:

tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 191

ncol: 2 nnew: 1 size: 0

KDO Op code: 21 row dependencies Disabled

xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01800097 hdba: 0x01800092

itli: 1 ispac: 0 maxfr: 4858

vect = 3

col 1: [ 6] 59 59 59 59 59 59

gyj@OCM> select UTL_RAW.CAST_TO_VARCHAR2(replace('59 59 59 59 59 59',' ')) from dual;

UTL_RAW.CAST_TO_VARCHAR2(REPLACE('595959595959',''))

YYYYYY

gyj@OCM>alter system dump datafile 3 block 11542;

  • Rec #0x6 slt: 0x0d objn: 74580(0x00012354) objd: 74580 tblspc: 7(0x00000007)

uba: 0x00c02d16.00bc.04 ctl max scn: 0x0000.000fff10 prv tx scn: 0x0000.000fff16

txn start scn: scn: 0x0000.001000f5 logon user: 91

prev brb: 12594451 prev bcl: 0

op: 0x03 ver: 0x01

op: Z

itli: 2 ispac: 0 maxfr: 4858

col 1: [ 6] 47 47 47 47 47 47

gyj@OCM> select UTL_RAW.CAST_TO_VARCHAR2(replace('47 47 47 47 47 47',' ')) from dual;

UTL_RAW.CAST_TO_VARCHAR2(REPLACE('474747474747',''))

GGGGGG

一到性讀的例子(看上圖)

 事務T1送出時的SCN是30.

 事務T2送出時的SCN是31.

 事務T3執行了SELECT操作查詢,SELECT時SNAP_SCN小于或等于30的資料,在查詢到這個資料之前已

被修改過了。

 假設,在這個例子中,在資料緩存中資料塊B1最佳的版本是目前的版本B1.事務T3對它之後所有的變

化是不可見的,需要復原的。對于這個問題需要兩個更新執行復原,因為當T3開始T2還沒有送出。

1、描述一緻性讀的概念?

一緻性讀(Read Consistency)的深入解析data_block_dump,data header at 0xd85664
一緻性讀(Read Consistency)的深入解析data_block_dump,data header at 0xd85664
一緻性讀(Read Consistency)的深入解析data_block_dump,data header at 0xd85664
一緻性讀(Read Consistency)的深入解析data_block_dump,data header at 0xd85664

2、解釋ORA-01555快照過舊的原因,利用實驗模拟重制ORA-01555錯誤?

(1)原因:

a. UNDO段太小,不足以在系統上執行工作

b.你的程式跨 commit擷取

c.塊清除

一緻性讀(Read Consistency)的深入解析data_block_dump,data header at 0xd85664

(2)實驗步驟:

create undo tablespace undotbs2 datafile '/u01/app/oracle/oradata/ocp/undotbs2.dbf' size 10M;

alter system set undo_tablespace=undotbs2;

alter system set undo_retention=2 scope=both;

第1步、session1: 目标是讓b表報快照過舊的報錯

conn gyj/gyj

create table a (id int,cc varchar2(10));
insert into a values(1,'hello');
commit;
 create table b(id int,cc varchar2(10));
insert into b values(10,'AAAAAA');
commit;           

select * from a;

select * from b;

var x refcursor;

exec open :x for select * from b;

第2步、session2:修改b表,字段cc前鏡像"OK"儲存在UDNO段中

update b set cc='BBBBBB' where id= 10;

commit;

第3步、session 3:該條語句就是重新整理緩存

conn / as sysdba

SQL> alter session set events = 'immediate trace name flush_cache'; --9i提供強制刷緩存

(alter system flush buffer_cache;--10g提供的一種刷緩存方法)           

第4步、 session2: 在A表上行大的事務,多運作幾次以確定,復原段被覆寫

begin

for i in 1..20000 loop

update a set cc='HELLOWWWW';
commit;           

end loop;

end;

/

第5步、session 1:在B表上執行查詢(第一步的查詢)

SQL> print :x

ERROR:

ORA-01555: snapshot too old: rollback segment number 21 with name "_SYSSMU21$" too small

(3)解決方法

a.加大undo表空間。

b.适當設定參數undo_retention.

c.減少SQL運作時間(修改SQL ,縮減where條件後面的查詢範圍)

d.收集相關對象統計資訊(與塊清除有關)

3、說說與一緻性讀相關的一些重要資料字典視圖?

V$TRANSACTION

V$LOCK_OBJECT

X$BH

UNDO$

TS$

dba_undo_extents

v$undostat

在整個實驗中最關鍵的是要看懂:

資料塊中的事務槽:

Itl Xid Uba Flag Lck Scn/Fsc

0x01 0x0004.010.00000211 0x00c02d8a.0090.20 --U- 1 fsc 0x0000.00100118

0x02 0x0003.00d.000002db 0x00c02d16.00bc.06 C--- 0 scn 0x0000.00100109

還有復原塊中的事務槽

op: L itl: xid: 0x0007.003.0000021e uba: 0x00c02c50.00a7.3a

flg: C---    lkc:  0     scn: 0x0000.001000f5
           

還有對UBA位址的解析:

0x00c02d8a.0090.20 ->0000000011=3号檔案,0x2d8a=11658号塊,0x90=undo塊被覆寫144次,0x20=第32條undo記錄

0x00c02d16.00bc.06 ->0000000011=3号檔案,0x2d16=11542号塊,0xbc=undo塊被覆寫188次,0x06=第6條undo記錄

0x00c02c50.00a7.3a ->0000000011=3号檔案,0x2c50=11344号塊,0xa7=undo塊被覆寫167次,0x3a=第58第undo記錄