INSERT 鎖 在DB2中提高INSERT性能的技巧
Posted on 2010-04-23 10:51 Prayer 閱讀(2399) 評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi): DB2為了盡可能好地進(jìn)行頁(yè)清除:
* 將 CHNGPGS_THRESH 數(shù)據(jù)庫(kù)配置參數(shù)的值從缺省的 60 減少到 5 這么低。這個(gè)參數(shù)決定緩沖池中臟頁(yè)的閾值百分比,當(dāng)臟頁(yè)達(dá)到這個(gè)百分比時(shí),就會(huì)啟動(dòng)頁(yè)清除。
* 嘗試啟用注冊(cè)表變量 DB2_USE_ALTERNATE_PAGE_CLEANING(在 DB2 V8 FixPak 4 中最新提供)。通過(guò)將這個(gè)變量設(shè)置成 ON,可以為頁(yè)清除提供一種比缺省方法(基于 CHNGPGS_THRESH 和 LSN 間隙觸發(fā)器)更積極的方法。我沒(méi)有評(píng)測(cè)過(guò)其效果。請(qǐng)參閱 FixPak 4 Release Notes 以了解這方面的信息。
* 確保 NUM_IOCLEANERS 數(shù)據(jù)庫(kù)配置參數(shù)的值至少等于數(shù)據(jù)庫(kù)中物理存儲(chǔ)設(shè)備的數(shù)量。
至于 I/O 本身,當(dāng)需要建立索引時(shí),可以通過(guò)使用盡可能大的緩沖池來(lái)將 I/O 活動(dòng)減至最少。如果不存在索引,則使用較大的緩沖池幫助不大,而只是推遲了 I/O。也就是說(shuō),它允許所有新頁(yè)暫時(shí)安放在緩沖池中,但是最終仍需要將這些頁(yè)寫(xiě)到磁盤(pán)上。
當(dāng)發(fā)生將頁(yè)寫(xiě)到磁盤(pán)的 I/O 時(shí),通過(guò)一些常規(guī)的 I/O 調(diào)優(yōu)步驟可以加快這一過(guò)程,例如:
* 將表空間分布在多個(gè)容器(這些容器映射到不同磁盤(pán))。
* 盡可能使用最快的硬件和存儲(chǔ)管理配置,這包括磁盤(pán)和通道速度、寫(xiě)緩存以及并行寫(xiě)等因素。
* 避免 RAID5(除非是與像 Shark 這樣有效的存儲(chǔ)設(shè)備一起使用)。
5. 鎖
缺省情況下,每一個(gè)插入的行之上都有一個(gè) X 鎖,這個(gè)鎖是在該行創(chuàng)建時(shí)就開(kāi)始有的,一直到 insert 被提交。有兩個(gè)跟 insert 和鎖相關(guān)的性能問(wèn)題:
* 為獲得和釋放鎖而產(chǎn)生的 CPU 開(kāi)銷(xiāo)。
* 可能由于鎖沖突而導(dǎo)致的并發(fā)問(wèn)題。
對(duì)于經(jīng)過(guò)良好優(yōu)化的批量插入,由獲得每一行之上的一個(gè) X 鎖以及后來(lái)釋放該鎖引起的 CPU 開(kāi)銷(xiāo)是比較可觀的。對(duì)于每個(gè)新行之上的鎖,惟一可以替代的是表鎖(DB2 中沒(méi)有頁(yè)鎖)。當(dāng)使用表鎖時(shí),耗時(shí)減少了 3%。有 3 種情況可以導(dǎo)致表鎖的使用,在討論表鎖的缺點(diǎn)之前,我們先用一點(diǎn)時(shí)間看看這 3 種情況:
* 運(yùn)行 ALTER TABLE
* 運(yùn)行 LOCK TABLE
* 使用缺省鎖,但是讓 LOCKLIST 和 MAXLOCKS 數(shù)據(jù)庫(kù)配置參數(shù)的值比較小。當(dāng)獲得少量的行鎖時(shí),行鎖就會(huì)自動(dòng)地逐漸升級(jí)為表鎖。
當(dāng)然,所有這些的缺點(diǎn)就在于并發(fā)的影響:如果表上有一個(gè) X 鎖,那么其他應(yīng)用程序除非使用了隔離級(jí)別 UR(未提交的讀),否則都不能訪問(wèn)該表。如果知道獨(dú)占訪問(wèn)不會(huì)導(dǎo)致問(wèn)題,那么就應(yīng)該盡量使用表鎖。但是,即使您堅(jiān)持使用行鎖,也應(yīng)記住,在批量插入期間,表中可能存在數(shù)千個(gè)有 X 鎖的新行,所以就可能與其他使用該表的應(yīng)用程序產(chǎn)生沖突。通過(guò)一些方法可以將這些沖突減至最少:
* 確保鎖的升級(jí)不會(huì)無(wú)故發(fā)生。您可能需要加大 LOCKLIST 和/或 MAXLOCKS 的值,以允許插入應(yīng)用程序有足夠的鎖。
* 對(duì)于其他的應(yīng)用程序,使用隔離級(jí)別 UR。
* 對(duì)于 V8 FixPak 4,或許也可以通過(guò) DB2_EVALUNCOMMITTED 注冊(cè)表變量來(lái)減少鎖沖突:如果將該變量設(shè)置為 YES,那么在很多情況下,只能獲得那些符合某個(gè)謂詞的行上的鎖,而并不是獲得被檢查的所有行上的鎖。
* 發(fā)出一個(gè) COMMIT 命令以釋放鎖,因此如果更頻繁地提交的話就足以減輕鎖沖突的負(fù)擔(dān)。
注意
* 在 V7 中,存在涉及 insert 和鍵鎖的并發(fā)問(wèn)題,但是在 V8 中,由于提供了 type-2 索引,這些問(wèn)題實(shí)際上已經(jīng)不見(jiàn)了。如果要遷移到 V8 中來(lái),那么應(yīng)該確保使用帶 CONVERT 關(guān)鍵字的 REORG INDEXES 命令,以便將索引從 type-1 轉(zhuǎn)換為 type-2。
* 在 V7 中,插入過(guò)程中可能使用 W 或 NW 鎖,但是在 V8 中只有在使用了 type-1 索引或者隔離級(jí)別為 RR 的情況下才會(huì)出現(xiàn)這兩種鎖。因此,應(yīng)盡可能避免這兩種情況。
* 一條 insert 所據(jù)有的鎖(通常是一個(gè) X 鎖)通常不會(huì)受隔離級(jí)別的影響。例如,使用隔離級(jí)別 UR 不會(huì)阻止從插入的行上獲得鎖。然而,如果使用了 INSERT ... SELECT,則隔離級(jí)別將影響從 SELECT 獲得的鎖。
6. 日志記錄
缺省情況下,每條 insert 都會(huì)被記錄下來(lái),以用于恢復(fù)。日志記錄首先被寫(xiě)到內(nèi)存中的日志緩沖池,然后再寫(xiě)到日志文件,通常是在日志緩沖池已滿或者發(fā)生了一次提交時(shí)寫(xiě)到日志文件的。對(duì)批量插入的日志記錄的優(yōu)化實(shí)際上就是最小化日志記錄寫(xiě)的次數(shù),以及使寫(xiě)的速度盡可能快。
這里首先考慮的是日志緩沖池的大小,這由數(shù)據(jù)庫(kù)配置參數(shù) LOGBUFSZ 來(lái)控制。該參數(shù)缺省值為 8 頁(yè)或 32 K,這與大多數(shù)批量插入所需的理想日志緩沖池大小相比要小些。舉個(gè)例子,對(duì)于一個(gè)批量插入,假設(shè)對(duì)于每一行的日志內(nèi)容有 200 字節(jié),則在插入了 160 行之后,日志緩沖池就將被填滿。如果要插入 1000 行,因?yàn)槿罩揪彌_池將被填滿幾次,再加上提交,所以大概有 6 次日志寫(xiě)。如果將 LOGBUFSZ 的值增加到 64 頁(yè)(256K)或者更大,緩沖池就不會(huì)被填滿,這樣的話對(duì)于該批量插入就只有一次日志寫(xiě)(在提交時(shí))。通過(guò)使用更大的 LOGBUFSZ 可以獲得大約 13% 的性能提升。較大日志緩沖池的不利之處是,緊急事故恢復(fù)所花的時(shí)間可能要稍微長(zhǎng)一點(diǎn)。


