ablog

不器用で落着きのない技術者のメモ

Oracle はどのようにして読み取り一貫性をとっているか(2)

Oracle はどのようにして読み取り一貫性をとっているか - ablog を実機で確認してみた。


[セッション1]emp表の中身を確認する。

$ sqlplus scott/tiger
SQL> select * from emp;

ID     NAME
------ --------------------
001    smith

[セッション1]update文を発行する。

SQL> update emp set name='neo' where id='001';

[セッション1]セッションIDを確認する。

SQL> select userenv('sid') from dual;

USERENV('SID')
--------------
           206

[セッション2]セッション1で変更したブロックをダンプする。

$ sqlplus / as sysdba
SQL> select extent_id, file_id, block_id, blocks from dba_extents where owner='SCOTT' and segment_name='EMP';

 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          4        169          8

SQL> alter system dump datafile 4 block 173;
SQL> !cat /export/home/oracle/admin/orcl/udump/orcl_ora_2147.trc
(中略)
Start dump data blocks tsn: 4 file#: 4 minblk 173 maxblk 173
buffer tsn: 4 rdba: 0x010000ad (4/173)
scn: 0x0000.0012f36a seq: 0x01 flg: 0x00 tail: 0xf36a0601
(中略) 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0007.023.000001ce  0x008008e9.00b5.17  C---    0  scn 0x0000.0012f02d
0x02   0x0006.026.000001d0  0x008000f8.01b8.09  ----    1  fsc 0x0002.00000000
(以下略) 

ダンプのITLを見ればUNDO情報がどのロールバックセグメントのどのブロックにあるかわかる。2行表示されてるのでどちらかになる。
[セッション1]使っているロールバックセグメント番号とスロット番号を調べる。

SQL> select addr, ses_addr,xidusn,used_ublk,xidslot,to_char(xidslot, 'XX') hexslot,start_scnb,ubablk from v$transaction t, v$session s where t.ses_addr=s.saddr and s.audsid=userenv('sessionid');

ADDR     SES_ADDR     XIDUSN  USED_UBLK    XIDSLOT HEXSLO START_SCNB     UBABLK
-------- -------- ---------- ---------- ---------- ------ ---------- ----------
602C7364 613DCE94          6          1         38  26             0        248

ロールバックセグメント番号6(XIDUSN)、スロット番号26(HEXSLOT)を使っている。ITLの2行目と一致する。
[セッション2]ロールバックセグメントの一覧を見てみる。

SQL> col segment_name for a10
SQL> select segment_name, owner,segment_id,file_id,block_id from dba_rollback_segs;

SEGMENT_NA OWNER        SEGMENT_ID    FILE_ID   BLOCK_ID
---------- ------------ ---------- ---------- ----------
SYSTEM     SYS                   0          1          9
_SYSSMU1$  PUBLIC                1          2          9
_SYSSMU2$  PUBLIC                2          2         25
_SYSSMU3$  PUBLIC                3          2         41
_SYSSMU4$  PUBLIC                4          2         57
_SYSSMU5$  PUBLIC                5          2         73
_SYSSMU6$  PUBLIC                6          2         89
_SYSSMU7$  PUBLIC                7          2        105
_SYSSMU8$  PUBLIC                8          2        121
_SYSSMU9$  PUBLIC                9          2        137
_SYSSMU10$ PUBLIC               10          2        153

セッション1でロールバックセグメント番号6を使っているから、FILE_ID=2、BLOCK_ID=89 がこのロールバックセグメントのヘッダ。
[セッション2]ロールバックセグメントヘッダをダンプする。

SQL> alter system dump datafile 2 block 89;
SQL> !cat /export/home/oracle/admin/orcl/udump/orcl_ora_2147.trc
(中略)
 TRN TBL::
 
  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
   0x00    9    0x00  0x01d0  0x0024  0x0000.0012ee76  0x008000f2  0x0000.000.00000000  0x00000001   0x00000000  1244741365
(中略)
   0x26   10    0x80  0x01d0  0x0006  0x0000.00000000  0x008000f8  0x0000.000.00000000  0x00000001   0x00000000  0
(以下略)

indexがスロット番号、wrap#が順序番号。「0x26 10 ...」の行を見ると、スロット番号、順序番号、SCNがさきほどのダンプのITLの2行目と一致している。
[セッション2]最後にロールバックセグメントのブロックをダンプしてみる。

SQL> alter system dump datafile 2 block 248;
SQL> !cat /export/home/oracle/admin/orcl/udump/orcl_ora_2147.trc
(中略)
********************************************************************************
UNDO BLK:  
xid: 0x0006.026.000001d0  seq: 0x1b8 cnt: 0x9   irb: 0x9   icl: 0x0   flg: 0x0000
(中略)
*-----------------------------
* Rec #0x9  slt: 0x26  objn: 13507(0x000034c3)  objd: 13768  tblspc: 4(0x00000004)
*       Layer:  11 (Row)   opc: 1   rci 0x00   
Undo type:  Regular undo    Begin trans    Last buffer split:  No 
Temp Object:  No 
Tablespace Undo:  No 
rdba: 0x00000000
*-----------------------------
uba: 0x008000f8.01b8.07 ctl max scn: 0x0000.0012ee39 prv tx scn: 0x0000.0012ee56
txn start scn: scn: 0x0000.0012f228 logon user: 32
 prev brb: 8388850 prev bcl: 0
KDO undo record:
KTB Redo 
op: 0x04  ver: 0x01  
op: L  itl: xid:  0x0005.01b.000001d5 uba: 0x008003a5.0171.33
                      flg: C---    lkc:  0     scn: 0x0000.0012f010
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x010000ad  hdba: 0x010000ab
itli: 2  ispac: 0  maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 8
ncol: 2 nnew: 1 size: 2
col  1: [ 5]  73 6d 69 74 68
 
End dump data blocks tsn: 1 file#: 2 minblk 248 maxblk 248

「xid: 0x0006.026.000001d0」となっており、ITLやTRN TBLのスロット番号、順序番号と一致している。
「col 1: [ 5] 73 6d 69 74 68」がUNDO情報。「col 1」は2カラム目を意味する。1カラム目は「col 0」になる。「73 6d 69 74 68」は16進数のASCIIコード。文字に変換すると「smith」。


[参考]
おら!オラ!オラクル
http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05771-03/statviews_4.htm#125534