• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            如何在 DB2 UDB 中監(jiān)控死鎖

            Posted on 2011-12-21 16:59 Prayer 閱讀(731) 評論(0)  編輯 收藏 引用 所屬分類: DB2
            http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0602jiangt/

            序言

            本文的目的就是通過詳細的實例來闡述如何在DB2 UDB 中監(jiān)控死鎖的發(fā)生。在DB2 UDB中有兩種類型的監(jiān)控器:快照監(jiān)控器和事件監(jiān)控器。快照顧名思義就是數(shù)據(jù)庫連續(xù)狀態(tài)下的一個切面,通過快照監(jiān)控器,你可以很方便地查看當前連接的應用程序,當前等待的鎖,當前的死鎖,以及正在執(zhí)行的SQL語句,同時你可以查看緩沖區(qū),表和表空間的用法。如果保存歷史數(shù)據(jù),并且能夠做出比較,對于分析數(shù)據(jù)庫的并發(fā)性能有很大的幫助。

            但是我們并不能預測什么時候發(fā)生死鎖,所以如果有一個后臺程序能夠一直監(jiān)控數(shù)據(jù)庫的活動,記錄下所有的死鎖事件,這對于數(shù)據(jù)庫管理員來說是非常重要的。DB2 UDB提供了事件監(jiān)控器。通過不遺漏地獲得一段時間內(nèi)所有的數(shù)據(jù)庫事件(在本文中只關心其中的死鎖事件),事件監(jiān)控器提供了一種可以分析歷史數(shù)據(jù)(本文的重點),預測將來趨勢的可能。DB2 UDB同時提供了DB2 Performance Expert (DB2/PE) 或者類似的程序用來生成分析報表,不過這已經(jīng)超出了本文的范疇。


            常用術語

            鎖是控制應用程序并發(fā)的數(shù)據(jù)庫軟件機制,鎖用來防止以下情況的發(fā)生:

            1. 丟失以前更新

            2. 不可重復讀取

            3. 訪問未提交數(shù)據(jù)

            鎖的模式包括共享鎖和排他鎖,共享鎖允許其他程序讀取已經(jīng)被其他共享鎖占用的資源,所以也叫讀鎖,排他鎖意味著在釋放資源以前其他的應用程序無法訪問同一資源,所以也叫寫鎖。此外,DB2 UDB 還提供了不同的鎖級別,不同的應用程序可能會要求訪問不同范圍的數(shù)據(jù),鎖級別有利于充分利用系統(tǒng)資源,提高系統(tǒng)性能。若一個應用程序請求一個鎖,而該鎖被另外一個應用程序所使用且不能共享,DB2 UDB 就會掛起前一個應用程序。鎖升級就是當LOCKLIST (LOCKLIST代表鎖能夠占用的內(nèi)存空間) 耗盡或者一個應用程序所擁有的鎖大于MAXLOCKS*LOCKLIST的時候(MAXLOCKS 代表應用程序所擁有的鎖占所空間的百分比),DB2 UDB 就試圖把幾個行級別的鎖合并為一個表級別的鎖,從而釋放鎖空間。雖然鎖升級本身并不耗費多少時間,但是鎖住整個表通常會大大地降低并發(fā)性能。

            當應用程序處于掛起狀態(tài)超過了一段規(guī)定的時間后,DB2 UDB就會自動中止這個應用程序,同時會向SQLCA發(fā)送描述性的錯誤信息。當兩個或者更多的應用程序都持有另外一個應用程序所需資源上的鎖,沒有這些資源,那些應用程序都無法繼續(xù)完成其工作的時候,就會發(fā)生死鎖。

            在DLCHKTIME超時之后,DB2 UDB會中止發(fā)生死鎖的某個應用程序(通常為所做工作最少的那個應用程序),這會釋放這個應用程序所持有的所有的鎖,并允許別的應用程序繼續(xù)工作,DB2 UDB 將向被終止的應用程序的SQLCA發(fā)送描述性的錯誤信息。LOCKTIMEOUT 指定一個應用程序被允許的鎖等待的時間,這將避免全局的死鎖從而導致整個應用崩潰。如果LOCKTIMEOUT 的值為-1,應用程序會等待直到該鎖被釋放或者發(fā)生一個死鎖。


            事件監(jiān)控器

            事件監(jiān)控器用來收集當一個數(shù)據(jù)庫事件發(fā)生時所關聯(lián)的應用程序的信息。這里的事件指,連接,死鎖,聲明和事務。你可以定義你想監(jiān)控的事件類型的監(jiān)控器。比如說,一個死鎖監(jiān)控器就是用來監(jiān)控死鎖的發(fā)生。

            在DB2 UDB 中存在兩種和死鎖有關的事件類型:

            • DEADLOCKS
              記錄簡單的應用程序信息。
            • DEADLOCKS WITH DETAILS
              記錄所有復雜的信息,包括應用程序、執(zhí)行語句聲明以及死鎖的詳細信息。但是使用這種事件監(jiān)控器會因為需要得到大量額外的信息而降低系統(tǒng)的性能。

            如何監(jiān)控死鎖

            為了詳細說明事件監(jiān)控器在死鎖監(jiān)控中的用途,我引入了一個簡單的死鎖場景來觸發(fā)一個死鎖,在隨后的章節(jié),我會告訴讀者如何分析監(jiān)控結(jié)果以及根據(jù)結(jié)果來避免死鎖的發(fā)生。

            這里我們需要至少三個應用程序來調(diào)用DB2 CLI,一個用來監(jiān)控死鎖的發(fā)生,另外兩個用來產(chǎn)生死鎖。我們可以使用DB2 UDB 安裝時附帶的SAMPLE數(shù)據(jù)庫。

            1. 首先建立一個死鎖事件監(jiān)控器


            Session Monitor
            db2 connect to sample
            db2 "create event monitor dlmon for tables, deadlocks with 
            details write to file 'C:\dlmon'"
            mkdir C:\dlmon
            db2 "set event monitor dlmon state 1"
            

            2. 用另外兩個應用程序來產(chǎn)生一個死鎖


            Session A
            db2 connect to sample
            db2 +c "insert into employee values('000350', 'Truman',
             'I', 'Jiang', 'B00', '5892',
            '1999-02-21', 'Engineer', 19, 'M',
             '1978-06-17', 60000, 2000, 6000)"
            

            現(xiàn)在應用程序A就擁有了一個EMPLOYEE表的行級別的排他鎖

            (注: +c 代表不自動提交SQL語句,DB2 中 autocommit 是缺省設置,也可以通過 db2 update command options using c off 關閉該缺省選項。)


            Session B
            db2 connect to sample
            db2 +c "insert into project values('AD3300', 'Dead Lock Monitor', 'B00', '000350', 7.00, 
            '1982-07-21', '1983-02-03', 'AD3111')"
            

            現(xiàn)在應用程序B就擁有了一個PROJECT表的行級別的排他鎖


            Session A
            db2 +c "select projname from project"
            

            應用程序A需要PROJECT表上所有行的共享鎖,但是因為PROJECT表正在被應用程序B以排他鎖的形式獨占,這時候應用程序1就進入一個鎖等待的狀態(tài)。


            Session B
            db2 +c "select firstnme from employee"
            

            應用程序B也進入一個鎖等待的狀態(tài)。此時就出現(xiàn)了一個死鎖狀態(tài)。

            3. 兩個本身處于鎖等待并且占有資源的應用程序互相等待另外一方所持有的資源,這時候Session A和Session B就出現(xiàn)了死鎖狀態(tài),這種狀態(tài)一直會延續(xù)直到死鎖檢查器(超出DLCHKTIME時間以后)檢查出一個死鎖并且回滾其中的一個事務。


            Session B
            SQLN0991N 因為死鎖或者超時,當前事務已經(jīng)被回滾。原因碼為 "2". SQLSTATE=40001
            這時候死鎖事件監(jiān)控器就會記錄這個死鎖,同時應用程序A可以完成他的工作。
            


            Session A
            PROJNAME
            ----------------------------------------
            ……
            20 條記錄已選擇
            


            Session A
            db2 connect reset
            


            Session B
            db2 connect reset
            

            4. 通過 db2evmon 工具可以獲得死鎖信息的日志,并且把日志文件導入到本地機器的文件系統(tǒng)當中。在下面一節(jié),我們將詳細分析導出的日志文件。


            Session Monitor
            db2 connect reset
            db2evmon -path c:\dlmon > c:\dlmon\dllog1.txt
            


            分析監(jiān)控結(jié)果

            本節(jié)我們開始詳細分析上一節(jié)產(chǎn)生的監(jiān)控結(jié)果,從監(jiān)控導出的日志文件中,我們可以分析出死鎖發(fā)生的時間,級別,模式以及產(chǎn)生死鎖的SQL語句,從而據(jù)此來進一步地修正可能由程序并發(fā)設計或者數(shù)據(jù)庫設計所導致的缺陷。


            	
            --------------------------------------------------------------------------
                                        EVENT LOG HEADER
              Event Monitor name: DLMON
              Server Product ID: SQL08022
            ……
              Server instance name: DB2
            --------------------------------------------------------------------------
            --------------------------------------------------------------------------
              Database Name: SAMPLE  
              Database Path: C:\DB2\NODE0000\SQL00001\
            	……
            --------------------------------------------------------------------------
            3) Deadlock Event ...
              Deadlock ID:   1
            	……
            4) Connection Header Event ...
              Appl Handle: 949
            	……
            5) Deadlocked Connection ...
              Deadlock ID:   1
              Participant no.: 2
              Participant no. holding the lock: 1
              Appl Id: G9B56A72.HE13.01B406083205
              Appl Seq number: 0001
              Appl Id of connection holding the lock: G9B56A72.HD13.02CE06083152
            	……
              Deadlock detection time: 2006-01-06 16:34:27.327582
              Table of lock waited on      : EMPLOYEE
            	(A鎖發(fā)生的表)
              Schema of lock waited on     : JT      
              Tablespace of lock waited on : USERSPACE1
              Type of lock: Row
            	(A鎖級別為行鎖)
              Mode of lock: X   - Exclusive
            	(A鎖模式為排他鎖)
              Mode application requested on lock: NS - Share (and Next Key Share)
            	(在A排他鎖上要求B共享鎖,發(fā)生死鎖)
            	……
            Text     : select name from employee
            (產(chǎn)生B共享鎖的SQL語句)
              List of Locks:
            	(當前所有鎖的列表)
            		……
                  Lock Name                   : 0x020005000D0000000000000052
                  Lock Attributes             : 0x00000008
                  Release Flags               : 0x40000000
                  Lock Count                  : 1
                  Hold Count                  : 0
                  Lock Object Name            : 13
                  Object Type                 : Row
                  Tablespace Name             : USERSPACE1
                  Table Schema                : JT      
                  Table Name                  : PROJECT
                  Mode                        : X   - Exclusive
            		  (在PROJECT表上有一個排他鎖)
            ……
                  Lock Name                   : 0x02000300000000000000000054
                  Lock Attributes             : 0x00000000
                  Release Flags               : 0x00000001
                  Lock Count                  : 1
                  Hold Count                  : 0
                  Lock Object Name            : 3
                  Object Type                 : Table
                  Tablespace Name             : USERSPACE1
                  Table Schema                : JT      
                  Table Name                  : EMPLOYEE
                  Mode                        : IS  - Intent Share
            		(在EMPLOYEE表上有一個共享鎖)
              Locks Held: 6
              Locks in List: 6
            ……
            9) Table Event ...
              Table schema: JT      
              Table name: EMPLOYEE
              Record is the result of a flush: FALSE
              Table type: User
              Data object pages: 1
            ……
              Rows read: 35
              Rows written: 1
            	……
              Tablespace id: 2
              Table event timestamp: 2006-01-06 16:37:28.972501
            	(記錄EMPLOYEE表上發(fā)生的事件)
            	

            我們可以分析一下dllog1.txt 文件,來準確定位死鎖發(fā)生的原因,看看5)Deadlocked Connection: 我們可以看出死鎖發(fā)生的表是EMPLOYEE,同時我們也可以判斷出這是一個對于已被排他鎖占有的資源申請共享鎖所導致的死鎖。更加重要的是我們得到了產(chǎn)生死鎖的SQL語句,從上面我們可以推斷出一定存在別的應用程序在以獨占鎖的方式占用EMPLOYEE表,這很有可能就是對于EMPLOYEE表的插入或者更新動作造成的。

            而這最有可能就是插入或者更新事務時間過長所導致的,導致事務時間過長的原因大體有兩種,一是來自于并發(fā)程序的設計和編寫,二是來自于數(shù)據(jù)庫的設計和數(shù)據(jù)庫參數(shù)的調(diào)整。

            本節(jié)我們通過仔細地分析事件監(jiān)控器的結(jié)果來推斷出導致死鎖發(fā)生的原因,從而采取有效的措施去避免死鎖的發(fā)生。這些措施包括調(diào)整數(shù)據(jù)庫參數(shù),或者修改應用程序的代碼,或者修改SQL語句甚至是數(shù)據(jù)庫的設計來提高代碼和SQL語句執(zhí)行的效率。


            避免死鎖的方法

            越早地考慮數(shù)據(jù)庫設計中的并發(fā)性問題,就越可以提高代碼執(zhí)行的效率,降低程序開發(fā)和維護的成本,這里我們提出了一些避免死鎖,提高應用程序并發(fā)性的方法。

            • 設置隔離級別,根據(jù)應用程序的業(yè)務邏輯和數(shù)據(jù)完整性需求來決定合適的隔離級別,包括:RR,RS,CS,UR。該決定需要對應用程序需求和相關的業(yè)務規(guī)則具有基本理解
            • 盡量避免鎖升級,正確調(diào)整參數(shù)LOCKLIST, MAXLOCKS
            • SQL0911N返回碼68(LOCKTIMEOUT參數(shù))的原因是鎖等待超時,而SQL0911返回碼2(DLCHKTIME參數(shù))的原因則是因為死鎖被強制回滾,避免這兩種錯誤的方法就是合理設計數(shù)據(jù)庫和建立合理的索引
            • 盡快提交事務,不要在事務中加入不必要的執(zhí)行時間過長的代碼,比如大的代碼循環(huán)和遠程調(diào)用,或者一些沒有用處的SELECT語句
            • 應用程序的框架實現(xiàn)保證一旦發(fā)現(xiàn)SQL錯誤,立刻執(zhí)行回滾事務,釋放鎖。
            • 如果多個應用程序訪問同一資源,最好以相同的次序訪問。這樣,即使前一個訪問資源的應用程序會延遲其他應用程序的訪問,也不會導致死鎖的發(fā)生
            • 設定外鍵索引,如果想刪除父表中的行,就需要掃描多個子表中的多行數(shù)據(jù),這樣就需要占用多個子表的鎖,我們可以通過在外鍵上建立索引來減少掃描子表的行數(shù),否則若不建立索引,如果從父表中刪除一行的時候,就需要掃描整個子表
            香蕉aa三级久久毛片| 精品一区二区久久久久久久网站| 久久国产高清一区二区三区| 久久天天日天天操综合伊人av| 尹人香蕉久久99天天拍| 久久精品国产亚洲av影院| 久久免费99精品国产自在现线 | 精品久久久久久中文字幕大豆网| 久久笫一福利免费导航| 国产99久久久国产精免费| 欧美精品乱码99久久蜜桃| 999久久久免费国产精品播放| 久久婷婷五月综合色奶水99啪| 久久电影网2021| 亚洲AV日韩精品久久久久| 久久99国产精品久久99小说| 久久精品成人| 亚洲国产精品热久久| 老色鬼久久亚洲AV综合| 99久久国产亚洲综合精品| 久久99精品久久久久久噜噜| 99久久99久久精品免费看蜜桃| 色老头网站久久网| 久久激情亚洲精品无码?V| 91亚洲国产成人久久精品| 国产一区二区精品久久| 99久久精品国内| 91精品国产9l久久久久| 麻豆AV一区二区三区久久| 久久久久人妻一区精品色| 久久精品国产免费观看| 亚洲人成伊人成综合网久久久| 久久国产AVJUST麻豆| 一本一道久久a久久精品综合| 亚洲欧美日韩久久精品| 精品久久久久中文字幕一区| 久久久久国产精品麻豆AR影院| 久久九色综合九色99伊人| 久久一区二区三区免费| 亚洲乱码日产精品a级毛片久久| 无码人妻少妇久久中文字幕|