Hugepages und Large Pages
Wenn Sie eine Oracle Datenbank auf einem Linux Server mit mehr als 16 GB physical Memory betreiben und die System Global Area (SGA) größer als 8 GB ist, sollten Sie HugePages konfigurieren. Oracle verspricht durch diesen Schritt eine höhere Performance. Eine HugePages Konfiguration bedeutet, dass der Linux Kernel mit „large pages“, wie Oracle sie allgemein nennt umgehen kann. Also statt der Standard 4 KB auf x86 und x86_64 oder 16 KB auf IA64 Systemen, dann mit 4 MB auf x86, 2 MB auf x86_64 und 256 MB auf IA64 System. Größere Pages bedeuten, dass das System weniger Page Tables benutzen, weniger Mappings verwalten muss, und so den Aufwand für deren Verwaltung und die Zugriffe reduziert werden.
Allerdings gibt es eine Einschränkung seitens Oracle, denn Automatic Memory Management unterstützt leider keine HugePages. Sollten Sie Automatic Memory Management (AMM) benutzen, also haben MEMORY_TARGET gesetzt, müssen Sie es an dieser Stelle abschalten und wieder auf Automatic Shared Memory Management (ASMM) umstellen, also wieder SGA_TARGET und PGA_AGGREGATE_TARGET setzen. Des Weiteren gibt es noch eine Neuerung namens Transparent Hugepages (THP), welche ausgeschalten werden sollte. Sie werden in einem Red Hat Linux ab Version 6 oder einem entsprechenden Derivat mitgeliefert. Sowohl Oracle als auch Red Hat empfehlen die Abschaltung von THP. Erklärung dazu in Punkt 5 – Serverkonfiguration ändern. Kommen wir also zur optimalen Konfiguration in 7 Schritten:
1. Physical Memory prüfen
Zunächst sollten wir unseren aktuellen „physikalisch“ verfügbaren Arbeitsspeicher überprüfen. Im Beispiel haben wir also knapp 128 GB RAM. SGA_TARGET und PGA_AGGREGATE_TARGET zusammen, sollten nicht größer als der vorhandene Arbeitsspeicher sein. Zudem sollte ausreichend Speicher für OS Prozesse selbst zur Verfügung stehen:
grep MemTotal /proc/meminfo MemTotal: 132151496 kB
2. Datenbankparameter prüfen
Im zweiten Schritt überprüfen wir unsere Datenbankparameter. Zunächst: AMM ausgeschalten? MEMORY_TARGET und MEMORY_MAX_TARGET sollten auf 0 stehen:
SQL> select value from v$parameter where name = 'memory_target'; VALUE --------------------------- 0
Wie groß ist unsere SGA? In diesem Beispiel knapp 40 GB. Wichtig: In der nachfolgenden Abfrage wird direkt in kB umgerechnet (value/1024). Sodass man mit diesem Wert anschließend weiter rechnen kann:
SQL> select value/1024 from v$parameter where name = 'sga_target'; VALUE --------------------------- 41943040
Schließlich sollte per Default der Parameter use_large_pages in der Datenbank eingeschalten sein:
SQL> select value from v$parameter where name = 'use_large_pages'; VALUE --------------------------- TRUE
3. Hugepagesize prüfen
In unserem Beispiel verwenden wir einen x86_64 Red Hat Enterprise Linux Server. Also sollte per default die Hugepagesize auf 2 MB gesetzt sein:
grep Hugepagesize /proc/meminfo Hugepagesize: 2048 kB
4. Hugepages kalkulieren
Für die Kalkulation der Anzahl der Hugepages gibt es eine einfache Faustformel:
SGA / Hugepagesize = Anzahl Hugepages
Also unserem Beispiel folgend:
41943040 / 2048 = 20480
Betreibt man auf einem Server mehrere Datenbanken, so sollte man in die Berechnung die SGA aller Instanzen einbeziehen. Also:
( SGA 1. Instanz + SGA 2. Instanz + … etc. ) / Hugepagesize = Anzahl Hugepages
Alternativ bietet Oracle unter der Doc ID 401749.1 auch ein Skript namens hugepages_settings.sh an, welches die entsprechende Berechnung vornimmt. Dieses bezieht auch eine Prüfung der Kernel Version und die aktuell verwendeten Shared Memory Bereiche durch das SGA ein. Beachten sollte man, dass sich die Berechnung auf die aktuelle SGA Größe und Verwendung bezieht. Das heißt also erst SGA anpassen, Datenbank durchstarten und dann das Skript ausführen. Ergebnis sollte dann folgender Satz sein. Überprüfen Sie doch einfach einmal Ihre Berechnung mit dem Ergebnis des Skripts:
Recommended setting: vm.nr_hugepages = 20480
5. Serverkonfiguration ändern
Im nächsten Schritt müssen wir die Anzahl der Hugepages im entsprechenden Server config-File eintragen. Dafür benötigen Sie root Berechtigungen. Unter Red Hat Linux 6 /etc/sysctl.conf
vi /etc/sysctl.conf vm.nr_hugepages=20480
Richtig eingetragen, sollte folgendes Ergebnis zurückgeliefert werden:
grep vm.nr_hugepages /etc/sysctl.conf vm.nr_hugepages=20480
Als weiteres müssen wir in der /etc/security/limits.conf die Parameter hard und soft memlock für den oracle User eintragen. Diese Werte sollten kleiner als der verfügbare Speicher in kB sein. Mindestens sollten aber unsere SGA bzw. unsere Hugepages hineinpassen. Daraus ergibt sich folgende Berechnung:
Anzahl Hugepages * Hugepagesize = minimum Memlock
Dem Beispiel folgend:
20480 * 2048 = 41943040
vi /etc/security/limits.conf oracle soft memlock 41943040 oracle hard memlock 41943040
Richtig eingetragen, sollte folgendes Ergebnis zurückgeliefert werden:
grep oracle /etc/security/limits.conf ... oracle soft memlock 41943040 oracle hard memlock 41943040
Wie bereits angesprochen müssen wir ab Red Hat Linux 6 Transparent Hugepages ausschalten:
cat /sys/kernel/mm/redhat_transparent_hugepage/enabled [always] madvise never echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled echo never > /sys/kernel/mm/redhat_transparent_hugepage/defrag cat /sys/kernel/mm/redhat_transparent_hugepage/enabled always madvise [never]
6. Server Reboot
Haben Sie alle Parameter gesetzt starten Sie den Server komplett durch. Alternativ kann man mit sysctl -p die Parameter auch für den laufenden Server aktivieren.
7. Konfiguration überprüfen
Sitzt memlock korrekt?
ulimit -l 41943040
Sind HugePages richtig konfiguriert und auch in Nutzung?
grep Huge /proc/meminfo AnonHugePages: 538624 kB HugePages_Total: 20480 HugePages_Free: 12292 HugePages_Rsvd: 8188 HugePages_Surp: 0 Hugepagesize: 2048 kB
Sind Transparent Hugepages ausgeschalten?
cat /sys/kernel/mm/redhat_transparent_hugepage/enabled always madvise [never]
Nutzt die Datenbank HugePages? Dazu schauen wir uns das Alert Log an. Nach dem „Starting ORACLE instance (normal)“ sollte als folgender Eintrag „Large Pages Information“ zu finden sein:
************************ Large Pages Information ******************* Per process system memlock (soft) limit = 100 GB Total Shared Global Region in Large Pages = 40 GB (100%) Large Pages used by this instance: 20481 (40 GB) Large Pages unused system wide = 0 (0 KB) Large Pages configured system wide = 20481 (40 GB) Large Page size = 2048 KB ********************************************************************
Bei einer Fehlkonfiguration gibt Oracle an dieser Stelle auch Empfehlungen für die richtige Konfiguration. Im nachfolgenden Beispiel fehlt eine einzige Page, also 2048 kB memlock um 100% des SGA als Hugepages zu allokieren:
************************ Large Pages Information ******************* ... ... RECOMMENDATION: Total System Global Area size is 40 GB. For optimal performance, prior to the next instance restart: 1. Increase the number of unused large pages by at least 1 (page size 2048 KB, total size 2048 KB) system wide to get 100% of the System Global Area allocated with large pages 2. Large pages are automatically locked into physical memory. Increase the per process memlock (soft) limit to at least 40 GB to lock 100% System Global Area's large pages into physical memory ********************************************************************
Fertig!
Hallo Sebastian,
wichtig:
Falls systemd zum Starten der instanz verwendet wird, wird limits.conf und damit die configurierten ulimits des „oracle“ Users ignoriert.
Daher muß in das service.unit File noch
LimitMEMLOCK=infinity
LimitNOFILE=65535+
aufgenommen werden.
Siehe:
https://bugzilla.redhat.com/show_bug.cgi?id=754285
https://oracle-base.com/articles/linux/linux-services-systemd
Viele Grüße
Peter
Vielen Dank für die Ergänzung!
Hallo Sebastian,
danke für die Erklärung, vielleicht kannst du noch eine Frage beantworten.
Nimmt sich der Parameter pga_aggregate_limit den Memory aus den konfigurierten HugePages oder bedient sich dieser aus dem verbleibenden physischen Memory?
Vielen Dank
LG
Harald
Hallo Harald,
nein, der Parameter pga_aggregate_limit bzw. pga_aggregate_target wird nicht aus dem Memory der Hugepages genommen, sondern aus dem „normalen“ Memory.
Gruß
Johannes Ahrends
Hallo Herr Ahrends,
lässt sich das auf einer XE11 realisieren mit 8G bzw 16G physikalischen RAM?
Macht das überhaupt Sinn?
Die läuft ja mit AMM,soweit ich das rausgekam und das ist bekanntlicherweise nicht komptibel mit large_pages.
Meine Werte zZt auf OL7:
vm.nr_hugepages = 1
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 1
HugePages_Free: 1
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
**************
memory_target
**************
1073741824
******************
memory_max_target
******************
1073741824
***********
sga_target
***********
0
****************
use_large_pages
****************
TRUE
Liese sich XE11 überhaupt umstellen auf ’nicht‘ AMM?
MfG
Ja, XE kann auch mit Hugepages und AMM benutzt werden. Das ist überhaupt kein Problem. Einfach memory_target auf 0 bzw. reset und dann sga_target etc. setzen.
Hallo Herr Ahrends
lässt sich das auch auf die XE11 anwenden mit 8GB bzw 16GB Physikalischen RAM?
Macht das überhaupt Sinn?
Mein Werte in OL7:
vm.nr_hugepages = 1
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 1
HugePages_Free: 1
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
**************
memory_target
**************
1073741824
******************
memory_max_target
******************
1073741824
***********
sga_target
***********
0
****************
use_large_pages
****************
TRUE
Wenn ich das richtig raus bekommen habe, läuft die XE11 ja mit AMM, lässt sich das in der XE11 überhaupt abschalten?
AMM ist ja nicht kompatible mit large_pages/huge_pages
MfG
Hallo Herr Klausmann,
nein, es ist nicht sinnvoll, einen Server mit mehr als 8 GB Hauptspeicher für XE zu betreiben, es sei denn, der Server dient auch als Anwendungsserver.
Bezüglich der Parameter würde ich Ihnen raten, Huge Pages zu nutzen und dem entsprechend SGA_TARGET und PGA_AGGREGATE_TARGET zu setzen. Außerdem würde ich Ihnen empfehlen, db_cache_size zu setzen, um zu vermeiden, dass der shared_pool zu groß wird. Gerade bei der doch sehr limitierten SGA Größe halte ich das für zwingend notwendig.
Hm, jetzt finde ich in der Readme für die XE11 den Bug 11738319:
An invalid parameter or a value more than the maximum allowed for memory was specified. These two parameters are not supported: use_indirect_buffers and db_cache_size.
Workaround:
Use allowed parameter or reduce memory size or upgrade to Standard or Enterprise edition.
Instead of db_cache_size, use sga_target or memory_target. There is no substitution for use_indirect_buffers.
Wäre also somit garnicht umsetzbar. Ich probiere es aus. Danke Herr Ahrends
ich kann die Anzahl der hugpages nicht größer als 20 setzen.
cat /proc/meminfo gibt folgende Werte zurück:
MemTotal: 8147780 kB
MemFree: 495868 kB
MemAvailable: 6931952 kB
Buffers: 748948 kB
Cached: 6039876 kB
SwapCached: 0 kB
Active: 3991828 kB
Inactive: 3007996 kB
Active(anon): 494432 kB
Inactive(anon): 235912 kB
Active(file): 3497396 kB
Inactive(file): 2772084 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 3999740 kB
SwapFree: 3999740 kB
Dirty: 952 kB
Writeback: 0 kB
AnonPages: 211028 kB
Mapped: 471688 kB
Shmem: 519344 kB
KReclaimable: 472536 kB
Slab: 534148 kB
SReclaimable: 472536 kB
SUnreclaim: 61612 kB
KernelStack: 3424 kB
PageTables: 6956 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 8053148 kB
Committed_AS: 1347140 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 20484 kB
VmallocChunk: 0 kB
Percpu: 4032 kB
HardwareCorrupted: 0 kB
AnonHugePages: 36864 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 0 kB
FilePmdMapped: 0 kB
HugePages_Total: 20
HugePages_Free: 20
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 40960 kB
DirectMap4k: 411520 kB
DirectMap2M: 7976960 kB
Was könnte dafür der Grund sein?
Hallo Marios,
so ganz verstehe ich das Problem nicht, zumindest wird es mir aus der Darstellung nicht ersichtlich. Vielleicht ein kleiner Hinweis: Wenn du Änderungen an den Hugepages machts (über sysctl oder editieren der Datei /etc/sysctl.conf), dann ist es sinnvoll, den Server neu zu starten. Ein sysctl -p hilft oft nicht.
sudo sysctl vm.nr_hugepages=440
vm.nr_hugepages = 440
sudo sysctl vm.nr_hugepages
vm.nr_hugepages = 20