Hello,
si comme bon nombre de DBAs Oracle, vous avez installé et configuré une instance de bases de données, que ce soit sur un système Linux classique ou une machine Exadata, vous avez surement été amené à mettre en place ce que l’on appelle des “HugePages”.
Qu’est-ce donc ?
Les HugePages sont des pages de 2Mo (par défaut), prises en charge par le kernel linux, que l’administrateur système et/ou bases de données peut utiliser pour les besoins d’une application. Il est tout à fait possible également, pour des machines Exadata par exemple, de définir des tailles de pages au delà de 2Mo. Si vous manipuler une base de forte volumétrie avec des fonctionnalités HCC (Hybrid Columnar Compression), choisissez une taille de page de 1Go .
Par défaut, une page sur un système Linux a une taille de 4Ko. Or, lorsqu’un SGBDR traite un volume de données conséquent, il est toujours bénéfique de limiter les aller-retour entre les différentes pages de la mémoire virtuelle et la mémoire physique supportée par le serveur via la gestion de la table de pages (la TLB) et la MMU (Memory Manager Unit).
L’idée est de positionner des pages plus grandes afin de stocker une quantité de données plus importante, et surtout de les “fixer” en mémoire afin d’éviter tout phénomène de swapping. Ceci réduit également la charge de TLB en réduisant la fragmentation mémoire allouée pour les processus.
Rappelons que dans le meilleur des mondes possibles, un serveur de bases de données ne doit pas ou peu swapper ! Et ce, que ce soit sous un système linux ou bien Windows.
Attention, le mécanisme de prise en charge des “HugePages”, y compris en 19c est toujours incompatible avec la gestion AMM Oracle (Automatic Memory Management). Définissez une SGA_TARGET et une PGA_AGGREGATE_TARGET et oubliez le MEMORY_TARGET.
La gestion des HugePages avant Oracle 19c
Avant la version 19c, et ce depuis la version 11.2.0.3, Oracle disposait déjà d’un paramètre appelé USE_LARGE_PAGES pour la prise en charge des HugePages au sein d’une instance Oracle.
Ce paramètre comportait 3 valeurs possibles :
- TRUE : Oracle supporte la prise en charge des HugePages si celles ci sont définies. Attention, si le nombre de HugePages est trop faible, une partie de la SGA sera intégrée dans des pages conventionnelles (taille de 4Ko). Dans tous les cas, l’instance pourra démarrer.
- FALSE : Oracle n’utilisera jamais de HugePages sur ce serveur. Uniquement des pages de 4Ko.
- ONLY : Oracle n’utilisera que des HugePages pour la SGA de cette instance. Attention, si les paramètres systèmes sont mal définis, ou bien si la valeur SGA_TARGET est trop haute vis à vis des paramètres kernel déclarés, l’instance peut ne pas démarrer.
Mettez en place les prérequis système nécessaires pour les versions antérieures à Oracle 19c.
la gestion des HugePages depuis Oracle 19c
Avec l’arrivée de la version 19c, Oracle a validé 2 nouvelles valeurs pour son paramètre USE_LARGE_PAGES.
- AUTO : Oracle va calculer son besoin en terme de HugePages lors du démarrage de l’instance, le processus en informe le kernel, qui lui accorde une certaine quantité de HugePages en fonction de ses ressources RAM disponibles.
Dans ce cas la, si le kernel dispose d’assez de mémoire (hard limit) pour configurer des HugePages, Oracle démarre avec 100% de sa SGA_TARGET avec des pages de 2Mo (soft limit). Oracle utilisera des pages conventionnelles de 4Ko si la place n’est pas suffisante. - AUTO_ONLY : Oracle calcule son besoin en terme de HugePages au moment du démarrage. Si le kernel dispose d’assez d’espace mémoire pour créer ces pages de 2Mo, l’instance démarre. Si le nombre de HugePages est insuffisant, ou bien si la limite défini dans les “soft/hard limit” est mal configurée, l’instance ne démarre pas.
A noter que sur Exadata, c’est la valeur qui est par défaut sur chaque instance.
Fonctionnement
Voici un test-case permettant de voir comment se comporte le système linux, et notre base de données vis à vis de la configuration de ces paramètres.
Pour notre exemple, nous disposons d’un système Linux Red Hat 8.3 et d’une instance Oracle version 19.10.
[root@ip-172-44-2-107 ~]# cat /etc/redhat-release Red Hat Enterprise Linux release 8.3 (Ootpa)
Celui ci dispose de 2 vCPU et 4 Go de RAM
[root@ip-172-44-2-107 ~]# cat /proc/meminfo | grep -i MemTotal MemTotal: 3823056 kB [root@ip-172-44-2-107 ~]# cat /proc/cpuinfo | grep -i core core id : 0 cpu cores : 2 core id : 1 cpu cores : 2
Prérequis
Afin de pouvoir bénéficier de la prise en charge des HugesPages pour ce serveur, il faudra définir des “limits” pour le compte Oracle de notre serveur.
Nous pourrons partir du principe que, le compte Oracle pourra, au plus, bloquer en mémoire jusqu’à 1,5Go.
A définir par le compte “root” dans le fichiers “limits.conf”.
# vi /etc/security/limits.conf .... domain type item value oracle soft memlock 1536000 oracle hard memlock 1536000
Nous nous assurons que ce serveur ne comporte aucune configuration de HugePages éventuelle.
[root]# sysctl -a | grep -i hugepages vm.nr_hugepages = 0 vm.nr_hugepages_mempolicy = 0 vm.nr_overcommit_hugepages = 0 [root]# cat /proc/meminfo | grep -i Huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB
Les valeurs “HugePages_Total” et “vm.nr_hugepages” sont bien nulles.
Mis à part la “limit” définie sur la mémoire à figer pour le compte Oracle, nous n’avons pas de trace de configuration HugePages sur ce serveur.
[oracle]$ ulimit -Sl 1536000
Validation du paramètre USE_LARGE_PAGES
Cas du mode AUTO
Voici les valeurs que nous avons défini sur l’init.ora de notre instance. Cette dernière se nomme CAPDATADB.
[oracle@ dbs]$ cat initCAPDATADB.ora ... *.sga_target=1200M *.use_large_pages='AUTO'
Nous partons sur une instance comportant 1,2Go de SGA. Avec le mode AUTO, Oracle laisse la possibilité de monter des HugesPages.
On démarre l’instance sans monter la base.
[oracle@ dbs]$ sqlplus / as sysdba startup nomount ORACLE instance started. Total System Global Area 1258290744 bytes Fixed Size 8896056 bytes Variable Size 436207616 bytes Database Buffers 805306368 bytes Redo Buffers 7880704 bytes
Dans l’alert.log de la base, nous voyons que l’instance Oracle a réussi à provisionner des pages de 2Mo au moment du démarrage.
**************************************************** Sys-V shared memory will be used for creating SGA **************************************************** 2022-07-27T15:01:09.749738+00:00 DISM started, OS id=1692 2022-07-27T15:01:09.784169+00:00 ********************************************************************** 2022-07-27T15:01:09.784260+00:00 Dump of system resources acquired for SHARED GLOBAL AREA (SGA) 2022-07-27T15:01:09.784382+00:00 Per process system memlock (soft) limit = 1500M 2022-07-27T15:01:09.784459+00:00 Expected per process system memlock (soft) limit to lock instance MAX SHARED GLOBAL AREA (SGA) into memory: 1202M 2022-07-27T15:01:09.784626+00:00 Available system pagesizes: 4K, 2048K 2022-07-27T15:01:09.784807+00:00 Supported system pagesize(s): 2022-07-27T15:01:09.784893+00:00 PAGESIZE AVAILABLE_PAGES EXPECTED_PAGES ALLOCATED_PAGES ERROR(s) 2022-07-27T15:01:09.785003+00:00 4K Configured 4 4 NONE 2022-07-27T15:01:09.785147+00:00 2048K 601 601 601 NONE 2022-07-27T15:01:09.785230+00:00 **********************************************************************
Oracle nous indique qu’il a réussi à monter 601 pages de 2Mo afin de les utiliser pour la SGA de notre instance.
S’il l’on regarde les paramètres kernel, nous voyons bien la présence de ces pages (HugePages_Total à 601)
$ cat /proc/meminfo | grep -i Huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 601 HugePages_Free: 11 HugePages_Rsvd: 11 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 1230848 kB
Une modification automatique du paramètrage “sysctl” nous assure la prise en charge des HugesPages.
[root~]# sysctl -a | grep -i Hugepages vm.nr_hugepages = 601 vm.nr_hugepages_mempolicy = 601 vm.nr_overcommit_hugepages = 0
S’il l’on regarde du coté des ipc , l’outil “sysresv” fourni par Oracle nous donne toutes les informations nécessaires sur la mémoire partagée de notre instance et les limites de notre compte Oracle.
[oracle ~]$ $ORACLE_HOME/bin/sysresv IPC Resources for ORACLE_SID "CAPDATADB" : Maximum shared memory segment size (shmmax): 18446744073692774399 bytes Total system shared memory (shmall): 18446744004990070784 bytes Total system shared memory count (shmmni): 4096 *********************** Dumping ipcs output ******************** ------ Message Queues -------- key msqid owner perms used-bytes messages ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 0 oracle 600 10485760 32 0x00000000 1 oracle 600 1241513984 32 0x00000000 2 oracle 600 8388608 32 0x679d3c3c 3 oracle 600 16384 32 ------ Semaphore Arrays -------- key semid owner perms nsems 0x3b5f1c70 3 oracle 600 154 *********************** End of ipcs command dump ************** ***************** Dumping Resource Limits(s/h) ***************** core file size UNLIMITED/UNLIMITED data seg size UNLIMITED/UNLIMITED scheduling priority 0 KB/0 KB file size UNLIMITED/UNLIMITED pending signals 14 KB/14 KB max locked memory 1500 MB/1500 MB max memory size UNLIMITED/UNLIMITED open files 256 KB/256 KB POSIX message queues 800 KB/800 KB real-time priority 0 KB/0 KB stack size 32 MB/UNLIMITED cpu time UNLIMITED/UNLIMITED max user processes 14 KB/14 KB virtual memory UNLIMITED/UNLIMITED file locks UNLIMITED/UNLIMITED ***************** End of Resource Limits Dump ******************
On retrouve pour le “shmid” 1 les 1,2Go provisionnés pour la SGA. Le “max locked memory” à 1,5Go pour le compte Oracle.
A noter également que lorsque l’on arrête l’instance, les HugesPages restent actifs.
Attention donc si vous avez plusieurs instances sur votre serveur et avec un mode AUTO sur chacune d’elle. La première instance qui démarre prend l’espace nécessaire dans les HugesPages, les suivantes utiliseront ce qu’il reste jusqu’aux limites définies dans “ulimit -l”. Il se peut donc que la(les) dernière(s) instance(s) démarre(nt) avec des pages de 4Ko potentiellement.
[oracle~]$ sqlplus / as sysdba shutdown immediate ORA-01507: database not mounted ORACLE instance shut down.
Mais les HugesPages sont toujours présents. Les 601 pages, toujours présentes, mais vues comme libres, dans la configuration kernel.
[root@ ~]# cat /proc/meminfo | grep -i Huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 601 HugePages_Free: 601 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 1230848 kB
Cas du mode AUTO_ONLY
avec le mode AUTO_ONLY, pas de souci pour ce server, dans la mesure ou nous avons deja 601 HugePages provisionnées et libres.
[oracle@ dbs]$ cat initCAPDATADB.ora ... *.sga_target=1200M *.use_large_pages='AUTO_ONLY'
Au démarrage
startup nomount ORACLE instance started. Total System Global Area 1258290744 bytes Fixed Size 8896056 bytes Variable Size 436207616 bytes Database Buffers 805306368 bytes Redo Buffers 7880704 bytes
Nous pouvons même voir qu’Oracle s’attribue 100% de la SGA dans les pages de 2Mo.
2022-07-27T15:28:14.054639+00:00 Available system pagesizes: 4K, 2048K 2022-07-27T15:28:14.054776+00:00 Supported system pagesize(s): 2022-07-27T15:28:14.054841+00:00 PAGESIZE AVAILABLE_PAGES EXPECTED_PAGES ALLOCATED_PAGES ERROR(s) 2022-07-27T15:28:14.054970+00:00 2048K 602 602 602 NONE 2022-07-27T15:28:14.055045+00:00 Reason for not supporting certain system pagesizes: 2022-07-27T15:28:14.055111+00:00 4K - Large pagesizes only
602 pages prises par Oracle et que le kernel enregistrera après démarrage
[oracle@ dbs]$ cat /proc/meminfo | grep -i Huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 602 HugePages_Free: 11 HugePages_Rsvd: 11 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 1232896 kB
Au niveau des ipc rien n’a changé dans l’attribution de la mémoire partagée. Nous avons toujours le découpage SGA de 1,2Go pris sur le segment numéro 5, et le reste représentant les “fixed size”, “redo buffers”.
[oracle@ dbs]$ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 4 oracle 600 10485760 32 0x00000000 5 oracle 600 1241513984 32 0x00000000 6 oracle 600 8388608 32 0x679d3c3c 7 oracle 600 2097152 32
Au dela des limites !
Mais que se passe-t-il si l’on choisit une SGA de taille plus importante que la “soft” limite définie pour le compte Oracle. Rappelons que nous avions capé à 1,5Go les limites en terme de “memlock” pour notre user Oracle.
Cas du mode AUTO
Supposons que nous choisissons les valeurs suivantes dans l’init.ora de notre instance. 1,8Go pour notre SGA.
[oracle@ dbs]$ cat initCAPDATADB.ora ... *.sga_target=1800M *.use_large_pages='AUTO'
Au démarrage de l’instance
startup nomount ORACLE instance started. Total System Global Area 1895822680 bytes Fixed Size 8897880 bytes Variable Size 436207616 bytes Database Buffers 1442840576 bytes Redo Buffers 7876608 bytes
L’instance démarre, mais que dit l’alert.log :
2022-07-27T15:38:35.723099+00:00 Available system pagesizes: 4K, 2048K 2022-07-27T15:38:35.723243+00:00 Supported system pagesize(s): 2022-07-27T15:38:35.723318+00:00 PAGESIZE AVAILABLE_PAGES EXPECTED_PAGES ALLOCATED_PAGES ERROR(s) 2022-07-27T15:38:35.723395+00:00 4K Configured 5 79752 NONE 2022-07-27T15:38:35.723516+00:00 2048K 901 905 749 NONE 2022-07-27T15:38:35.723594+00:00 RECOMMENDATION: 2022-07-27T15:38:35.723676+00:00 1. For optimal performance, configure system with expected number of pages for every supported system pagesize prior to the next instance restart operation. 2022-07-27T15:38:35.727289+00:00 2. Increase per process memlock (soft) limit to at least 1810MB to lock 100% of SHARED GLOBAL AREA (SGA) pages into physical memory 2022-07-27T15:38:35.727468+00:00 **********************************************************************
Notre instance réclame 1,8Go de SGA. Le kernel n’a pu lui fournir que 749 pages de 2Mo, soit 1498Mo, alors qu’Oracle en réclame 905.
le reste de la mémoire SGA va donc se positionner dans des pages conventionnelles de 4Ko, soit 79752 pages, donc 311Mo.
S’il l’on regarde les segments de mémoire partagée, nous voyons des espaces fragmentées , avec au plus, un espace contigu de 900Mo sur le shmid 9. Nous voyons également le shmid 14 représentant les 311 Mo en pages de 4Ko.
[oracle@ dbs]$ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 8 oracle 600 10485760 31 0x00000000 9 oracle 600 939524096 31 0x00000000 10 oracle 600 469762048 31 0x00000000 11 oracle 600 117440512 31 0x00000000 12 oracle 600 16777216 31 0x00000000 13 oracle 600 16777216 31 0x00000000 14 oracle 600 318767104 31 0x00000000 15 oracle 600 7876608 31 0x679d3c3c 16 oracle 600 20480 31
la situation n’est pas la plus optimale, surtout dans un système ou l’on charge en mémoire de grandes volumétries de données. Il est fort possible que cette instance fasse plus de lectures/écritures des IO dans la mesure ou nos segments de mémoire sont fragmentés.
Cas du mode AUTO_ONLY
mais alors, qu’en est-il du mode AUTO_ONLY si je dépasse la valeur “soft limit” des 1,5Go ?
Nous avons auparavant déjà alloué 901 pages de 2Mo au niveau du kernel. Ces pages sont présentes, même avec notre instance arrêtée.
[oracle@ dbs]$ ipcs -m -u ------ Shared Memory Status -------- segments allocated 0 pages allocated 0 pages resident 0 pages swapped 0 Swap performance: 0 attempts 0 successes
[oracle@ dbs]$ cat /proc/meminfo | grep -i Huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 901 HugePages_Free: 901 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 1845248 kB
Mais au démarrage de notre instance avec 1,8Go de SGA configurée
[oracle@ dbs]$ cat initCAPDATADB.ora ... *.sga_target=1800M *.use_large_pages='AUTO_ONLY'
startup nomount ORA-27125: unable to create shared memory segment Linux-x86_64 Error: 1: Operation not permitted Additional information: 4641 Additional information: 16777216
et l’alert.log est claire
2022-07-27T15:54:04.922034+00:00 PAGESIZE AVAILABLE_PAGES EXPECTED_PAGES ALLOCATED_PAGES ERROR(s) 2022-07-27T15:54:04.922154+00:00 2048K 901 906 749 ORA-27125 2022-07-27T15:54:04.922230+00:00 Reason for not supporting certain system pagesizes: 2022-07-27T15:54:04.922305+00:00 4K - Large pagesizes only 2022-07-27T15:54:04.922378+00:00 RECOMMENDATION: 2022-07-27T15:54:04.922448+00:00 1. Configure system with expected number of pages for every supported system pagesize prior to the next instance restart operation. 2022-07-27T15:54:04.925893+00:00 2. Increase per process memlock (soft) limit to at least 1812MB to lock 100% of SHARED GLOBAL AREA (SGA) pages into physical memory 2022-07-27T15:54:04.926083+00:00 **********************************************************************
Nous rencontrons une erreur ORA 27125, impossible d’affecter les pages demandées, l’instance ne démarre pas.
Oracle nous conseille d’augmenter le “soft limit” afin de faire tenir les 1,8Go de SGA dans des “HugePages” de 2Mo.
Conclusion
Comme nous venons de voir, Oracle, depuis la version 19c, est capable de réclamer dynamiquement au kernel des pages de 2Mo, sans pour autant les avoir provisionner dans le fichier “sysctl.conf“. Il est cependant, indispensable, de fixer des soft/hard limits au user Oracle afin de pouvoir verrouiller des pages en mémoire.
Lors du reboot du server, le système dispose de pages conventionnelles de 4Ko avec les paramètres “vm.nr_hugepages” et “HugePages_Total” à 0.
Optimisations de configuration
Voici les configurations que je préconiserais pour un système Linux 64 bits si vous souhaitez profiter de la gestion dynamique des HugePages par Oracle.
Cas d’un serveur dédié SGBDR avec 1 instance Oracle :
- Positionner le SHMMAX (en bytes) de 50% à 75% de la RAM serveur. Sur un système Exadata vous pouvez monter jusqu’à 80% de la RAM pour 1 taille max de segment mémoire.
- Positionner le SHMALL (en pages) à une taille légèrement supérieur à la valeur de SGA_TARGET.
- les limites “memlock” hard et soft doivent être identique à SHMALL (attention en Ko).
- Positionner USE_LARGE_PAGES à AUTO_ONLY afin de profiter des HugePages pour votre instance.
- Bien entendu, ne pas oublier de mettre MEMORY_TARGET à 0.
Cas d’un serveur SGBDR avec plusieurs instances Oracle.
- Positionner SHMMAX (en bytes) à 50% de la RAM. La taille d’un segment de mémoire ne doit pas dépasser 1/2 de la RAM. (cas d’un serveur disposant de bases de production par exemple).
- Le SHMALL (en pages) représente la somme totale des SGA de toutes les bases, avec un marge de quelques pages.
- Les limites “memlock” hard et soft doivent être identique à SHMALL (attention, en Ko).
- Positionner USE_LARGE_PAGES à
- AUTO_ONLY sur les bases dans le cas d’un serveur de production manipulant de forts volumes de données (Datawarehouse). Ceci afin de s’assurer que Oracle n’utilisera que des HugePages en mémoire et qu’il pourra les verrouiller. C’est la valeur par défaut sur une instance d’un dbnode Exadata.
- AUTO sur un serveur comportant des bases de dev/test ou bien sur des bases ou l’on souhaite changer facilement la valeur de SGA_TARGET sans risquer d’avoir un souci de démarrage sur l’une des instances.
- mettre MEMORY_TARGET à 0 sur toutes les instances.
Dans tous les cas, sur un serveur Linux dédié pour des instances de bases de données, Oracle recommande de désactiver les Transparent Huges Pages (THP) dans la mesure ou ces pages sont dynamiquement “swappable” . Ce qui peut être très problématique, notamment dans le cadre d’un environnement RAC (éviction de nœud possible).
- lancer la commande :
echo never | tee /sys/kernel/mm/transparent_hugepage/enabled
- éditer “/etc/grub.conf” et ajouter “transparent_hugepage=never“
🙂
Emmanuel RAMI
Continuez votre lecture sur le blog :
- Installation Oracle 64 bits sur Red Hat 5 (Capdata team) [OracleVintage]
- Limiter la PGA totale en 12c (Benjamin VESAN) [Oracle]
- Linux Out-Of-Memory Killer (OOM-Killer) pour un serveur base de données PostgreSQL (Emmanuel RAMI) [Non classé]
- “PGA memory operation”, “Acknowledge over PGA limit” et ORA-04036 après migration vers 12c (Benjamin VESAN) [Oracle]
- Oracle 12c à la maison (Benjamin VESAN) [Oracle]
Bonjour Emmanuel,
Attention avec les Huge Pages et les services systemD permettant le démarrage automatique des bases.
Pour qu’une instance Oracle démarrée avec un service puisse utiliser les Huge Pages, il faut ajouter dans le fichier de configuration du service (/etc/systemd/system/ les lignes suivantes, dans la section [Service] :
LimitMEMLOCK=infinity
LimitNOFILE=65535