Ik leg uit hoe je vm.max_map_count op Linux-databaseservers begrijpt, meet en zonder risico instelt. Dit artikel beschrijft concrete stappen, typische waarden en in de praktijk beproefde controles, zodat PostgreSQL, MySQL/MariaDB, Elasticsearch of OpenSearch onder belasting soepel blijven draaien.
Centrale punten
- Functie: Maximum aantal Virtual Memory Areas (VMAs) per proces
- Relevantie: Databases, zoeksystemen, Java-stacks met veel mappings
- Symptomen: „Cannot allocate memory“, opstartfouten, vastlopers
- Praktische waarden: 262.144 tot 1.048.576 voor grote workloads
- Procedure: De behoefte meten, met een reserve verhogen, monitoring integreren
Wat betekent vm.max_map_count?
De kernelparameter bepaalt hoeveel Geheugengebieden (VMAs) dat één proces maximaal mag aanmaken. Elke mmap-bewerking, elk geladen shared object, veel toewijzingen en shared-memory-blokken verhogen dit aantal. Hiermee beperk ik niet de hoeveelheid RAM, maar de Hoeveelheid de afzonderlijke gebieden in de virtuele adresruimte. Grote processen kunnen met een klein aantal grote mappings veel geheugen gebruiken, terwijl gefragmenteerde workloads door veel kleine mappings al snel tegen de limiet aanlopen. Wie geheugenintensieve software gebruikt, moet deze bovengrens kennen, anders stuit hij pas onder belasting op de fout.
Waarom databaseservers hierdoor worden getroffen
Databases en zoekdiensten maken veel gebruik van mmap, gedeeld geheugen, caches en talrijke bibliotheken. PostgreSQL-instanties met veel uitbreidingen en verbindingen, MySQL/MariaDB met plug-ins of Elasticsearch/OpenSearch met veel indexsegmenten genereren veel VMA’s. Als het aantal de grenswaarde nadert, mislukken verdere toewijzingen en meldt het proces Geheugenfout. Juist dan starten diensten niet op, lopen ze vast onder belasting of raken ze knooppunten in clusters kwijt. Ik voorkom dergelijk gedrag door de benodigde bovengrens vooraf te bepalen en deze correct in te stellen.
Symptomen en risico's van een verkeerde instelling
De meest voorkomende tekenen van een te lage grenswaarde zijn Startfout ondanks dat er nog geheugen vrij is. Diensten zoals Elasticsearch geven de foutmelding „Cannot allocate memory“ weer, hoewel de machine nog over voldoende resources beschikt. Ook treden er af en toe procesafbrekingen op zodra er intern meer VMA’s nodig zijn dan is toegestaan. Een te hoge waarde leidt doorgaans niet tot problemen, omdat de kernel slechts iets meer Administratie nodig voor vm_area_structs. Dit wordt pas relevant wanneer processen daadwerkelijk miljoenen mappings aanmaken, wat bij typische database-workloads meestal niet het geval is.
Praktijkcijfers en duiding
Veel distributies hanteren conservatieve standaardwaarden rond 65.536, wat volstaat voor eenvoudige diensten, maar te krap is voor zoek- en analyse-workloads. In typische hostingconfiguraties gebruik ik 262.144 als solide startwaarde voor grotere stacks. Voor zeer grote Elasticsearch-/OpenSearch-instanties plan ik 1.048.576 in, mits de meetwaarden in die richting wijzen. Een hogere waarde levert geen direct prestatieverbetering, het voorkomt fouten wanneer er veel mappings nodig zijn. De documentatie van de Linux-kernel en gangbare praktijkverslagen bevestigen deze indeling.
| Type app | VMA-profiel (typisch) | Startwaarde vm.max_map_count | Bovengrens (indien nodig) |
|---|---|---|---|
| Kleine DB / Hulpprogramma's | laag-gemiddeld | 65.536 | 262.144 |
| PostgreSQL/MySQL | gemiddeld-hoog | 262.144 | 524.288 |
| Elasticsearch/OpenSearch | hoog - zeer hoog | 262.144 | 1.048.576 |
| Grote Java-stacks | gemiddeld-hoog | 262.144 | 524.288 |
De huidige behoefte in kaart brengen
Voordat ik iets wijzig, controleer ik de huidige Instelling met sysctl vm.max_map_count of per cat /proc/sys/vm/max_map_count. Vervolgens bepaal ik de werkelijke behoefte van een proces met wc -l /proc//maps, bij voorkeur onder belasting. Deze waarde varieert afhankelijk van de modules, caches en werklast, daarom houd ik dit gedurende meerdere belastingperiodes in de gaten. Zodra de piek 50–70 % van de limiet bereikt, zorg ik voor een passende reserve. Zo neem ik een weloverwogen Besluit in plaats van te raden.
Zo pas ik vm.max_map_count veilig aan
Voor tests stel ik de waarde tijdelijk in met sysctl -w vm.max_map_count=262144, wat onmiddellijk effect heeft en bij het opnieuw opstarten verdwijnt. Voor continu gebruik voer ik de waarde in /etc/sysctl.conf en laad het op met sysctl --system nieuw, zodat de Configuratie blijft. Grote zoekclusters of zeer modulaire DB-stacks profiteren, afhankelijk van de meting, van 524.288 tot 1.048.576. Ik verhoog het aantal stapsgewijs, controleer de logbestanden en houd de statistieken over het geheugengebruik in de gaten. Zo houd ik het Risico in bedrijf is het verbruik laag en bouw ik op een voorspelbare manier een buffer op.
Best practices voor productieve omgevingen
Ik voer herhaaldelijk metingen uit bij normale en piekbelasting, in plaats van af te gaan op eenmalige waarden. De bovengrens stel ik niet precies vast, maar met een factor twee tot vier boven de waargenomen piek. In clusters kies ik consistente waarden, zodat alle knooppunten op dezelfde manier reageren en er geen Uitschieters genereren. De monitoring controleert op fouten met betrekking tot mmap/malloc en het verloop van het aantal VMA’s per proces. Voordat ik ze live zet, test ik nieuwe Waarden in een staging-omgeving met een vergelijkbare belasting.
Interactie met andere kernelparameters: swappiness, dirty ratios, bestandslimieten
vm.max_map_count staat nooit op zichzelf, want andere instellingen zijn hier bepalend voor Gedrag ook. De swappiness bepaalt hoe agressief het systeem pagina’s naar de swapruimte verplaatst, wat de latentie kan verhogen. Dirty Ratios bepalen wanneer gewijzigde pagina’s terug naar de schijf worden verplaatst en daarmee IO-pieken afvlakken of juist versterken. Limieten voor open bestanden bepalen hoeveel bestanden en sockets databases tegelijkertijd mogen aanhouden. Ik controleer deze Parameters samen, zodat er geen nieuwe knelpunt ontstaat.
Transparent Huge Pages gericht controleren
THP beïnvloedt het geheugenbeheer door grote pagina’s te bundelen en zo de toegangs patronen te veranderen. Databases reageren, afhankelijk van de werklast, gevoelig op THP; daarom controleer ik de status en modus en stel ik deze in op „madvise“ of „never“ wanneer de latentie toeneemt. Details over de effecten en het afstemmen heb ik opgenomen in mijn opmerking over Transparante enorme pagina's samengevat. Het blijft belangrijk om de verandering met statistieken te onderbouwen en niet blindelings over te stappen. Zo blijft het Opslaggedrag begrijpelijk en reproduceerbaar.
Inzicht in VFS-cache-afdrukken
De VFS-cache slaat metagegevens en bestandsinhoud op in het werkgeheugen en concurreert daarmee met databasepagina’s. Met de parameter voor de VFS-cache-afdruk bepaal ik hoe snel het systeem deze cache vrijgeeft. Een te hoge druk kan de IO-belasting verhogen, een te lage druk verdringt database-caches en heeft een negatieve invloed op de latentie. Ik pas de instellingen in kleine stapjes aan en meet de effecten op de page-cache-hitratio, de IO-wachttijd en de doorvoer. Dit Fijnafstemming heeft vaak een grotere impact dan verwacht wanneer databases en bestandssystemen nauw met elkaar zijn verweven.
NUMA-richtlijnen en databases
NUMA-architecturen verdelen het geheugen over knooppunten, wat van invloed is op de toegangstijden. Zonder passende richtlijnen komen pagina’s op de „verkeerde“ knooppunten terecht, wat de latentie en het aantal cache-misses verhoogt. Informatie over modi en beleidsregels vind je onder NUMA-richtlijnen, inclusief praktijkgerichte startparameters. Voor grote DB-processen stel ik voorkeursknooppunten in en controleer ik de interleaving, zodat geheugentoegangen lokale blijven. De wisselwerking met vm.max_map_count heeft een positief effect wanneer processen veel mappings krijgen via consistente NUMA-strategieën.
Hoe de VMA’s tot stand komen – en waarom ze kunnen ontploffen
Ik onderscheid drie belangrijke bronnen voor VMA’s: (1) aan bestanden gekoppelde toewijzingen (bijv. gegevens- en indexsegmenten van Elasticsearch/OpenSearch), (2) anonieme mappings via allocators (glibc, jemalloc, tcmalloc) en (3) stacks voor threads. Veel kleine shared objects, JIT-code (bijv. in JVM's) en gefragmenteerde toewijzingspatronen zorgen voor extra gebieden. Elke thread heeft minstens één stack-VMA; naarmate het aantal werkthreads toeneemt, groeit ook het aantal VMA’s. Dit verklaart waarom systemen bij dezelfde hoeveelheid gegevens, maar met meer threads/plugins, sneller tegen hun grenzen aanlopen.
Belangrijk: ik maak onderscheid tussen „veel opslagruimte“ en „veel mappings“. Grote, aaneengesloten gebieden vormen zelden een probleem. Het wordt pas kritiek wanneer software vaak voor veel kleine objecten mmap gebruikt (allocatorstrategieën), bibliotheken dynamisch laadt of heel veel bestanden tegelijkertijd toewijst.
De overhead per VMA is beperkt (enkele honderden bytes aan beheersgegevens). Een hogere drempelwaarde vergroot de theoretisch mogelijke structuren zonder het RAM-geheugen te belasten, zolang processen er geen gebruik van maken. Pas wanneer er daadwerkelijk honderdduizenden tot miljoenen VMA’s ontstaan, wordt de beheerslast voor de kernel meetbaar merkbaar.
Meetmethoden verdiepen: pieken nauwkeurig registreren
- Ik voer metingen uit op verschillende tijdstippen van de dag en tijdens piekbelasting (batch-processen, herindexering, onderhoudsvensters).
- Ik houd niet alleen één proces in de gaten, maar de volledige reeks kritieke diensten (DB, sidecars, back-up-/monitoringagenten).
- Om reproduceerbare resultaten te verkrijgen, maak ik onderscheid tussen „koud“ (lege paginacache) en „warm“ (gevulde cache) en leg ik de verschillen vast.
Handige hulpmiddelen om VMA-hotspots te vinden:
# Top-10 processen op basis van het aantal VMA's
for p in /proc/[0-9]*; do
pid=${p##*/}; test -r "$p/maps" || continue
c=$(wc -l /dev/null || echo 0)
cmd=$(tr -d '\0' /dev/null)]}"
done | sort -k2,2nr | head -n 10
Bij clusters analyseer ik de resultaten over meerdere knooppunten en zoek ik naar systematische uitschieters (bijvoorbeeld bepaalde shards, specifieke uitbreidingen of versies). Ik stel waarschuwingen in wanneer een proces >70 % van de grens bereikt of wanneer de piekbelasting een stijgende trend vertoont.
Foutopsporing: typische logberichten en controles
Als de limiet wordt bereikt, zie ik vaak „Cannot allocate memory“, „mmap failed“, „failed to map segment from shared object“ of afgebroken opstartpogingen zonder dat er sprake is van een duidelijk tekort aan RAM. Ik controleer dan het volgende:
grep -i mmap /var/log/*en dienstspecifieke logbestanden met betrekking tot ENOMEM-meldingen- Huidig aantal mappings:
wc -l /proc//maps - Ulimit/Nofile-limieten, omdat veel segmentbestanden niet op een zinvolle manier worden toegewezen als er onvoldoende geopende bestanden zijn
- Aantal threads (
ps -eLo pid,comm,nlwp | sort -k3 -nr | head), aangezien veel threads het VMA-getal verhogen
Ik breng deze bevindingen in verband met belastingprofielen (indexopbouw, Vacuum/Analyze, grootschalige importen). Als het VMA-cijfer duidelijke pieken laat zien bij bepaalde taken, pas ik de reserve daarop aan.
Containers, clouddiensten en orkestratie: bijzondere kenmerken
In containers is vm.max_map_count in de praktijk meestal een Host-instelling. Ik stel de waarde op het knooppunt (bare metal of VM) in via sysctl en laad het permanent via /etc/sysctl.conf of bestanden in /etc/sysctl.d/. In Docker-omgevingen kan ik weliswaar --sysctl Hoewel vm.max_map_count in de praktijk op hostniveau lijkt te werken, plan ik de wijziging dus als een maatregel op knooppuntniveau. In orchestratiessystemen (bijv. Kubernetes) stel ik de waarde bij voorkeur in via Node-Init/Cloud-Init of het machine-image, zodat pods zonder privileges correct opstarten. Belangrijk: ik documenteer de gekozen Compliance-lijn (welk type node bevat welke waarde), zodat de planning en automatische schaalbaarheid consistent blijven.
Automatisering en naleving
Ik leg de instelling „als code“ vast, bijvoorbeeld in configuratiebeheer. Als voorbeeld gebruik ik een sysctl-drop-in-bestand:
# /etc/sysctl.d/90-db-mappings.conf
vm.max_map_count = 524288
De uitrol verloopt op een gecontroleerde manier (staging → canary → brede uitrol). Direct na de implementatie voer ik health checks uit en controleer ik of nieuwe pods/services dezelfde limiet zien. Voor audits leg ik meetgegevens (piek-VMA's, reservefactor, datum van de laatste aanpassing) vast in de operationele documentatie.
Afstemming met Overcommit en OOM-Killer
Een hogere VMA-limiet vermindert het RAM-gebruik niet, maar maakt wel meer mappings mogelijk. Tijdens piekperiodes kan de wisselwerking met overcommit-strategieën en de OOM-killer van belang zijn: als ik meer mappings toestaat, kunnen processen agressiever reserveren. Ik ben daarom van mening dat vm.overcommit_memory en vm.overcommit_ratio in de gaten houden en zorgen voor voldoende reserves (swap/headroom) of strengere overcommit-beleidsregels wanneer workloads de neiging hebben om te worden overboekt. Het doel is een waarschuwingsvenster: in plaats van een abrupte OOM krijg ik in de monitoring tijdig signalen van stijgende foutpercentages/latentie die wijzen op de noodzaak van tegenmaatregelen.
Uitzonderlijke gevallen: 32-bits, veel threads, keuze van de allocator
- 32-bits processen: De virtuele adresruimte is beperkter, waardoor fragmentatie sneller een rol gaat spelen. Een hogere vm.max_map_count lost een tekort aan adresruimte niet op – hier helpen 64-bits builds of een architectuurwijziging.
- Diensten met veel threads: Elke thread heeft minstens één eigen stack-VMA. Als het aantal workers sterk toeneemt, groeit het aantal VMA’s lineair mee. Ik zorg ervoor dat threadpools beperkt zijn en op een zinvolle manier worden geschaald.
- Allocator: Sommige allocators maken gebruik van
mmapte veel voor grote of veel kleine blokken. Bij opvallende VMA-pieken test ik alternatieve allocators of hun afstemmingsopties om het aantal mappings te verminderen. - Gedeelde bibliotheken: Veel kleine, dynamisch geladen modules zorgen ervoor dat het aantal mappings hoog is. Ik ga na of modules kunnen worden samengevoegd of dat onnodige plug-ins kunnen worden verwijderd.
Checklist vóór de wijziging
- De huidige grens vaststellen en documenteren
- Proces-specifieke VMA-pieken over meerdere belastingsvensters meten
- Reserve afleiden (factor 2–4 boven de piek) en staging-tests plannen
- Controleer de bijbehorende limieten (nofile), het aantal threads, THP, swappiness en dirty-ratio's
- Monitoring/waarschuwingen voor VMA-nadering, mmap-fouten en OOM-gebeurtenissen inschakelen
- Rollout- en rollback-pad definiëren (Canary, onderhoudsvenster, sysctl.d-bestanden)
- De consistentie van clusters en knooppunten waarborgen en documenteren
Planning voor clusters en groei
Ik houd niet alleen rekening met de huidige situatie, maar ook met de verwachte groei van de gegevens en indexen. Nieuwe functies, meer klanten of extra uitbreidingen zorgen vaak voor een toename van het aantal Koppelingen. Daarom houd ik rekening met een buffer boven de waargenomen piek en leg ik de beslissing duidelijk vast. In clusters houd ik de waarden gesynchroniseerd, zodat knooppunten identiek reageren en failover niet op limieten strandt. Regelmatige controles tijdens onderhoudsvensters waarborgen de Continuïteit de instellingen.
Kort samengevat: veilige instellingen voor databaseservers
Ik controleer de huidige limiet, meet het aantal VMA’s onder belasting en stel vm.max_map_count in met een reserve. Voor veel database- en zoekworkloads werkt 262.144 als Startwaarde en 1.048.576 als bovenste niveau, indien meetwaarden en groei dat vereisen. De wijziging levert geen onmiddellijke prestatieverbetering op, maar voorkomt fouten zodra er zeer veel mappings nodig zijn. Stabiliteit ontstaat wanneer ik logs, metrics en gerelateerde kernelparameters in hun onderlinge samenhang bekijk. Zo blijft de Databasebeheer robuust, goed te plannen en klaar voor toenemende belastingen.


