天天看點

一條UPDATE從生到死的整個過程的深入解析data_block_dump,dataheader at 0xa5d664

1、sqlplus gyj/gyj@orcl

這一塊涉及到Oracle的網絡連接配接的知識點。我們先來看一幅描述Oracle用戶端與伺服器網絡連接配接的圖,并給出了連接配接的整個步驟:

一條UPDATE從生到死的整個過程的深入解析data_block_dump,dataheader at 0xa5d664

1)用戶端SQL Plus請求連接配接,監聽接受用戶端的TCP連接配接,并擷取用戶端發過來的TNS資料包。

(2)監聽程序打開用于與子程序通信的管道,同時fork一個子程序,稱為“監聽子程序1”的子程序,然後監聽程序一直等待,直到這個“監聽子程序1”結束。

(3)監聽子程序1 Fork出子程序2。

(4)完成上面一步,子程序1馬上退出并結束子程序1。

(5)子程序2收集本程序所在的主機名、IP位址及程序号等資訊,并把子程序2重名成server process(這裡我們也把server process叫前台程序或叫伺服器程序),申請占用一小塊PGA記憶體。

(6)前台程序把主機名、IP位址及程序号發送給監聽程序。

(7)監聽程序收到前台程序的資訊,并傳回用戶端的資訊(比如使用者密碼環境變量等)給前台程序。

(8)前台程序查詢USER$、PROFILE$等資料字典,校驗使用者名密碼是否合法,如果使用者密碼錯誤就報錯使用者名密碼無效,否則就與用戶端進行互動。

(9)用戶端收到前台程序的資訊與之互動,整個連接配接建立完成。

2、update t_gyj set name='gyj1' where id=1;

當這條sql發出來時,Oracle要做些什麼呢?我們先來看一張圖(來自DSI405的Library cache)

一條UPDATE從生到死的整個過程的深入解析data_block_dump,dataheader at 0xa5d664

在整個SGA中最複雜的就是sharedpool,而shared pool中最複雜就是library cache,這裡對它的機制不做詳細讨論,簡單講講sql在裡面的運作流程。

首先sql(update t_gyjset name='gyj1' where id=1)的每個字元當然包括空格轉化成ASCII碼後,再拿這一堆ASCII碼通過HASH函數生成一個sql_hash值,Oracle拿着這個sql_hash值去描掃HASH Buckets(看上面的圖,這個幅畫的不太好,隻畫了0号的HASH BUCKETS),假如剛好sql_hash值=0,那麼Oracle就延着0号HASH Buckets去搜尋Object Handle鍊,在這個Object Handle上存有sql的文本,如果和我們的update t_gyj set name='gyj1' where id=1一模一樣對上,那就說明這條sql已被緩存在共享池了,這個過程就是軟解析。當然再往下我就不說了,再說下去很複雜了父子遊标,最後執行計劃是被存放在堆6中。

   好,那麼如果通過上面的方式在Object Handle鍊沒搜尋到這條sql的文本,那說明sql不在共享池中,這個時侯就要做硬解析(過程大要做文法,語義,權限,查詢視圖展開、劃分小的查詢塊、sql等價轉換、代價估算、最後生成執行計劃),這個代價會有點高,如果有大量的硬解析那會消耗CPU和占用共享池。

   其實解析還有:軟軟解析、無解析。。。。嘻嘻!這裡不細說了,先簡單說到這裡,我們再往下看。

(一)如果ID列上無索引

(1)查詢SEG$等資料字典,找到T_GYJ表段頭

(2)從段頭讀出Extent Map,開始全掃描

(3)找到第一個滿足條件的行,進行修改

(4)查找同一塊中剩下的行,先構造一個CR塊,在CR塊中繼續查找,如果又找到滿足條件的行,在Xcur塊中修改。

(二)如果ID列上有索引,且版本不是11GR1(10G、11GR2),則不需要構造CR塊

(三)ID列無論是否有索引,在11GR1下都需要構造CR塊。

