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