一、概念:
Oracle 數(shù)據(jù)庫(kù)和 Linux 內(nèi)存管理
系統(tǒng)中使用的內(nèi)存越多,管理該內(nèi)存所需的資源也就越多。對(duì)于 Linux 操作系統(tǒng)豆挽,通過(guò) Linux kswapd 進(jìn)程和頁(yè)表內(nèi)存結(jié)構(gòu)(針對(duì)系統(tǒng)中存在的每個(gè)進(jìn)程包含一條記錄)實(shí)現(xiàn)內(nèi)存管理。每條記錄包含進(jìn)程使用的每頁(yè)虛擬內(nèi)存及其物理地址(RAM 或磁盤)券盅。通過(guò)使用處理器的轉(zhuǎn)換旁路緩沖區(qū)(TLB帮哈,一小塊緩存)為該進(jìn)程提供幫助。
當(dāng)大量?jī)?nèi)存用于 Oracle 數(shù)據(jù)庫(kù)時(shí)锰镀,操作系統(tǒng)將消耗大量資源來(lái)管理虛擬地址到物理地址轉(zhuǎn)換娘侍,其結(jié)果往往是一個(gè)非常大的頁(yè)表結(jié)構(gòu)。由于每條頁(yè)表?xiàng)l目包含進(jìn)程正在使用的所有內(nèi)存頁(yè)面的虛擬地址到物理地址的轉(zhuǎn)換泳炉,因此對(duì)于非常大的系統(tǒng)全局區(qū) (SGA)憾筏,每個(gè)進(jìn)程的頁(yè)表?xiàng)l目都可能很大。例如花鹅,使用 8 GB 內(nèi)存的 Oracle 數(shù)據(jù)庫(kù)進(jìn)程的頁(yè)表?xiàng)l目將達(dá) 8 GB/4 KB(即 2097152 條記錄或頁(yè)面)氧腰。如果有 100 個(gè) Oracle 數(shù)據(jù)庫(kù)會(huì)話/進(jìn)程,則將頁(yè)面數(shù)乘以 100刨肃。您可以看到古拴,要管理的頁(yè)面數(shù)量巨大。
同樣真友,操作系統(tǒng)使用頁(yè)表?xiàng)l目管理系統(tǒng)中進(jìn)程所用的內(nèi)存黄痪。在 Linux 中,執(zhí)行此管理的操作系統(tǒng)進(jìn)程被稱作 kswapd锻狗,可在操作系統(tǒng)工具中找到满力。
TLB 緩存將緩存頁(yè)表?xiàng)l目來(lái)提高性能。典型的 TLB 緩存可保存 4 到 4096 個(gè)條目轻纪。對(duì)于數(shù)百萬(wàn)甚至數(shù)十億個(gè)頁(yè)表?xiàng)l目,這種緩存就不夠用了叠纷。
如上所述刻帚,對(duì)于使用大型 SGA 的系統(tǒng),頁(yè)表結(jié)構(gòu)可能會(huì)變得非常大涩嚣。清單 1 中的 Linux 系統(tǒng)輸出示例顯示頁(yè)表?xiàng)l目占用了 766 MB 的 RAM崇众。這可能導(dǎo)致顯著的系統(tǒng)開(kāi)銷掂僵。我親眼見(jiàn)過(guò)數(shù) GB 的頁(yè)表?xiàng)l目。
HugePages 是 Linux 操作系統(tǒng)的一個(gè)內(nèi)核特性顷歌,讓操作系統(tǒng)可以支持現(xiàn)代硬件架構(gòu)的大頁(yè)面容量功能锰蓬。對(duì)于 Oracle 數(shù)據(jù)庫(kù),通過(guò)啟用 HugePages 并使用大頁(yè)面眯漩,可以用一個(gè)頁(yè)表?xiàng)l目代表一個(gè)大頁(yè)面芹扭,而不是使用許多條目代表較小的頁(yè)面,從而可以管理更多內(nèi)存赦抖,減少操作系統(tǒng)對(duì)頁(yè)面狀態(tài)的維護(hù)并提高 TLB 緩存命中率舱卡。在 Linux 中,大頁(yè)面大小為 2 MB队萤。
在 Oracle Linux 6 或 Red Hat Enterprise Linux 6 (RHEL 6) 中轮锥,可在 /proc/meminfo 中找到分配的 HugePages 數(shù),如清單 1 所示:
[root@ptc1 ~]# cat /proc/meminfo
MemTotal: 4045076 kB
MemFree: 14132 kB
Buffers: 656 kB
Cached: 1271560 kB
SwapCached: 6184 kB
Active: 2536748 kB
Inactive: 625616 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 4045076 kB
LowFree: 14132 kB
SwapTotal: 1052216 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
Mapped: 2036576 kB
Slab: 49712 kB
CommitLimit: 3074752 kB
Committed_AS: 8054664 kB
PageTables: 766680 kB
VmallocTotal:536870911 kB
VmallocUsed: 263168 kB
VmallocChunk:536607347 kB
HugePages_Total: 0
HugePages_Free: 0
Hugepagesize: 2048 kB
清單 1
在 Oracle Linux 6 中要尔,分配的 HugePages 略有不同舍杜,如清單 2 所示:
AnonHugePages: 0 kB
HugePages_Total: 1508
HugePages_Free: 60
HugePages_Rsvd: 57
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 10240 kB
DirectMap2M: 16766976 kB
清單 2
Oracle Linux 6 HugePages 值如下所示:
* `AnonHugePages`。匿名 HugePages 數(shù)量赵辕。Oracle Linux 6.5 中已刪除此計(jì)數(shù)器蝴簇。與透明 HugePages 有關(guān)。(有關(guān)透明 HugePages 的詳細(xì)信息匆帚,請(qǐng)參見(jiàn)“[透明 HugePages 和 Oracle 數(shù)據(jù)庫(kù)](https://www.oracle.com/cn/technical-resources/articles/it-infrastructure/dev-hugepages.html#trans)”一節(jié)熬词。)
* `HugePages_Total`。HugePages 數(shù)量吸重』ナ埃空間大小為 HugePages 數(shù)乘以 2M。
* `HugePages_Free`嚎幸。池中尚未分配的 HugePages 數(shù)量颜矿。
* `HugePages_Rsvd`〖稻В“reserved”的縮寫形式骑疆,表示池中已經(jīng)承諾分配但尚未分配的 HugePages 數(shù)量。保留的 HugePages 保證應(yīng)用程序隨時(shí)請(qǐng)求都能夠從 HugePages 池分配 HugePages替废,即使系統(tǒng)已經(jīng)運(yùn)行一段時(shí)間箍铭。
* `HugePages_Surp`∽盗停“surplus”的縮寫形式诈火,表示池中大于 `/proc/sys/vm/nr_hugepages` 中值的 HugePages 數(shù)量。剩余 HugePages 的最大數(shù)量由 `/proc/sys/vm/nr_overcommit_hugepages` 控制状答。此值為 `0` 的情況很常見(jiàn)冷守。
* `Hugepagesize`刀崖。HugePage 的大小。此參數(shù)當(dāng)前為 2048 或 2 MB拍摇。
二亮钦、解決方案
通過(guò)在 Linux 中啟用 HugePages,可以通過(guò)增大頁(yè)面大小來(lái)減少 TLB 條目數(shù)充活。對(duì)于 Linux蜂莉,HugePages 大小為 2 MB。通過(guò)為 Oracle 數(shù)據(jù)庫(kù) SGA 選用更大的頁(yè)面堪唐,可大大減少要管理的頁(yè)面數(shù)巡语。
1、控制SGA大小淮菠, sga+pga最好控制在50%物理內(nèi)存以內(nèi)男公,pga內(nèi)存不要操作sga內(nèi)存的20%;
2合陵、當(dāng)主機(jī)的物理內(nèi)存為64G枢赔,設(shè)SGA>=32G時(shí),建議開(kāi)啟大頁(yè)拥知;
內(nèi)存都是以頁(yè)的形式劃分的踏拜,默認(rèn)情況下每頁(yè)是4K,這就意味著如果物理內(nèi)存很大低剔,則映射表的條目將會(huì)非常多速梗,會(huì)影響CPU的檢索效率。因?yàn)閮?nèi)存大小是固定的襟齿,為了減少映射表的條目姻锁,可采取的辦法只有增加頁(yè)的尺寸。
在清單 1 所示示例中猜欺,單條記錄的虛擬地址到物理地址轉(zhuǎn)換數(shù)將從 2097152 減少至 4096位隶。這將減小頁(yè)表結(jié)構(gòu)的大小,提高 TLB 命中率开皿,并降低 kswapd 使用率涧黄。
注:?jiǎn)⒂?HugePages 可顯著提升性能。
在 Linux 中啟用 HugePages
在 Linux 中赋荆,通過(guò)將 Linux 初始化參數(shù) vm.nr_hugepages 設(shè)置為您希望為 Oracle 數(shù)據(jù)庫(kù) SGA 提供的 2 MB 頁(yè)面數(shù)來(lái)配置 HugePages 功能笋妥。設(shè)置此參數(shù)可通過(guò)將其值調(diào)大來(lái)減少頁(yè)面數(shù)。
注:Oracle Database 11g 中引入的 Oracle 數(shù)據(jù)庫(kù)自動(dòng)內(nèi)存管理特性與 Linux HugePages 不兼容糠睡。HugePages 提供的性能改進(jìn)優(yōu)于自動(dòng)內(nèi)存管理所提供的易用性挽鞠。
有關(guān)如何實(shí)現(xiàn) HugePages 配置的詳細(xì)信息,可在表 1 所示的 My Oracle Support 文檔中找到狈孔。
除了配置 vm.nr_hugepages信认,還可以將可選的 vm.hugetlb_shm_group 參數(shù)設(shè)置為有權(quán)使用 HugePages 的操作系統(tǒng)組。默認(rèn)情況下均抽,此參數(shù)設(shè)置為 0嫁赏,從而允許所有組使用 HugePages∮突樱可以將此參數(shù)設(shè)置為 Oracle 數(shù)據(jù)庫(kù)進(jìn)程所屬的操作系統(tǒng)組潦蝇,如 oinstall。
驗(yàn)證是否已對(duì) Oracle 數(shù)據(jù)庫(kù)實(shí)例啟用大頁(yè)面
可以通過(guò)檢查警報(bào)日志來(lái)驗(yàn)證是否對(duì)數(shù)據(jù)庫(kù)實(shí)例啟用了大頁(yè)面深寥。啟動(dòng)實(shí)例時(shí)攘乒,您應(yīng)在警報(bào)日志中參數(shù)列表前面看到如下內(nèi)容:
****************** Large Pages Information *****************
Total Shared Global Region in Large Pages = 28 GB (100%)
Large Pages used by this instance: 14497 (28 GB)
Large Pages unused system wide = 1015 (2030 MB) (alloc incr 64 MB)
Large Pages configured system wide = 19680 (38 GB)
Large Page size = 2048 KB
透明 HugePages 和 Oracle 數(shù)據(jù)庫(kù)
最近,RHEL 6惋鹅、Oracle Linux 6 和 SUSE Linux Enterprise Server 11 中引入了一個(gè)新特性 - 透明 HugePages则酝。透明 HugePages 旨在自動(dòng)、動(dòng)態(tài)地利用 HugePages闰集。遺憾的是沽讹,目前透明 HugePages 與傳統(tǒng) HugePages 聯(lián)用會(huì)出現(xiàn)一些問(wèn)題,導(dǎo)致性能問(wèn)題和系統(tǒng)重啟武鲁。在 My Oracle Support 說(shuō)明 1557478.1 中爽雄,Oracle 建議不要同時(shí)使用透明 HugePages 和 Oracle 數(shù)據(jù)庫(kù)。
注:在 Oracle Linux 6.5 版中沐鼠,已刪除透明 HugePages挚瘟。
總結(jié)
通過(guò)使用更大的頁(yè)面,可以減少頁(yè)表?xiàng)l目數(shù)饲梭,從而最大程度減少開(kāi)銷乘盖。使用 HugePages 可顯著提升性能,增加系統(tǒng)中的內(nèi)存數(shù)量和 SGA 大小排拷。
三侧漓、 具體過(guò)程
1、關(guān)閉Oracle Database 11g中的AMM(Automatic Memory Management)监氢,
即把兩個(gè)參數(shù)MEMORY_TARGET / MEMORY_MAX_TARGET設(shè)為0
如果alter system set MEMORY_MAX_TARGET=0 scope=spfile;重啟后發(fā)現(xiàn)沒(méi)有改為0布蔗,可以alter system reset memory_max_target; 來(lái)設(shè)置
禁用AMM特性須要將memory_max_target, memory_max_target2個(gè)參數(shù)重置,而不能過(guò)設(shè)置為0浪腐。最好的辦法是創(chuàng)建一個(gè)pfile,在pfile中將這2個(gè)參數(shù)刪除纵揍,再依據(jù)這個(gè)pfile創(chuàng)建spfile.
2、參考metalink(文檔 ID 401749.1)提供的腳本,計(jì)算hugepages的大小
3议街、對(duì)hugepages_settings.sh這個(gè)腳本授可執(zhí)行的權(quán)限
chmod +x hugepages_settings.sh
4泽谨、執(zhí)行執(zhí)行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
得出大頁(yè)的大小為1028頁(yè)(注:一頁(yè)為2M,這個(gè)值不可改,1028*2M=2056M)吧雹,實(shí)際上hugepages與參數(shù)sga_max_size有關(guān)骨杂,比sga_max_size的值稍微大一點(diǎn)點(diǎn)(比SGA_MAX_SIZE最少要多加一頁(yè),2M的頁(yè)不要分配超過(guò)sga_max_size太多雄卷,會(huì)造成內(nèi)存的浪費(fèi))
注意:使用Hugepage內(nèi)存是共享內(nèi)存搓蚪,它會(huì)一直keep在內(nèi)存中的,不會(huì)被交換出去丁鹉,也就是說(shuō)使用hurgepage的內(nèi)存不能被其他的進(jìn)程使用妒潭,所以,一定要合理設(shè)置這個(gè)值揣钦,避免造成浪費(fèi)雳灾。對(duì)于只使用Oracle的服務(wù)器來(lái)說(shuō),把Hugepage_pool設(shè)置成大于SGA大小才能被Oracle使用冯凹。
SQL>show parameter sga_max_size
NAME TYPE VALUE
sga_max_size big integer 2G
5谎亩、設(shè)置hugepages,在內(nèi)核參數(shù)中添加一行,vi /etc/sysctl.conf
vm.nr_hugepages = 1028
6谈竿、修改內(nèi)核參數(shù)立即生效
[root@el5 ~]# sysctl -p
[email protected] ~]# grep -i huge /proc/meminfo
AnonHugePages: 602112 kB
HugePages_Total: 30739
HugePages_Free: 30739
HugePages_Rsvd: 0
HugePages_Surp: 0
7团驱、別忘記設(shè)定內(nèi)存鎖memlock,以K為單位空凸,memlock數(shù)量要大于大頁(yè)的數(shù)量嚎花,當(dāng)然也要大于sga_max_size,這里設(shè)定為2056000,設(shè)置為-1呀洲,表示不限制紊选。
[root@el5 ~]# vi /etc/security/limits.conf
oracle soft memlock 2056000
oracle hard memlock 2056000
* Soft memlock 稍小於RAM值
* hard memlock 稍小於RAM值
Memlock值大於sga沒(méi)關(guān)系的,所以我們能夠設(shè)置這個(gè)值在我們想要的SGA size和物理內(nèi)存size之間道逗,這個(gè)值得單位是kb兵罢。
[[email protected] ~]# grep -i memtot /proc/meminfo
MemTotal: 132250576 kB
8、檢查limits是否正確
[root@el5 ~]# su - oracle
[oracle@el5 ~] ulimit -l
2056000
9滓窍、重啟數(shù)據(jù)庫(kù)
10卖词、查看大頁(yè),已被使用
[oracle@el5 ~]$ watch -n1 'cat /proc/meminfo |grep -i HugePage'
HugePages_Total: 總共頁(yè)
HugePages_Free: 空閑頁(yè)
HugePages_Rsvd: 操作系統(tǒng)承諾給Oracle預(yù)留頁(yè)
Hugepagesize: 2048 kB 每頁(yè)是2M吏夯,不可修改
如:
HugePages_Total: 1028 ---總共1028頁(yè)
HugePages_Free: 869 ---空閑869 頁(yè)此蜈,即當(dāng)前大頁(yè)被使用了1028-869=159頁(yè),即被用了1592M=118M噪生,小于sga_target裆赵。
HugePages_Rsvd: 842 ---操作系統(tǒng)承諾給Oracle預(yù)留842頁(yè),即8422M=1684M(1684+118==SGA_MAX_SIZE)
使用了hugepage之后,SGA就默認(rèn)pin在內(nèi)存里了跺嗽,那么就不用lock sga了战授。接下來(lái)我們研究一下參數(shù):pre_page_sga页藻,這個(gè)參數(shù)默認(rèn)是false,我把它打開(kāi)。
sys@OCM> alter system set pre_page_sga=true scope=spfile;
sys@OCM> show parameter sga
NAME TYPE VALUE
lock_sga boolean FALSE
pre_page_sga boolean TRUE
sga_max_size big integer 2G
sga_target big integer 1G
HugePages_Total: 1028 ---總共1028頁(yè)
HugePages_Free: 548 ---空閑548頁(yè)植兰,即當(dāng)前大頁(yè)被使用了1028-548=480頁(yè)份帐,即被用了4802M=960M,約等于sga_target,參數(shù)pre_page_sga起作用了。
HugePages_Rsvd: 521 ---操作系統(tǒng)承諾給Oracle預(yù)留521頁(yè)钉跷,即5212M=1042M(理解為sga_max_size-sga_target)
Hugepagesize: 2048 kB --每頁(yè)是2M弥鹦,不可修改
參考metalink:USE_LARGE_PAGES To Enable HugePages (文檔 ID 1392497.1)
補(bǔ)充關(guān)于內(nèi)存申請(qǐng)的OverCommit
Linux下的OverCommit機(jī)制肚逸,主要是為了應(yīng)對(duì)可能的異常的大量?jī)?nèi)存申請(qǐng)對(duì)OS本身造成沖擊爷辙。
Linux有三種OverCommit機(jī)制,可以通過(guò):/proc/sys/vm/overcommit_memory來(lái)配置朦促,三種配置的具體含義:
0:?jiǎn)l(fā)式策略膝晾,后果比較嚴(yán)重的Overcommit將不能成功,而輕微的Overcommit將被允許务冕。
1:永遠(yuǎn)允許Overcommit血当,這種策略適合那些不能承受內(nèi)存分配失敗的應(yīng)用,比如某些科學(xué)計(jì)算應(yīng)用禀忆。
2:永遠(yuǎn)禁止Overcommit臊旭,在這個(gè)情況下,系統(tǒng)所能分配的內(nèi)存不會(huì)超過(guò)swap+RAM*系數(shù)(/proc/sys/vm /overcmmit_ratio箩退,默認(rèn)50%离熏,你可以調(diào)整),如果這么多資源已經(jīng)用光戴涝,那么后面任何嘗試申請(qǐng)內(nèi)存的行為都會(huì)返回錯(cuò)誤滋戳,這通常意味著此時(shí) 沒(méi)法運(yùn)行任何新程序。
## 另請(qǐng)參見(jiàn)
* [性能調(diào)優(yōu)網(wǎng)站](http://www.perftuning.com/)
* [Ed Whalen 的博客](http://www.perftuning.com/author/ewhalen/)
* [Ed Whalen 的 Twitter](https://twitter.com/etwhalen)
## 關(guān)于作者
Edward Whalen 是 Oracle ACE 并且是 Performance Tuning Corporation 的首席技術(shù)專家啥刻,Performance Tuning Corporation 是一家咨詢公司奸鸯,在數(shù)據(jù)庫(kù)性能、管理可帽、遷移娄涩、虛擬化和災(zāi)難恢復(fù)解決方案方面擁有超過(guò) 25 年的專業(yè)經(jīng)驗(yàn)。他在通過(guò)系統(tǒng)架構(gòu)設(shè)計(jì)實(shí)現(xiàn)最佳性能方面有著豐富經(jīng)驗(yàn)映跟。其職業(yè)生涯涉及許多不同公司的硬件蓄拣、操作系統(tǒng)、數(shù)據(jù)庫(kù)和虛擬化項(xiàng)目申窘。Edward 編寫過(guò) 6 本關(guān)于 Oracle 產(chǎn)品的書和 5 本關(guān)于 Microsoft SQL Server 的書弯蚜,他還剛剛為 Oracle Press 完成了《Oracle Enterprise Manager Cloud Control 12c Deep Dive》一書。他還參與過(guò)許多基準(zhǔn)測(cè)試和性能調(diào)優(yōu)項(xiàng)目剃法,既涉及 Oracle 產(chǎn)品碎捺,又涉及 Microsoft SQL Server。
Edward 具有豐富的架構(gòu)經(jīng)驗(yàn),包括云/應(yīng)用程序體系所有層面收厨,從存儲(chǔ)和硬件到虛擬機(jī)管理程序和操作系統(tǒng)晋柱,再到數(shù)據(jù)庫(kù)。這些經(jīng)驗(yàn)為他過(guò)去從事的系統(tǒng)架構(gòu)工作奠定了堅(jiān)實(shí)的基礎(chǔ)诵叁。
Edward 最初作為實(shí)驗(yàn)物理學(xué)家在費(fèi)米實(shí)驗(yàn)室和斯坦福線性加速器中心從事高能物理研究項(xiàng)目雁竞。在短暫從事超導(dǎo)超級(jí)對(duì)撞機(jī)工作之后,他轉(zhuǎn)移到計(jì)算機(jī)軟件領(lǐng)域拧额,然后涉足計(jì)算機(jī)硬件和操作系統(tǒng)開(kāi)發(fā)碑诉,最終轉(zhuǎn)入數(shù)據(jù)庫(kù)性能工程。