A.7 HugePages概述
HugePages是集成到Linux內核2.6中的一項特性。啟用HugePages使操作系統可以支持的內存頁大於默認值(通常為4 KB)。使用非常大的頁面大小可以通過減少訪問page table entries所需的系統資源量來提高系統性能。HugePages對32位和64位配置都很有用。HugePage大小從2 MB到256 MB不等,具體取決於內核版本和硬件架構。對於Oracle數據庫,使用HugePages可以減少page states的操作系統維護,並提高轉換后備緩沖區(Translation Lookaside Buffer ,TLB)命中率。
注意:
透明Hugepages目前不是手動配置HugePages的替代方案。
本節包括以下主題:
A.7.1查看HugePages內存分配
如果您的操作系統啟用了HugePages,請查看此信息。
在Linux平台安裝中,Oracle建議您使用HugePages獲取Oracle數據庫的最佳性能。在啟用了HugePages的服務器上升級Oracle Grid Infrastructure和Oracle數據庫時,Oracle建議您查看HugePages內存分配要求。
GIMR和HugePages內存
Oracle Grid Infrastructure安裝包括Grid Infrastructure Management Repository(GIMR)。如果在群集成員節點上配置了HugePages,GIMR系統全局區域(SGA)將安裝到HugePages內存中。GIMR SGA最高占用1 GB的HugePages內存。
如果群集成員節點操作系統內存分配到HugePages不足以滿足群集上所有Oracle數據庫實例的SGA大小,那么您可能會發現一個或多個Oracle數據庫SGA映射到常規頁面,而不是的巨大頁面,降低了預期的性能。為避免此問題,在計划升級時,請確保為HugePages保留的內存足夠大,以滿足您的內存要求。
為集群上計划運行SGA的所有數據庫分配足夠大的內存到HugePages,也要考慮到Grid Infrastructure Management Repository的SGA。
筆記:也就是說每個節點可能運行多個共享內存段,比如有GI的SGA,有多個數據庫實例,那么HugePages 應該大於他們內存的總和
A.7.2在Linux上使用HugePages
要使Oracle數據庫在Linux上使用大頁面(有時稱為HugePages),請設置vm.nr_hugepages內核參數的值以指定要保留的大頁面數。您必須指定足夠的大頁面來保存數據庫實例的整個SGA。要確定所需的參數值,請將實例的SGA大小除以大頁面的大小,然后將結果向上舍入為最接近的整數。
要確定默認的大頁面大小,請運行以下命令:
# grep Hugepagesize /proc/meminfo例如,如果/proc/meminfo 顯示大頁面大小2 MB,並且實例的總SGA大小為1.6 GB,則將vm.nr_hugepages內核參數的值設置為820(1.6 GB / 2 MB = 819.2)。
A.7.3使用HugePages調整SGA
如果沒有HugePages,操作系統會將每個4 KB的內存保留為一個page。當它將pages分配給數據庫系統全局區域(SGA)時,操作系統內核必須為分配給該數據庫SGA的每個4 KB頁面不斷更新其page table 上的生命周期(臟,空,映射到進程等)。
使用HugePages,操作系統頁表(虛擬內存到物理內存映射)較小,因為每個頁表條目指向2 MB到256 MB的頁面。
此外,內核中生命周期必須受到監視的pages較少。例如,如果將HugePages與64位硬件一起使用,並且要映射256 MB內存,則可能需要一個page table entry(PTE)。如果您不使用HugePages,並且想要映射256 MB內存,則必須具有256 MB * 1024 KB / 4 KB = 65536個PTE。
HugePages具有以下優勢:
-
通過增加TLB命中率提高性能
-
頁面被鎖定在內存中,永遠不會被換出,這為共享內存結構(如SGA)提供了RAM
-
連續頁面是預分配的,不能用於除System V共享內存之外的任何其他內容(例如,SGA)
-
由於頁面大小較大,內核對於該部分虛擬內存的簿記工作較少 筆記:SGA是虛擬內存,RAM 是物理內存,它們之間有一個映射關系,使用HugePage,需要維護的映射關系減少。
A.7.4在Linux上配置HugePages
完成以下步驟以在計算機上配置HugePages:
-
運行以下命令以確定內核是否支持HugePages:
$ grep Huge / proc / meminfo
-
某些Linux系統默認不支持HugePages。對於此類系統,請使用CONFIG_HUGETLBFS和CONFIG_HUGETLB_PAGE 配置選項構建Linux內核。CONFIG_HUGETLBFS位於文件系統下,在您選擇CONFIG_HUGETLBFS時,CONFIG_HUGETLB_PAGE會被一並選中。
-
編輯文件中的memlock設置/etc/security/limits.conf。該memlock設置以KB為單位指定,當啟用HugePages內存時,最大鎖定內存限制應設置為當前RAM的至少90%,並且當禁用HugePages內存時,應設置至少3145728 KB(3 GB)。例如,如果安裝了64 GB RAM,則添加以下條目以增加最大鎖定內存地址空間:
* soft memlock 60397977 * hard memlock 60397977
您還可以將memlock值設置為高於SGA要求.
-
已oracle用戶重新登陸,運行ulimit -l 命令驗證新memlock設置.
$ ulimit -l 60397977
-
運行以下命令以顯示
Hugepagesize變量的值:$ grep Hugepagesize / proc / meminfo
-
完成以下過程以創建一個腳本,該腳本計算當前共享內存段的
hugepages配置建議值:-
創建一個名為hugepages_settings.sh 的文本文件。
-
在文件中添加以下內容:
#!/bin/bash # # hugepages_settings.sh # # Linux bash script to compute values for the # recommended HugePages/HugeTLB configuration # # Note: This script does calculation for all shared memory # segments available when the script is run, no matter it # is an Oracle RDBMS shared memory segment or not. # Check for the kernel version KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'` # Find out the HugePage size HPG_SZ=`grep Hugepagesize /proc/meminfo | awk {'print $2'}` # Start from 1 pages to be on the safe side and guarantee 1 free HugePage NUM_PG=1 # Cumulative number of pages required to handle the running shared memory segments for SEG_BYTES in `ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"` do MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q` if [ $MIN_PG -gt 0 ]; then NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q` fi done # Finish with results case $KERN in '2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`; echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;; '2.6'|'3.8') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;; *) echo "Unrecognized kernel version $KERN. Exiting." ;; esac # End
-
-
運行hugepages_settings.sh 計算
hugepages參數值.$ chmod + x hugepages_settings.sh $ ./hugepages_settings.sh注意:
在運行此腳本之前,請確保所有使用hugepages的應用程序都在運行。
-
設置以下內核參數,其中value是您在步驟7中確定的HugePages值:
#sysctl -w vm.nr_hugepages = value -
要確保在系統重新啟動后自動分配HugePages,請將以下條目添加到
/etc/sysctl.conf文件中,其中value是您在步驟7中確定的HugePages值:vm.nr_hugepages = value -
運行以下命令以檢查可用hugepages:
$ grep Huge /proc/meminfo
- 重啟實例。
-
運行以下命令檢查可用
hugepages(1或2 pages 空閑):$ grep Huge /proc/meminfo
注意:
如果您無法通過
nr_hugepages設置HugePages,則您的可用內存可能是碎片化的。重新啟動服務器以使Hugepages分配生效
A.7.5 HugePages配置的限制
HugePages具有以下限制:
-
您必須取消設置
MEMORY_TARGET和MEMORY_MAX_TARGET初始化參數。例如,要取消設置數據庫實例的參數,請使用命令ALTER SYSTEM RESET。 -
自動內存管理(AMM)和HugePages不兼容。使用AMM時,整個SGA內存通過在/dev/shm下創建文件來分配。當Oracle數據庫使用AMM分配SGA時,HugePages不支持。要在Oracle Database 19c上使用HugePages,您必須禁用AMM。
-
如果在32位環境中使用VLM(Very Large Memory),則不能將HugePages用於Database Buffer cache。可以用於SGA的其他部分,如shared_pool, large_pool等。VLM(buffer cache)的內存分配使用共享內存文件系統(
ramfs/tmpfs/shmfs)完成。內存文件系統不提供或使用HugePages。 -
除非系統管理員通過修改可用頁數或修改池大小來更改HugePages配置,否則HugePages不會在系統啟動后進行分配或釋放。如果在系統啟動期間未在內存中預留所需的空間,則HugePages分配失敗。
-
確保正確配置HugePages,因為如果過多的HugePages未被應用程序使用,系統可能會耗盡內存。筆記:vm.nr_hugepages不能配置過大
-
如果實例啟動時HugePages不足,且初始化參數use_large_pages設置為的
only,則數據庫無法啟動,並且警報日志消息提供有關Hugepages的必要信息。
A.7.6 禁用透明HugePages
Oracle建議您在開始安裝之前禁用Transparent HugePages。
透明HugePages內存與標准HugePages內存不同,因為內核khugepaged線程在運行時動態分配內存。標准HugePages內存在啟動時預先分配,並且在運行時不會更改。
注意:
雖然在UEK2和更高版本的UEK內核上禁用了透明HugePages,但您的Linux系統上可能默認啟用了Transparent HugePages。
Red Hat Enterprise Linux 6,Red Hat Enterprise Linux 7,SUSE 11,Oracle Linux 6和Oracle Linux 7 早期版本的Oracle Linux具有Unbreakable Enterprise Kernel 2(UEK2)內核默認啟用了透明HugePages內存。
透明HugePages可能會在運行時導致內存分配延遲。為避免性能問題,Oracle建議您在所有Oracle數據庫服務器上禁用透明HugePages。Oracle建議您使用標准HugePages來提高性能。
要檢查是否已啟用Transparent HugePages,請以root用戶身份運行以下命令之一:
紅帽企業Linux內核:
# cat /sys/kernel/mm/redhat_transparent_hugepage/enabled
其他內核:
# cat /sys/kernel/mm/transparent_hugepage/enabled
以下是一個示例輸出,顯示正在使用透明HugePages,因為[always]標志已啟用。
[always] never
注意:
如果從內核中刪除了Transparent HugePages ,則既不存在/sys/kernel/mm/transparent_hugepage 也不存在/sys/kernel/mm/redhat_transparent_hugepage。
要禁用透明HugePages:
-
對於Oracle Linux 6或更早版本,請將以下條目添加到
/etc/grub.conf文件中的內核引導行:transparent_hugepage=never例如:title Oracle Linux Server (2.6.32-300.25.1.el6uek.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-300.25.1.el6uek.x86_64 ro root=LABEL=/ transparent_hugepage=never initrd /initramfs-2.6.32-300.25.1.el6uek.x86_64.img
對於Oracle Linux 7或更高版本的操作系統,文件名可能有所不同。檢查操作系統文檔以獲取確切的文件名和禁用透明HugePages的步驟。
例如,對於Oracle Linux 7.3,禁用透明HugePages的過程涉及編輯
/etc/default/grub文件然后運行命令grub2-mkconfig。 -
重新啟動系統以使更改成為永久更改。
步驟簡化整理
* soft memlock 60397977 * hard memlock 60397977
#!/bin/bash # # hugepages_settings.sh # # Linux bash script to compute values for the # recommended HugePages/HugeTLB configuration # # Note: This script does calculation for all shared memory # segments available when the script is run, no matter it # is an Oracle RDBMS shared memory segment or not. # Check for the kernel version KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'` # Find out the HugePage size HPG_SZ=`grep Hugepagesize /proc/meminfo | awk {'print $2'}` # Start from 1 pages to be on the safe side and guarantee 1 free HugePage NUM_PG=1 # Cumulative number of pages required to handle the running shared memory segments for SEG_BYTES in `ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"` do MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q` if [ $MIN_PG -gt 0 ]; then NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q` fi done # Finish with results case $KERN in '2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`; echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;; '2.6'|'3.8') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;; *) echo "Unrecognized kernel version $KERN. Exiting." ;; esac # End
chmod +x hugepages_settings.sh
vm.nr_hugepages = value #來自上一步計算結果
5.禁用透明HugePages
