日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hugepages详解

發(fā)布時間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hugepages详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文地址:https://www.tuicool.com/articles/vYZJ3i3

IBM的創(chuàng)始人Thomas J. Watson曾經(jīng)說: “全世界只需要5臺電腦就足夠了”。

Microsoft的創(chuàng)始人Bill Gates曾在一次演講中說:“個人用戶的計(jì)算機(jī)內(nèi)存只需640K?”。

Intel創(chuàng)始人之一Gordon Moore曾經(jīng)說:“當(dāng)價(jià)格不變時,集成電路上可容納的晶體管數(shù)目,約每隔18個月便會增加一倍,性能也會增加一倍”。

前面兩句話在今天看來實(shí)際上是十分荒謬的,而最后那條就是著名的摩爾定律。

hugepages的出現(xiàn)同樣也是因?yàn)槟柖蓪?dǎo)致了主機(jī)內(nèi)存越來越大,最后不得不對于標(biāo)準(zhǔn)pages的改進(jìn)以提高效率。要了解hugepages首先必須清楚Unix/Linux內(nèi)存的分配機(jī)制。本文從入門的角度介紹Linux的內(nèi)存分配機(jī)制,當(dāng)然這一部分內(nèi)容相信很多人都在計(jì)算機(jī)體系結(jié)構(gòu)這門課程中學(xué)到過,這里就重新溫習(xí)一下。

早期因?yàn)槌绦蚍浅:唵尾⑶沂褂玫膬?nèi)存也非常小,程序的內(nèi)存地址都是使用程序地址對應(yīng)物理地址這種這種直接映射的模式,通俗的說就是物理地址是在程序中寫死的。想想使用匯編直接操作物理地址是多么壯觀的工程呀。對于一個大型的軟件系統(tǒng)來說,這部分工作幾乎是不可能完成的。后來開始使用“段頁式”的方式來管理內(nèi)存的尋址。用一個時髦的詞來說就是引入了“虛擬化”技術(shù)。現(xiàn)代操作系統(tǒng)都會使用受保護(hù)的虛擬地址模式(?protected virtual address mode?)來管理內(nèi)存,Linux下分為三類地址:邏輯地址(Logic Address)、線性地址(Linear Address)與物理地址(Physics Address)。這三者的對應(yīng)關(guān)系如下所示:????

簡單的說就是邏輯地址通過?分段機(jī)制映射?轉(zhuǎn)化為線性地址,然后線性地址通過?分頁機(jī)制映射轉(zhuǎn)化為物理地址。因?yàn)檫@里是介紹hugepages,所以我這里不打算介紹分段機(jī)制,主要對分頁機(jī)制做簡單的闡述。 事實(shí)上,地址映射的過程遠(yuǎn)遠(yuǎn)不止上圖中這么簡單。例如在分頁機(jī)制映射中,一般需要經(jīng)過四級映射,也就是將線性地址映射為物理地址的過程中,需要從內(nèi)存中讀取至少四次頁目錄表(Page Directory)和頁表 (Page Table)。眾所周知,CPU寄存器與內(nèi)存的訪問速率相差至少一個數(shù)量級,所以如果使用傳統(tǒng)的分頁機(jī)制的開銷將會非常大。所以在現(xiàn)代的X86架構(gòu)中,集成了一種被成為TLB(?Translation Lookaside Buffer?)的硬件級緩存。TLB讀寫速度非???#xff0c;基本和CPU寄存器的速率在一個數(shù)量級,而TLB中保緩存了最近使用過的線性地址和物理地址的映射關(guān)系。如下圖所示:

?

那么將線性地址映射為物理地址的過程如下:首先到TLB中找到這個條目是否存在,如果不存在則為TLB miss,然后使用頁表的方式進(jìn)行尋址,最后把這個映射關(guān)系更新到TLB中以備下次使用。由于TLB是大小有限,而一旦出現(xiàn)TLB miss,則其查詢的代價(jià)很高,所以現(xiàn)代CPU架構(gòu)基本都進(jìn)行了一些優(yōu)化以提高地址映射的效率。例如:

  • 線性地址到物理地址轉(zhuǎn)換一開始就選擇同時在TLB和頁表進(jìn)行查詢,而不經(jīng)過TLB查找是否成功的等待;
  • 使用多級TLB以及軟TLB,
  • 在CPU context swtch的時候不flush整個TLB。

