Jag förklarar hur du vm.max_map_antal förstår, mäter och justerar på Linux-databasserver utan risk. Artikeln visar konkreta steg, typiska värden och beprövade kontroller för att säkerställa att PostgreSQL, MySQL/MariaDB, Elasticsearch eller OpenSearch fungerar smidigt även under hög belastning.
Centrala punkter
- Funktion: Övre gräns för virtuella minnesområden (VMA) per process
- Relevans: Databaser, söksystem, Java-stackar med många mappningar
- Symptom: „Cannot allocate memory“, startfel, avbrott
- Praktiska värden: 262 144 till 1 048 576 för stora arbetsbelastningar
- Förfarande: Mäta behovet, öka kapaciteten med en reserv, integrera övervakning
Vad betyder vm.max_map_count?
Kärnparametern anger hur många Lagringsområden (VMAs) som en enskild process får skapa som maximalt. Varje mmap-operation, varje laddat delat objekt, många allokeringar och block av delat minne ökar detta antal. Jag begränsar därmed inte mängden RAM, utan Antal de separata områdena i det virtuella adressutrymmet. Stora processer kan utnyttja mycket minne med ett fåtal stora mappningar, medan fragmenterade arbetsbelastningar snabbt når gränsen genom många små mappningar. Den som kör minneskrävande programvara måste känna till denna övre gräns, annars upptäcker man felet först när systemet belastas.
Varför databasserver drabbas av detta
Databaser och söktjänster utnyttjar i hög grad mmap, delat minne, cacher och ett stort antal bibliotek. PostgreSQL-instanser med många tillägg och anslutningar, MySQL/MariaDB med plugins eller Elasticsearch/OpenSearch med många indexsegment genererar många VMA:er. Om antalet närmar sig gränsvärdet misslyckas ytterligare mappningar och processen rapporterar Fel i minnet. Det är just då som tjänsterna inte startar, avbryts under belastning eller förlorar noder i kluster. Jag förhindrar sådant beteende genom att i förväg fastställa den nödvändiga övre gränsen och ställa in den korrekt.
Symtom och risker vid felaktig inställning
De vanligaste tecknen på en för låg gräns är Startfel trots ledigt minne. Tjänster som Elasticsearch visar felmeddelandet „Cannot allocate memory“, trots att maskinen fortfarande har lediga resurser. Det uppstår även sporadiska processavbrott så snart det internt krävs fler VMA:er än vad som är tillåtet. Ett för högt värde medför i regel inga problem, eftersom kärnan bara använder lite mer Administration krävs för vm_area_structs. Detta blir först relevant när processer faktiskt skapar miljoner mappningar, vilket typiska databasarbetsbelastningar oftast inte når upp till.
Praktiska värden och tolkning
Många distributioner använder konservativa standardvärden på omkring 65 536, vilket räcker för enkla tjänster men blir otillräckligt för sök- och analysbelastningar. I typiska hostingmiljöer använder jag 262 144 som ett stabilt utgångsvärde för större stackar. För mycket stora Elasticsearch-/OpenSearch-instanser planerar jag med 1 048 576, förutsatt att mätvärdena pekar i den riktningen. Ett högre värde ger ingen direkt Prestandaförbättring, det förhindrar fel när många mappningar krävs. Dokumentationen för Linux-kärnan och vanliga praktiska rapporter bekräftar denna bedömning.
| Apptyp | VMA-profil (typisk) | Startvärde för vm.max_map_count | Övre gräns (vid behov) |
|---|---|---|---|
| Liten databas / Verktyg | låg-medel | 65.536 | 262.144 |
| PostgreSQL/MySQL | medel-hög | 262.144 | 524.288 |
| Elasticsearch/OpenSearch | hög – mycket hög | 262.144 | 1.048.576 |
| Stora Java-stackar | medel-hög | 262.144 | 524.288 |
Mäta det aktuella behovet
Innan jag gör någon ändring kontrollerar jag den aktuella Inställning med sysctl vm.max_map_count eller per cat /proc/sys/vm/max_map_count. Därefter beräknar jag det faktiska behovet för en process med wc -l /proc//maps, helst under belastning. Detta värde varierar beroende på moduler, cacheminnen och arbetsbelastning, därför övervakar jag det under flera belastningsperioder. Så snart toppen når 50–70 % av gränsen sätter jag in en lämplig reserv. På så sätt fattar jag ett välgrundat Beslut istället för att gissa.
Så här justerar jag vm.max_map_count på ett säkert sätt
För teständamål ställer jag in värdet tillfälligt med sysctl -w vm.max_map_count=262144, vilket ger omedelbar effekt men försvinner vid omstart. För kontinuerlig drift anger jag värdet i /etc/sysctl.conf och ladda ner den med sysctl --system ny, så att den Konfiguration kvar. Stora sökkluster eller mycket modulära databasstackar drar nytta av mellan 524 288 och 1 048 576, beroende på mätning. Jag ökar stegvis, kontrollerar loggarna och övervakar mätvärdena för lagringsanvändningen. På så sätt håller jag det Risk är låg under drift och bygger upp en förutsägbar buffert.
Bästa praxis för produktiva miljöer
Jag mäter upprepade gånger under normal belastning och toppbelastning, istället för att förlita mig på engångsvärden. Jag sätter inte den övre gränsen precis vid toppvärdet, utan med en faktor på två till fyra över den observerade toppen. I kluster väljer jag konsekventa värden så att alla noder reagerar på samma sätt och ingen Utbrytare generera. Övervakningen kontrollerar fel relaterade till mmap/malloc samt utvecklingen av antalet VMA per process. Innan driftsättning testar jag nya Värden i staging med jämförbar belastning.
Samverkan med andra kärnparametrar: swappiness, dirty ratios, filgränser
vm.max_map_count förekommer aldrig isolerat, eftersom andra inställningsparametrar påverkar det Beteende likaså. Swappiness avgör hur aggressivt systemet placerar sidor i swap-utrymmet, vilket kan öka latensen. Dirty Ratios styr när ändrade sidor flyttas tillbaka till hårddisken och därmed kan jämna ut eller förvärra IO-toppar. Gränsvärden för öppna filer avgör hur många filer och socklar som databaser får hålla öppna parallellt. Jag kontrollerar dessa Parametrar tillsammans, så att det inte uppstår någon ny flaskhals.
Genomföra riktade kontroller av Transparenta Huge Pages
THP påverkar minneshanteringen genom att sammanfoga stora sidor och därmed förändra åtkomstmönstren. Databaser reagerar känsligt på THP beroende på arbetsbelastningen, vilket är anledningen till att jag kontrollerar status och läge och ställer in dem på „madvise“ eller „never“ när latensen ökar. Mer information om effekter och finjustering finns i mitt inlägg om Transparenta stora sidor sammanfattat. Det är viktigt att underbygga förändringen med mätvärden och inte genomföra den i blindo. På så sätt förblir Lagringsbeteende förståeligt och reproducerbart.
Att förstå VFS-cache-utskrift
VFS-cachen lagrar metadata och filinnehåll i arbetsminnet och konkurrerar därmed med databassidor. Med parametern för VFS-cache-utskrift påverkar jag hur snabbt systemet frigör denna cache. För högt tryck kan öka IO-belastningen, medan för lågt tryck tränger undan databascacher och försämrar latensen. Jag justerar i små steg och mäter effekterna på sidcache-träfffrekvensen, IO-väntetiden och genomströmningen. Detta Finjustering har ofta en större effekt än väntat när databaser och filsystem är tätt integrerade.
NUMA-riktlinjer och databaser
NUMA-arkitekturer fördelar minnet över noder, vilket påverkar åtkomsttiderna. Utan lämpliga riktlinjer hamnar sidor på „fel“ noder, vilket ökar latensen och antalet cache-missar. Information om lägen och riktlinjer finns under NUMA-riktlinjer, inklusive praktiska startparametrar. För stora DB-processer anger jag prioriterade noder och kontrollerar interleaving så att minnesåtkomst lokal förblir. Samverkan med vm.max_map_count har en positiv effekt när processer tilldelas många mappningar via konsekventa NUMA-strategier.
Hur VMA-priserna tillkommer – och varför de kan explodera
Jag skiljer mellan tre huvudkällor för VMA:er: (1) filbundna mappningar (t.ex. data- och indexsegment från Elasticsearch/OpenSearch), (2) anonyma mappningar via allokatorer (glibc, jemalloc, tcmalloc) och (3) stackar för trådar. Många små delade objekt, JIT-kod (t.ex. i JVM:er) och fragmenterade allokeringsmönster skapar ytterligare områden. Varje tråd har minst en stack-VMA; om antalet arbetartrådar ökar, ökar också antalet VMA:er. Detta förklarar varför system med samma datamängd men fler trådar/plugins snabbare når sina gränser.
Viktigt: Jag skiljer mellan „mycket lagringsutrymme“ och „många mappningar“. Stora, sammanhängande områden utgör sällan ett problem. Det blir kritiskt när programvaran ofta hanterar många små objekt mmap använder (allokeringsstrategier), laddar bibliotek dynamiskt eller mappar ett mycket stort antal filer parallellt.
Överhuvudkostnaden per VMA är måttlig (några hundra byte administrationsdata). Ett högre gränsvärde utökar de teoretiskt möjliga strukturerna utan att belasta RAM-minnet, så länge processerna inte använder dem. Först när det verkligen uppstår hundratusentals till miljoner VMA:er blir kärnans administrationsarbete märkbart.
Fördjupa kunskaperna om mätmetoder: Registrera toppvärden på ett säkert sätt
- Jag mäter vid flera olika tidpunkter under dagen och under perioder med hög belastning (batchkörningar, omindexering, underhållsfönster).
- Jag övervakar inte bara en process, utan hela uppsättningen av kritiska tjänster (databas, sidecars, backup-/övervakningsagenter).
- För att få reproducerbara resultat skiljer jag mellan „kallt“ (tom sidcache) och „varmt“ (fylld cache) och dokumenterar skillnaderna.
Praktiska verktyg för att hitta VMA-hotspots:
# Topp 10-processer efter antal VMA
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
När det gäller kluster analyserar jag resultaten från flera noder och letar efter systematiska avvikelser (t.ex. vissa shards, specifika tillägg eller versioner). Jag ställer in larm om en process når >70 % av gränsvärdet eller om toppbelastningen visar en trendmässig ökning.
Felsökning: typiska loggmeddelanden och kontroller
När gränsen nås ser jag ofta meddelanden som „Cannot allocate memory“, „mmap failed“, „failed to map segment from shared object“ eller att systemet avbryter uppstarten utan att det finns någon uppenbar brist på RAM-minne. Då kontrollerar jag följande:
grep -i mmap /var/log/*och tjänstespecifika loggar om ENOMEM-meddelanden- Aktuellt antal mappningar:
wc -l /proc//maps - Ulimit/Nofile-gränser, eftersom många segmentfiler inte kan mappas på ett meningsfullt sätt utan tillräckligt många öppna filer
- Antal trådar (
ps -eLo pid,comm,nlwp | sort -k3 -nr | head), eftersom många trådar ökar VMA-värdet
Jag korrelerar dessa resultat med belastningsprofiler (indexbyggnader, Vacuum/Analyze, stora importer). Om VMA-värdet visar tydliga toppar vid specifika jobb dimensionerar jag reservkapaciteten därefter.
Containrar, molntjänster och orkestrering: Särdrag
I containrar finns vm.max_map_antal i praktiken oftast en Värdinställning. Jag ställer in värdet på noden (bare metal eller VM) via sysctl och ladda ner den permanent via /etc/sysctl.conf eller filer i /etc/sysctl.d/. I Docker-miljöer kan jag visserligen --sysctl Ange att vm.max_map_count i praktiken verkar på hela värden – jag planerar därför att genomföra ändringen som en åtgärd på nodnivå. I orkestratorer (t.ex. Kubernetes) ställer jag helst in värdet via Node-Init/Cloud-Init eller maskinavbildning, så att podar utan privilegier startar korrekt. Viktigt: Jag dokumenterar det valda Compliance-linje (vilken nodtyp har vilket värde), så att schemaläggningen och den automatiska skalningen förblir konsekventa.
Automatisering och regelefterlevnad
Jag sparar inställningen „som kod“, till exempel i konfigurationshanteringen. Som exempel använder jag en sysctl-drop-in-fil:
# /etc/sysctl.d/90-db-mappings.conf
vm.max_map_count = 524288
Utrullningen sker på ett kontrollerat sätt (Staging → Canary → bred utrullning). Omedelbart efter driftsättningen kontrollerar jag med hjälp av hälsokontroller och verifierar att nya podar/tjänster ser samma gräns. För revisioner dokumenterar jag mätdata (topp-VMA:er, reservfaktor, datum för senaste justeringen) i driftsdokumentationen.
Justering med Overcommit och OOM-Killer
En högre VMA-gräns minskar inte RAM-användningen, men den tillåter fler mappningar. Vid hög belastning kan samspelet med overcommit-strategier och OOM-killer bli relevant: Om jag tillåter fler mappningar kan processerna reservera minne på ett mer aggressivt sätt. Jag anser därför vm.overcommit_memory och vm.overcommit_ratio Håll koll på detta och se till att det finns tydliga reserver (swap/headroom) eller striktare överbokningsregler om arbetsbelastningarna tenderar att överbelastas. Målet är ett förvarningsfönster: istället för ett plötsligt OOM-fel får jag tidigt signaler om stigande felfrekvenser och ökad latens i övervakningen, vilket indikerar att åtgärder behövs.
Extrema fall: 32-bitars, många trådar, val av allokator
- 32-bitarsprocesser: Det virtuella adressutrymmet är mindre, vilket gör att fragmentering snabbare blir ett problem. Ett högre värde på vm.max_map_count löser inte problemet med brist på adressutrymme – här hjälper 64-bitarsversioner eller ett byte av arkitektur.
- Tjänster med många trådar: Varje tråd har minst en egen stack-VMA. Om antalet arbetare ökar kraftigt växer antalet VMA:er linjärt i takt med detta. Jag ser till att trådpoolerna är begränsade och skalas på ett rimligt sätt.
- Allokator: Vissa allokatorer använder
mmapöverdrivet för stora eller många små block. Vid påfallande VMA-toppar testar jag alternativa allokatorer eller deras inställningsalternativ för att minska antalet mappningar. - Delade bibliotek: Många små, dynamiskt laddade moduler gör att antalet mappningar ökar. Jag undersöker om det går att slå samman moduler eller ta bort onödiga plugins.
Checklista inför ändringen
- Fastställa och dokumentera den aktuella gränsen
- Mäta processspecifika VMA-toppar över flera belastningsfönster
- Beräkna reservvärdet (faktor 2–4 över toppvärdet) och planera staging-tester
- Kontrollera tillhörande gränsvärden (nofile), antal trådar, THP, swappiness och dirty-ratio
- Aktivera övervakning/varningar för VMA-närhet, mmap-fel och OOM-händelser
- Definiera utrullnings- och återställningsvägar (Canary, underhållsfönster, sysctl.d-filer)
- Säkerställa och dokumentera kluster-/nodkonsistens
Planering för kluster och tillväxt
Jag tar inte bara hänsyn till nuläget, utan även till den förväntade tillväxten av data och index. Nya funktioner, fler kunder eller ytterligare utbyggnader leder ofta till att antalet Avstämningar. Därför räknar jag med en marginal utöver den observerade toppen och dokumenterar beslutet noggrant. I kluster håller jag värdena synkroniserade så att noderna reagerar på samma sätt och så att failover inte misslyckas på grund av gränsvärden. Regelbundna kontroller under underhållsfönster säkerställer att Kontinuitet inställningarna.
I korthet: säkra inställningar för databasserver
Jag kontrollerar det aktuella gränsvärdet, mäter antalet VMA:er under belastning och ställer in vm.max_map_count med en reserv. För många databas- och sökbelastningar fungerar 262 144 som Startvärde och 1 048 576 som övre gräns, om mätvärden och tillväxt kräver det. Ändringen ger ingen omedelbar prestandaförbättring, men den förhindrar fel när ett mycket stort antal mappningar krävs. Stabilitet uppnås när jag betraktar loggar, mätvärden och relaterade kärnparametrar tillsammans. På så sätt förblir Databasdrift tålig, planerbar och redo för ökande belastningar.


