程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 淺談DB2數據庫的故障處理及最佳實踐

淺談DB2數據庫的故障處理及最佳實踐

編輯:DB2教程

當你在使用數據庫時,可能會遇到各種不同的問題。我認為解決問題的關鍵在於分清問題的種類,並清楚每種問題的解決辦法。另外很多的數據庫的問題都是由於錯誤的操作,錯誤的配置引起的,所以本文在解釋如何處理問題時也會給出一些好的建議,來避免產生問題。本文重點介紹實用的方法。

對問題的分類有很多種方法,在本文中我我采用了兩種分類方案。

第一種方案是是否有錯誤碼。即發生錯誤時是否同時返回了錯誤碼,錯誤碼既包括執行命令的返回碼,也包擴應用程序的返回碼。

有返回碼的錯誤解決方案是,在db2 CLP中運行 db2 ? SQLXXXX,然後根據對該問題的解釋采取相應的解決方案。對沒有錯誤碼的問題,如數據庫hang,CPU使用率過高等問題,解決問題的經驗將非常重要,在本文中會有詳細的說明。

根據錯誤碼解決問題舉例(在下文中,再出現需要用這種方法解決問題時將不再重復):

如在連接數據庫時發生錯誤

db2 connect to sample
SQL0332N There is no available conversion for the source code page "1386" to
the target code page "819". Reason Code "1". SQLSTATE=57017

錯誤碼分為返回碼(SQL0332N)和原因碼(Reason Code "1"),針對不同的原因碼有不同的解決方案

運行db2 ? sql0332

從輸出種可以看到對於 reason code 1的解釋是

……
1 source and target code page combination is not supported by the database manager.
……

所以可以通過設置代碼頁來解決這個問題

db2set db2codepage=1386
db2 terminate
db2 connect to sample

就可以成功連接了。

第二種分類方案是按照問題的范圍和性質進行分類。分類如下:

1.數據庫實例問題

2.數據庫問題

3.數據庫性能問題

4.應用開發與數據庫有關的問題

下面對每一類問題進行詳細說明。

一、數據庫實例的問題

數據庫實例問題可以分為兩種情況

1.實例無法啟動,運行db2start後,直接返回錯誤碼,如SQL1042C。

如果根據錯誤碼信息無法解決,可以嘗試如下方案:

重新更新該實例,以root身份登錄,

cd /usr/opt/db2_08_01/instance/
./db2iupdt <inst_name>

Tip:常見的產生實例無法啟動的原因

數據庫安裝了新的補丁後沒有運行db2iupdt

數據庫文件的權限被改成了777,數據庫文件的權限是有要求的,所以不能將所有的文件都改成777的權限

數據庫實例文件被刪除或損壞

主機名與db2nodes.cfg裡記錄的不一致

2.運行db2start時,hang在那裡,既不報錯,也無法啟動實例

這種情況一般是由於實例沒有正常的停止造成的,一般運行下列命令可以解決:

su - <inst_owner>
db2_kill
ipclean
su – root

(將所有的與該實例有關的db2進程殺死 kill -9 )

然後重新啟動實例。

3.數據庫實例崩潰問題

遇到實例崩潰的問題,首先查看db2diag.log,根據裡面的信息來分析數據庫宕機的原因。再看db2dump目錄中是否有trap文件。可以根據這些信息來分析原因,一般這類問題都需要IBM工程師協助解決。

宕機的原因可以分為兩類,一類是數據庫的BUG,即數據庫的缺陷引起的,一般如果遇到了數據庫的缺陷,都有臨時的解決方案,或者通過安裝最新的補丁來解決,對某些問題IBM也提供臨時的修訂來解決(需要付費)。另一類是操作系統,誤操作等非產品問題導致的,對非產品問題導致的宕機盡量要避免。

Tip:常見的數據庫宕機原因

系統的交換空間(paging space)用盡

數據庫的某個進程被kill

二、數據庫問題

1.數據連接問題

無法連接數據庫,常見的錯誤有代碼頁錯誤,通訊協議錯誤,數據庫狀態錯誤等。