下面用例子來說明為什么使用傳統(tǒng)的 4k大小的頁表相比hugepages對大內(nèi)存的管理效率會很低。在x86平臺,一條PTE的大小為4Byte;而在x86_64平臺,一條PTE的大小為8Byte。 以下這種場景并不罕見:

Linux x86_64, SGA大小為100G,使用常規(guī)的4k的page,連接到數(shù)據(jù)庫的進(jìn)程數(shù)約1000。page table一共需要100×1024×1024K/4K=26214400條PTE;

那么26214400條PTE需要100×1024×1024K/4K×8Byte=209715200Byte=200M;

從而1000個進(jìn)程需要100×1024×1024K/4K×8Byte×1000=209715200000Byte=200G。

計(jì)算出來的結(jié)果真是令人崩潰,但是事實(shí)上在你沒有崩潰以前,數(shù)據(jù)庫就已經(jīng)因?yàn)闆]有內(nèi)存而崩潰了。同樣條件下,如果使用2M的hugepages進(jìn)行對比,則以上的計(jì)算方法變?yōu)?#xff1a;

page table一共需要100×1024M/2M=51200條PTE;

那么51200條PTE需要100×1024M/2M×8Byte=409600Byte=400K;

從而1000個進(jìn)程需要100×1024M/2M×8Byte×1=409600Byte=400K。

綜上,可以看到同樣是1000個進(jìn)程,同樣是管理100G的SGA,結(jié)果卻大不相同。使用傳統(tǒng)的4k大小的page開銷竟然會達(dá)到驚人的200G;而使用2M的hugepages,開銷只有400K。 這其中不僅僅只是對于因?yàn)閱蝹€進(jìn)程而言,2M page需要的PTE小于4K ?page的PTE,最大的一個原因是在于使用4K page的話,有多少進(jìn)程使用SGA,就需要多少套PTE,相反如果使用2M page則無論有多少進(jìn)程使用SGA,共享的都是同一套PTE。

眾所周知,x86是32位的,所以默認(rèn)情況下,其可尋址的空間為2的32次方——4G。在X86設(shè)計(jì)之初,4G內(nèi)存似乎是一個遙不可及的天文數(shù)字,但是摩爾定律打破了這一切,所以軟硬件的設(shè)計(jì)和開發(fā)商必須想出一個對策來解決4G以上不可尋址的問題。注意:這里沒有說4G以上的內(nèi)存不可尋址,而是說4G以上的地址空間不可尋址,這兩者實(shí)際上有區(qū)別的。例如4G內(nèi)存的CPU在32bit的Windows(非server版本)能識別到的內(nèi)存一般在3G左右。?這其中的主要是主板或者操作系統(tǒng)的限制。因?yàn)橛?jì)算機(jī)上一些其他的設(shè)備同樣需要可尋址,而這一部分地址需要從總的可尋址空間中預(yù)留,例如BIOS芯片的ROM,顯卡上的顯存(RAM)和BIOS(ROM),以及PCI、PCI-E設(shè)備上的RAM和ROM都需要占用一定的可尋址的空間。這個叫?MMIO?(Memory-mapped I/O)。這里有點(diǎn)off the topic了,所以不再贅述,要了解更詳細(xì)的原因和機(jī)制,請參考以下鏈接:(?RAM limit?PCI hole?,????Conventional memory?,????3GB barrier?)

CPU的設(shè)計(jì)者碰到了難題了:既要解決4G以上可尋址,又要兼容已有的架構(gòu)和程序,那該怎么辦呢?一種最可行的方式就是通過增加擴(kuò)展地址來解決4G以上的尋址問題。于是Intel引入一個workaround?PAE?(Physical Address Extensions)機(jī)制:增加20位擴(kuò)展地址,將原來的32位的物理地址擴(kuò)展為52位,那么可尋址的空間就增加到了2的52次方——4PB,但是實(shí)際上x86只使用了其中的36位,也就是X86實(shí)際可尋址的物理地址為64G,而轉(zhuǎn)化的過程為操作系統(tǒng)通過使用頁表將4GB的地址空間映射到大小為64GB的物理地址空間。盡管物理地址為52位,但是線性地址還是32位,所以在這種架構(gòu)下單個程序/進(jìn)程使用的內(nèi)存限制實(shí)際上仍然還是4G。?????注:?PSE?(Page Size Extension)使得用戶可以使用4M的頁表。?PAE?(Physical Address Extension)使得32位的系統(tǒng)就能夠使用接近64GB的內(nèi)存的一種技術(shù)。如果PAE和PSE同時使用,則只能使用2M的頁表。x86_64默認(rèn)使用PAE的擴(kuò)展——??long mode?。

