天天看點

提高DB2通路的并發性

最近在研究DB2資料庫的鎖與并發性,在DB2 V8之前,DB2的并發通路沒Oracle做的好,這一點是事實,以下我們先看一下Oracle的并發讀、寫互相影響的機制:

[color=red]先出現[/color]\[color=blue]後出現[/color] [color=blue]讀工作負載[/color] [color=blue]寫工作負載[/color]

[color=red]讀工作負載[/color] 否(不堵塞) 否(不堵塞)

[color=red]寫工作負載[/color] 否(不堵塞) 是( 堵塞 )

而DB2 V8之前的并發讀、寫互相影響的機制:

[color=red]先出現[/color]\[color=blue]後出現[/color] [color=blue]讀工作負載[/color] [color=blue]寫工作負載[/color]

[color=red]讀工作負載[/color] 否(不堵塞) 可能

[color=red]寫工作負載[/color] 是(堵塞) 是( 堵塞 )

在DB2 V8之前,在遊标穩定性(CS)和讀穩定性(RS)隔離級别下DB2資料庫的并發通路性能不是很好:讀通路會影響寫通路、寫通路會影響讀通路、寫通路會影響寫通路;

為了提高DB2資料庫在遊标穩定性(CS)和讀穩定性(RS)隔離級别下的查詢(讀)并發性,從DB2 V8以後引入了三個DB2系統資料庫變量:

1、DB2_EVALUNCOMMITTED這個DB2系統資料庫變量:

當它被啟用時,它将修改DB2中隻讀查詢的行為,以減少鎖沖突,使之允許在索引掃描(必須是type-2索引)或表通路時推遲鎖,直到限定語句的所有謂詞都是已知的。

引入這個新的系統資料庫變量是為了可選地提高一些應用程式的并發性,其實質是允許讀掃描推遲或避免行鎖,隻能獲得那些符合某個謂詞的行上的鎖,而并不是獲得被檢查的所有行上的鎖。直到适合特定查詢的一個資料記錄成為已知。

這個系統資料庫變量的作用是判斷該SQL謂詞所掃描的行是否有鎖,如果沒有就可以檢索到資料。

這個系統資料庫變量影響DB2在遊标穩定性(CS)和讀穩定性(RS)隔離級别下的行鎖機制。

當你啟用該功能時,DB2可以對未送出的插入(INSERT)或者更新(UPDATE)資料進行謂詞判斷,如果未送出資料不符合這條語句的謂詞判斷條件,DB2将不對未送出資料加鎖。

這樣就免了因為要對未送出資料加鎖而引起的鎖等待狀态,提高了應用程式通路的并發性,同時DB2在無條件進行表掃描時會忽略删除的行資料(不管是否送出)。

這裡分兩種情況來看待:

第一種情況:對于插入(INSERT)或者更新(UPDATE),如果未送出資料不符合這條語句的謂詞判斷條件,DB2将不對未送出資料加鎖。

第二種情況:通過上面的實驗我們發現在啟用DB2_EVALUNCOMMITTED=ON時,對于DELETE操作,DB2在無條件進行表掃描時會忽略删除的行資料(不管是否送出)。

個人覺得有很大的問題,通過上面的這個測試,一個會話删除一條記錄并沒有送出,另外一個會話查詢的時候已經沒有這條記錄了,這相當于UR隔離級别。這樣顯然是不符合業務要求的。與其這樣還不如鎖住。

是以啟用DB2_EVALUNCOMMITTED=ON時,對于删除操作應該注意多多測試。

當您的DB2 環境中啟用了DB2_EVALUNCOMMITTED行為時,您應該清楚,謂詞計算可能發生在未送出的資料上。

而且,在表掃描通路中,被删除行會被無條件忽略,而對于type-2索引掃描,被删除的鍵不會被忽略(除非您還設定了DB2_SKIPDELETED系統資料庫變量)。

如果您要在DB2環境中單獨設定DB2_SKIPDELETED系統資料庫變量,DB2将允許在表掃描通路時無條件地忽略被删除行,并忽略type-2索引掃描通路的僞删除索引鍵。

2、DB2_SKIPDELETED這個DB2系統資料庫變量:

當它被啟用時,将允許使用CS或RS隔離級别的語句在索引掃描期間無條件地跳過被删除的鍵,而在表通路期間則無條件地跳過被删除的行。