對代碼頁類錯誤,可以通過設置db2codepage,db2country來解決,這兩個變量需要用db2set 設置成與數據庫一致的值。

當發生通訊類錯誤時,首先要要檢查環境變量DB2COMM=TCPIP是否已經設置,然後要檢查dbm cfg的SVCENAME,該變量可以直接設置成端口號,或者設置成服務名,該服務名要在services文件中設置成對應的端口號。要檢查該端口號是否已經被其他服務占用。在啟動數據庫後,可以運行netstat –an |grep ,來查看該端口處於的狀態。

TCP  0.0.0.0:50000     0.0.0.0:0       LISTENING

還有一種情況,當連接數據庫時,數據庫處於backup pending 狀態,無法連接。這是只要對數據庫做一個備份就可以了。

Tip:通常導致數據庫處於備份贊掛的原因

當一個數據庫從循環日志改成歸檔日志時,數據庫要求進行一次脫機備份,在重新啟動數據庫後,數據庫就處於備份贊掛的狀態

對於一個使用線形日志的數據庫,當做load時,表空間會處於備份贊掛的狀態,為了避免這種情況,load命令需要使用copy yes,或者nonrecoverable參數。

2.數據庫損壞

數據庫最嚴重的問題莫過於數據庫損壞,那麼當數據庫損壞時,最好的辦法是從備份恢復數據庫。

如果無法從備份恢復,可以根據損壞的原因嘗試相應的解決方案。

由於存儲問題導致部分數據文件損壞,但是數據庫還可以連接,這種情況可以采用導出數據庫的表結果和數據的方法來恢復數據庫。當然對損壞的表,導出是無法完成的,這是可以使用db2dart的導出數據功能來導出這些損壞的表的數據。

如果數據庫損壞到已經無法連接的程度,那麼除了從備份恢復,唯一的辦法是使用db2dart來導出所有的數據了。

Tip:如何使用db2dart來導出數據

運行命令

db2dart <dbname> /DDEL
# Table object data formatting start.
# Please enter
# Table ID or name, tablespace ID, first page, num of pages:
# (suffic page number with 'p' for pool relative),

按照提示輸入表名,表空間id,起始頁數,需要導出的頁數

3.數據庫的活動日志被刪除

這個問題經常會遇到。也屬於數據庫損壞的一種情況。並且數據庫無法連接。

首先考慮是否有可以恢復的備份,如果有,可以從備份恢復,然後前滾到日志的末尾,可以完全恢復該數據庫。如果沒有可用的備份來恢復,可以通過IBM的技術支持中心來協助解決。如果想自己解決那只有使用db2dart工具了。

Tip:如何避免數據庫的活動日志被刪除

啟用數據庫的鏡像日志功能

啟用數據庫的日志出口程序,這樣可以避免手工來刪除活動日志目錄中的日志

當一定要手工刪除活動日志目錄中的歸檔日志時,使用命令

PRUNE LOGFILE PRIOR TO log-file-name,]

可以避免失誤將活動日志刪除

三、數據庫性能問題

數據庫的性能問題一般不屬於故障,但是當性能問題變得很嚴重時,就變成了故障。

解決數據庫的性能問題,可以從以下方面入手,檢查數據庫的配置,如緩沖池,排序堆等是否合理;檢查數據庫是否收集過統計信息,准確的統計信息對語句優化起著重要的左右;對sql語句進行優化;查看是否有系統資源瓶頸。

確認性能問題首先要從系統的資源消耗來分析,一般可以借助操作系統的工具,如aix的topas命令。數據庫的性能問題一般的表現是應用變慢,甚至沒有響應。

Tip:如何快速定位問題

如果系統的CPU利用很高,IO很少,那麼數據庫的排序較多

如果系統的IO繁忙,CPU很多是wait,那麼說明數據庫有過多的IO

如果系統CPU,IO都很空閒,那麼說明可以是有鎖的問題

如果系統IO,CPU都非常忙,說明有執行代價非常高的sql在執行