通過上圖可知:是否使用分頁是通過CR0寄存器的PG表示來控制的,如果只使用傳統(tǒng)的分段模式,則將CR0.PG置為0, 如果啟用分頁則需要將PG設(shè)置為1。使用page的大小則是由IA32_EFER寄存器LME標(biāo)志以及CR4寄存器的PAE標(biāo)志和PSE標(biāo)志控制的,其中IA32_EFER.LME標(biāo)志控制是否是否啟用IA-32e模式,而CR4.PAE標(biāo)志為控制是否啟用PAE, CR4.PSE標(biāo)志控制是否啟用PSE。但是并不是這三者的任意組合都是存在的,現(xiàn)實(shí)中存在的情況為以下幾種: 當(dāng)前x86/x86_64架構(gòu)支持的page的大小包括: 4k, 2M, 4M, 1G (操作系統(tǒng)到目前還不支持1G的page table) 以下以x86_64的Linux為例,說明page的大小是如何得到的:在內(nèi)核源代碼include/asm-x86_64/pgtable.h文件中,可以找到如下宏定義:

#define PMD_SHIFT 21...#define PMD_SIZE (1UL <<PMD_SHIFT)

可知使用long mode的page的大小為:

1 << 21 = 2097152

這個移位運(yùn)算的結(jié)果,請參考?http://www.wolframalpha.com/input/?i=1%3C%3C21

需要注意的是page table的大小用戶無法自定義,在Linux中即使修改這個宏定義,重新編譯內(nèi)核,也無法修改page的大小。

ArchitecturePage SizeHuge Page SizeLarge Page Size
i3864?KB4M (2M in PAE mode)1?GB
IA-644?KB4K, 8K, 64K, 256K, 1M, 4M, 16M, 256M-
ppc644?KB-16M
sparc8?KB-8K, 64K, 4M, 256M, 2G

在Exadata甚至所有的大內(nèi)存Linux平臺, hugepages的重要性怎么強(qiáng)調(diào)都不過分。那么為什需要配置hugepages呢?使用hugepages的好處,總結(jié)起來包括如下五個方面:

Not swappable?(使得?SGA?不可交換)

為啥SGA是可以被換到虛擬內(nèi)存的???Bug?160033?-?Kernel swaps out Oracle instead of releasing cache 這個bug最終關(guān)閉的狀態(tài)為Not a bug, 但是同時在這個bug中提到: ? The basic design of the VM in RHEL 4 and RHEL 5 will not allow a complete fix for this issue, only tweaks to make it behave better most of the time.In the upstream kernel (and for RHEL 6), this problem has been addressed with the split LRU VM, which was merged in 2.6.28 and continues to get small fixes and tweaks.? In RHEL 6 this issue should be resolved. Oracle SGA區(qū)的內(nèi)存被swap到磁盤只有到Linux Kernel2.6.28或者RHEL 6以后才通過引入新的機(jī)制得到解決。而一旦SGA區(qū)被換出內(nèi)存會造成很大的性能抖動。所以在這個問題徹底解決之前,絕大多數(shù)版本的Linux依然需要通過hugepages來固定SGA區(qū)。(Linux平臺并不支持通過設(shè)置lock_sga和參數(shù)的方法來固定SGA, pre_page_sga這個參數(shù)存在太多的弊端已經(jīng)強(qiáng)烈不推薦使用)

Relief of TLB pressure:?(減輕?TLB?的壓力)

我們知道TLB是直接緩存虛擬地址到物理地址的緩存表,用于提升性能,省去查找page table減少開銷,但是如果出現(xiàn)的大量的TLB miss,必然會給系統(tǒng)的性能帶來較大的負(fù)面影響,尤其對于連續(xù)的讀操作。從第二篇文章中我們知道如果使用hugepages能大量減少PTE的數(shù)量,也就意味著訪問同樣多的內(nèi)容需要的PTE會更少,而通常TLB的槽位是有限的,一般只有512個,所以更少的PTE也就意味著更高的TLB的命中率。

Decreased page table overhead:?(減少頁表的開銷)