(四)如果NAME列上有索引,增加索引維護步驟:

(1)先在原索引塊中删除要修改的原值

(2)、再将新值插入

(五)任何塊的修改,都有以下步驟(非IMU)

(1)在PGA中生成UNDO段頭事務表的後映像(5.2)

(2)在PGA中生成UNDO塊的後映像(5.1)

(3)在PGA中生成DataBlock塊的後映像(11.9)

(4)将前三個Redo矢量做為一條Redo Recorder寫入Log buffer

(5)修改UNDO段頭的事務表,事務正式開始。

(6)修改UNDO塊,寫入DataBlock的前映像。

(7)修改DataBlock,将新值“gyj1”寫入Buffer cache。

(六)任何塊的修改,都有以下步驟(IMU)

(1)在PGA中生成DataBlock塊的後映像(11.9)

(2)在PGA中生成UNDO段頭事務表的後映像(5.2)

(3)在PGA中生成UNDO塊的後映像(5.1)

(4)将前三個Redo矢量做為一條Redo Recorder寫入Shared pool中的Private strand。

(5)将DataBlock中的前映像值,寫入Shared pool中的Imu pool。

(6)修改UNDO段頭的事務表。

(7)修改UNDO塊,寫入DataBlock的前映像。

(8)修改DataBlock,将新值“gyj1”寫入Buffer cache。

3、commit;

(一)非IMU下(按最常見的快速送出):

(1)在PGA中生成Commit的Redo 資訊(編号5.4),另做為一條Redo recorder,寫入Log buffer

(2)修改事務表相應Slot,聲明事務已送出。

(3)修改DataBlock,在ITL Slot中寫入快速送出标志和SCN。每行上的行鎖不清0。

(4)通知Lgwr,将Log buffer寫入Redo file。

(5)收到Lgwr通知,寫入完成。

(6)向使用者發收送出完成資訊。

(一)IMU下(按最常見的快速送出):

(1)在PGA中生成Commit的Redo 資訊(編号5.4),傳入Shared pool中的Private strand,追加在事務之前的Redo recorder之後。

(4)将Private Strand中的Redo資料寫入Log buffer。

(5)通知Lgwr,将Log buffer寫入Redo file。

(6)收到Lgwr通知,寫入完成。

(7)向使用者發收送出完成資訊。

4、exit

(1)、斷開連接配接,中止伺服器程序,釋放PGA

最後附:dump的資訊(針對update t_gyj set name='gyj1' where id=1;),有興趣大家可以去dump一下這樣可以更深入了解Oracle,使之成為自己的體系結構。

  1. redolog的dump

alter system dump logfile '/u01/app/oracle/oradata/ocm/redo02.log ';

REDO RECORD - Thread:1 RBA:0x0000d4.00000088.015c LEN: 0x00a4 VLD: 0x01

SCN: 0x0000.00f5e121 SUBSCN: 1 04/12/2013 08:45:43

CHANGE #1 TYP:0 CLS:23 AFN:6 DBA:0x018000b0OBJ:4294967295 SCN:0x0000.00f5e120 SEQ:1 OP:5.4 ENC:0 RBL:0

ktucm redo: slt: 0x0013 sqn: 0x00005a4dsrt: 0 sta: 9 flg: 0x2 ktucf redo: uba: 0x01800c05.0747.34 ext: 6 spc: 578 fbi:0

CHANGE #2 MEDIA RECOVERY MARKERSCN:0x0000.00000000 SEQ:0 OP:24.4 ENC:0

REDORECORD - Thread:1 RBA: 0x0000d4.00000089.0010 LEN: 0x0214 VLD: 0x05

SCN: 0x0000.00f5e123 SUBSCN: 1 04/12/2013 08:45:48

CHANGE #1 TYP:0 CLS:17 AFN:6 DBA:0x01800080OBJ:4294967295 SCN:0x0000.00f5e114 SEQ:1 OP:5.2 ENC:0 RBL:0

