對與DML操作Oracle在內部按如下順序執行:
1,相應事務分配復原段(undo segment).
2,分配復原段後,在復原段頭上建立事務表slot(transaction table slot).
3.建立事務表後會生出TXID(TransactionID),再將TXID分配給當前事務。這個值指向分給事務的復原段頭上存在的事務表的準確位置。
4.事務對象的資料區塊載入到高速緩衝區,在塊頭的ITL(Intersted transaction list)上登記事務條目。
如果itl上沒有所需空間,就會發生等待enq:TX-allocate ITL entry。
5.將需要修改的塊的修改資訊儲存到PGA,儲存的方式是change vector,之後進程將PGA中的change vector以redo record複製到重做緩衝區。
6.將之前映像資訊記錄到撤銷塊,繼而修改資料區塊,被修改的資料區塊變為髒狀態。而且在高速緩衝區中建立以修改的資料區塊的CR塊。
7.執行commit後給事務分配SCN,提交資訊儲存在重做緩衝區。
8.復原段頭的事務表中儲存已成功提交的資訊,結束包括TX鎖在內的所有資源佔有。
9.重做緩衝區的內容記錄在重做記錄檔上。
下面通過轉儲來探究一下這個過程:
- 會話1
- SQL> update emp set sal=sal+100 where rownum=1;
-
- 1 rows updated.
- 獲得已執行update行位置
- SQL> select rowid,dbms_rowid.rowid_relative_fno(rowid) as fno,
- 2 dbms_rowid.rowid_block_number(rowid) as blkno
- 3 from emp where rownum=1;
-
- ROWID FNO BLKNO
- ------------------ ---------- ----------
- AAAQ+LAAEAAAAAfAAA 4 31
-
- file number是4,block number是31,dump 這個block。
-
- SQL> alter system dump datafile 4 block 31;
-
- System altered.
- SQL> l
- 1 SELECT a.VALUE
- 2 || b.symbol
- 3 || c.instance_name
- 4 || '_ora_'
- 5 || d.spid
- 6 || '.trc' trace_file
- 7 FROM (SELECT VALUE
- 8 FROM v$parameter
- 9 WHERE NAME = 'user_dump_dest') a,
- 10 (SELECT SUBSTR (VALUE, -6, 1) symbol
- 11 FROM v$parameter
- 12 WHERE NAME = 'user_dump_dest') b,
- 13 (SELECT instance_name
- 14 FROM v$instance) c,
- 15 (SELECT spid
- 16 FROM v$session s, v$process p, v$mystat m
- 17* WHERE s.paddr = p.addr AND s.SID = m.SID AND m.statistic# = 0) d
- SQL> /
-
- TRACE_FILE
- --------------------------------------------------------------------
- /opt/app/oracle/diag/rdbms/liqian/liqian/trace/liqian_ora_4118.trc