在前面的內(nèi)容中我們通過計(jì)算,對4k page和hugepages的頁表開銷的進(jìn)行對照發(fā)現(xiàn),使用hugepages可以極大的減少維護(hù)頁表的開銷。這篇文章中也提到了一個計(jì)算方法:

Each page table entry can be as large as 64 bytes and if we are trying to handle 50GB of RAM, the pagetable will be approximately 800MB in size which is practically will not fit in 880MB size lowmem (in 2.4 kernels – the page table is not necessarily in lowmem in 2.6 kernels) considering the other uses of lowmem. When 95% of memory is accessed via 256MB hugepages, this can work with a page table of approximately 40MB in total.

注意這里說PTE為64Bytes是一種最極端的情況,考慮的是極值,所以實(shí)際上這種估算方法并不是太合理。前面說過:一般來說x86的PTE的大小為4Bytes, x86_64的PTE的大小為8Bytes,這里說的PTE為64Bytes實(shí)際上指的是由8個PTE組成的PTEG(PTE group),在?《Microprocessor 8085, 8086》?這本書的425頁中提到A?PTEG?contains eight Page Table Entries (PTEs) of eight bytes each

Eliminated page table lookup overhead:?(減少頁表查詢的開銷)

PTE的數(shù)量減少,那么使得很多頁表的查詢就不需要了,并且更少的PTE使得頁表的查詢更快。如果TLB miss,則可能需要額外三次內(nèi)存讀取操作才能將線性地址翻譯為物理地址。

Faster overall memory performance:?(提升內(nèi)存訪問的整體性能)

現(xiàn)代操作系統(tǒng)都是使用虛擬內(nèi)存管理,每一次對內(nèi)存的訪問實(shí)際上都是由兩次抽象的內(nèi)存操作組成。如果只要使用更少的頁面,那么原本在頁表訪問的瓶頸也得以避免。

來看一個具體的問題。

某客戶新上線的Oracle數(shù)據(jù)庫系統(tǒng),運(yùn)行在Linux x86_64平臺上,主機(jī)配置較高,32核+120G內(nèi)存,SGA設(shè)置90G左右,但是每當(dāng)數(shù)據(jù)庫運(yùn)行大約一周以后,前臺應(yīng)用就會變得異常緩慢,經(jīng)常假死,有時新連接都沒有響應(yīng),如果DBA不加干涉殺掉部分local=NO的進(jìn)程,過一段時間就可能有節(jié)點(diǎn)被驅(qū)逐。 經(jīng)過簡單的分析,當(dāng)前數(shù)據(jù)庫主機(jī)有如下一些特征:

  • 前臺響應(yīng)緩慢或者新連接無法建立時,CPU占用率并不高,但是奇怪的是有一個系統(tǒng)進(jìn)程kswapd0占據(jù)了單核CPU的100%,其它進(jìn)程的CPU占用率都控制在單核的各位數(shù);
  • 通過free命令來查看剩余內(nèi)存,發(fā)現(xiàn)所剩的內(nèi)存已經(jīng)不多,通過sar -B和vmstat查看發(fā)現(xiàn)有較為嚴(yán)重的page in和page out。
  • 問題發(fā)生時刻,連接數(shù)有一定程度的增加,但是基本都是呈緩慢線性的方式增加,沒有劇增的情況。從oracle進(jìn)程來看,每個連接占的CPU和內(nèi)存資源都差不多;
  • 從/proc/meminfo來看,頁表占用了內(nèi)存的絕大部分; 操作系統(tǒng)重啟的時候,在/var/logs/message中有類似的信息:
messages: Feb 10 10:11:40 rac01 kernel: SysRq : Resetting messages: Feb 10 10:16:35 rac01 syslogd 1.4.1: restart.

這個問題并不復(fù)雜:本質(zhì)就是一個內(nèi)存耗盡的問題,但是另客戶非常不解的是:按照規(guī)劃,物理內(nèi)存應(yīng)該是綽綽有余的,那為什么還出現(xiàn)了內(nèi)存耗竭的情況呢? 從前面的例子可以看到,因?yàn)闆]有配置hugepages,導(dǎo)致了隨著連接數(shù)的增加頁表急劇膨脹,并且SGA被頻繁的從swap交換空間換入/換出。在Linux中, ?kswapd是負(fù)責(zé)內(nèi)核頁面交換管理的一個守護(hù)進(jìn)程,它的職責(zé)是保證Linux內(nèi)存管理操作的高效。當(dāng)物理內(nèi)存不夠時,它就會變得非常aggressive,就像上文中所說的能占用單核CPU的100%. ? kswapd 進(jìn)程負(fù)責(zé)確保內(nèi)存空間總是在被釋放中,它監(jiān)控內(nèi)核中的pages_high和pages_low閥值。如果空閑內(nèi)存的數(shù)值低于pages_low,則每次 kswapd 進(jìn)程啟動掃描并嘗試釋放32個free pages.并一直重復(fù)這個過程,直到空閑內(nèi)存的數(shù)值高于 pages_high。kswapd 進(jìn)程完成以下幾個操作:

  • 如果該頁處于未修改狀態(tài),則將該頁放置回空閑列表中.
  • 如果該頁處于已修改狀態(tài)并可備份回文件系統(tǒng),則將頁內(nèi)容寫入到磁盤.
  • 如果該頁處于已修改狀態(tài)但沒有任何磁盤備份,則將頁內(nèi)容寫入到swap device.

注:?每次?kswapd?進(jìn)程啟動掃描并嘗試釋放?32?個?free pages??不再適用于RHEL 5.4以后的版本。 以上方框中的內(nèi)容來自Linux System and Performance?Monitoring, 原文鏈接已不可考。當(dāng)然也可以參考MOS文檔kswapd / krefilld Process Consumes All the CPU Resources [ID 272249.1]。

在Linux系統(tǒng)中,有兩種方式可以用來使用hugepages。一種是2.6內(nèi)核就已經(jīng)引入的Hugetlbfs虛擬文件系統(tǒng),還有一種方式就是從2.6.38版本開始(RHEL 6)引入的THP(Transparent Hugepages).

在現(xiàn)實(shí)世界中,hugetlbfs主要用于數(shù)據(jù)庫,需要專門的進(jìn)行配置以及應(yīng)用程序的代碼支持,而THP則可用于更廣泛的應(yīng)用程序,一切都交給操作系統(tǒng)來完成,也不再需要額外的配置,所以對于應(yīng)用程序是透明的。 我們首先來看hugetlbfs。hugetlbfs是一個虛擬文件系統(tǒng),它運(yùn)行在內(nèi)核層,不與磁盤空間相對應(yīng)。如果需要使用hugetlbfs,則需要在編譯Linux內(nèi)核的時候在file system這個配置欄中勾選CONFIG_HUGETLB_PAGE和CONFIG_HUGETLBFS選項(xiàng)(如果勾選了CONFIG_HUGETLB_PAGE則CONFIG_HUGETLBFS會自動勾選)。內(nèi)核編譯完成并啟動操作系統(tǒng)以后,將hugetlbfs文件系統(tǒng)掛載到特定的目錄(不同的發(fā)行版目錄可能不一樣,Red Hat一般mount在/dev/hugepages),則hugetlbfs就可以訪問了。完成以后可以通過

cat /proc/filesystems | grep tlb

來查看hugetlbfs是否已經(jīng)開啟。因?yàn)镽HEL/OL提供二進(jìn)制內(nèi)核的rpm包,所以這些操作在RHEL/OL都不需要做。RHEL/OL上惟一需要做的就是在nr_hugepages中輸入需要使用的hugepages的數(shù)量,例如:

echo 25000 > /proc/sys/vm/nr_hugepages

當(dāng)然我們都知道/proc文件系統(tǒng)的內(nèi)容只對當(dāng)前生效,如果需要重啟后依然有效則需要把vm.nr_hugepages?= 25000這個條目加入到/etc/sysctl.conf內(nèi)核配置文件中,然后重啟操作系統(tǒng)或者使用sysctl -p 刷新內(nèi)核參數(shù)配置才能生效。 如果一個程序要使用hugetlbfs,那么用戶只能使用mmap 標(biāo)準(zhǔn)的SYSV函數(shù)shmget/ shmat來調(diào)用/訪問它。如果使用mmap調(diào)用,則在mmap函數(shù)的第四個參數(shù)帶入的標(biāo)志位為MAP_HUGETLB,具體實(shí)例請參考Linux內(nèi)核文檔:?https://www.kernel.org/doc/Documentation/vm/map_hugetlb.c?,

