天天看點

《DB2性能管理與實戰》——2.2 資料庫管理器共享記憶體

本節書摘來自異步社群出版社《db2性能管理與實戰》一書中的第2章,第2.2節,作者: ibm中國開發中心(cdl) 資訊管理軟體開發部,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

db2性能管理與實戰

資料庫管理器共享記憶體由若幹個不同的記憶體區組成,可使用配置參數控制這些區域的大小。圖2-2顯示了資料庫管理器共享記憶體的配置設定方式。

每個db2執行個體都有一個執行個體共享記憶體。執行個體共享記憶體是在資料庫管理器啟動(db2start)時配置設定的,并随着資料庫管理器的停止(db2stop)而釋放。這種記憶體集用于執行個體級的任務,例如監控、審計和節點間通信。下面的資料庫管理器配置(dbm cfg)參數控制着對執行個體共享記憶體以及其中個别記憶體池的限制。

boll 執行個體記憶體(instance_memory)。

boll 螢幕堆(mon_heap_sz):用于監控。

boll audit buffer(audit_buf_sz):用于db2audit實用程式。

boll 對于分區資料庫系統,快速通信管理器(fcm)需要足夠多的記憶體空間,fcm_ num_buffers的值較大時尤其如此。所需的fcm記憶體将從fcm緩沖池中進行配置設定。

《DB2性能管理與實戰》——2.2 資料庫管理器共享記憶體

instance_memory參數指定為執行個體管理預留的記憶體數量。instance_memory的預設值為automatic。automatic設定将導緻在激活資料庫分區時計算值。計算值介于系統上的實體ram的75%~95%之間,系統越大,此百分比越高。對于具有記憶體使用量限制的db2資料庫産品,計算值也會受到産品許可證允許的最大值的限制。對于具有多個邏輯資料庫分區的資料庫分區伺服器,此計算值是除以邏輯資料庫分區數而獲得的值。

從v9.7 fp1和v9.5 fp5開始,對于沒有記憶體使用量限制的db2資料庫産品,automatic設定的計算值不會對執行個體中配置設定的記憶體施加限制。對于v9.7和v9.5 fp4或更低版本,automatic設定的計算值表示對于所有db2資料庫産品的限制。

如果instance_memory被設定為某一個數字,則采用instance_memory與mon_heap_sz、audit_buf_sz和fcm_num_buffers的和之間的較大者。這時,對執行個體記憶體就施加了一個硬性的限制,而不是軟限制。當達到這個限制時,就會收到記憶體配置設定錯誤。出于這個原因,建議将instance_memory的設定保留為automatic。

如果instance_memory被設為automatic,則可以使用下面的指令來确定它的值:

boll db2 attach to instance_name(其中instance_name是執行個體的名稱)

boll db2 get dbm cfg show detail

下面的輸出表明有42 mb的記憶體被預留給執行個體共享記憶體集(10313頁×4096位元組/頁):

boll size of instance shared memory(4kb)(instance_memory)= automatic(10313) automatic(10313)

instance_memory參數隻是設定了執行個體共享記憶體的限制,它并沒有說出目前使用了多少記憶體。要查明一個執行個體的記憶體使用情況,可以使用db2記憶體跟蹤器工具db2mtrk。

上面的例子表明,雖然預留給執行個體共享記憶體集的記憶體有42 mb,但在db2mtrk運作時隻用到了大約21 mb。

注意:

在某些情況下,db2mtrk顯示的大小會大于指定給配置參數的值。在這種情況下,賦予配置參數的值被作為一種軟限制,記憶體池實際使用的記憶體可能會增長,進而超出配置的大小。

使用admin_get_mem_usage表函數來擷取特定資料庫分區或所有資料庫分區的db2執行個體耗用的執行個體記憶體總量。此表函數還會傳回目前上限值。

配置設定快速通信管理器(fcm)共享記憶體時,将在每個本地資料庫分區的instance_ memory使用中說明該資料庫分區在系統的總fcm共享記憶體大小中所占的份額。

每個資料庫有一個資料庫共享記憶體集。資料庫共享記憶體是在資料庫被激活或者第一次連接配接的時候配置設定的。該記憶體集将在資料庫處于非激活狀态時釋放(如果資料庫先前是處于激活狀态)或者最後一個連接配接被斷開的時候釋放。這種記憶體用于資料庫級的任務,例如備份/恢複、鎖定和sql的執行。

圖2-3展示了資料庫共享記憶體集内的各種記憶體池。括号中顯示了控制這些記憶體池大小的配置參數。

《DB2性能管理與實戰》——2.2 資料庫管理器共享記憶體

陰影方框意味着,在資料庫啟動的時候,該記憶體池是完全配置設定的,否則,就隻配置設定部分的記憶體。例如,當一個資料庫第一次啟動時,不管util_heap_sz的值是多少,隻有大約16 kb的記憶體被配置設定給實用程式堆。當一個資料庫實用程式(例如備份、恢複、導出、導入和裝載)啟動時,才會按 util_heap_sz指定的大小配置設定全額的記憶體。

1.主緩沖池

資料庫緩沖池通常是資料庫共享記憶體中最大的一塊記憶體。db2在其中操縱所有正常資料和索引資料。一個資料庫必須至少有一個緩沖池,并且可以有多個緩沖池,這要視工作負載的特征、資料庫中使用的資料庫頁面大小等因素而定。例如,頁面大小為8kb的表空間隻能使用頁面大小為8kb的緩沖池。

可以通過create bufferpool語句中的extended storage選項“擴充”緩沖池。擴充的存儲(estore)充當的是從緩沖池中被逐出的頁的輔助緩存,這樣可以減少i/o。estore的大小由num_estore_segs和estore_seg_sz這兩個資料庫配置參數來控制。如果使用estore,就要從資料庫共享記憶體中拿出一定的記憶體,用于管理estore,這意味着用于其他記憶體池的記憶體将更少。

2.隐藏的緩沖池

當資料庫啟動時,要配置設定4個頁寬分别為4kb、8kb、16kb和32kb的小型緩沖池(大小為16頁)。這些緩沖池是“隐藏”的,因為在系統編目中看不到它們(通過select * from syscat.bufferpools顯示不出)。

如果主緩沖池配置得太大,則可能出現主緩沖池不适合可尋址記憶體空間的情況。這意味着db2無法啟動資料庫,因為一個資料庫必須至少有一個緩沖池。如果資料庫沒有啟動,那麼就不能連接配接到資料庫,也就不能更改緩沖池的大小。出于這個原因,db2預先配置設定了4個這樣的小型緩沖池。這樣,一旦主緩沖池無法啟動,db2還可以使用這些小型緩沖池來啟動資料庫(在此情況下,使用者将收到一條警告[sqlstate 01626])。這時,應該連接配接到資料庫,并減少主緩沖池的大小。

3.排序堆的門檻值(sheapthres,sheapthres_shr)

如果沒有索引滿足所取的行的要求順序,或者優化器斷定排序的代價低于索引掃描,那麼就需要進行排序。db2中有兩種排序,一種是私有排序,一種是共享排序。私有排序發生在代理的私有代理記憶體(在下一節讨論)中,而共享排序發生在資料庫的資料庫共享記憶體中。

對于私有排序,資料庫管理器配置參數 sheapthres指定了私有排序在任何時刻可以消耗的記憶體總量在執行個體範圍内的軟限制。如果一個執行個體總共消耗的私有排序記憶體達到了這一限制,那麼為額外傳入的私有排序請求所配置設定的記憶體将大大減少,這樣就會在db2diag.log中看到如下消息。

如果啟用了内部分區并行性(intra-partition parallelism)或者集中器(concentrator),那麼當db2斷定共享排序比私有排序更有效時,db2就會選擇執行共享排序。如果執行共享排序,那麼就會在資料庫共享記憶體中配置設定用于這種排序的排序堆。用于共享排序的最大記憶體量是由 _shr sheapthres資料庫參數指定的。這是對共享排序在任何時刻可以消耗的記憶體總量在資料庫範圍内的硬限制。當達到這個限制時,請求排序的應用程式将收到錯誤sql0955(rc2)。之後,在共享記憶體總消耗量回落到低于由 sheapthres_shr指定的限制之前,任何共享排序記憶體的請求都得不到允許。

下面的公式可以計算出資料庫共享記憶體集大緻需要多少記憶體。

資料庫共享記憶體 =(主緩沖池 + 4個隐藏的緩沖池 + 資料庫堆 +實用程式堆 + locklist + 包緩存 + 編目緩存)+(estore的頁數×100位元組)+ 大約10% 的開銷

對于啟用了intra_parallel或集中器情況下的資料庫,共享排序記憶體必須作為資料庫共享記憶體的一部分預先配置設定,因而上述公式變為:

資料庫共享記憶體 =(主緩沖池 + 4個隐藏的緩沖池 + 資料庫堆 +實用程式堆 + locklist + 包緩存 + 編目緩存 + sheapthres_shr)+(estore的頁數×100位元組)+ 大約10% 的開銷

提示:

為了發現配置設定給主緩沖池的記憶體有多少,可以執行下述指令:

雖然大多數記憶體池的大小是由它們的配置參數預先确定的,但下面兩種記憶體池的大小在預設情況下卻是動态的。

boll 程式包緩存:pckcachesz = maxappls * 8

boll 編目緩存:catalogcache_sz = maxappls * 4

boll 活動應用程式的最大數量:maxappls = automatic

将maxappls設為automatic的效果是,允許任意數量的連接配接資料庫的應用程式。db2将動态地配置設定所需資源,以支援新的應用程式。是以,包緩存和編目的大小可以随着maxappls的值而變化。

除了上述參數以外,還有一個參數也會影響資料庫共享記憶體的數量。這個參數就是database_memory。該參數的預設值是automatic。這意味着db2将根據以上列出的各記憶體池的大小來計算目前配置所需的資料庫記憶體量。此外,db2還将為溢出緩沖區配置設定一些額外的記憶體。每當某個堆超出了其配置的大小時,便可以使用溢出緩沖區來滿足執行個體共享記憶體區内任何堆的峰值需求。

如果 database_memory被設為某個數字,則采用database_memory與各記憶體池之和這兩者之間的較大者。

如果database_memory被設為automatic,則可以使用以下指令來顯示它的值。

使用db2mtrk工具顯示目前使用的記憶體量:db2mtrk-i-d-v(在windows中,-i必須指定。在unix中,-i是可選的)。

這種共享記憶體集僅适用于以下環境(對于其他環境,這種記憶體集不存在)。

boll 多分區(multi-partitioned)資料庫。

boll 啟用了内部并行(intra_parallel)處理的未分區(non_partitioned)資料庫。

boll 支援連接配接集中器的資料庫。

當 max_connections的值大于max_coordagents的值時,連接配接集中器便被啟用。這兩個參數可以在資料庫管理器配置中找到(使用get dbm cfg顯示資料庫管理器配置)。

在以上環境中,應用程式通常需要不止一個的代理來執行其任務。允許這些代理之間能夠彼此通信(互相發送/接收資料)很有必要。為了實作這一點,将這些代理放入到一個稱作應用程式組的組中。屬于相同應用程式組的所有db2代理都使用應用程式組共享記憶體進行通信。

應用程式組記憶體集是從資料庫共享記憶體集中配置設定的,其大小由appgroup_mem_sz資料庫配置參數決定。多個應用程式可以指派給同一個應用程式組。一個應用程式組内可以容納的應用程式數可以這樣計算:appgroup_mem_sz / app_ctl_heap_sz。

在應用程式組内,每個應用程式都有其自己的應用程式控制堆。此外,應用程式組共享記憶體中有一部分要預留給應用程式組共享堆,如圖2-4所示。