數據庫一般有三類的性能問題,一是CPU占用過多,二是IO過於繁忙,三是有鎖等待。

1.快速找到執行成本較高的sql

首先要打開監視器的開關

db2 update monitor switches using bufferpool on lock on sort on statement on table on uow on

在系統最繁忙的時候,運行

db2 get snapshot for all applications > app.out

然後在該文件中查找處於Executing狀態的應用,找到執行的對應的sql語句。

如果用這種方法找不到,可以收集sql的快照

db2 get snapshot for dynamic sql on <dbname> > sql.out

這個快照記錄了動態語句的快照信息,可以根據

Total execution time (sec.ms)   = 0.000000
Total user cpu time (sec.ms)    = 0.000000
Total system cpu time (sec.ms)   = 0.000000

這些信息來找到最耗時的語句。

2.如何優化sql語句

DB2提供了很好的工具來做sql語句優化。首先要對找到的sql語句進行分析,看是否是該語句引起了性能問題。我們可以使用db2expln來查看sql語句的訪問計劃和執行成本。

首先將找到的sql語句寫到一個文本文件中sql.in,以“;”結尾,然後運行

db2expln –d <dbname> -f <sql.in> -z “;” –g –o sql.exp

查看 sql.exp可以看到這個sql語句的執行成本。

如果確認該語句有問題,可以使用db2advis來通過建索引的方法來優化該語句

db2advis –d <dbname> -i sql.in

如果通過創建索引無法優化該語句,一般只能從業務角度優化。

3.如果發生鎖的問題如何處理

發生鎖的問題,一般有兩種情況,一是鎖等待,二是死鎖。首先檢查數據庫配置參數locktimeout,該參數一定不能設為-1,因為會引起某些應用無限期的等待。

可以通過快照來確定數據庫發生的問題是哪一種。

db2 get snapshot for db on <dbname>

查看輸出中的下列內容:

Deadlocks detected             = 0
Lock Timeouts               = 0

如果發生了死鎖,可以通過創建死鎖監視器來分析產生死鎖的原因,命令如下:

mkdir /tmp/dlmon
db2 connect to <db>
db2 create event monitor dlmon for deadlocks with detail write to file ‘/tmp/dlmon’ replace
db2 set event monitor dlmon state 1
…..等有死鎖發生後
db2 set event monitor dlmon state 0
db2evmon –d /tmp/dlmon >/tmp/dlmon.out

分析/tmp/dlmon.out文件就可以找到造成死鎖的信息,結合應用就可以找到造成死鎖的原因了。

四、應用開發與數據庫有關的問題

1.與64位實例數據庫問題

目前隨著硬件的升級,64位實例數據庫開始廣泛使用。

有些人擔心數據庫使用64位以後,對程序的運行很大,因此不願意使用64位的數據庫,實際上64位數據庫對客戶的應用影響非常小,所以建議如果資源充足,盡量使用64位實例的數據庫。

可以通過創建一個32位實例的客戶端,然後通過客戶端來使用64位實例數據庫的方法來將64位的問題完全忽略。

如果使用Java 存儲過程或自定義函數,64位實例數據庫需要安裝64位的JDK。

2.從DB2 V7移植程序到V8有關問題

sqlc的應用程序中,數據類型long在V8中需要改成sqlint32,否則編譯無法通過。如果確定long類型的數據長度與平台無關,也可以在編譯時,指定LONGERROR NO選項。

在編譯sqlc程序時可能會遇到sql20230的錯誤,原因是在V8中不允許在call中使用主機變量,將執行語句改成動態sql後,可以解決該問題。

在執行存儲過程時,遇到sql0433的錯誤,原因同上,將call 存儲過程的語句改成動態調用即可。

3.Java程序問題

編寫良好的程序是避免產生問題的關鍵。對Java程序有如下建議,一定要用數據庫的連接池;在執行大量的sql語句時使用prepared statement。

結束語

本文描述常見的數據庫故障,並給出了簡單有效的解決方案。對某些技術問題,如命令的使用沒有詳細介紹,當需要時可以查閱DB2相關的文檔。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved