詳解數據庫中的分頁、內存和I/O延遲
幾年前我寫了一篇關于 AIX 調優的文章,現在 AIX 7 出現了,所以有必要重新審視需要在 AIX 系統上執行的基本調優措施。已經發布的許多技術級別 (TL) 和一些建議可能會改變。在本文中,我將提供與 AIX 5.3、6.1 和 7 中的可調項相關的 AIX 調優信息。
我主要關注 I/O、內存和網絡。在默認情況下,AIX 6 和 7 在內存調優方面做得相當好,只需要做幾個小調整。但是,AIX 5.3 在這個方面需要更多調優。圖 1 給出不同的可調項及其默認設置。第四欄是對于這三個版本最新的 TL 的這些設置的推薦值。
圖 1.不同可調項及其默認設置
請記住一個要點:在安裝全新的 AIX 6 或 7 時,會自動地設置新的內存可調項默認值。如果是從 AIX 5.3 遷移系統,那么在 AIX 5.3 中設置的所有可調項會隨同遷移。在執行遷移之前,建議記錄已經修改的所有可調項(取得 /etc/tunables/nextboot 的拷貝),然后把可調項恢復為默認值。在遷移之后,檢查 nextboot 并確保其中沒有任何內容。現在,討論需要為 AIX 6 或 7 修改的可調項。
最佳實踐建議在不同的不太忙的硬盤驅動器 (hdisk) 上配置多個相同大小的分頁空間。所有分頁空間應該建立鏡像,或者放在 RAID(1 或 5)存儲區域網絡 (SAN) 上。除非數據庫需要,分頁空間一般不需要達到內存量的兩倍。我曾經在 AIX 上用 250 GB 內存和三個 24 GB 的分頁空間運行大型 Oracle 數據庫。關鍵是使用并發 I/O (CIO) 等技術避免分頁,提供分頁空間是為了以防萬一需要分頁。
在默認情況下,AIX 在 rootvg 中創建一個分頁空間 (hd6),它太小了。如果 rootvg 被鏡像,那么這個分頁空間也會被鏡像。我通常使用幾個來自 SAN 的自定義大小的邏輯單元號 (LUN) 添加額外的分頁空間。不要在當前 rootvg 分頁空間所在的內部磁盤(或 SAN LUN)中添加分頁空間。在相同的 hdisk 上配置多個分頁空間會降低分頁速度。
在構建虛擬 I/O 服務器 (VIOS) 時,會自動地配置兩個分頁空間,它們都在 hdisk0 上。hd6 是 512 MB,paging00 是 1,024 MB。我總是關閉并刪除 paging00,然后把 hd6 增加到 4,096 MB。正如前面提到的,在相同的 hdisk 上配置兩個分頁空間是不好的做法。
在 AIX 5.3 的默認設置中,page_steal_method 設置為 0。這影響最近最少使用守護進程 (least recently used daemon LRUD) 掃描可釋放頁面的方式。設置 lru_file_repage=0 意味著強烈建議 LRUD 不偷取可執行代碼的頁面,總是嘗試偷取文件系統(持久)頁面。偷取持久頁面比偷取工作存儲頁面代價低得多,因為后者會導致換出/換入頁面。假設使用 100 GB 內存和五個內存池,內存會劃分為五個大約 20 GB 的池,每個 LRUD 處理大約 20 GB(這是非常簡化的描述)。根據圖 2 中的 numclient 值,可以假設大約 45% 的內存用于文件系統,即大約 45 GB;另外的 55 GB 是工作存儲。
如果設置 page_steal_method=0,在尋找空閑頁面時 LRUD 不得不掃描它們控制的所有內存頁面,盡管很可能只釋放持久頁面。如果設置 page_steal_method=1,LRUD 會改用基于列表的頁面管理方案。這意味著 LRUD 把內存劃分為一個持久頁面列表和一個工作存儲頁面列表。當 LRUD 搜索可從文件系統緩存中釋放的頁面時,它們只搜索持久頁面列表。對于圖 2 中的示例,這應該會把掃描可釋放頁面的速度提高一倍多,這會降低開銷。在“vmstat -I 2 2”的輸出中可以看到掃描速度和空閑率。
在探索最佳內存設置時,有幾個命令很有用,尤其是 vmstat -v。圖 2 顯示 vmstat -v 的部分輸出。
在內存中有兩類頁面:持久頁面(與文件系統關聯)和工作存儲或者說動態頁面(包含可執行代碼及其工作區)。如果偷取持久頁面,就不需要換出頁 面,除非頁面被修改過(在這種情況下,把它寫回文件系統)。如果偷取工作存儲頁面,就必須先把它寫到分頁數據集,下一次需要它時再從分頁數據集讀回來;這 是開銷很大的操作。
設置 minperm%=3 和 lru_file_repage=0 意味著,強烈建議 LRUD 在文件系統正在使用超過 3% 的內存的情況下總是嘗試偷取持久頁面。LRUD 在大多數情況下忽略最大設置,除非是要限制文件系統可以使用的內存量。maxperm% 指所有持久頁面,包括日志文件系統 (JFS)、網絡文件服務器 (NFS)、Veritas File System (VxFS) 和增強型日志文件系統 (JFS2)。maxclient% 是其中的子集,只包括 NFS 和 JFS2 文件系統。maxperm% 是軟限制,maxclient% 是硬限制(而且不能超過 maxperm%)。因為新的文件系統通常是 JFS2,應該把最大設置保持在 90%,以免意外限制文件系統使用的內存量。
在 vmstat -v 的輸出中,有幾個指標有助于判斷要調整哪些值。在圖 2 中,可以看到 numperm 和 numclient 是相同的,都是 45.1%。這意味著 NFS 和/或 JFS2 文件系統正在使用 45.1% 的內存。如果這是一個數據庫系統,我會檢查是否正在使用 CIO,因為它可以消除雙重頁面存儲和處理,從而降低內存和 CPU 使用量。
在構建 I/O 請求時,邏輯卷管理程序 (LVM) 請求一個 pbuf,這是固定的內存緩沖區,它保存 LVM 層中的 I/O 請求。然后把 I/O 放到另一個稱為 fsbuf 的固定內存緩沖區中。有三種 fsbuf:文件系統 fsbuf(供 JFS 文件系統使用)、客戶機 fsbuf(由 NFS 和 VxFS 使用)和外部分頁程序 fsbuf(由 JFS2 文件系統使用)。另外,還有 psbuf,它們是對分頁空間的 I/O 請求所用的固定內存緩沖區。
在圖 2 中,vmstat -v 命令顯示的值是自引導以來的平均值。因為服務器可能很長時間不重新引導,所以一定要間隔幾小時取兩個快照,檢查這些值是否有變化。在這里,它們快速增長,需要調優。
在 vmstat -v 的輸出中,有幾個表示存在 I/O 延遲的跡象。I/O 延遲會影響性能和內存。下面介紹識別 I/O 阻塞的原因和解決問題的一些常用方法。
1468217 pending disk I/Os blocked with no pbuf 這一行清楚地說明一個或多個未完成的磁盤 I/O 在試圖獲得固定內存緩沖區(具體地說是 pbuf)時被阻塞了。這表明在 LVM 層上出現排隊。因為 AIX 無法獲得緩沖區以存儲 I/O 請求的信息,導致請求被延遲。使用下面的 lvmo 命令應該可以解決這個問題。
圖 3 給出 lvmo -a 命令的輸出,它表明 datavg 的 pbuf 不足(查看 pervg_blocked_io_count)。應該只對正在使用的這個卷組糾正此問題,因為這些是固定的內存緩沖區,把它們設置得過大是沒有意義的:
通常,我會檢查當前設置,如果它是 512 或 1024,那么在需要增加時把它提高一倍。
11173706 paging space I/Os blocked with no psbuf 。lvmo 命令還表明 rootvg 中的 pbuf 有問題。看一下 vmstat -v 的輸出,會發現有大量分頁空間 I/O 請求由于無法獲得 psbuf 被阻塞。psbuf 用于在虛擬內存管理程序 (VMM) 層上保存 I/O 請求,缺少 psbuf 會嚴重影響性能。它也表明正在執行分頁,這是問題。最好的解決方法是停止導致分頁的東西。另一種方法是增加分頁空間。
39943187 file system I/Os blocked with no fsbuf 。在默認情況下,系統只為 JFS 文件系統提供 196 個 fsbuf。在 JFS2 之前,需要大大提高這個限制(常常增加到 2048),從而確保 JFS I/O 請求不會由于缺少 fsbuf 在文件系統層上被阻塞。即使在系統中沒有 JFS 的情況下,有時候也會見到阻塞的 I/O 請求達到 2,000 個左右。但是,上面的數字表明在系統中有大量 JFS I/O 被阻塞,在這種情況下我會調整 JFS 并嘗試和計劃轉移到 JFS2;在 JFS2 中,可以對數據庫使用 CIO 等技術。在 AIX 6 和 7 中,numfsbufs 現在是 ioo 命令中的受限制參數。
238 client file system I/Os blocked with no fsbuf 。NFS 和 VxFS 都是客戶機文件系統,這一行是指在文件系統層上由于缺少客戶機 fsbuf 被阻塞的 I/O 數量。要想解決此問題,需要進一步研究,查明這是 VxFS 問題還是 NFS 問題。
1996487 external pager file system I/Os blocked with no fsbuf 。JFS2 是外部分頁程序客戶機文件系統,這一行是指在文件系統層上由于缺少固定內存 fsbuf 被阻塞的 I/O 數量。在以前,調整 j2_nBufferPerPagerDevice 可以解決此問題。現在,通過使用 ioo 命令提高 j2_dynamicBufferPreallocation 來糾正 JFS2 緩沖區。默認設置是 16,在嘗試減少這些 I/O 阻塞時,我通常會慢慢提高它(試一下 32)。
vmo 命令中的 minfree 和 maxfree 可調項也會影響分頁。它們現在是針對各個內存池設置的,可以使用幾個命令之一查明有多少個內存池。根據版本或 TL 不同,應該使用 vmo -a、vmo -a -F(對于 6.1)或 vmstat -v 獲取此信息。
如果這些值設置得過大,可能會看到 vmstat 輸出中“fre”欄中的值很高,而同時卻在執行分頁。默認設置是 960 和 1,088;根據其他設置,我通常使用 1,000 和 1,200。minfree 和 maxfree 的正確計算方法取決于 j2MaxPageReadAhead 的設置、邏輯 CPU 數量和內存池數量。
在這里,假設 vmstat 顯示有 64 個邏輯 CPU (lcpu) 和 10 個內存池。當前設置為默認值,即 minfree=960 和 maxfree=1088。J2_maxPageReadahead=128。對于這些設置,計算過程如下:
Min=max(960,((120*lcpu)/mempools)
Max=minfree + (max(maxpgahead,j2MaxPageReadahead)*lcpu)/mempools)
lcpu 為 64,mempools 為 10,j2_MaxPageReadahead 為 128,因此:
Min=max(960,((120*64)/10) = max(960,768)=960
Max=960+((max(8,128)*64)/10) = 960+819=1780
我可能會把結果向上取整到 2,048。每當修改 j2_maxPageReadahead 時,應該重新計算 maxfree。在這里,我保持 minfree 為 960,但是把 maxfree 提高到 2,048。