當DB2_EVALUNCOMMITTED被啟用時,被删除的行會被自動跳過,但是除非同時啟用了DB2_SKIPDELETED,否則type-2索引中未送出的僞删除鍵不會被跳過。

但是這個功能在實際環境中用的時候一定要結合業務邏輯使用,因為這種情況下等同于"髒讀",是以一定多測試。

3、DB2_SKIPINSERTED這個DB2系統資料庫變量:

當它被啟用時,DB2将把未送出的INSERT(隻适于CS和RS隔離級别)看作它們還沒有被插入(如果沒有啟用該功能,如果未送出的插入資料符合這條語句的謂詞判斷條件,将會導緻鎖等待)。

該特性增加了并發性,同時又不犧牲隔離語義。

DB2為掃描器實作了這種能力,通過鎖屬性和鎖請求的回報,使其忽略未送出的插入行,而不是等待。

以上這三個DB2系統資料庫變量都是實力級别的,每次啟用/停用這些特性後都需要重新開機執行個體才能生效,輸出結果如下:

db2set DB2_EVALUNCOMMITTED=ON(OFF) -i

db2set DB2_SKIPDELETED=ON(OFF) -i

db2set DB2_SKIPINSERTED=ON(OFF) -i

db2stop force

db2start

----------------------------------------------------------------------------------

到DB2 V9.7版本時增加了"目前已落實"(Currently Committed)的功能:

目前已落實(Currently Committed)工作原理:

從 DB2 V9.7 開始,DB2 通過采用完全鎖定避免(full lock avoidance techniques)技術,當能夠明确獲得資料或者頁的"已落實"版本時,允許掃描避免使用行級鎖。當無法獲知索引或行記錄是否已落實時,掃描将改為使用傳統的鎖定方式。 DB2 通過在行級鎖定中增加新的回報機制,來辨別哪些“日志記錄”描述了該行的首次修改(從該行的首次修改,就可以獲得修改前的資料值,也就是該行的已落實版本),當發生一個鎖沖突時鎖管理器将使用該回報機制直接傳回這些日志記錄編号。一個目前已落實掃描将用使用該回報結果,用來從日志(日志緩沖區中或者活動日志檔案中)通路該行的"目前已落實"版本(也就是首次更新之前的結果值)。未送出的插入行在行級鎖中是直接被辨別的,允許"目前已落實"掃描直接忽略或跳過該行。

預設情況下,新建立的資料庫"目前已落實"處于開啟狀态,這将允許任何的應用程從DB2 V9.7目前已落實這個新特性中獲益(不需要對現有的應用做任何的更改)。

如果你的資料庫是從之前的版本更新上來的,那麼預設情況下,"目前已落實"設定是處于不啟用狀态的。你可以通過資料庫配置參數cur_commit來啟用或不啟用"目前已落實"設定。

同時,你還可以通過BIND和PRECOMPILE/PREP指令對其CONCURRENTACCESSRESOLUTION子句指定USE CURRENTLY COMMITTED或WAITFOROUTCOME 來請求指令,對某個獨立的應用單獨設定"目前已落實",以替代資料庫級别的設定。

如何擷取或請求"目前已落實":

可以通過配置資料庫配置參數 CUR_COMMIT 擷取"目前已落實"或者通過 BIND/PRECOMPILE/PREP指令對其CONCURRENTACCESSRESOLUTION子句指定USE CURRENTLY COMMITTED 或 WAIT FOR OUTCOME 來請求"目前已落實"。

一、資料庫配置參數 cur_commit:

該資料庫配置參數主要是用來控制遊标穩定性掃描的行為,預設值為 ON,可選值為:

(1)ON :打開;

對于新建立的資料庫,預設值是 ON,在此情況下,當你試圖讀取一個正在被其他應用程式修改的行時,将直接傳回該行的目前已落實版本資料(也就是首次更改之前的值)。

(2)AVAILABLE:可用;

此值表示你的應用需要顯式地請求“目前已落實行為”才能得到“目前已落實”結果。

(3)DISABLED:禁用;

如果資料庫是從之前的版本更新而來,這個參數将被設定成 DISABLED,這是為了和以前版本的行為保持一緻。如果你希望使用目前已落實來控制遊标穩定性掃描的行為,需要将這個參數更改成 ON 。

