DB2中內存的使用

簡介

理解 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 種內存集分別是:
  • 實例共享內存(instance shared memory)
  • 數據庫共享內存(database shared memory)
  • 應用程序組共享內存(application group shared memory)
  • 代理私有內存(agent private memory)
每種內存集由各種不同的內存池(亦稱堆)組成。圖 1 也給出了各內存池的名稱。例如, locklist是屬於數據庫共享內存集的一個內存池。 sortheap是屬於代理私有內存集的一個內存池。
我們將詳細討論每一種內存集。
實例共享內存
每個 DB2 實例都有一個實例共享內存。實例共享內存是在數據庫管理器啓動(db2start)時分配的,並隨着數據庫管理器的停止(db2stop)而釋放。這種內存集用於實例級的任務,例如監控、審計和節點間通信。下面的數據庫管理器配置(dbm cfg)參數控制着對實例共享內存以及其中個別內存池的限制:
  • 實例內存( instance_memory)。
  • 監視器堆( mon_heap_sz):用於監控。
  • Audit Buffer( audit_buf_sz):用於 db2audit 實用程序。
  • Fast Communication buffers ( fcm_num_buffers):用於分區之間的節點間通信。僅適用於分區的實例。
instance_memory參數指定爲實例管理預留的內存數量。默認值是 AUTOMATIC。這意味着 DB2 將根據監視器堆、審計緩衝區和 FCM 緩衝區的大小計算當前配置所需的實例內存數量。此外,DB2 還將分配一些額外的內存,作爲溢出緩衝區。每當某個堆超出了其配置的大小時,便可以使用溢出緩衝區來滿足實例共享內存區內任何堆的峯值需求。在這種情況下,個別堆的設置是 限制的,它們可以在內存使用的峯值期間進一步增長。
如果 instance_memory被設置爲某一個數字,則採用 instance_memorymon_heap_szaudit_buf_szfcm_num_buffers的和之間的較大者。這時,對實例內存就施加了一個硬性的限制,而不是軟限制。當達到這個限制時,就會收到內存分配錯誤。出於這個原因,建議將 instance_memory的設置保留爲 AUTOMATIC
如果 instance_memory被設爲 AUTOMATIC,則可以使用下面的命令來確定它的值:
  • db2 attach to instance_name(其中 instance_name是實例的名稱)
  • db2 get dbm cfg show detail
下面的輸出表明有 42 MB 的內存被預留給實例共享內存集(10313 頁 * 4096 字節/頁):
  • Size of instance shared memory (4KB) (INSTANCE_MEMORY) = AUTOMATIC(10313) AUTOMATIC(10313)
instance_memory參數只是設置了實例共享內存的限制。它並沒有說出當前使用了多少內存。要查明一個實例的內存使用情況,可以使用 DB2 內存跟蹤器工具 db2mtrk。例如,
  • db2start
  • db2mtrk -i -v
  • Memory for instance
  • FCMBP Heap is of size 17432576 bytes
  • Database Monitor Heap is of size 180224 bytes
  • Other Memory is of size 3686400 bytes
  • Total: 21299200 bytes
