DB2 Universal Database (UDB) 是首個支援多媒體與 Web 的關聯式資料庫管理系統,功能強大滿足大企業需求,靈活符合中小企業要求。DB2 產品系列與網際網路技術結合,讓我們便利跨平台存取、使用資訊並確保安全。全球 30 萬家公司、6000 萬用戶仰賴 IBM 資料管理解決方案。
DB2 UDB 支援大多數電子商務應用(電子商務、ERP、CRM、SCM、Web 自助服務、BI)。這是可擴展的工業級資料庫,極適合作為電子商務發展的資料管理基礎。
線上交易處理(OLTP)是一類為面向交易應用提供便利並管理此類應用的程式,常用於銀行、航空、郵購、超市、製造業等行業的資料輸入與檢索交易。典型 OLTP 工作負載包含大量並發執行的短交易。現代 OLTP 日益要求跨網路、跨公司的交易支援,新軟體採用客戶端/伺服器處理與代理軟體,允許交易在網路不同電腦平台運行。
在任何資料庫系統中,效能是最重要因素之一。本文依據運行 OLTP 類型效能基準測試程式(TPC-C、TPC-W、Trade2 等)經驗,重點討論 DB2 效能調優技巧。雖資料庫應用效能受多因素影響,但著重配置而非容量規劃、資料庫設計或應用程式設計。
本文結構:效能基本要素、更新目錄統計資訊、監控與調優資料庫配置參數(按重要性排序)。通常無需嘗試所有參數,只需嘗試列表頂端的幾個即可觀察效能改善。
netstat 監控連線流量。透過 DB2 Control Center 的 DB2 Performance Configuration Wizard 設定初始 DB2 資料庫管理器與資料庫配置參數。精靈會詢問一系列工作負載性質問題以確定參數起始值,您可修改以滿足生產負載需求。
DB2_RR_TO_RS 登錄參數,透過不鎖定插入或更新列的下一個鍵改善並發性。若無程序對同組表用 RR 隔離層級,可用此操作。用 DB2 Snapshot 監控死鎖與鎖等待數。用 Visual Explain 或 db2exfmt 分析每條 SQL 陳述式。確保使用合適索引,在選擇與連接表時將必須內部存取的列數減至最少。
RUNSTATS 公用程式更新系統目錄表統計資訊,協助查詢優化。沒有這些統計資訊,資料庫管理器可能做出對 SQL 效能不利的決定。RUNSTATS 允許收集表與/或索引資料的統計資訊。以下情況應收集統計資訊為存取路徑選擇提供精確資訊:
REORG 重組表時。REDISTRIBUTE NODEGROUP 公用程式時。優化 SQL 查詢時,SQL 編譯器的決定受優化器資料庫內容模型重大影響。優化器用該資料模型估計解決特定查詢的其他存取路徑成本。資料模型關鍵元素是一組統計資訊,收集資料庫所含資料與系統目錄表儲存資料的資訊,含表、別名、索引、欄、使用者定義函數 (UDF) 統計資訊。資料統計變化會引起存取路徑選擇變化——作為存取期望資料的最有效方法。
關鍵統計資訊包括:表頁數與非空頁數、從原始頁移至溢位頁程度、表列數、單欄統計(如唯一值數)、索引群集程度、索引統計(層級數、葉頁數)、常用欄值出現次數、欄值分布、UDF 成本估計。
RUNSTATS 協助確定資料庫變更與效能關係。統計資訊顯示表中資料分布。常規使用提供一段時期內表與索引資料,隨時間流逝可確定資料模型效能趨勢。使用 RUNSTATS 後需重新綁定使用靜態 SQL 的應用程式,查詢優化器才能選擇新統計給出的最佳存取路徑。但對動態 SQL 應用(如大多數廠商應用)無需重新綁定,因陳述式優化根據統計資訊在執行時進行。統計資訊不準確可能導致效能問題,最糟情況是特定 SQL 導致 DB2 用表掃描而非索引掃描。
RUNSTATS 公用程式。LOAD。reorgchk update statistics 指令。當不完全知道所有表名或表名太多時,最簡單方法是 db2 reorgchk update statistics on table all。正確腳本:
db2 -v connect to DB_NAME
db2 -v "select tbname, nleaf, nlevels, stats_time from sysibm.sysindexes"
db2 -v reorgchk update statistics on table all
db2 -v "select tbname, nleaf, nlevels, stats_time from sysibm.sysindexes"
db2 -v terminate
此指令對所有表執行 RUNSTATS。記住:填充資料庫後再執行 RUNSTATS。
若知道表名想避免對大量表執行 RUNSTATS(可能花很長時間),一次對一張表較佳:
db2 -v runstats on table TAB_NAME and indexes all
收集該表及其所有索引(基本層級)統計資訊。
快速方法查詢系統目錄表。如上腳本所示,執行:
db2 -v "select tbname, nleaf, nlevels, stats_time from sysibm.sysindexes"
未執行 RUNSTATS 時,nleaf 與 nlevels 為 -1,stats_time 為 -。已執行則包含實際數字,stats_time 含時間戳記。若 stats_time 離現在很久,該再次執行 RUNSTATS。
以下技巧使您在 OLTP 環境獲得極好效能,同時避開顯而易見的陷阱。資料庫管理器配置參數需重啟資料庫管理器,大多數資料庫配置參數需應用程式重新連接資料庫生效。
背景:緩衝池是記憶體儲存區,用於暫時讀入與更改資料庫頁(含表列或索引項)。目的為提升資料庫系統效能。從記憶體存取資料比磁碟快得多。資料庫管理器從磁碟讀寫次數越少,效能越好。配置一或多個緩衝池是調優最重要面向,因連接資料庫應用程式的大多數資料操作(不含大物件與長欄位資料)都在緩衝池進行。
預設應用程式使用 IBMDEFAULTBP(建立資料庫時建立)。當 SYSCAT.BUFFERPOOLS 中該緩衝池 NPAGES 為 -1 時,BUFFPAGE 控制緩衝池大小;否則忽略 BUFFPAGE,用 NPAGES 指定頁數建立緩衝池。
建議:
NPAGES 改為 -1,讓 BUFFPAGE 控制大小,方便更新與報告緩衝池大小及其他參數。BUFFPAGE 控制緩衝池大小後,設為合適值。根據資料庫大小與應用性質設為合理大值很安全。預設值通常很小可能滿足不了需求。考慮:一開始若機器記憶體夠大,設 BUFFPAGE 為 40,000 頁(160 MB)或機器總記憶體 10%。大型 OLTP 資料庫,在保持系統穩定前提下為緩衝池留出盡可能多記憶體,一開始試 1.6 GB 然後更多。如何更改:
db2 -v connect to DB_NAME
db2 -v select * from syscat.bufferpools
db2 -v alter bufferpool IBMDEFAULTBP size -1
db2 -v connect reset
db2 -v update db cfg for dbname using BUFFPAGE bigger_value
db2 -v terminate
研究步驟:確定緩衝池大小是否由 BUFFPAGE 決定,查 SYSCAT.BUFFERPOOLS 的 NPAGES 是否為 -1。確定大小是否足夠,運行應用時收集資料庫/緩衝池快照:
db2 -v update monitor switches using bufferpool on
db2 -v get monitor switches
db2 -v reset monitor all
-- run your application --
db2 -v get snapshot for all databases > snap.out
db2 -v get snapshot for dbm >> snap.out
db2 -v get snapshot for all bufferpools >> snap.out
db2 -v reset monitor all
db2 -v terminate
確保斷開連接前發出 get snapshot。最後一個應用斷開時資料庫停止,快照統計遺失。確保持續有連接保持資料庫運行:保持一個單獨連接或用 ACTIVATE DATABASE。快照輸出中找 logical reads 與 physical reads 計算緩衝池命中率:
Buffer pool data logical reads = 702033
Buffer pool data physical reads = 0
Buffer pool index logical reads = 168255
Buffer pool index physical reads = 0
命中率 = (1 - (data physical reads + index physical reads) / (data logical reads + index logical reads)) * 100%。理想超過 95% 並盡可能接近 100%。提高命中率:增加緩衝池大小、考慮分配多個緩衝池(經常存取大表各自一個、小表群一個)、嘗試不同大小組合、若分配記憶體無助提升效能避免過度分配。根據測試環境快照資訊決定大小。
背景:資料庫配置參數,指定資料庫共享記憶體大小作為日誌記錄寫入磁碟前的緩衝區。以下事件發生時寫入磁碟:交易提交、日誌緩衝區已滿、其他內部事件。將日誌記錄留在緩衝區產生更有效日誌檔 I/O,降低寫入頻率、每次寫更多記錄。若專用日誌磁碟有相當多讀操作或希望有較高磁碟利用率,可增加緩衝區大小。增加此參數時也要考慮 DBHEAP,因日誌緩衝區空間由 DBHEAP 控制。
如何更改:預設 8(4KB 頁),對 OLTP 通常不夠。最佳值 128 或 256 個 4KB 頁:db2 -v update database cfg for DB_NAME using LOGBUFSZ 256
研究步驟:資料庫快照看 Log pages read 與 Log pages written。比值應盡可能小。理想 read=0、written 很大。read 太多意味著需更大 LOGBUFSZ。
背景:資料庫配置參數,定義代表特定代理程式或子代理程式的資料庫管理器可用私有記憶體頁數。初始化代理程式時分配堆,大小為處理請求所需最小值。需要更多堆空間處理大型 SQL 時,管理器按需分配,最大至參數指定值。
如何更改:預設 DB2 EE 128、DB2 EEE 64(4KB 頁),改為最佳值 256:db2 -v update db cfg for DB_NAME using applheapsz 256
研究步驟:應用程式收到堆空間不足錯誤時增加 APPHEAPSZ。
背景:SORTHEAP(資料庫配置)定義私有排序用私有記憶體頁最大數或共享排序用共享記憶體頁最大數。私有排序影響代理程式私有記憶體,共享排序影響資料庫共享記憶體。每個排序有單獨由管理器按需分配的排序堆。優化器指導分配時,分配大小小於參數指定值。SHEAPTHRES(資料庫管理器配置)私有與共享排序記憶體來源不同。共享排序記憶體區大小在首次連接資料庫時根據 SHEAPTHRES 靜態預先決定。私有排序記憶體區大小無限制。應用方式不同:私有排序為實例級「軟」限制,達限制時後續私有排序分配大幅減少;共享排序為資料庫級「硬」限制,達限制時不允許其他共享排序請求直到消耗回落。使用排序堆操作包括記憶體中表雜湊連接與操作。閾值顯式定義防止管理器將過多記憶體用於大量排序。
建議:用資料庫系統監視器追蹤排序活動、用合適索引將排序堆用量降至最低、頻繁大型排序時增加 SORTHEAP、增加 SORTHEAP 時確定是否需調整 SHEAPTHRES、優化器用排序堆大小確定存取路徑,更改後考慮重新綁定應用程式、理想將 SHEAPTHRES 合理設為實例中設定的最大 SORTHEAP 倍數,至少為任何資料庫定義最大 SORTHEAP 的兩倍。
如何更改:
db2 -v update db cfg for DB_NAME using SORTHEAP a_value
db2 -v update dbm cfg using SHEAPTHRES b_value
db2 -v terminate
研究步驟:OLTP 不應執行大型排序(CPU 與 I/O 成本太高)。預設 256(4KB 頁)通常足夠。高並發 OLTP 甚至可能想降低預設值。需進一步研究時:db2 -v update monitor switches using sort on,運行應用一會,db2 -v get snapshot for database on DBNAME。輸出範例:
Total sort heap allocated = 0
Total sorts = 1
Sort overflows = 0
Active sorts = 0
Commit statements attempted = 1
Rollback statements attempted = 0
Dynamic statements attempted = 4
Static statements attempted = 1
計算每交易排序數與溢出百分比:
SortsPerTransaction = Total Sorts / (Commit + Rollback)
PercentSortOverflow = (Sort overflows * 100) / Total sorts
經驗:SortsPerTransaction > 5 可能表明每交易排序太多;PercentSortOverflow > 3% 可能發生嚴重未預期大型排序。增加 SORTHEAP 只會掩蓋問題無法修正。正確解法是添加正確索引改進問題 SQL 的存取路徑。
背景:資料庫管理器配置參數。MAXAGENTS 為任何給定時間接受應用請求的最大代理程式數,值至少為並發存取每資料庫 MAXAPPLS 值總和。若資料庫數大於 NUMDB,最安全方案用 NUMDB * MAXAPPLS 最大值乘積。每額外代理程式需資源開銷,啟動管理器時分配。NUM_POOLAGENTS 為代理程式池增長準則。創建代理程式超過此值時,執行完當前請求後終止而非返回池。值為 0 時按需創建,執行完終止。為避免 OLTP 環境頻繁創建終止代理程式成本,將 NUM_POOLAGENTS 增加至接近 MAXAGENTS。NUM_INITAGENTS 決定啟動時池中空閒代理程式初始數,指定合適可縮短預熱時間。
建議:多數情況將 MAXAGENTS 與 NUM_POOLAGENTS 設為略大於並發應用連接最大預計數。NUM_INITAGENTS 保留預設較好。
如何更改:
db2 -v update dbm cfg using MAXAGENTS a_value
db2 -v update dbm cfg using NUM_POOLAGENTS b_value
db2 -v update dbm cfg using NUM_INITAGENTS c_value
db2 -v terminate
研究步驟:運行期間任何時候用 db2 -v get snapshot for database manager 取得快照。看 Agents waiting for a token 或 Agents stolen from another application 不為 0 時可能需增加 MAXAGENTS。
背景:資料庫配置參數。LOCKLIST 為鎖清單儲存容量。每資料庫一個鎖清單,含所有並發連接應用持有的鎖。鎖定控制多應用並發存取資料。列與表可被鎖定。每把鎖需 32 或 64 位元組:無其他鎖時 64 位元組,已有鎖時 32 位元組。MAXLOCKS 定義應用持有鎖清單百分比,達此百分比時管理器執行鎖升級(用表鎖取代列鎖減少清單鎖數)。任何應用持有鎖達整個清單大小此百分比時升級。鎖清單用盡也會升級。管理器查看應用鎖清單找列鎖最多的表決定升級哪些鎖。若用一表鎖取代這些列鎖不超出 MAXLOCKS 則停止,否則繼續直到百分比低於 MAXLOCKS。MAXLOCKS * MAXAPPLS 不能小於 100。升級過程本身不花太多時間,但鎖定整個表(相對於鎖定個別列)降低並發性,整體效能可能因後續存取受升級影響的表而降低。
控制鎖清單大小建議:頻繁提交釋放鎖;大量更新時先用 LOCK TABLE 鎖定整個表(僅用一把鎖防止其他交易干擾,但減少其他用戶並發性);用 ALTER TABLE LOCKSIZE 控制持久基礎上如何鎖定特定表;檢視應用隔離層級,RR 可能導致自動表鎖定,CS 可減少共享鎖,若不損害完整性可用 UR 進一步減少鎖。確定鎖清單所需頁數:下限 (512 * 32 * MAXAPPLS) / 4096,上限 (512 * 64 * MAXAPPLS) / 4096。估計並發數,在上下限間選擇初始值。用監視器調優 MAXLOCKS。設 MAXLOCKS 時考慮 LOCKLIST:MAXLOCKS = 100 * (512 * 32 * 2) / (LOCKLIST * 4096)(允許任何應用持有平均兩倍鎖)。少數應用並發時可增大 MAXLOCKS。LOCKTIMEOUT 指定應用等待鎖秒數,協助避免全域死鎖。0 為不等待,請求時無可用鎖立即收到 -911。-1 關閉超時檢測,等待直到授予鎖或死鎖。
建議:設 LOCKTIMEOUT 快速檢測異常等待(如用戶離開工作站),設夠高使有效鎖請求不因尖峰負載超時。OLTP 從 30 秒開始,純查詢環境可從更大值開始,用基準測試技術調優。
如何更改:
db2 -v update db cfg for DB_NAME using LOCKLIST a_number
db2 -v update db cfg for DB_NAME using MAXLOCKS b_number
db2 -v update db cfg for DB_NAME using LOCKTIMEOUT c_number
db2 -v terminate
研究步驟:開啟鎖監視器 db2 -v update monitor switches using lock on,收集資料庫快照。檢查 Lock list memory in use 超過 LOCKLIST 50% 時增加 LOCKLIST。鎖升級、超時、死鎖表明系統或應用潛在問題。鎖定問題通常表明應用存在嚴重並發性問題,增大鎖參數前應解決。
背景:資料庫配置參數,指定可連接資料庫的並發應用(本地與遠端)最大數。允許更多並發應用意味著用更多記憶體。值必須大於等於已連接應用數加上這些應用中完成兩階段提交或回滾過程中可能並發存在的數量總和。
建議:運行 OLTP 確保 MAXAPPLS 設正確(足夠大但非不必要大)容納最多並發用戶/連接。使用連接池的應用,建議 MAXAPPLS 設為連接池大小 +1 或 +2(以防需命令列連接同時做事)。
如何更改:db2 -v update db cfg for DB_NAME using MAXAPPLS a_number
研究步驟:應用嘗試連接但已達 MAXAPPLS 時返回 SQL1040N The maximum number of applications is already connected to the database. SQLSTATE=57030。
背景:資料庫配置參數,指定資料庫非同步頁面清除程式數。在資料庫代理程式需要緩衝池空間前,這些清除程式將緩衝池中已更改頁寫入磁碟。允許代理程式不等待已更改頁寫入即可讀取新頁,加快交易運行。設 0 時不啟動清除程式,代理程式將緩衝池所有頁寫入磁碟。對儲存於多個物理儲存裝置的單一資料庫效能有顯著影響,因某裝置極可能處於空閒。無配置清除程式時應用可能遇到不時發生的「日誌已滿」。主要執行更新交易的應用連接時增加清除程式數可提升效能。增加清除程式數也減少軟故障(如斷電)恢復時間,因磁碟上資料庫內容在任何時候都較新。
設值考慮:多交易運行時設在 1 到資料庫所用物理儲存裝置數之間,建議至少設為系統 CPU 數。高更新交易率環境可能需較多清除程式。大緩衝池環境也可能需較多。
如何更改:db2 -v update db cfg for DB_NAME using NUM_IOCLEANERS a_number
研究步驟:用系統監視器,利用緩衝池寫操作快照資料調優。監控:Buffer pool data writes、Asynchronous pool data page writes、Buffer pool index writes、Asynchronous pool index page writes、LSN Gap cleaner triggers、Dirty page steal cleaner triggers、Dirty page threshold cleaner triggers。若前兩者約等於後兩者則減少 NUM_IOCLEANERS;若前兩者遠大於後兩者則增加。Dirty page steal cleaner triggers 指出調用清除程式次數(受損緩衝區替換期間需同步寫)。為更好回應時間該值應盡可能低。計算所有清除程式調用百分比:Dirty page steal / (Dirty page steal + Dirty page threshold + LSN Gap)。比率高可能表明清除程式太少,會使故障恢復時間變長。
背景:備份恢復等公用程式用 I/O 伺服器代表代理程式執行預取 I/O 與非同步 I/O。資料庫配置參數,指定資料庫 I/O 伺服器數。超過此數量的預取與公用程式 I/O 不能同時運行。啟動 I/O 操作時伺服器處於等待。非預取 I/O 直接從代理程式調度,不受 NUM_IOSERVERS 約束。
建議:OLTP 環境用預設值。
如何更改:db2 -v update db cfg for DB_NAME using NUM_IOSERVERS a_number
背景:資料庫配置參數,讓您將日誌記錄寫入磁碟工作延遲到執行最小提交數為止。延遲可減少寫日誌記錄相關管理器開銷。多應用對資料庫運行且極短時間內請求大量提交時可提升效能。只有參數值大於 1 且連接應用數大於等於參數值時才發生提交分組。執行提交分組時,應用提交請求被掛起,直到時間過去 1 秒或提交請求數等於參數值。
建議:預設 1。多讀寫應用通常請求並發提交時從預設遞增。產生更有效日誌檔 I/O(較少次數、每次寫較多記錄)。覺得預設不夠大時建議從 3 開始調整,在 3 附近嘗試看效能影響。也可對每秒交易量採樣,調整參數適應每秒尖峰交易量(或其較大百分比)。適應尖峰活動使重負載期間寫日誌開銷降至最低。增大 MINCOMMIT 可能需增大 LOGBUFSZ 避免重負載期間強制將滿日誌緩衝區寫入磁碟。LOGBUFSZ = MINCOMMIT * (交易平均使用日誌空間)。
用系統監視器調優:計算每秒尖峰交易數(重設監視器、取快照、用時間差與提交/回滾總和計算);計算每交易日誌空間(類似方式用 log_space_used 平均值)。
如何更改:db2 -v update db cfg for DB_NAME using MINCOMMIT a_number
本文描述 DB2 效能基本要素、調優技巧與技術、可能影響 OLTP 效能的主要配置參數。遵循簡單步驟可設定、監控、調優 DB2 資料庫系統。希望指導能助您實現最優化 DB2 應用程式效能目標。