ktudh redo: slt: 0x0018 sqn: 0x000057efflg: 0x0012 siz: 164 fbi: 0

uba: 0x018021ba.0724.0f   pxid:  0x0000.000.00000000           

CHANGE #2 TYP:0 CLS:18 AFN:6 DBA:0x018021baOBJ:4294967295 SCN:0x0000.00f5e113 SEQ:1 OP:5.1 ENC:0 RBL:0

ktudb redo: siz: 164 spc: 6094 flg: 0x0012seq: 0x0724 rec: 0x0f

xid:  0x0001.018.000057ef           

ktubl redo: slt: 24 rci: 0 opc: 11.1 [objn:77365 objd: 77365 tsn: 7]

Undo type: Regular undo Begintrans Last buffer split: No

Temp Object: No

Tablespace Undo: No

0x00000000  prev ctl uba:0x018021ba.0724.0e           

prev ctl max cmt scn: 0x0000.00f5dc35 prev tx cmt scn: 0x0000.00f5dc3f

txn start scn: 0xffff.ffffffff logon user: 91 prev brb: 25174454 prev bcl: 0 BuExt idx: 0 flg2: 0

KDO undo record:

KTB Redo

op: 0x03 ver: 0x01

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

op: Z

KDO Op code: URP row dependencies Disabled

REDO RECORD - Thread:1 RBA:0x0000d4.00000089.0010 LEN: 0x0214 VLD: 0x05

uba: 0x018021ba.0724.0f   pxid:  0x0000.000.00000000           
xid:  0x0001.018.000057ef           
0x00000000  prev ctl uba:0x018021ba.0724.0e           

xtype: XA flags: 0x00000000 bdba:0x00c0027d hdba: 0x00c0027a

itli: 2 ispac: 0 maxfr: 4858

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

ncol: 2 nnew: 1 size: 2

col 1: [ 6] 41 41 41 41 41 41

CHANGE #3 TYP:2 CLS:1 AFN:3 DBA:0x00c0027dOBJ:77365 SCN:0x0000.00f5e0cc SEQ:1 OP:11.5 ENC:0 RBL:0

op: 0x11 ver: 0x01

op: F xid: 0x0001.018.000057ef uba: 0x018021ba.0724.0f

Block cleanout record, scn: 0x0000.00f5e123 ver: 0x01 opt: 0x02, entriesfollow...

itli: 1 flg: 2 scn: 0x0000.00f5e0cc

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

ncol: 2 nnew: 1 size: -2

col 1: [ 4] 67 79 6a 31

CHANGE #4 MEDIA RECOVERY MARKERSCN:0x0000.00000000 SEQ:0 OP:5.20 ENC:0

session number = 162

serial number = 7

transaction name =

version 186646784

audit sessionid 1362603

Client Id =

  1. undo的dump

(1) 對應OP=5.2的操作

alter system dump undo header"_SYSSMU1_1918248848$";

index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt

0x18 10 0x80 0x57ef 0x0010 0x0000.00f5e123 0x018021ba 0x0000.000.00000000 0x00000001 0x00000000 0

(2) 對應OP=5.1的操作,即undo塊資料

alter systemdump datafile 6 block 8634;

  • Rec #0xf slt:0x18 objn: 77365(0x00012e35) objd: 77365 tblspc: 7(0x00000007)
  • Layer: 11 (Row) opc: 1 rci 0x00

Undotype: Regular undo Begin trans Last buffer split: No

TempObject: No

TablespaceUndo: No

rdba:0x00000000Ext idx: 0

flg2: 0

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

uba:0x018021ba.0724.0e ctl max scn: 0x0000.00f5dc35 prv tx scn: 0x0000.00f5dc3f

txn startscn: scn: 0x0000.00f5e123 logon user: 91

prev brb: 25174454 prev bcl: 0

KDO undorecord:

op:0x03 ver: 0x01

compatbit: 4 (post-11) padding: 1