上面的例子表明,雖然預留給實例共享內存集的內存有 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))。這時,應該連接到數據庫,並減少主緩衝池的大小。
排序堆的閾值( sheapthressheapthres_shr
如果沒有索引滿足所取的行的要求順序,或者優化器斷定排序的代價低於索引掃描,那麼就需要進行排序。DB2 中有兩種排序,一種是私有排序,一種是共享排序。私有排序發生在代理的私有代理內存(在下一節討論)中,而共享排序發生在數據庫的數據庫共享內存中。
對於私有排序,數據庫管理器配置參數 sheapthres指定了私有排序在任何時刻可以消耗的內存總量在實例範圍內的 限制。如果一個實例總共消耗的私有排序內存達到了這一限制,那麼爲額外傳入的私有排序請求所分配的內存將大大減少。這樣就會在 db2diag.log 中看到如下消息:
"Not enough memory available for a (private) sort heap of size size of sortheap. Trying smaller size..."
如果啓用了內部分區並行性(intra-partition parallelism)或者集中器(concentrator),那麼當 DB2 斷定共享排序比私有排序更有效時,DB2 就會選擇執行共享排序。如果執行共享排序,那麼就會在數據庫共享內存中分配用於這種排序的排序堆。用於共享排序的最大內存量是由 sheapthres_shr數據庫參數指定的。這是對共享排序在任何時刻可以消耗的內存總量在數據庫範圍內的 限制。當達到這個限制時,請求排序的應用程序將收到錯誤 SQL0955 (rc2)。之後,在共享內存總消耗量回落到低於由 sheapthres_shr指定的限制之前,任何共享排序內存的請求都得不到允許。
下面的公式可以計算出數據庫共享內存集大致需要多少內存:數據庫共享內存 = (主緩衝池 + 4 個隱藏的緩衝池 + 數據庫堆 +實用程序堆 + locklist + 包緩存 + 編目緩存) + (estore 的頁數 * 100 字節) + 大約 10% 的開銷
對於啓用了 intra_parallel 或集中器情況下的數據庫,共享排序內存必須作爲數據庫共享內存的一部分預先分配,因而上述公式變爲:數據庫共享內存 = (主緩衝池 + 4 個隱藏的緩衝池 + 數據庫堆 +實用程序堆 + locklist + 包緩存 + 編目緩存 + sheapthres_shr) + (estore 的頁數 * 100 字節) + 大約 10% 的開銷
提示: 爲了發現分配給主緩衝池的內存有多少,可以發出:

SELECT * FROM SYSCAT.BUFFERPOOLS
雖然大多數內存池的大小是由它們的配置參數預先確定的,但下面兩種內存池的大小在默認情況下卻是動態的:
  • 包緩存: pckcachesz = maxappls * 8
  • 編目緩存: catalogcache_sz = maxappls * 4
  • 活動應用程序的最大數量: maxappls = AUTOMATIC
maxappls設爲 AUTOMATIC的效果是,允許任意數量的連接數據庫的應用程序。DB2 將動態地分配所需資源,以支持新的應用程序。因此,包緩存和編目的大小可以隨着 maxappls的值而變化。
除了上述參數以外,還有一個參數也會影響數據庫共享內存的數量。這個參數就是 database_memory。該參數的缺省值是 AUTOMATIC。這意味着 DB2 將根據以上列出的各內存池的大小來計算當前配置所需的數據庫內存量。此外,DB2 還將爲溢出緩衝區分配一些額外的內存。每當某個堆超出了其配置的大小時,便可以使用溢出緩衝區來滿足實例共享內存區內任何堆的峯值需求。
如果 database_memory被設爲某個數字,則採用 database_memory與各內存池之和這兩者之間的較大者。
如果 database_memory被設爲 AUTOMATIC,則可以使用以下命令來顯示它的值:
  • db2 connect to dbnameuser useridusing pwd
  • db2 get db cfg for dbnameshow detail
使用 db2mtrk 工具顯示當前使用的內存量: db2mtrk -i -d -v (在 Windows 中,-i 必須指定。在 UNIX 中,-i 是可選的。)
 
Memory for database: SAMPLE
   Backup/Restore/Util Heap is of size 16384 bytes
   Package Cache is of size 81920 bytes
   Catalog Cache Heap is of size 65536 bytes
   Buffer Pool Heap is of size 4341760 bytes
   Buffer Pool Heap is of size 655360 bytes
   Buffer Pool Heap is of size 393216 bytes
   Buffer Pool Heap is of size 262144 bytes
   Buffer Pool Heap is of size 196608 bytes
   Lock Manager Heap is of size 491520 bytes
   Database Heap is of size 3637248 bytes
   Other Memory is of size 16384 bytes
   Application Control Heap is of size 327680 bytes
    Application Group Shared Heap is of size 57344000 bytes
   Total: 67829760 bytes
應用程序組共享內存
這種共享內存集僅適用於以下環境。(對於其他環境,這種內存集不存在。)
  • 多分區(multi-partitioned)數據庫。
  • 啓用了內部並行(intra-parallel)處理的未分區(non-partitioned)數據庫。
  • 支持連接集中器的數據庫。
注意:max_connections的值大於 max_coordagents的值時,連接集中器便被啓用。這兩個參數可以在數據庫管理器配置中找到。(使用 GET DBM CFG 顯示數據庫管理器配置。)
在以上環境中,應用程序通常需要不止一個的代理來執行其任務。允許這些代理之間能夠彼此通信(相互發送/接收數據)很有必要。爲了實現這一點,我們將這些代理放入到一個稱作 應用程序組的組中。屬於相同應用程序組的所有 DB2 代理都使用 應用程序組共享內存進行通信。
應用程序組內存集是從數據庫共享內存集中分配的。其大小由 appgroup_mem_sz數據庫配置參數決定。
多個應用程序可以指派給同一個應用程序組。一個應用程序組內可以容納的應用程序數可以這樣計算: appgroup_mem_sz / app_ctl_heap_sz
在應用程序組內,每個應用程序都有其自己的 應用程序控制堆。此外,應用程序組共享內存中有一部分要預留給應用程序組共享堆。如下圖所示:
 
圖 3 - DB2 應用程序組共享內存

例 1考慮以下數據庫配置:
  • 最大應用程序內存集大小 (4KB) (APPGROUP_MEM_SZ) = 40000
  • 最大應用程序控制堆大小 (4KB) (APP_CTL_HEAP_SZ) = 512
  • 用於應用程序組堆的內存所佔百分比 (GROUPHEAP_RATIO) = 70
可以計算出下面的值:
  • 應用程序組共享內存集是: 40000 頁 * 4K/頁 = 160 MB
  • 應用程序組共享堆的大小是: 40000 * 70% = 28000 4K 頁 = 114MB
  • 該應用程序組內可容納的應用程序數爲: 40000/512 = 78
  • 用於每個應用程序的應用程序控制堆爲: (100-70)% * 512 = 153 4K 頁 = 0.6MB
不要被 app_ctrl_heap_sz 參數迷惑。這個參數不是一個應用程序組內用於每個應用程序的各應用程序控制堆的大小。它只是在計算這個應用程序組內可容納多少應用程序時用到的一個值。每個應用程序的實際應用程序控制堆大小都是通過圖 3中給出的公式計算的,這個公式就是 ((100 - groupheap_ratio)% * app_ctrl_heap_sz)。
因此,groupheap_ratio 越高,應用程序組共享堆就越大,從而用於每個應用程序的應用程序控制堆就越小。
例 2假設在一天中最忙的時間裏,有 200 個應用程序連接到例 1 中所描述的數據庫上。由於每個應用程序組可以容納 78 個應用程序,因此我們需要 200/78 = 3 個應用程序組來容納總共 200 個應用程序。這裏應確保系統有足夠多的 RAM 來支持這一配置。否則就會發生 SQL10003N 錯誤。
代理私有內存
每個 DB2 代理進程都需要獲得內存,以執行其任務。代理進程將代表應用程序使用內存來優化、構建和執行訪問計劃,執行排序,記錄遊標信息(例如位置和狀態),收集統計信息,等等。爲響應並行環境中的一個連接請求或一個新的 SQL 請求,要爲一個 DB2 代理分配代理私有內存。
代理的數量受下面兩者中的較低者限制:
  • 所有活動數據庫的數據庫配置參數 maxappls 的總和,這指定了允許的活動應用程序的最大數量。
  • 數據庫管理器配置參數 maxagents 的值,這指定了允許的最大代理數。
代理私有內存集由以下內存池組成。這些內存池的大小由括號中的數據庫配置參數指定:
  • Application Heap ( applheapsz
  • Sort Heap ( sortheap
  • Statement Heap ( stmtheap
  • Statistics Heap ( stat_heap_sz
  • Query Heap ( query_heap_sz
  • Java Interpreter Heap ( java_heap_sz
  • Agent Stack Size ( agent_stack_sz) (僅適用於 Windows)
我們曾提到,私有內存是在一個 DB2 代理被“指派”執行任務時分配給該代理的。那麼,私有內存何時釋放呢?答案取決於 dbm cfg 參數 num_poolagents的值。該參數的值指定任何時候可以保留的閒置代理的最大數目。如果該值爲 0,那麼就不允許有限制代理。只要一個代理完成了它的工作,這個代理就要被銷燬,它的內存也要返回給操作系統。如果該參數被設爲一個非零值,那麼一個代理在完成其工作後不會被銷燬。相反,它將被返回到閒置代理池,直到閒置代理的數目到達 num_poolagents指定的最大值。當傳入一個新的請求時,就要調用這些閒置代理來服務該新請求。這樣就減少了創建和銷燬代理的開銷。
當代理變成閒置代理時,它仍然保留了其代理的私有內存。這樣設計是爲了提高性能,因爲當代理被再次調用時,它便有準備好的私有內存。如果有很多的閒置代理,並且所有這些閒置代理都保留了它們的私有內存,那麼就可能導致系統耗盡內存。爲了避免這種情況,DB2 使用一個註冊表變量來限制每個閒置代理可以保留的內存量。這個變量就是 DB2MEMMAXFREE。它的默認值是 8 388 608 字節。這意味着每個閒置代理可以保留最多 8MB 的私有內存。如果有 100 個閒置代理,那麼這些代理將保留 800MB 的內存,因此它們很快就會耗盡 RAM。您可能希望降低或增加這一限制,這取決於 RAM 的大小。
圖 1展示了一個 DB2 實例的 DB2 內存結構。 圖 4將展示在同一個系統上有兩個實例併發運行的情況。虛擬內存包括物理 RAM 和調頁空間(paging space)。共享內存“傾向於”留在 RAM 中,因爲對它們的訪問更頻繁。如果代理閒置了較長的一段時間,則其代理私有內存將被調出。
圖 4 - 併發運行的兩個 DB2 實例

共享內存與私有內存
至此,我們已經討論了實例共享內存、數據庫共享內存和應用程序組共享內存以及代理私有內存。但是共享內存和私有內存的意義是什麼呢?
爲了理解共享內存與私有內存之間的不同之處,首先讓我們通過快速閱讀 DB2 進程 model來了解一下 DB2 代理進程。在 DB2 中,所有數據庫請求都是由 DB2 代理或子代理來服務的。例如,當一個應用程序連接到一個數據庫時,就有一個 DB2 代理指派給它。當該應用程序發出任何數據庫請求(例如一個 SQL 查詢)時,該代理就會出來執行完成這個查詢所需的所有任務 —— 它代表該應用程序工作。(如果數據庫是分區的,或者啓用了 intra-parallel,那麼可以分配不止一個的代理來代表應用程序工作。這些代理叫做 子代理。)
每個代理或子代理都被當作一個 DB2 進程,它獲得一定數量的內存來執行工作。這種內存被稱作 代理私有內存—— 它不能與其他任何代理共享。之前我們曾提到過,代理私有內存包括一些內存池,例如應用程序堆大小、排序堆大小和語句堆大小。(參見圖 1)
除了私有內存(代理在其中使用 排序堆執行“私有”任務,例如私有排序)外,代理還需要數據庫級的資源,例如緩衝池、 locklist和日誌緩衝區。這些資源在數據庫共享內存中(參見 圖 1)。 DB2 的工作方式是,數據庫共享內存中的所有資源都由連接到相同數據庫的所有代理或子代理共享。因此,該內存集被稱作共享內存,而不是私有內存。例如,連接到數據庫 A 的代理 x 使用數據庫 A 的數據庫共享內存中的資源。現在又有一個代理,即代理 y 也連接到數據庫 A。那麼代理 y 將與代理 x 共享數據庫 A 的數據庫內存。(當然,代理 x 和代理 y 都有其自己的代理私有內存,這些代理私有內存不是共享的。)
這樣的邏輯同樣適用於實例共享內存和應用程序組共享內存。
下圖展示了當兩個 DB2 代理(代理 x 和代理 y)連接到數據庫 A 時分配的 DB2 內存集。假設:
  • 數據庫 A 屬於實例 db2inst1。
  • 數據庫 A 爲應用程序組 1 啓用了 intra-parallel。
  • 代理 x 和 代理 y 都屬於應用程序組 1。
圖 5 - DB2 代理進程內存地址空間

圖 5 展示了在 RAM 中分配的以下內存集:
  • 用於實例 db2inst1 的實例共享內存集。
  • 用於 數據庫 A 的數據庫共享內存集。
  • 用於 應用程序組 1 的應用程序組共享內存。
  • 用於代理 x 的代理私有內存集。
  • 用於代理 y 的代理私有內存集。
  • 爲內核和庫之類的東西預留的內存。
代理 x 和代理 y 共享相同的實例內存、數據庫內存和應用程序組內存,因爲它們屬於相同的實例、相同的數據庫和相同的應用程序組。此外,它們有其自己的代理私有內存。
每個 DB2 代理進程都有其自己的內存地址空間。在內存空間中的內存地址允許代理訪問物理 RAM 中的內存。我們可以把這些地址看作指向 RAM 的指針,如 圖 5所示。對於任何 DB2 進程,這個地址空間必須能夠容納上述所有 4 種內存集。
前面已提到,ESTORE 是用於擴展緩衝池的大小。那麼您可能要問,爲什麼不創建一個更大的緩衝池呢。答案是:因爲地址空間受到限制,地址空間可能容不下一個更大的緩衝池!在此情況下,需要定義一個較小的地址空間能夠容納的緩衝池。如果有過量的物理內存,那麼可以用該內存來配置 ESTORE。
那麼,我們怎麼知道一個 DB2 代理的地址空間是多大呢?地址空間的大小取決於當前的實例是 32 位的實例還是 64 位的實例。我們將在下一節對此進行解釋。
32 位體系結構與 64 位體系結構中的可尋址內存

如果有一個 64 位的 DB2 實例,則意味着 DB2 使用的是 64 位的內存體系結構。在這種體系結構中,對於所有平臺,每個進程的地址空間都是 2 的 64 次方,或者 18,446,744,073 GB。這是一個相當巨大的內存。將所有 DB2 內存集放入這個地址空間應該沒有問題。
另一方面,如果有一個 32 位 DB2 實例,則對於所有平臺,地址空間只有 2 的 32 次方,或者 4 GB(Linux/390 平臺除外,在此平臺下地址空間實際上只有 2 的 31 次方。不過,在本文中我們不討論 Linux/390 中的 DB2)。所以,不管物理 RAM 有多大,要使一個 DB2 進程能夠訪問它所需的所有資源,包括實例共享內存、數據庫共享內存、應用程序組共享內存、它自己的代理私有內存以及用於內核的內存等,所有這些資源必須能放入到 4GB 的地址空間內。
這就導致了兩個非常重要的問題:
  • 應該爲實例內存、數據庫內存和應用程序共享內存分配多少的內存,以使它們能放入到 4GB 的可尋址空間?
  • 應該如何配置 圖 1中列出的每個參數,以最有效地利用可用的內存?
雖然 4GB 的地址空間限制適用於所有平臺,但是對於上述問題的回答卻與平臺有關。例如,在 AIX 系統上可以分配給 DB2 數據庫的最大數據庫內存數就與 Solaris 系統上的數據庫不同。接下來的幾節將討論不同的平臺對 DB2 中的內存配置有何影響。注意:本文的後續部分只針對 32 位內存體系結構。我們即將討論的問題不適用於 64 位的體系結構。
32 位 AIX 中的 DB2 內存配置
在 32 位的 AIX 上,4GB 的可尋址內存空間被拆分爲 16 個段,每段 256MB。 圖 6展示了用於一個 DB2 代理進程的 32位 內存地址空間。(假設 DB2_MMAP_READ 和 DB2_MMA_WRITE 這兩個 DB2 註冊表變量都被設爲 NO。如果這兩個變量沒有設爲 NO,則表示方法會有點不同。我們將在後面解釋。)
圖 6 - AIX 中的 DB2 32 位內存地址空間

段 0 - 預留給 AIX 內核。
段 1 - 預留給 db2sysc 進程。
段 2 - 預留給代理私有內存。
段 3 - 預留給實例共享內存。
段 4 到段 B - 數據庫共享內存始於段 4,這些段必須緊挨在一起。所有這 8 個段(2GB)可能都被用於數據庫共享內存。但是,下面的每種配置都會從數據庫共享內存中拿出一個段(256MB)。
注意: 對於下面的每種配置,DB2 將從數據庫共享內存中拿出一個段,這個段始於段 B。
  • 如果數據庫是分區的,或者啓用了 intra-parallel 或連接集中器,那麼數據庫共享內存中有一個段被預留給應用程序組共享內存。
  • Fast Communication Manager (FCM):FCM 用於系統物理節點上不同分區之間的通信。默認情況下,這種通信是通過 UNIX socket 進行的。如果 DB2_FORCE_FCM_BP 被設爲 YES,那麼 FCM 通信發生在共享內存內。這意味着數據庫共享內存中有一個段被預留給 FCM 通信。雖然 FCM 通信變得更快,但是它也令數據庫共享內存減少了一個段。
  • fenced UDF 和存儲過程:如果數據庫上運行着一個 fenced 函數或過程,那麼數據庫共享內存中有一個段要預留給 fenced 模式的通信。
  • 如果數據庫允許任何本地連接,那麼數據庫共享內存中有一個段要預留給代理/本地應用程序通信。如果將所有本地連接配置爲 loopback 連接,那麼就可以爲這些連接使用 TCP/IP,而不需要共享內存(即使數據庫就在服務器本地)。這樣就有效地爲數據庫共享內存空出一個段來。 然而,如果您不想使用 loopback 解決方案,還有一種方法可以迫使 DB2 選擇段 E 來用於代理/本地應用程序通信,這樣數據庫共享內存就不受影響(即不會減少)。請參閱後面的解釋。
  • 如果啓用了 ESTORE,那麼還要從數據庫共享內存中拿出另一個段。因此,如果啓用 ESTORE,則應確保它至少是 256MB,否則就不起作用,因爲要從數據庫共享內存中拿出一個 256 MB 的段來僅用於管理這個 ESTORE。建議將 estore 段的大小( estore_seg_sz)設爲 256MB,然後根據可用的內存更改段的數目( num_estore_segs)。
段 C - 預留給 DB2 跟蹤使用程序。
段 D 和 F- 預留給 DB2 共享庫
段 E - 在默認情況下,這個段是不用的。不過,如果設置 DB2_MMAP_READ=NO 和 DB2_MMAP_WRITE=NO,那麼該段用於 DB2 代理以及本地應用程序之間的通信(如 圖 6所示)。這將有效地爲數據庫共享內存一個段。
注意: 爲了最大化數據庫共享內存的空間,應使用以下注冊表變量設置:DB2_FORCE_FCM_BP=NO (該值是默認值),DB2_MMAP_READ=NO,DB2_MMAP_WRITE=NO。
需要從這種結構中瞭解到的最重要的事情是:
  • 對於禁用了 intra-parallel 的單分區系統,我們可以得到至多 2GB 的空間用於數據庫共享內存(段 4 到段 B)。
  • 下面每種配置都將數據庫共享內存減少了一個段(256MB):帶 fenced UDF 或存儲過程的數據庫、帶本地連接的數據庫、DB2_FORCE_FCM_BP=YES 情況下的數據庫、支持 intra_parallel、或支持集中器以及分區的數據庫,以及啓用了 ESTORE 的數據庫。
  • 如果允許與數據庫進行本地連接,那麼應該將 DB2_MMAP_READ 和 DB2_MMAP_WRITE 都設置成 NO,以便使用段 E。否則,任何本地連接都要從數據庫共享內存中拿走一個段。
這些限制規定了我們該如何配置數據庫共享內存集中的每個內存池。可以使用前面給出的公式來計算數據庫共享內存。得到的總和不能超過這個限制。
注意:內存可以分配,釋放,也可以當數據庫正在運行時在不同區域之間交換。例如,您可以減少 locklist 而增加相同數量的任何一個給定的緩衝池。
使用 svmon 監控 AIX 上的內存使用情況
在 AIX 上,除了 db2mtrk 工具外,還可以使用 svmon 工具來監控 DB2 代理進程的內存消耗情況(需要 root 權限)。這個命令是: "svmon -P PID",其中 PID是 DB2 代理(db2agent 或 db2agentp)的進程 ID。
圖 7 展示了 svmon 對於一個名爲 db2agent 的進程的示例輸出。與這個 db2agent 進程相關的數據庫有如下特徵:
  • 數據庫名是 TEST。
  • INTRAP_PARALLEL = YES (get dbm cfg)
  • DB2_FORCE_FCM_BP = YES (db2set -all)
  • DB2_MMAP_READ=NO, DB2_MMAP_WRITE=NO (db2set -all)
圖 7 - svmon 對於一個 DB2 代理進程 (svmon -P 11649046) 的輸出

從 圖 7中觀察到的一些情況:
  • 進程 ID 是 11649046,進程名爲 db2agent(左上角)。這個代理被連接到數據庫 TEST(數據庫的名稱在 svmon 輸出中已經被截斷,只顯示了 'TES')。
  • Esid 列顯示已經分配的內存段:
  • 4 (綠色)被分配給數據庫共享內存。
  • 2 (橙色)被分配給代理私有內存。
  • 3 (藍色)被分配給實例共享內存。
  • B (紫色)被分配給應用程序組共享內存,因爲數據庫支持 intra_parallel。
  • A (粉紅色)被分配給 FCM,因爲 DB2_FORCE_FCM_BP=YES。
  • 本地連接段被移到段 E(紅色)。這是因爲 DB2_MMAP_READ 和 DB2_MMAP_WRITE 都被設爲 NO。否則,就必須將段 8 用於代理和本地連接通信,因爲段 A 和段 B 都已經被佔用,而段 9 被預留給 fenced 模式的通信。
觀察到的這些情況與 圖 6中說明的相匹配。
設置 32 位 AIX 系統上數據和堆棧的 ulimit
我們早先說過, 圖 6中的段 #2 是用於代理私有內存的。實際上,並非完全如此。
確切地說,段 #2 被預留給數據和堆棧。數據包含用戶數據(即代理私有內存)。而堆棧則包含要執行的指令。在這個 256M 的段中,數據是從地址 0x20000000 向下增長的。而堆棧是從地址 0x2FFFFFFF 向上增長的。爲了不讓數據和堆棧有衝突,設置它們的限制就十分重要。如果數據和堆棧真的有衝突,那麼實例就會崩潰,併產生信號 4 或信號 11。
圖 8 - 數據段和堆棧段

數據和堆棧的限制是在 ulimits(/etc/security/limits)中設置的。使用 SMIT 將它們設置成如下值:

Data = 491519, Stack = 32767 (512 字節)
上述值以 512 字節爲單位,其中對於數據是 240MB,對於堆棧是 16MB。當使用 "ulimit -a" 顯示這兩個限制時,顯示的值以 1K 字節爲單位,而不是以 512 字節爲單位。因此這兩個值變爲:

Data = 245760, Stack = 16384
注意: /etc/security/limits 包含了以 512 字節爲單位的限制,而不是以 1 KB 爲單位的限制。
32 位 AIX 上與分配數據庫共享內存有關的常見問題
初始化數據庫共享內存失敗可能產生如下問題:
  • 在數據庫啓動時(激活數據庫或第一次連接數據庫) - SQL1478W, SQL0987C, SQL1084C。
  • 在運行時 - SQL10003N, SQL1042C。
下面的例子展示了會導致問題的不恰當配置。
例 1考慮以下配置:(所有頁的大小爲 4KB)
  • 單分區,禁用集中器,INTRA_PARALLEL OFF,DB2_MMAP_READ=NO,DB2_MMAP_WRITE=NO,無 fenced 函數或過程
  • IBMDEFAULTBP 450,000 頁
  • UTILHEAP 17,500 頁
  • DBHEAP 10,000 頁
  • LOCKLIST 1000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
限制:在此配置中,對於數據庫共享內存的限制是 2GB 或 8 個段。
計算:使用公式計算數據庫共享內存,我們得到:

數據庫共享內存 = (486,000 頁 x 4KB/頁的總數) x 1.1 (考慮到 10% 的開銷) = ~2.1GB = 9 個段
注意:我們會將 4 個隱藏緩衝池排除在計算之外,因爲它們太小了,不會產生明顯的不同。
問題:這超出了 2GB 的限制。當激活數據庫或第一次連接到數據庫時,您將收到如下警告:

SQL1478W The defined buffer pools could not be started. Instead, one small buffer pool for each page size supported by DB2 has been started. SQLSTATE=01626
在 db2diag.log 中,您將看到有消息說 DB2 將利用隱藏緩衝池啓動。要解決這個問題,可以減少主緩衝池的大小。
例 2考慮如下配置: (所有頁的大小都是 4K)
  • 單分區,無 fenced 函數或過程,INTRA_PARALLEL=ON
  • IBMDEFAULTBP 300,000 頁
  • UTILHEAP 17,500 頁
  • DBHEAP 10,000 頁
  • SHEAPTHRES_SHR 50,000 頁
  • LOCKLIST 1000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
限制: 1.5GB (6 個段)。一個段用於應用程序組內存,因爲 INTRA_PARALLEL 是 ON。另一個段用於本地連接,因爲 DB2_MMAP_READ 和 DB2_MMAP_WRITE 都被設爲 YES (該值是默認值)。
計算:數據庫共享內存 = (386,000 頁 x 4KB/頁的總數) x 1.1 = ~1.67GB = 7 個段
問題:這超出了 1.5GB 的限制。當嘗試激活數據庫或第一次連接到數據庫時,您將得到以下錯誤消息:

SQL1042C An unexpected system error occurred. SQLSTATE=58004
要解決這一問題:
  • 使用 db2set 將 DB2_MMAP_READ 和 DB2_MMAP_WRITE 設爲 NO。這樣便迫使 DB2 將段 E 用於本地連接,從而爲數據庫共享內存空出一個段。
例 3考慮如下配置: (所有頁的大小都爲 4K)
  • IBMDEFAULTBP 250,000
  • INTRA_PARALLEL=ON
  • UTILHEAP 17,500 頁
  • DBHEAP 10,000 頁
  • SHEAPTHRES_SHR 20,000 頁
  • LOCKLIST 1000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
  • 存在 Fenced UDF
限制: 以下各佔一個段:Intra-parallel ON,本地連接,以及 fenced UDFB。這樣還剩下 5 個段,或者 1.25G 給數據庫共享內存。
計算:

數據庫共享內存 = (306,000 頁 x 4KB/頁的總數) x 1.1% = ~1.35GB = 6 個段
問題: 引用了 fenced UDF 的查詢就會失敗,並返回錯誤 sql10003C。要解決這個問題,可以在 unfenced 模式下運行 UDF,或者將數據庫共享內存減少至不多於 5 個段。
32-位 Sun Solaris Version 2.6 及及其更高版本中的 DB2 內存配置

在 AIX 中,每個段的大小都是 256MB,而在 Solaris 中則有所不同,其內存段的大小不是固定的。32 位 Solaris 可尋址內存結構如 圖 9所示。
圖 9 - 32 位 Sun SolarisDB2 中的 32 位內存地址空間

從 0x0 到 0x00010000 之間的地址不能使用。第一個段始於 0x00010000,這個段被預留給 db2sysc 可執行程序和代理私有內存。在缺省情況下,這個段結束於 0x10000000,因而這個段總共是 256MB。(我們可以通過設置 DB2DBMSADDR DB2 註冊表變量使這個段更大一些,見後面)。在這個段內,db2sysc 可執行程序只佔用很小的一片內存,剩下的用於代理私有內存(200MB+)。
在默認情況下,實例共享內存的起始地址固定於 0x10000000。不過,也可以將其改爲一個更高的地址,以便有更多的空間留給代理私有內存。例如,如果實例共享內存始於 0x12000000,而不是 0x10000000,那麼就有 0x12000000 減去 0x10000000 即 32MB 的額外內存被用於代理私有內存。要做到這一點,可以將 DB2DBMSADDR DB2 註冊表變量設爲如下值:

db2set DB2DBMSADDR=0x12000000
注意: DB2DBMSADDR 值的範圍是從 0x10000000 到 0x10FFFFFF,每次遞增 0x10000。
實例共享內存的結束地址是不固定的。這意味着實例共享內存可能會很大。緊接着實例共享內存的是數據庫共享內存。因爲實例共享內存的結束地址不固定,所以數據庫共享內存的起始地址也是不固定的。
在數據庫共享內存之後的是用於 DB2 跟蹤、共享庫和堆棧(即將執行的指令)的內存。在 AIX 中,堆棧和代理私有內存共享相同的內存段,而在 Solaris 中則有所不同,其中代理私有內存和堆棧分別使用不同的內存段。因此,這裏不存在兩者之間發生衝突的風險。
由於這些內存段的大小不是固定的,我們只能估計實例共享內存和數據庫共享內存的大小爲:

4GB - 代理私有內存 - DB2 跟蹤 - DB2 共享庫 - 堆棧
注意這個數量同時還包括實例共享內存和數據庫共享內存,並且它們的內存段必須是鄰接的。爲了看一看實際中如何使用內存,可以對 db2sysc 或 db2agent 進程的 ID 運行 /usr/proc/bin/pmap 命令(以 root 的身份)。
注意:在 Solaris 中,當使用 "pe -ef | grep instance_name" 命令顯示 DB2 進程時,所有進程都作爲 db2sysc 進程顯示。可以使用 db2ptree命令來以“真實”名稱顯示 DB2 進程。 圖 9展示了 pmap 命令的一個示例輸出
圖 10 - pmap 命令對於 db2sysc 進程的示例輸出(/usr/proc/bin/pmap -x 15444)

從 圖 10 中可以觀察到下面一些情況:
  • 0x00010000 到 0x023F8000 這一部分被預留給 db2sysc 可執行程序(~36MB)。
  • 橙色的那部分(堆),即從 0x023F8000 到 0x10000000,被用於代理私有內存(~220MB)。
  • 實例共享內存,即綠色那部分,始於默認地址 0x10000000。這意味着沒有設置 DB2DBMSADDR。
  • 所有 3 個綠色的段被用於共享內存,包括實例共享內存和數據庫共享內存。pmap 輸出並沒有說出哪一個段是實例共享內存,哪一個段是數據庫共享內存。我們只知道,數據庫共享內存在 0xFE002000 結束,因爲從這個地址開始的是一個用於匿名內存的段。因此,實例共享內存和數據庫共享內存總共的大小是 0xFE002000 - 0x10000000 = 3,992,985,600 字節 = ~3.7 GB。
  • 0xFFBC0000 到 0xFFFFFFFF 是用於堆棧的內存段(~4MB)。
注意:在 32 位 Solaris 中,我們通常將 DB2 數據庫共享內存限制在大約 3.5 GB。
如果設置了 DB2DBMSADDR 註冊表變量,那麼實例共享內存將從該變量指定的地址開始。下面的例子展示了這一點是如何實現的。
例子 設置 DB2DBMSADDR 註冊表變量:
  • db2set DB2DBMSADDR = 0x12000000
  • db2stop
  • db2start (需要重新啓動實例,以使更改生效)。
獲得 db2sys 進程的進程 ID
  • ps -ef | grep sylviaq ('sylviaq' 是實例名)。
  • -ef | grep sylviaq
  • sylviaq 13166 1 0 13:09:12 pts/2 0:00 /export/home/sylviaq/sqllib/bin/db2bp 13049C11221 5
  • sylviaq 13263 13256 0 13:11:02 ? 0:00 db2sysc
  • sylviaq 13265 13256 0 13:11:03 ? 0:00 db2sysc
  • sylviaq 13257 13254 0 13:10:59 pts/3 0:00 -ksh
  • sylviaq 13256 13253 0 13:10:59 ? 0:00 db2sysc
  • sylviaq 13262 13256 0 13:11:00 ? 0:00 db2sysc
  • sylviaq 13360 13049 0 13:11:41 pts/2 0:00 grep sylviaq
  • sylviaq 13264 13256 0 13:11:02 ? 0:00 db2sysc
  • sylviaq 13266 13261 0 13:11:03 ? 0:00 db2sysc
以 root 的身份 cd 到 /usr/proc/pmap,並對任何 db2sysc 進程運行 pmap:

./pmap -x 13263
pmap 輸出:
  • 13263: db2sysc
  • Address Kbytes Resident Shared Private Permissions Mapped File
  • 00010000 35808 4064 1608 2456 read/exec db2sysc
  • 02316000 896 168 48 120 read/write/exec db2sysc
  • 023F6000 744 264 8 256 read/write/exec [ heap ]
  • 12000000 243472 243472 - 243472 read/write/exec/shared [shmid=0xbc3]
  • 21000000 22512 22512 - 22512 read/write/exec/shared [shmid=0xbc4]
  • FCC00000 8328 8328 - 8328 read/write/exec/shared [shmid=0xa96]
  • FE002000 8 - - - read/write/exec [ anon ]
注意,實例共享內存現在從 0x12000000 開始,而不是從默認地址 0x10000000 開始。代理私有內存的大小(由 'heap' 標出)從 220MB ( 圖 10)增加到了 252 MB。(0x12000000 - 0x023F6000 = 0xFC0A000 = 264282112 (十進制) = ~252MB)
您可能注意到, 圖 9中給出的 4GB 地址空間沒有包括任何內核內存。這就對了,在 Solaris 中,內核有其自己的地址空間,該地址空間與進程的地址空間是分開的。這樣就將更多的空間留給了其他內存集,例如數據庫共享內存。
雖然與 AIX 相比,在 Solaris 中我們有更大的地址空間用於數據庫共享內存(在 AIX 上是 2GB),但是在 Solaris 上所有共享內存都是固定在物理 RAM 中。如果 RAM 比較小,那麼對於可以併發運行的數據庫數目就有很大的影響。請參閱 “Sun Solaris 中與分配數據庫共享內存有關的常見問題”一節中的例 2。
需要從這種結構中瞭解到的最重要的事情是:
  • AIX 不同,Solaris 的內存段其大小不是固定的。我們可以通過設置 DB2DBMSADDR DB2 註冊表變量,將實例共享內存移到更高的地址,從而增加代理私有內存。
  • 數據庫共享內存的限制大約是 3.5GB。
  • 功能內存與 RAM 固定,因而不能交換出去。
32 位 Sun Solaris 中與分配數據庫共享內存有關的常見問題

沒有充分配置內核參數以及初始化數據庫共享內存失敗可能導致如下失敗:
  • 在數據庫啓動時(激活數據庫或第一次連接到數據庫) - SQL1478W, SQL1084C, hang condition
  • 在運行時 - SQL2043N, 掛起條件
在 Solaris 系統中,DB2 提供了一個叫做 db2osconf的工具。該工具根據系統的大小對內核參數的值給出建議。對於一個給定的系統,建議的值要足夠高,以便能夠容納最合理的工作負載。
最常見的未能正確設置的內核參數是 shmmax。該參數按字節指定系統中可以分配的共享內存段的最大大小。如果把 DB2 配置成創建大於這個值的數據庫共享內存,那麼請求就會失敗。其他要知道的內核參數是 shmsegshmmni
Solaris 中另一個與分配數據庫共享內存有關的常見問題是由於這樣的一個事實導致的,即共享內存段的所有頁都是固定在物理 RAM 中的。如果在 RAM 中沒有足夠的空閒頁可用,或者沒有足夠的可以被 OS 爲滿足數據庫段而調出的其他頁,那麼啓動數據庫的請求就會遭到失敗。
下面的例子展示了會導致問題的不恰當配置。
例 1考慮如下配置: (所有頁的大小都爲 4K)
服務器:
  • 服務器上的物理 RAM 16GB
  • shmsys:shminfo_shmmax = 2097152 (2GB)
數據庫:
  • IBMDEFAULTBP 400,000 頁
  • UTILHEAP 17,500 頁
  • DBHEAP 30,000 頁
  • LOCKLIST 1000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
限制: DB2 發出的任何創建大於 shmmax 值(這裏是 2GB)的數據庫共享內存集的請求都將失敗,並返回一個 out of memory type 錯誤。
計算:

數據庫共享內存 = (456,000 頁 x 4KB/頁) x 1.1 = ~2.0GB
問題: 可能仍然可以激活數據庫或者連接到數據庫。但是,嘗試運行一個應用程序時可能返回如下錯誤消息:

SQL1224N A database agent could not be started to service request, or was terminated as a result of a database system shutdown or a force command. SQLSTATE=55032
這是 DB2 經常返回的一個錯誤。不過,如果不是在 AIX 服務器上,而是在 UNIX 服務器上,那麼這就很可能與內存資源問題有關。特別地,可能是內核參數沒有進行適當的調優。
爲解決這個問題,可以適當地配置內核參數。設置:

shmsys:shminfo_shmmax = 15099494 (~90% of 16GB)
例 2考慮如下配置: (所有頁的大小都爲 4K)
服務器上的物理 RAM 是 1 GB。
數據庫 A:
  • IBMDEFAULTBP 137,500 頁
  • INTRA_PARALLEL ON
  • UTILHEAP 10,000 頁
  • DBHEAP 10,000 頁
  • SHEAPTHRES_SHR 20,000 頁
  • LOCKLIST 1000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
  • APPGROUP_MEM_SZ 20,000 頁
數據庫 B:
  • IBMDEFAULTBP 92,500 頁
  • INTRA_PARALLEL ON
  • UTILHEAP 5,000 頁
  • DBHEAP 10,000 頁
  • SHEAPTHRES_SHR 15,000 頁
  • LOCKLIST 1000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
  • APPGROUP_MEM_SZ 20,000 頁
限制: 因爲共享內存是固定到物理 RAM 的,所以這種內存不會被換出。因此,我們只能分配最多 1GB (可用的物理 RAM)的共享內存給數據庫使用。
計算:
  • 數據庫 A 共享內存 = (186,000 頁 x 4KB/頁) x 1.1% = ~818MB
  • 數據庫 A 應用程序組內存 = 20,000 頁 x 4KB/頁 = 80MB
  • 數據庫 B 共享內存 = (131,000 頁 x 4KB/頁) x 1.1% = ~576MB
  • 數據庫 B 應用程序組內存 = 20,000 頁 x 4KB/頁 = 80MB
  • 爲了啓動數據庫 A,要求: 818MB + 80MB = ~898MB
  • 爲了啓動數據庫 B,要求: 576MB + 80MB = ~656MB
問題: 假設數據庫 A 是激活的。至少有 898MB 的共享內存固定在物理 RAM 中。當嘗試激活數據庫 B 時,就會碰到如下錯誤消息:

SQL1084C Shared memory segments cannot be allocated. SQLSTATE=57019
如果同時啓動數據庫 A 和數據庫 B,我們將請求至少 1.55GB (898MB + 656MB) 的可用物理 RAM,以便同樣地將共享內存固定在 RAM 中。顯然,1GB 的 RAM 不夠。爲解決這一問題:
  • 嘗試減少這兩個數據庫的緩衝池大小。或者
  • 嘗試減少應用程序組內存。或者
  • 更可能的是,增加更多的物理 RAM。在這種情況下,您將需要至少 1.55GB 的物理 RAM,才能同時啓動這兩個數據庫。
在這種情況下,按照上面的數據庫配置參數,在任何時刻啓動某一個數據庫(數據庫 A 或數據庫 B)是可行的,但是不能同時啓動兩個數據庫。這是必須增加更多的物理 RAM。
這個問題在 AIX 中不會出現,因爲在 AIX 中共享內存沒有固定在物理 RAM 中。在這種場景中,可以啓動數據庫 B。但是,這意味着數據庫 A 的數據庫內存必須調出。當一個應用程序訪問數據庫 A 時,又得將數據庫 B 的數據庫內存調出。您可以想象未來要發生的調頁次數有多少。
例 3考慮如下配置: (所有頁的大小都是 4K)
服務器:
  • 服務器上的物理 RAM 16GB
  • shmsys:shminfo_shmmax = 15099494 (16GB 的 ~90%)
數據庫:
  • IBMDEFAULTBP 350,000 頁
  • UTILHEAP 17,500 頁
  • DBHEAP 10,000 頁
  • LOCKLIST 1000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
  • ESTORE_SEG_SZ = 400000 頁
  • NUM_ESTORE_SEGS = 1
計算:
  • 數據庫共享內存 = (386,000 頁 x 4KB/頁 + 400,000 頁的 estore * 100 字節) x 1.1 = ~1.66GB
  • ESTORE memory = 400000 x 4KB = 1.6GB
問題: 數據庫共享內存是 1.66GB。這個數小於 3.35GB 的數據庫共享內存限制。shmmax 參數設置得比較恰當。但是在啓動數據庫時可能返回下面的錯誤消息!您可以在 db2diag.log 中看到如下錯誤消息:
  • 2003-12-04-10.10.13.362027 Instance:db2inst1 Node:000
  • PID:18327(db2agent (SAMPLE) 0) TID:1 Appid:*LOCAL.sample.047844091013
  • oper system services sqloVLMAttachVLMSegment Probe:20 Database:SAMPLE
  • sqloVLMAttachVLMSegment - shmat failed
  • 0xFFBE833C : 0x0000000C
shmat 是一個 UNIX 函數,它將與 shmid(另一個 Solaris 函數)所標識的共享內存相關的共享內存段附加到調用進程的數據段上。shmat 失敗於 0x000000C,即 ENOMEM 或可用數據空間不足以容納共享內存段。
換句話說,不能激活數據庫或連接到數據庫,因爲沒有足夠的共享內存來滿足請求。
那麼該怎麼辦呢?答案在於我們分配 ESTORE 的方式。每個 ESTORE 段必須是一個連續的塊。在我們的例子中,我們試圖爲 ESTORE 分配很大的一塊(連續的)內存(1.6GB)。即使有 16GB 的 RAM,它也可能會被分段,從而沒有一塊連續的 1.6GB 的內存。
爲解決這個問題,在數據庫配置文件中像下面這樣設置 ESTORE 的值:
  • ESTORE_SEG_SZ = 40000 頁
  • NUM_ESTORE_SEGS = 10
通過設置上面的 ESTORE 值,實際上我們仍然試圖爲 ESTORE 分配總共 1.6 GB 的內存。然而,我們將嘗試爲 ESTORE 分配 10 塊 160MB 的內存。這樣分配的連續空間就要小得多,因此最有可能解決問題
32 HP-UX 中的 DB2 內存配置

32-位 HP-UX 平臺上,默認 HP-UX 內存管理是基於象限(quadrant)的,其中每個進程都有其自己的空間。每個進程(包括 DB2 代理)可以尋址最多 4GB 的內存。4G 的可尋址內存被拆分成 4 個象限,每個象限大小爲 1G,如 圖 11所示。
11 - HU-UX 中的 DB2 32 位內存地址空間

象限 1 (1GB) 被預留給程序文本(可執行代碼)。
象限 2 (1GB) 被預留給全局程序數據。
象限 1 和象限 2(減去內核內存和其他進程的內存)可一起用於私有內存。象限 1 和 2 存在了 n 次(每個進程一次)
象限 3 (1GB) 被預留給全局共享內存。
象限 4 (0.75GB) 被預留給全局共享內存。最後 0.25GB 用於 I/O 映射。
系統範圍共享內存的限制是 1.75GB。也就是說,所有共享對象(不僅僅是 DB2)都被映射到象限 3 和 4 上由所有進程共享的一個單獨的空間內。這個共享內存空間分爲象限 3 中的 1GB 和象限 4 中的 0.75GB。但是,共享內存段不能跨象限“拆分”,而應該保證是一個連續的地址空間。根據進程的不同,DB2 分配各種不同的段。每個段只能映射到象限 3 或象限 4 中的某一個象限,但是不能同時映射到這兩個象限。因此,DB2 允許分配的最大共享內存段在象限 3 中的大小爲 1GB,在象限 4 中的大小爲 0.75GB。實際上,很可能不會分配這麼大的內存段,因爲之前可能已經分配了一些小的內存段(或者是由 DB2 分配的,或者是由其他進程分配的)。這意味着數據庫共享內存集實際上被限制在大約 0.75 到 1GB。這比其他 UNIX 平臺上可用的任何數據庫共享內存集要少得多。
注意: 缺省的 HP-UX 內存架構使用 SHARE_MAGIC 內核可執行程序。隨着 HP-UX 10.20 內核的更改,可以通過編譯應用程序使之使用 SHMEM_MAGIC 內核可執行程序,可以將全局共享內存的限制從 1.75G 增加到 2.75GB。不過,目前還沒有計劃使用 SHMEM_MAGIC 可執行程序編譯 DB2 代碼。
對於 HP-UX 11.0 或更新的版本,有一種方法可以以內存窗(Memory Windows)的形式繞過 1.75GB 的共享內存限制。內存窗允許每個進程從共享內存中定義最多 1GB 的惟一的全局空間。放在這個惟一空間內的共享內存段只能被相同內存窗中的進程訪問。但是不同的應用程序或同一應用程序的不同實例可以放在不同的內存窗中,並消耗系統上更多的可用物理內存。
內存窗使象限 3 能夠作爲 /etc/services.window 中定義的一個進程組的私有共享內存空間。在內存窗的 DB2 實現中,每個實例都被映射到一個單獨的內存窗。換句話說,每個 DB2 實例都可以有自己的象限 3 內存空間。象限 4 仍然用作全局共享內存區,其中任何共享進程都可以分配段。注意,如果象限 4 有可用的空間,那麼共享庫總是首先被映射到象限 4。於是,每個實例的可用共享內存就變爲 1GB 加上象限 4 中仍然可用的空間。不過,共享內存段依然不能跨越象限邊界。根據段的類型和大小,DB2 可以指定在象限 4 中創建段。數據庫共享內存集仍然有大約 1GB 的限制。因此,內存窗的好處是允許我們爲一個 DB2 實例分配整個象限(象限 3,大約 1GB)。然而,如果沒有內存窗,則所有實例都必須共享最多 1.75GB 的系統範圍的共享«內存。
提示: 如果爲每個實例都創建一個數據庫,就可以有效地爲所有數據庫分配最多 1GB 的數據庫共享內存。
注意: 內存窗只是爲 32 位應用程序擴展了系統範圍的虛擬容量。通過擴展虛擬容量,可以使用更多的底層 RAM。在不使用內存窗的情況下,不管 RAM 有多大,最多隻能消耗 1.75GB 的物理內存。
要了解有關如何爲 DB2 啓用內存窗的更多信息,請參閱
需要從這種結構中瞭解到的最重要的事情是:
  • HP-UX 默認內存體系結構只允許所有進程(不僅僅是 DB2)共享最多 1.75GB 的共享內存。只有啓用了內存窗,HP-UX 才能爲每個實例分配共享內存。
  • 共享內存段要求是連續的,因此不能跨越象限邊界。這有效地將數據庫共享內存集限制爲 1GB。
  • 內存窗可以用來爲每個 DB2 實例提供一個有效的 1GB 私有數據庫共享內存空間,再加上全局共享內存象限(象限 4)中的所有可用空間。
  • 如果爲每個實例都創建一個數據庫,那麼就可以爲一個數據庫分配最多 1GB 的空間作爲共享內存。
32 位 HP-UX 上與分配數據庫共享內存有關的常見問題

沒有充分配置內核參數或者初始化數據庫共享內存失敗可能導致以下失敗:
  • 在數據庫管理器啓動時 - SQL1220N
  • 在數據庫啓動時(激活數據庫或第一次連接到數據庫) - SQL1478W, SQL1084C, SQL3605C, hang condition
  • 在運行時 - SQL2043N, hang condition
最常見的未能正確設置的內核參數是 shmmax。請參考 Quick Beginnings,以瞭解如何根據物理 RAM 設置適當的值。SHMMAX 按字節指定系統上可以分配的最大共享內存段。如果將 UDB 配置爲創建一個大於該值的數據庫共享內存集,則請求將遭到失敗。
下面的例子展示了會導致問題的不正確的配置。
例 1考慮如下配置: (所有頁的大小都爲 4K)
服務器:
  • 服務器上的物理 RAM 1GB
  • shmmax = 966 367 641 (1GB)
  • shmseg = 32
數據庫:
  • IBMDEFAULTBP 100,000 頁
  • UTILHEAP 5000 頁
  • DBHEAP 10,000
  • LOCKLIST 17,500 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
計算:數據庫共享內存 = (140,000 頁 x 4KB/頁) x 1.1% = ~616MB
問題:可能仍然可以激活數據庫或連接到數據庫。但是,當嘗試連接到數據庫時,在 db2diag.log 中可能間歇地出現如下錯誤消息。

DIA3605C Memory allocation failure occurred.
注意,對數據庫共享內存的計算表明,我們仍然沒有超出 1GB 可用共享內存的限制。接下來我們看一看內核參數的設置。查看 "Quick Beginnings for DB2 Servers" 以獲得對 32 位 HP-UX 平臺上調優內核參數的建議。在查看這本書時,實際上您會發現其中沒有寫到 shmseg 參數。這意味着您應該使用默認設置。shmseg 的默認設置是 120。(由於 SHMSEG 內核參數被設得太低,有些共享內存段不能適當地分配。)
要解決這個問題,需適當地配置內核參數。
  • 在這種情況下,設置 shmseg = 120
例 2考慮如下配置: (所有頁的大小都爲 4K)
服務器:
  • 服務器上的物理 RAM 1GB
  • shmmax = 966 367 641 (1GB)
  • shmseg = 120
  • 服務器上的交換空間 500MB
數據庫 A:
  • IBMDEFAULTBP 100,000 頁
  • UTILHEAP 2500 頁
  • DBHEAP 10,000
  • LOCKLIST 20,000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
數據庫 B:
  • IBMDEFAULTBP 160,000 頁
  • UTILHEAP 7,500 頁
  • DBHEAP 20,000 頁
  • LOCKLIST 10,000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
限制: 由於物理 RAM 只有 1GB,數據庫共享內存集只能映射到它在物理上可以使用的空間,即 1GB + 交換空間。
計算:
  • 數據庫 A 共享內存 = (140,000 頁 x 4KB/頁) x 1.1% = ~616MB
  • 數據庫 B 共享內存 = (205,000 頁 x 4KB/頁) x 1.1% = ~902MB
問題: 分別激活或連接到數據庫 A 或數據庫 B 是可行的,但是不能併發進行。嘗試同時激活這兩個數據庫將產生如下錯誤消息:

SQL1478W The defined buffer pools could not be started. Instead, one small buffer pool for each page size supported by DB2 has been started. SQLSTATE=01626
如果同時啓動數據庫 A 和數據庫 B,需要至少 1.52GB (616MB + 902MB) 的共享內存。將數據庫 A 映射到象限 4 (~0.75GB 可用共享內存)和將數據庫 B 映射到象限 3 (~1GB)應該沒有問題。但是,這一次,我們會受到物理內存的限制。顯然,1GB 的 RAM 不足以處理 1.52GB 的共享內存映射。此外,SWAP 空間也被設置得太低。要解決這一問題:
  • 嘗試減少這兩個數據庫的緩衝池大小。或者
  • 嘗試將交換空間增加到物理 RAM 的兩倍。或者
  • 最好的解決方案是,增加更多的物理 RAM。在這種情況下,您將需要至少 2GB 的物理 RAM,才能同時啓動這兩個數據庫。
例 3考慮如下配置: (所有頁的大小都爲 4K)
服務器:
  • 服務器上的物理 RAM 6GB
  • Instance 1 (3 個數據庫)
數據庫 A:
  • IBMDEFAULTBP 140,000 頁
  • UTILHEAP 7,500 頁
  • DBHEAP 20,000 頁
  • LOCKLIST 10,000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
  • APPGROUP_MEM_SZ 20,000 頁
數據庫 B:
  • IBMDEFAULTBP 80,000 頁
  • UTILHEAP 2500 頁
  • DBHEAP 10,000 頁
  • LOCKLIST 20,000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
  • APPGROUP_MEM_SZ 20,000 頁
數據庫 C:
  • IBMDEFAULTBP 130,000 頁
  • UTILHEAP 7,500 頁
  • DBHEAP 20,000 頁
  • LOCKLIST 10,000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
  • APPGROUP_MEM_SZ 20,000 頁
限制: 由於物理 RAM 只有 1GB,數據庫共享內存集只能映射到它在物理上可以使用的那些空間,即 1GB + 交換空間。
計算:
  • 數據庫 A 共享內存 = (185,000 頁 x 4KB/頁) x 1.1% = ~814MB
  • 數據庫 A 應用程序組內存 = 20,000 頁 x 4KB/頁 = 80MB
  • 數據庫 B 共享內存 = (120,000 頁 x 4KB/頁) x 1.1% = ~528MB
  • 數據庫 B 應用程序組內存 = 20,000 頁 x 4KB/頁 = 80MB
  • 數據庫 C 共享內存 = (175,000 頁 x 4KB/頁) x 1.1% = ~770MB
  • 數據庫 C 應用程序組內存 = 20,000 頁 x 4KB/頁 = 80MB
  • 要啓動數據庫 A,要求: 816MB + 80MB = ~894MB
  • 要啓動數據庫 B,要求: 530MB + 80MB = ~608MB
  • 要啓動數據庫 C,要求: 772MB + 80MB = ~850MB
問題: 啓動數據庫 A 和數據庫 B 成功。但是啓動數據庫 C 時失敗,並返回如下錯誤:

SQL1478W The defined buffer pools could not be started. Instead, one small buffer pool for each page size supported by DB2 has been started. SQLSTATE=01626
在這裏,物理內存不是問題,因爲我們有足夠多的 RAM(6GB)。進一步的測試得處了以下啓動組合:
  • 啓動 A + B ->成功
  • 啓動 B + C ->成功
  • 啓動 A + C ->不成功
  • 啓動 (A + B) + C ->不成功
  • 啓動 (B + C) + A ->不成功
組合 (A + B) 和組合 (B + C) 獲得成功,因爲它們初始化數據庫所需的共享內存總量分別是 1.5GB (894 + 608) 和 1.46GB (608+850)。這低於 1.75GB 的共享內存限制,並且每個數據庫共享內存段可以安全地連續映射到一個象限。而其他組合將失敗於 SQL1478W,因爲它們要麼超出了 1.75GB 共享內存限制,要麼不能在一個象限內爲一個數據庫分配連續的共享內存段。
要解決這一問題:
  • 實現內存窗。最好的解決方案是定義 3 個 DB2 實例。將一個數據庫恢復到每個實例。併爲每個實例創建一個內存窗。這樣一來,每個實例都可以完全訪問它自己的 1GB 內存窗共享內存空間。注意: max_mem_windows 內核參數必須設爲 2 (實例數 -1)。
32-位 Linux/Intel 中的 DB2 內存配置
圖 12中展示了 32 位 Linux/Intel 上的 4GB 可尋址內存。
圖 12 - Linux/Intel 中的 DB2 32 位內存地址空間

從 0x08048000 到 0x0FFFFFFF 的段是預留給 db2sysc 可執行程序的。從 0x10000000 到 0x3FFFFFFF 的段是實例共享內存,總共是 0.75GB。在默認情況下,DB2 共享庫始於 0x40000000。
在低地址裝載共享庫,而將更多的空間留給數據庫共享內存,這是可行的。(這也意味着用於實例共享內存的空間將更少。但是由於實例內存與數據庫內存相比通常比較小,因此這樣可以獲得好處。)例如,如果在低於 0x40000000 的地址裝載共享庫,那麼就可以在 0x38000000 裝載數據庫共享內存。如果在低於 0x2a000000 的地址裝載共享庫,那麼就可以在 0x30000000 裝載數據庫共享內存,這樣就有超過 2GB 的空間留給數據庫共享內存。這些更改要求重新編譯內核,我們在本文中不會對此加以討論。請參考 Linux 手冊中內核重編譯那一節,以瞭解更多信息。
不過,對於 Redhat Advanced Server 和 SuSE SLES 8 上的 v8.1 FP2,DB2 將嘗試自動將共享庫重新分配到一個較低的地址,這樣就不需要重新編譯內核。在這些企業發行版中,有一個叫做 /proc/ pid/mapped_base 的文件包含了一個地址,共享庫將從該地址裝載到內存。在默認情況下,該地址是 0x40000000,但是我們可以把它降低一些(降到 0x20000000)。當 db2sysc 啓動時,我們檢查 mapped_base 文件是否存在。如果存在,則使用新的值並重新執行。然後,mapped_base 值發生了改變的進程中產生的每個進程都使用這個新值。
數據庫共享內存(包括緩衝池)始於 0x50000000 (默認值)。它從 0x50000000 開始朝着堆棧方向向下增長。堆棧包含要執行的指令。堆棧從 0xC0000000 開始向上增長。
使數據庫共享內存和堆棧不發生衝突,這一點很重要。我建議爲堆棧使用 16MB 這麼大的空間。在這樣的情況下,我們有 ~1.73GB 用於數據庫共享內存(從 0x50000000 到 0xC0000000,減去 16MB 的堆棧)。
在使用 "ulimit -a" 或 "ulimit -s" 顯示限制時,這些值是以 1K 字節爲單位顯示的。
Stack = 16384
設置這個限制,使堆棧和共享內存地址空間不會相互衝突,這一點很重要。如果它們之間有衝突,那麼實例就會崩潰,併發出信號 4 或信號 11。最後 1GB 的內存 被預留給 Linux 內核
您可能已經注意到,沒有用於代理私有內存的段。這就對了,在 32 位的 Linux/Intel 中,沒有預留特定的段給私有內存。代理私有內存是從共享庫之間的任意空閒空間中分配的。
爲了看一看這裏是如何使用內存的,請參閱叫作 /proc/ PID/maps 的文件,其中 PID 是 db2agent 進程的進程 ID。 圖 12展示了 maps 文件的示例輸出。
圖 13 - db2sysc 進程的 maps 文件

從 圖 13 中可以觀察到下面一些情況:
  • 0x10000000 開始的綠色的段是實例共享內存。
  • 共享庫從 0x40000000 開始裝載。在共享庫之間,橙色的段是代理私有內存。
  • 綠色是數據庫共享內存,始於 0x50000000。
  • 最後一個紫色的段是堆棧。
需要從這種結構中瞭解到的最重要的事情是:
  • 在默認情況下,數據庫共享內存的大小是 1.75GB 減去堆棧大小。
  • 將共享庫裝載到一個較低的地址,從而使留給實例共享內存的空間更少,留給數據庫共享內存的空間更多。
32 位 Linux 中與分配數據庫共享內存有關的常見問題

沒有充分配置內核參數或者初始化數據庫共享內存失敗可能導致以下失敗:
  • 在數據庫管理器啓動時 - SQL1220N
  • 在數據庫啓動時(激活數據庫或第一次連接到數據庫) - SQL1478W, SQL1084C, hang condition
  • 在運行時 - SQL2043N, hang condition
最常見的未能正確設置的內核參數是 shmmax。請參考 Quick Beginnings ,瞭解如何根據物理 RAM 設置適當的值。 shmmax按字節指定了系統中可以分配的最大共享內存段。如果將 UDB 配置成創建大於這個值的數據庫共享內存集,那麼該請求將遭到失敗。其他要指定的內核參數是 shmmni。下面的例子展示了會導致問題的不恰當配置。
例 1服務器:
  • 服務器上的物理 RAM 2GB
  • kernel.shmmax = 32768(32KB)
數據庫:
  • IBMDEFAULTBP 200,000 頁
  • INTRA_PARALLEL ON
  • UTILHEAP 17,500 頁
  • DBHEAP 10,000 頁
  • SHEAPTHRES_SHR 50,000 頁
  • LOCKLIST 1000 頁
  • PCKCACHE 5000 頁
  • CATALOGCACHE 2500 頁
  • APPGROUP_MEM_SZ 20,000 頁(v8 中的默認值)
限制: SHMMAX 被設爲 32KB。DB2START 可以分配足夠多的共享內存來成功地啓動實例。
計算:
  • 數據庫共享內存 = (286,000 頁 x 4KB/頁) x 1.1 = ~1.26GB
  • 數據庫應用程序組內存 = 20,000 頁 x 4KB/頁 = 80MB
問題: 在 db2start 期間,將碰到以下錯誤:

SQL1220N The database manager shared memory set cannot be allocated.
要解決這個問題,可以將 SHMMAX 參數增加到一個更合理的大小,例如 2GB。
例 2服務器:
  • DB2 v8.1.0.0
  • OS: Linux SuSE SLES-8
  • glibc version : 2.2.5
  • Kernel: 2.4.19
問題: 如 SHMMAX 被設爲 2GB,即 2147483648,那麼一次 db2start 就會使其降至 268435456。如果將這個值減少 1 個字節,那麼 db2start 不會作出任何變化。該問題在 v8 FP2, APAR LI70159中已得到修復。
對 SuSe 8.0 不會發生問題。
32 位 Windows 中的 DB2 內存配置

在 Windows 上,DB2 UDB 有着根本不同的體系結構。所有 DB2 操作都是以進程(db2sysc.exe)內的線程的形式實現的。Windows 進程模型最多可尋址 4GB 的內存,如 圖 14中所示。
圖 14 - Windows 中的 DB2 32-位內存地址空間

在 Windows 中沒有真正的共享內存集的概念。在 UNIX 中,所有共享內存池通常都是某個內存集(例如緩衝池,dbheap,等等)的一部分,而在 Windows 中,這些共享內存池都是根據需要從 db2sysc 的私有內存集中分配的。
在非 Advanced Server Windows 環境(NT,2000 Pro/Standard)中,4GB 地址空間被分成 2GB 的用戶空間和 2GB 的內核空間。這樣可以有效地將 db2sysc 進程可訪問的內存總數限制到 2GB。
在 Advanced Server 環境中,將 2GB/2GB 的內存拆分重新配置爲 3GB 的用戶空間和 1GB 的內核空間是可行的,如 圖 14中所示。
爲了允許內存使用量超出這些限制,必須在 boot.ini 文件中使用 /3GB switch。這裏要警告的是,/3GB switch 只在 Windows 2000 Advanced Server、Windows 2000 DataCenter、Windows2003 Enterprise Edition 和 Windows 2003 DataCenter 中受支持。您可以在 Windows2000 Pro/Standard 中設置這個 switch,但是用戶空間最多隻能有 2GB,而內核空間縮小到 1GB,這會導致 1GB 的內存丟失。
注意: 爲了有效地使用 /3GB switch,必須在 Windows 32 位環境中安裝了最少 4GB 的物理 RAM。
爲了克服 2GB (或 3GB)的用戶空間限制,Windows 2000 Advanced Server 和 Windows 2003 Advanced Server 提供了對更大內存的支持。它們是 Address Windowing Extensions (AWE) 和 Physical Address Extension (PAE)。
AWE 是一種機制,用於通過一個可能更小的窗口訪問內存中一個很大的部分。按照這種方法,如果某個大的內存池是線性的,那麼它就可以被尋址。實際上,AWE 允許創建超過 2GB 限制的緩衝池。AWE 功能是通過使用 boot.ini 文件中的 /PAE switch 來實現的。/PAE 在 Windows2000 Pro/Standard 中有效,但如果不是使用 Windows 2000 Advanced Server、Windows 2000 DataCenter、Windows2003 Enterprise Edition 和 Windows 2003 DataCenter,則 Microsoft 不會允許你的操作系統與這樣的 switch 一起運行。
需要從這種結構中瞭解到的最重要的事情是:
  • 在 Windows 體系結構中沒有真正的內存集概念。DB2 使用的所有內存(共享的或私有的)池都是從相同的內存段中分配的 - 這個內存段就是用戶空間,在非 Advanced Servers 環境中限於 2GB。
  • Advanced Servers 中使用文件中的 /3GB switch 將這一限制增加到 3GB 是可行的。
  • 通過使用 AWE 可以將緩衝池增加到超過 2GB 的限制。實際上,可以定義最大 64GB 的緩衝池。
結束語
DB2 的內存結構由 4 個內存集組成:實例共享內存、數據庫共享內存、應用程序組共享內存(只有在數據庫啓用了 intra-parallel,或者啓用了集中器,或者多分區的時候才適用)以及代理私有內存。每種內存集由各個內存池組成。例如,緩衝池和數據庫堆是數據庫內存集內的兩個不同的內存池。
每個實例有一個實例共享內存集,由這個實例中的所有數據庫共享。每個數據庫有一個數據庫共享內存集,由連接到該數據庫的所有代理共享。每個應用程序組有一個應用程序組共享內存集,由屬於該應用程序組的所有代理共享。每個代理(或進程)都有一個代理私有內存集。該內存集是由代理獨佔使用的。
對於 32 位內存結構,不管系統有多少物理 RAM,在任何平臺上任何進程的可尋址內存都是 4GB。而且,這 4GB 中有一部分要預留給操作系統。剩下的所有內存(亦稱用戶空間)是由應用程序(包括 DB2)使用的。
在配置 DB2 內存的使用時應記住,所有內存池應該能夠納入可尋址用戶空間。這個空間的大小隨平臺的不同而不同。表 1 列出了每種 DB2 內存集的限制。應用程序組共享內存集沒有列出,因爲它是從數據庫共享內存集中分配的。
表 1 - 基於 32 位內存結構的 DB2 內存集限制
平臺
實例共享內存
數據庫共享內存
代理私有內存
AIX
256MB
1.25 – 2GB (1)
240MB (2)
Solaris
不固定(3)
3.5GB
~220MB (4)
HP-UX
0.75 - 1GB (5)
0.75 – 1GB
象限 1 & 2 (6)
Linux
256MB
1.75 – 2.25GB
256MB
Windows
n/a (7)
n/a (7)
n/a (7)
注意:

(0) 在多分區環境中,這些限制適用於每個分區。

(1) 當 DB2_MMAP_READ=NO 並且 DB2_MMAP_WRITE=NO 時,限制的最大值爲 2GB。以下每種情況都會佔用一個 256MB 的段,致使 1.25GB 的最小值出現:fenced 函數和過程;DB2_FORCE_FCM_BP=YES;啓用了 intra-parallel/啓用了集中器/多分區。

(2) Data (代理私有內存)和 Stack 之間共享 256MB 的段。在 ulimit 中將堆棧設爲 16MB,便可以將 240MB 留給代理私有內存。

(3) 在 Solaris 中,實例共享內存可能非常大,因爲共享內存段沒有固定的地址。實例共享內存和數據庫共享內存合起來大約是 3.7GB。

(4) 在 Solaris 中,代理私有內存與 db2sysc 可執行程序共享同一個 256MB 的段。這個可執行程序大約佔 36MB。

(5) 在 HP-UX 中,所有共享內存都位於象限 3 (1GB)和象限 4 (0.75 GB)中。

(6) 象限 1 和 2(減去內核內存和其他進程內存)可以一起用作私有內存。

(7) 所有實例共享內存、數據庫共享內存和代理私有內存都必須能納入 2GB 的用戶空間限制,或者在 Advanced Server 上使用了 boot.ini 文件中的 /3GB switch 之後 3GB 的限制。如果支持 AWE 則是 64GB。
對於 32 位內存結構,不管物理 RAM 有多大,實例、數據庫配置都受到 4GB 可尋址空間的限制。不過,如果有足夠的 RAM,只需每個實例或數據庫都符合以上限制,就可以在系統中併發地運行多個實例或數據庫。爲了克服這一限制,應該考慮轉換到 64 位的 DB2。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章