如果使用shmget接口來調(diào)用,則需要則shmget的第三個參數(shù)的位置帶入SHM_HUGETLB參數(shù)(shmat沒有這個參數(shù), 所以通過listener新建一個連接無法獲知是否使用了hugepages??蓞⒖磗hmat的man頁面:??http://linux.die.net/man/2/shmat?)。具體實(shí)例請參考Linux內(nèi)核文?https://www.kernel.org/doc/Documentation/vm/hugepage-shm.c???赡苡型瑢W(xué)覺得知道這個對于一個dba毫無意義,因?yàn)榭赡芪矣肋h(yuǎn)不會進(jìn)行與hugepages開發(fā)相關(guān)的任何工作,但是實(shí)際上卻不是這樣的。

Linux平臺上無法從操作系統(tǒng)層面得知數(shù)據(jù)庫是不是真正使用了hugepages。那么這個時候我們通過strace跟蹤數(shù)據(jù)庫的啟動過程(啟動以后無法看到)發(fā)現(xiàn),其調(diào)用了shmget, 并且第三個參數(shù)為SHM_HUGETLB標(biāo)志。這樣我們就可以斷定數(shù)據(jù)庫使用了hugepages。例如:如果kernel.shmmax為32G,通過strace跟蹤就能看到類似的調(diào)用信息。(可以看出shmget的第二個參數(shù)為申請的內(nèi)存大小,單位為Bytes)

$ strace -fo strace.out $ sqlplus / as sysdba SQL>startup nomount; $ grep HUGETLB strace.out | less shmget(0xxxxxxxxx, 13625196544, IPC_CREAT|IPC_EXCL|SHM_HUGETLB|0660) ...

那么能否可以通過/proc/meminfo中的信息來確認(rèn)數(shù)據(jù)庫使用了hugepages,我這里舉例說明:以下是一個Exadata用戶的hugepages信息:

#cat /proc/meminfo | grep -i hugepage HugePages_Total: 13007 HugePages_Free: 11813 HugePages_Rsvd: 3372 HugePages_Surp: 0 Hugepagesize: 2048 kB

從上面的信息可以得出以下結(jié)論:當(dāng)前hugepages一共實(shí)際使用了13007-11813=1194個pages (不包括預(yù)留的),預(yù)留了3372個pages。永遠(yuǎn)不會使用達(dá)到了11813-3372=8841個pages。每個page大小為2M,也就是說有接近16.5G的hugepages內(nèi)存被浪費(fèi)了(因?yàn)閔ugepages無法swap,所以不能被其它程序所使用)。換句話說:當(dāng)前系統(tǒng)使用中或者即將被使用的hugepages的總和為HugePages_Total – HugePages_Free + HugePages_Rsvd=13007-11813+3372=4566個。產(chǎn)生這樣令人困惑的結(jié)果是因?yàn)橛脩魹榱耸≠Y源,在這臺主機(jī)上配置了多個數(shù)據(jù)庫實(shí)例,但是只有一個實(shí)例使用了hugepages。 之所以要提這個事情,是因?yàn)樵贠racle 11.2.0.3版本以前,如果當(dāng)前操作系統(tǒng)配置了hugepages,但是數(shù)據(jù)庫實(shí)例設(shè)置的SGA大小如果比hugepages總的大小還要大,則SGA無法使用hugepages的內(nèi)存,然后會去使用其它非hugepages的內(nèi)存,并且在alert中也沒有任何信息,進(jìn)而導(dǎo)致系統(tǒng)內(nèi)存占用率高,數(shù)據(jù)庫性能非常糟糕。

Kevin Closson?在他的blog中有抱怨過這個問題,但是他卻沒說這實(shí)際上是一個Bug 12654172: EXHAUST THE AVAILABLE HUGEPAGES FOR ALLOCATING A REALM。當(dāng)然11.2.0.3以后的版本,會在alert日志提示hugepages沒有使用的警告信息。 目前在Linux的主流版本,依然無法像其它平臺那樣使用操作系統(tǒng)工具來獲取到數(shù)據(jù)庫是否使用了hugepages。例如:在Solaris中可以使用pmap -s來查看,在AIX中可以使用vmstat來查看,在RHEL/OL 6可以使用cat /proc/<pid>/smaps來查看。

配置hugepages

接下來講述如何在RHEL/OL/SLES如何設(shè)置hugepages,Exadata后期的版本onecommand默認(rèn)為數(shù)據(jù)庫配置了hugepages,早期的版本配置方式與RHEL/OL 類似。 在RHEL/OL上,大致有如下步驟:

1?)???首先需要配置?memlock

在/etc/security/limits.conf最后添加:

oracle hard memlock lock_value oracle soft memlock lock_value

其中上述lock_value使用比SGA值略大的一個值代替。

2?)估算?hugepages?的大小

在RHEL/OL平臺,如果是數(shù)據(jù)庫沒有啟動,則可以按照如下公式大致估算所需要的hugepages數(shù)目: #hugepages=(SGA(MB)+(20k * # of Oracle processes running)/1024) / hugepage_size (MB) 例如:如果sga的大小為64G,運(yùn)行的oracle進(jìn)程數(shù)為1000, 那么則大致需要32777個hugepages。RedHat Consultant?Scott Croft認(rèn)為計(jì)算的時候?應(yīng)該加上PGA的值?,但是pga是無法用到hugetlbfs的,所以這里沒有算到pga的值。 當(dāng)然在數(shù)據(jù)庫實(shí)例沒有啟動的時候只能是估算,如果Oracle數(shù)據(jù)庫正在運(yùn)行,則可以得到更準(zhǔn)確的值。以下腳本根據(jù)數(shù)據(jù)庫啟動以后的的共享內(nèi)存段總和除上hugepages的大小,計(jì)算出來所需的hugepages的數(shù)量。

# # 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 #查看Oracle Kernel的版本,因?yàn)?.4和2.6使用的hugepages的參數(shù)是不一樣的; #2.4使用vm.hugetlb_pool,而2.6使用vm.nr_hugepages。 KERN='uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'' # Find out the HugePage size #查找Hugepages的大小,x86非PAE為4096,x86+PAE以及x86_64為2048,注意# 這里單位為K。 HPG_SZ=`grep Hugepagesize /proc/meminfo | awk {'print $2'}` # Start from 1 pages to be on the safe side and guarantee 1 free HugePage #保證至少有1個page,也就是計(jì)數(shù)從1開始,MOS文檔401749.1的初始計(jì)數(shù)從0開始。 NUM_PG=1 # Cumulative number of pages required to handle the running shared memory segments #循環(huán)計(jì)算一共需要多少hugepages #ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"的結(jié)果是列出所有的shared memory的大#小,單位為Bytes;echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q 為將shared memory處理單 #個page的大小,得到單個shared memory所需的hugepages的數(shù)量。將所有的shared memory #循環(huán)累加,最終得到總的hugepages的數(shù)量。 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 #根據(jù)不同的內(nèi)核,提示設(shè)置不同的hugepages參數(shù) 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') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;; *) echo "Unrecognized kernel version $KERN. Exiting." ;; esac # End

3?)?設(shè)置?hugepages?內(nèi)核參數(shù)

運(yùn)行上述hugepages_settings.sh,得到一個值。將這個值寫入/etc/sysctl.conf, 例如:

#echo "vm.nr_hugepages=20480">>/etc/sysctl.conf #sysctl -p #grep Huge /proc/meminfo

4?)?禁用?AMM?特性

因?yàn)镺racle自動內(nèi)存管理的AMM特性與hugetlbfs不兼容,所以需要禁用這個特性,但是可以使用SGA自動管理。具體做法將MEMORY_TARGET/MEMORY_MAX_TARGET設(shè)置為0,并且手工指定SGA_TARGET/SGA_MAX_SIZE/PGA_AGGREGATE_TARGET的值。

5?)重啟主機(jī)和數(shù)據(jù)庫確認(rèn)生效

設(shè)置完成以后,最好重啟主機(jī)(不是必須的,但是建議)和數(shù)據(jù)庫(必須)使得hugepages生效。如果使用的Linux是SLES (SUSE Linux Enterprise Server) ,則Oracle提供了一個名為orarun的rpm包,可以用于自動配置其hugepages。 This package creates the user and the groups for Oracle, sets the Oracle environment variables, sets kernel parameters to values recommended by Oracle, and provides for automated start and stop of Oracle components at system start and stop time. SLES 11的orarun包可以在以下ftp站點(diǎn)找到:?http://ftp.novell.com/partners/oracle/sles-10/?SLES 11的orarun包可以在以下ftp站點(diǎn)找到:??http://ftp.novell.com/partners/oracle/sles-11/??


總結(jié)

以上是生活随笔為你收集整理的Hugepages详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。