本文通過對oracle數(shù)據(jù)庫鎖機制的研究,首先介紹了oracle數(shù)據(jù)庫鎖的種類,并描述了實際應(yīng)用中遇到的與鎖相關(guān)的異常情況,特別對經(jīng)常遇到的由于等待鎖而使事務(wù)被掛起的問題進行了定位及解決,并對死鎖這一比較嚴(yán)重的現(xiàn)象,提出了相應(yīng)的解決方法和具體的分析過程。
數(shù)據(jù)庫是一個多用戶使用的共享資源。當(dāng)多個用戶并發(fā)地存取數(shù)據(jù)時,在數(shù)據(jù)庫中就會產(chǎn)生多個事務(wù)同時存取同一數(shù)據(jù)的情況。若對并發(fā)操作不加控制就可能會讀取和存儲不正確的數(shù)據(jù),破壞數(shù)據(jù)庫的一致性。
加鎖是實現(xiàn)數(shù)據(jù)庫并發(fā)控制的一個非常重要的技術(shù)。當(dāng)事務(wù)在對某個數(shù)據(jù)對象進行操作前,先向系統(tǒng)發(fā)出請求,對其加鎖。加鎖后事務(wù)就對該數(shù)據(jù)對象有了一定的控制,在該事務(wù)釋放鎖之前,其他的事務(wù)不能對此數(shù)據(jù)對象進行更新操作。
在數(shù)據(jù)庫中有兩種基本的鎖類型:排它鎖(exclusive locks,即x鎖)和共享鎖(share locks,即s鎖)。當(dāng)數(shù)據(jù)對象被加上排它鎖時,其他的事務(wù)不能對它讀取和修改。加了共享鎖的數(shù)據(jù)對象可以被其他事務(wù)讀取,但不能修改。數(shù)據(jù)庫利用這兩種基本的鎖類型來對數(shù)據(jù)庫的事務(wù)進行并發(fā)控制。
在實際應(yīng)用中經(jīng)常會遇到的與鎖相關(guān)的異常情況,如由于等待鎖事務(wù)被掛起、死鎖等現(xiàn)象,如果不能及時地解決,將嚴(yán)重影響應(yīng)用的正常執(zhí)行,而目前對于該類問題的解決缺乏系統(tǒng)化研究和指導(dǎo),本文在總結(jié)實際經(jīng)驗的基礎(chǔ)上,提出了相應(yīng)的解決方法和具體的分析過程。
oracle數(shù)據(jù)庫的鎖類型
根據(jù)保護的對象不同,oracle數(shù)據(jù)庫鎖可以分為以下幾大類:dml鎖(data locks,數(shù)據(jù)鎖),用于保護數(shù)據(jù)的完整性;ddl鎖(dictionary locks,字典鎖),用于保護數(shù)據(jù)庫對象的結(jié)構(gòu),如表、索引等的結(jié)構(gòu)定義;內(nèi)部鎖和閂(internal locks and latches),保護數(shù)據(jù)庫的內(nèi)部結(jié)構(gòu)。
dml鎖的目的在于保證并發(fā)情況下的數(shù)據(jù)完整性,本文主要討論dml鎖。在oracle數(shù)據(jù)庫中,dml鎖主要包括tm鎖和tx鎖,其中tm鎖稱為表級鎖,tx鎖稱為事務(wù)鎖或行級鎖。
當(dāng)oracle執(zhí)行dml語句時,系統(tǒng)自動在所要操作的表上申請tm類型的鎖。當(dāng)tm鎖獲得后,系統(tǒng)再自動申請tx類型的鎖,并將實際鎖定的數(shù)據(jù)行的鎖標(biāo)志位進行置位。這樣在事務(wù)加鎖前檢查tx鎖相容性時就不用再逐行檢查鎖標(biāo)志,而只需檢查tm鎖模式的相容性即可,大大提高了系統(tǒng)的效率。tm鎖包括了ss、sx、s、x等多種模式,在數(shù)據(jù)庫中用0-6來表示。不同的sql操作產(chǎn)生不同類型的tm鎖。如表1所示。
在數(shù)據(jù)行上只有x鎖(排他鎖)。在 oracle數(shù)據(jù)庫中,當(dāng)一個事務(wù)首次發(fā)起一個dml語句時就獲得一個tx鎖,該鎖保持到事務(wù)被提交或回滾。當(dāng)兩個或多個會話在表的同一條記錄上執(zhí)行dml語句時,第一個會話在該條記錄上加鎖,其他的會話處于等待狀態(tài)。當(dāng)?shù)谝粋€會話提交后,tx鎖被釋放,其他會話才可以加鎖。
當(dāng)oracle數(shù)據(jù)庫發(fā)生tx鎖等待時,如果不及時處理常常會引起oracle數(shù)據(jù)庫掛起,或?qū)е滤梨i的發(fā)生,產(chǎn)生ora-60的錯誤。這些現(xiàn)象都會對實際應(yīng)用產(chǎn)生極大的危害,如長時間未響應(yīng),大量事務(wù)失敗等。
tx鎖等待的分析
在介紹了有關(guān)地oracle數(shù)據(jù)庫鎖的種類后,下面討論如何有效地監(jiān)控和解決鎖等待現(xiàn)象,及在產(chǎn)生死鎖時如何定位死鎖的原因。
監(jiān)控鎖的相關(guān)視圖 數(shù)據(jù)字典是oracle數(shù)據(jù)庫的重要組成部分,用戶可以通過查詢數(shù)據(jù)字典視圖來獲得數(shù)據(jù)庫的信息。和鎖相關(guān)的數(shù)據(jù)字典視圖如表2所示。
tx鎖等待的監(jiān)控和解決在日常工作中,如果發(fā)現(xiàn)在執(zhí)行某條sql時數(shù)據(jù)庫長時間沒有響應(yīng),很可能是產(chǎn)生了tx鎖等待的現(xiàn)象。為解決這個問題,首先應(yīng)該找出持鎖的事務(wù),然后再進行相關(guān)的處理,如提交事務(wù)或強行中斷事務(wù)。
死鎖的監(jiān)控和解決在數(shù)據(jù)庫中,當(dāng)兩個或多個會話請求同一個資源時會產(chǎn)生死鎖的現(xiàn)象。死鎖的常見類型是行級鎖死鎖和頁級鎖死鎖,oracle數(shù)據(jù)庫中一般使用行級鎖。下面主要討論行級鎖的死鎖現(xiàn)象。
當(dāng)oracle檢測到死鎖產(chǎn)生時,中斷并回滾死鎖相關(guān)語句的執(zhí)行,報ora-00060的錯誤并記錄在數(shù)據(jù)庫的日志文件alertsid.log中。同時在user_dump_dest下產(chǎn)生了一個跟蹤文件,詳細描述死鎖的相關(guān)信息。
在日常工作中,如果發(fā)現(xiàn)在日志文件中記錄了ora-00060的錯誤信息,則表明產(chǎn)生了死鎖。這時需要找到對應(yīng)的跟蹤文件,根據(jù)跟蹤文件的信息定位產(chǎn)生的原因。
如果查詢結(jié)果表明,死鎖是由于bitmap索引引起的,將ind_t_product_his_state索引改為normal索引后,即可解決死鎖的問題。
| 表1 oracle的tm鎖類型 | |||
| 鎖模式 | 鎖描述 | 解釋 | sql操作 |
| 0 | none | ||
| 1 | null | 空 | select |
| 2 | ss(row-s) | 行級共享鎖,其他對象只能查詢這些數(shù)據(jù)行 | select for update、lock for update、lock row share |
| 3 | sx(row-x) | 行級排它鎖,在提交前不允許做dml操作 | insert、update、delete、lock row share |
| 4 | s(share) | 共享鎖 | create index、lock share |
| 5 | ssx(s/row-x) | 共享行級排它鎖 | lock share row exclusive |
| 6 | x(exclusive) | 排它鎖 | alter table、drop able、drop index、truncate table 、lock exclusive |
| 表2 數(shù)據(jù)字典視圖說明 | ||
| 視圖名 | 描述 | 主要字段說明 |
| v$session | 查詢會話的信息和鎖的信息。 | sid,serial#:表示會話信息。 program:表示會話的應(yīng)用程序信息。 row_wait_obj#:表示等待的對象。 和dba_objects中的object_id相對應(yīng)。 |
| v$session_wait | 查詢等待的會話信息。 | sid:表示持有鎖的會話信息。 seconds_in_wait:表示等待持續(xù)的時間信息 event:表示會話等待的事件。 |
| v$lock | 列出系統(tǒng)中的所有的鎖。 | sid:表示持有鎖的會話信息。 type:表示鎖的類型。值包括tm和tx等。 id1:表示鎖的對象標(biāo)識。 lmode,request:表示會話等待的鎖模式的信 息。用數(shù)字0-6表示,和表1相對應(yīng)。 |
| dba_locks | 對v$lock的格式化視圖。 | session_id:和v$lock中的sid對應(yīng)。 lock_type:和v$lock中的type對應(yīng)。 lock_id1: 和v$lock中的id1對應(yīng)。 mode_held,mode_requested:和v$lock中 的lmode,request相對應(yīng)。 |
| v$locked_object | 只包含dml的鎖信息,包括回滾段和會話信息。 | xidusn,xidslot,xidsqn:表示回滾段信息。和 v$transaction相關(guān)聯(lián)。 object_id:表示被鎖對象標(biāo)識。 session_id:表示持有鎖的會話信息。 locked_mode:表示會話等待的鎖模式的信 息,和v$lock中的lmode一致。 |
新聞熱點
疑難解答
圖片精選