需要注意的是,系統資料庫變量 DB2_EVALUNCOMMITTED、DB2_SKIPDELETED 和 DB2_SKIPINSERTED 在啟用 cur_commit 參數後會受到影響。在綁定(BIND)或預編譯(PRECOMPILE)時對 CONCURRENTACCESSRESOLUTION 選項指定 USE CURRENTLY COMMITTED 或 WAIT FOR OUTCOME,那麼系統資料庫變量DB2_EVALUNCOMMITTED、DB2_SKIPDELETED 和 DB2_SKIPINSERTED 将被忽略。

二、BIND 和 PRECOMPILE/PREP 的指令 CONCURRENTACCESSRESOLUTION 子句BIND 和 PRECOMPILE/PREP 指令的 CONCURRENTACCESSRESOLUTION 子句主要是為了對程式包中的語句指定使用并行通路解析,文法結構如清單 3 所示:

清單 3. BIND 指令 CONCURRENTACCESSRESOLUTION 子句文法結構:

>> - BIND - - filename - - - - - - - - - - - - - - - - - - - - - - - - - - >

> - - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - >

' - CONCURRENTACCESSRESOLUTION - - + - USE CURRENTLY COMMITTED - + - '

' --- WAIT FOR OUTCOME - - --- - '

- - 清單 3 - 2 . PRECOMPILE/PREP 指令 CONCURRENTACCESSRESOLUTION 子句文法結構:

>> - + - PRECOMPILE - + - - filename - - - - - - - - - - - - - - - - - - ->

' - -- PREP - - - '

> - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - >

' - CONCURRENTACCESSRESOLUTION - - + - USE CURRENTLY COMMITTED - + - '

' ---- WAIT FOR OUTCOME - - - - - '

1、USE CURRENTLY COMMITTED:

該選項值表示:當資料處于更新或删除的過程中時,指定資料庫管理器對掃描行為使用“目前已落實版本”,當行處于插入的過程中時這個設定将被跳過。當隔離級别處于遊标穩定性或者讀穩定性隔離級别時(對讀穩定性隔離級别這個子句将隻跳過未送出的插入操作)這個子句将有效,并且将忽略掉其他設定。

2、WAIT FOR OUTCOME:

該選項值表示:當遇上資料正處于更新的過程中時,指定遊标穩定性或更高的隔離級别掃描等待其送出或復原完成。當行處于插入或删除的過程中時這些行在掃描時将不再被跳過。這個選項值将會造成 DB2_EVALUNCOMMITTED、 DB2_SKIPDELETED 和 DB2_SKIPINSERTED 不再生效。

對于這個配置參數,在必須在所有應用程式都與此資料庫斷開連接配接之後,更改才會生效:

db2 update db cfg using cur_commit on

db2 force applications all

下面我們解釋幾個名詞的含義:

(1)隐式“目前已落實”:

是指當資料庫上的“目前已落實”設定啟用,而請求沒有顯式的請求“目前已落實”(也就是資料庫配置參數 CUR_COMMIT=ON,而且請求沒有通過BIND 或 PREP 指令将 CONCURRENTACCESSRESOLUTION 選項設定成 USE CURRENTLY COMMITTED 或 WAIT FOR OUTCOME)。

(2)顯式“目前已落實”:

是指程式包中的語句通過 BIND 或 PREP 指令顯式的請求“目前已落實”(通過 BIND 或 PREP 指令将 CONCURRENTACCESSRESOLUTION 選項設定成 USE

CURRENTLY COMMITTED)。

(3)“等待運作結果”(Wait For Outcome):

是指程式包中的語句通過 BIND 或 PREP 指令顯式的發出“等待運作結果”請求(通過 BIND 或 PREP 指令将 CONCURRENTACCESSRESOLUTION 選項設定成 WAIT FOR OUTCOME)。

以下是“目前已落實”對一些系統資料庫變量的影響:

[color=red]隐式"目前已落實"[/color] 隐式"目前已落實" [color=red]顯式"目前已落實"[/color] "等待運作結果"

[color=red]顯式"目前已落實"[/color] CS寫操作 [color=red]CS寫操作[/color] CS讀/寫操作

[color=red]CS隻讀操作[/color] RS讀/寫操作 [color=red]RS讀/寫操作[/color] RS讀/寫操作

[color=red]DB2_SKIPINSERTED[/color] 無效 無效 無效 無效

[color=red]DB2_SKIPDELETED[/color] 無效 [color=green]有效[/color] 無效 無效

[color=red]DB2_EVALUNCOMMITTED[/color] 無效 [color=green]有效[/color] 無效 無效

參考資料:[url]http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0906chengy/[/url]