《DB2性能管理與實戰》——2.2 資料庫管理器共享記憶體

例1

考慮以下資料庫配置。

boll 最大應用程式記憶體集大小(4kb)(appgroup_mem_sz)= 40000

boll 最大應用程式控制堆大小(4kb)(app_ctl_heap_sz)= 512

boll 用于應用程式組堆的記憶體所占百分比(groupheap_ratio)= 70

可以計算出下面的值。

boll 應用程式組共享記憶體集是:40000頁×4kb/頁 = 160 mb

boll 應用程式組共享堆的大小是:40000×70% = 28000頁×4kb/ 頁 = 114mb

boll 該應用程式組内可容納的應用程式數為:40000/512 = 78

boll 用于每個應用程式的應用程式控制堆為:(100-70)%×512 = 153×4kb/頁 = 0.6mb

不要被app_ctl_heap_sz參數迷惑。這個參數不是一個應用程式組内用于每個應用程式的各應用程式控制堆的大小。它隻是在計算這個應用程式組内可容納多少應用程式時用到的一個值(此參數在v9.5以後被appl_memory參數所取代)。每個應用程式的實際應用程式控制堆大小都是通過圖2-4中給出的公式計算的,這個公式就是((100- groupheap_ratio)%×app_ctl_heap_sz)。

是以,groupheap_ratio越高,應用程式組共享堆就越大,進而用于每個應用程式的應用程式控制堆就越小。

例2

假設在一天中最忙的時間裡,有200個應用程式連接配接到例1中所描述的資料庫上。由于每個應用程式組可以容納78個應用程式,是以需要200/78 = 3個應用程式組來容納總共200個應用程式。這裡應確定系統有足夠多的ram來支援這一配置,否則就會發生sql10003n錯誤。

每個db2代理程序都需要獲得記憶體,以執行其任務。代理程序将代表應用程式使用記憶體來優化、建構和執行通路計劃、執行排序、記錄遊标資訊(例如位置和狀态)、收集統計資訊等。為響應并行環境中的一個連接配接請求或一個新的sql請求,要為一個db2代理配置設定代理私有記憶體。

代理的數量受下面兩者中的較低者限制。

boll 所有活動資料庫的資料庫配置參數maxappls的總和,這指定了允許的活動應用程式的最大數量。

boll 資料庫管理器配置參數maxagents的值,這指定了允許的最大代理數。

代理私有記憶體集由以下記憶體池組成,這些記憶體池的大小由括号中的資料庫配置參數指定。

boll application heap(applheapsz)

boll sort heap(sortheap)

boll java interpreter heap(java_heap_sz)

boll agent stack size(agent_stack_sz)(僅适用于windows)

前面曾提到,私有記憶體是在一個db2代理被“指派”執行任務時配置設定給該代理的。那麼,私有記憶體何時釋放呢?答案取決于dbm cfg參數num_poolagents的值。該參數的值指定任何時候可以保留的閑置代理的最大數目。如果該值為0,那麼就不允許有閑置代理。隻要一個代理完成了它的工作,這個代理就要被銷毀,它的記憶體也要傳回給作業系統。如果該參數被設為一個非零值,那麼一個代理在完成其工作後不會被銷毀。相反,它将被傳回到閑置代理池,直到閑置代理的數目到達num_poolagents指定的最大值。當傳入一個新的請求時,就要調用這些閑置代理來服務該新請求,這樣就減少了建立和銷毀代理的開銷。

當代理變成閑置代理時,它仍然保留了其代理的私有記憶體。這樣設計是為了提高性能,因為當代理被再次調用時,它便有準備好的私有記憶體。如果有很多的閑置代理,并且所有這些閑置代理都保留了它們的私有記憶體,那麼就可能導緻系統記憶體耗盡。

本文僅用于學習和交流目的,不代表異步社群觀點。非商業轉載請注明作譯者、出處,并保留本文的原始連結。