KDO Opcode: URP row dependencies Disabled

xtype: XA flags: 0x00000000 bdba: 0x00c0027d hdba: 0x00c0027a

itli:2 ispac: 0 maxfr: 4858

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

ncol: 2nnew: 1 size: 2

col 1: [ 6] 41 41 41 41 41 41

  1. data的dump

對應OP=11.9的操作

alter system dump datafile 3 block 637

Object idon Block? Y

seg/obj: 0x12e35 csc: 0x00.f5e123 itc: 2 flg: E typ: 1 - DATA

brn: 0 bdba: 0xc00278 ver: 0x01 opc: 0
 inc: 0 exflg: 0
           

Itl Xid Uba Flag Lck Scn/Fsc

0x01 0x0003.00d.00007825 0x01802b0c.0a53.2d C--- 0 scn 0x0000.00f5e0cc

0x02 0x0001.018.000057ef 0x018021ba.0724.0f ---- 1 fsc 0x0002.00000000

bdba:0x00c0027d

data_block_dump,dataheader at 0xa5d664

tsiz:0x1f98

hsiz:0x14

pbl:0x00a5d664

76543210           

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f80

avsp=0x1f77

tosp=0x1f79

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

0x12:pri[0] offs=0x1f80

block_row_dump:

tab 0,row 0, @0x1f80

tl: 11fb: --H-FL-- lb: 0x2 cc: 2

col 0: [ 2] c1 02

col 1: [ 4] 67 79 6a 31

  

附OPCODE:

Layer 5 : Transaction Undo - KCOCOTUN [ktucts.h]

Opcode 1 : Undo block or undo segment header - KTURDB
    Opcode 2 : Update rollback segment header - KTURDH
    Opcode 3 : Rollout a transaction begin
    Opcode 4 : Commit transaction (transaction table update)           
  • no undo record

    Opcode 5 : Create rollback segment (format) - no undo record

    Opcode 6 : Rollback record index in an undo block - KTUIRB

    Opcode 7 : Begin transaction (transaction table update)

    Opcode 8 : Mark transaction as dead

    Opcode 9 : Undo routine to rollback theextend of a rollback segment

    Opcode 10 :Redo to perform the rollback of extend of rollback segment

    to the segment header.           

    Opcode 11 :Rollback DBA in transaction table entry - KTUBRB

    Opcode 12 :Change transaction state (in transaction table entry)

    Opcode 13 :Convert rollback segment format (V6 -> V7)

    Opcode 14 :Change extent allocation parameters in a rollback segment

    Opcode 15 :

    Opcode 16 :

    Opcode 17 :

    Opcode 18 :

    Opcode 19 : Transaction start audit log record

    Opcode 20 : Transaction continue audit log record

    Opcode 24 : Kernel Transaction Undo Relog CHanGe – KTURLGU

Layer 11 : Row Access - KCOCODRW [kdocts.h]

Opcode 1 : Interpret Undo Record (Undo)
    Opcode 2 : Insert Row Piece
    Opcode 3 : Drop Row Piece
    Opcode 4 : Lock Row Piece
    Opcode 5 : Update Row Piece
    Opcode 6 : Overwrite Row Piece
    Opcode 7 : Manipulate First Column (add or delete the 1rst column)
    Opcode 8 : Change Forwarding address
    Opcode 9 : Change the Cluster Key Index
    Opcode 10 :Set Key Links (change the forward & backward key links
                on a cluster key)
    Opcode 11 :Quick Multi-Insert (ex: insert as select …)
    Opcode 12 :Quick Multi-Delete
    Opcode 13 :Toggle Block Header flags
           

注:11.19是在11g中才有,是11.5的改進update操作碼。

  Oracle的魅力也許就在于任何一個小概念都可以講出一大堆東西, 這裡沒有涉及到鎖、Latch、Mutex等,要整的東西太實在太多了,這幾個步驟完完整整寫下來可以出一本書了,涉及到Oracle的方方面面。