簡介
理解 DB2 如何使用內存,可以防止過度分配內存,並有助於對內存的使用進行調優,從而獲得更好的性能。
本文將向您傳授 DB2 內存使用的基礎,以及共享內存和私有內存的概念。這些內容同時適用於 32 位和 64 位的系統。雖然對於 64 位系統有一些限制,但是在未來的一段時間內還不大可能觸及這些限制。因此,我們將焦點放在影響 32 位系統的內存限制,並對之進行詳細的討論。
我們首先討論一般情況下 DB2 如何使用內存,接著討論內存管理如何隨著平台AIX、Sun、HP、Linux 和 Windows)的不同而變化,以及它們對 DB2 的影響。最後,我們將給出一些實際生活中客戶處境/問題以及他們的解決方案的有意義的例子。本文的內容適用於 DB2 version 8。
DB2 內存結構概述
圖 1中說明了 DB2 內存結構。這種內存結構在所有平台上都是一致的。 注意:在多分區環境中,下面的圖適用於多分區實例中的每個分區。
圖 1 - DB2 內存結構
DB2 在 4 種不同的內存集memory set)內拆分和管理內存。這 4 種內存集分別是:
每種內存集由各種不同的內存池亦稱堆)組成。圖 1 也給出了各內存池的名稱。例如, locklist是屬於數據庫共享內存集的一個內存池。 sortheap是屬於代理私有內存集的一個內存池。
我們將詳細討論每一種內存集。
實例共享內存
每個 DB2 實例都有一個實例共享內存。實例共享內存是在數據庫管理器啟動db2start)時分配的,並隨著數據庫管理器的停止db2stop)而釋放。這種內存集用於實例級的任務,例如監控、審計和節點間通信。下面的數據庫管理器配置dbm cfg)參數控制著對實例共享內存以及其中個別內存池的限制:
instance_memory參數指定為實例管理預留的內存數量。默認值是 AUTOMATIC。這意味著 DB2 將根據監視器堆、審計緩沖區和 FCM 緩沖區的大小計算當前配置所需的實例內存數量。此外,DB2 還將分配一些額外的內存,作為溢出緩沖區。每當某個堆超出了其配置的大小時,便可以使用溢出緩沖區來滿足實例共享內存區內任何堆的峰值需求。在這種情況下,個別堆的設置是 軟限制的,它們可以在內存使用的峰值期間進一步增長。
如果 instance_memory被設置為某一個數字,則采用 instance_memory與 mon_heap_sz、 audit_buf_sz和 fcm_num_buffers的和之間的較大者。這時,對實例內存就施加了一個硬性的限制,而不是軟限制。當達到這個限制時,就會收到內存分配錯誤。出於這個原因,建議將 instance_memory的設置保留為 AUTOMATIC。
如果 instance_memory被設為 AUTOMATIC,則可以使用下面的命令來確定它的值:
下面的輸出表明有 42 MB 的內存被預留給實例共享內存集10313 頁 * 4096 字節/頁):
instance_memory參數只是設置了實例共享內存的限制。它並沒有說出當前使用了多少內存。要查明一個實例的內存使用情況,可以使用 DB2 內存跟蹤器工具 db2mtrk。例如,
上面的例子表明,雖然預留給實例共享內存集的內存有 42 MB,但在 db2mtrk運行時只用到了大約 21 MB。注意:在某些情況下,db2mtrk 顯示的大小會大於指定給配置參數的值。在這種情況下,賦予配置參數的值被作為一種軟限制,內存池實際使用的內存可能會增長,從而超出配置的大小。
數據庫共享內存
每個數據庫有一個數據庫共享內存集。數據庫共享內存是在數據庫被激活或者第一次被連接上的時候分配的。該內存集將在數據庫處於非激活狀態時釋放如果數據庫先前是處於激活狀態)或者最後一個連接被斷開的時候釋放。這種內存用於數據庫級的任務,例如備份/恢復、鎖定和 SQL 的執行。
圖2展示了數據庫共享內存集內的各種內存池。括號中顯示了控制這些內存池大小的配置參數。
圖 2 - DB2 數據庫共享內存
完整的綠色方框意味著,在數據庫啟動的時候,該內存池是完全分配的,否則,就只分配部分的內存。例如,當一個數據庫第一次啟動時,不管 util_heap_sz的值是多少,只有大約 16 KB 的內存被分配給實用程序堆。當一個數據庫實用程序例如備份、恢復、導出、導入和裝載)啟動時,才會按 util_heap_sz指定的大小分配全額的內存。
主緩沖池數據庫緩沖池通常是數據庫共享內存中最大的一塊內存。DB2 在其中操縱所有常規數據和索引數據。一個數據庫必須至少有一個緩沖池,並且可以有多個緩沖池,這要視工作負載的特征、數據庫中使用的數據庫頁面大小等因素而定。例如,頁面大小為 8KB 的表空間只能使用頁面大小為 8KB 的緩沖池。
可以通過 CREATE BUFFERPOOL 語句中的 EXTENDED STORAGE 選項“擴展”緩沖池。擴展的存儲ESTORE)充當的是從緩沖池中被逐出的頁的輔助緩存,這樣可以減少 I/O。ESTORE 的大小由 num_estore_segs 和 estore_seg_sz 這兩個數據庫配置參數來控制。如果使用 ESTORE,那麼就要從數據庫共享內存中拿出一定的內存,用於管理 ESTORE,這意味著用於其他內存池的內存將更少。
這時您可能要問,為什麼要這麼麻煩去使用 ESTORE?為什麼不分配一個更大的緩沖池呢?答案跟可尋址內存而不是物理內存)的限制有關,我們在後面會加以討論。
隱藏的緩沖池
當數據庫啟動時,要分配 4 個頁寬分別為 4K、8K、16K 和 32K 的小型緩沖池。這些緩沖池是“隱藏”的,因為在系統編目中看不到它們通過 SELECT * FROM SYSCAT.BUFFERPOOLS 顯示不出)。
如果主緩沖池配置得太大,則可能出現主緩沖池不適合可尋址內存空間的情況。我們在後面會談到可尋址內存。)這意味著 DB2 無法啟動數據庫,因為一個數據庫至少必須有一個緩沖池。如果數據庫沒有啟動,那麼就不能連接到數據庫,也就不能更改緩沖池的大小。由於這個原因,DB2 預先分配了 4 個這樣的小型緩沖池。這樣,一旦主緩沖池無法啟動,DB2 還可以使用這些小型的緩沖池來啟動數據庫。在此情況下,用戶將收到一條警告SQLSTATE 01626))。這時,應該連接到數據庫,並減少主緩沖池的大小。