Notiz zum Skript onconfig_memory.py. Es setzt die Speicherzeilen einer Informix-onconfig aus dem RAM des Hosts, legt die Bufferpools fest und schaltet die HugePage-Reservierung aus.
Die onconfig wird erst nach einem Neustart von Informix gelesen. Die Sysctl-Änderung gilt sofort, soweit der Kernel HugePages freigeben kann.
sudo python3 onconfig_memory.py [RAM_GB] [ONCONFIG] python3 onconfig_memory.py --self-check
RAM_GB ist optional und muss eine ganze Zahl ohne Einheit sein. 32 wird als 32 GiB gelesen und intern in Kibibyte umgerechnet (32 GiB = 33554432 KiB). 32.5, 32GB oder ein negativer Wert gelten nicht als Zahl. Dann nimmt das Skript MemTotal aus /proc/meminfo. Diese Angabe steht im Kernel bereits in Kibibyte.
ONCONFIG ist optional. Standard ist /opt/IBM/informix/etc/onconfig.local. Die Argumente stehen fest: zuerst RAM, danach der Pfad.
–self-check darf an beliebiger Stelle der Argumente stehen. Dann prüft das Skript nur die Formel für 8 GiB und 64 GiB, druckt self-check ok und beendet sich mit Exit 0. Es wird keine Datei angefasst.
Unter 4 GiB RAM endet der Lauf mit Exit 1, bevor etwas geschrieben wird. Genau 4 GiB läuft durch. Der Benutzer informix muss existieren (id -g informix). Fehlt er, bricht Python ab, ebenfalls bevor etwas geschrieben wird. Root-Rechte, Schreibrechte und ob Informix online ist, prüft das Skript nicht. Es gibt keinen Probelauf.
Alle Teilungen runden ab. Für ein ganzes GiB-Vielfaches sind die Anteile exakt.
| Anteil | Rechnung aus dem RAM |
|---|---|
| 2K-Pool | 40/64, also 62,5 % |
| 16K-Pool | 10/64, also 15,625 % |
| erstes virtuelles Segment | 4/64, also 6,25 % |
| Summe | 54/64, also 84,375 % |
Der Rest von 10/64 bleibt für das Betriebssystem, den Overhead im Resident-Segment und für später nachgelegte virtuelle Segmente. Diesen Rest reserviert das Skript nicht.
Die Poolgrößen stehen in der onconfig in Megabyte, SHMVIRTSIZE in Kilobyte. Kontrolle, dieselben Werte wie im Self-Check:
| RAM | 2K-Pool | 16K-Pool | SHMVIRTSIZE |
|---|---|---|---|
| 8 GiB | 5120 MB | 1280 MB | 524288 KB |
| 64 GiB | 40960 MB | 10240 MB | 4194304 KB |
Bei 4 GiB sind es 2560 MB, 640 MB und 262144 KB. Die drei Größen zusammen bleiben unter dem RAM.
SHMADD ist fest 256000 KB, EXTSHMADD fest 8192 KB. Beides hängt nicht vom RAM ab.
Vorher liegt eine bytegenaue Kopie neben der Datei: onconfig.bak_YYYYMMDD_HHMMSS. Zwei Läufe in derselben Sekunde treffen denselben Namen. Die zweite Kopie enthält dann schon die erste Änderung.
Bestehende Zeilen SHMVSIZE mit Wert werden auskommentiert. Alle Zeilen, die am Zeilenanfang mit BUFFERPOOL beginnen, werden auskommentiert. Danach setzt oder ergänzt das Skript:
SHMTOTAL 0 SHMADD 256000 EXTSHMADD 8192 RESIDENT 1 SHMVIRTSIZE <Kilobyte aus 4/64 des RAM> SHMVIRT_ALLOCSEG 0,3 BUFFERPOOL size=2K,extendable=0,start_memory=<MB>MB,memory=<MB>MB BUFFERPOOL size=16K,extendable=0,start_memory=<MB>MB,memory=<MB>MB
start_memory und memory sind gleich. extendable=0 lässt die Pools nicht wachsen. lrus, lru_min_dirty, lru_max_dirty und buffers schreibt das Skript nicht.
Ein zweiter Lauf kommentiert die zuvor geschriebenen Poolzeilen und hängt ein neues Paar an. Die alten Zeilen bleiben als Kommentar in der Datei.
Ersetzt wird nur die erste Zeile eines Parameters, die am Zeilenanfang steht. Eine eingerückte Zeile bleibt stehen, das Skript hängt eine zweite Zeile an. Informix würde dann beide sehen.
Erst nach dem Schreiben der onconfig. Scheitert ein späterer Schritt, ist die onconfig schon neu.
/etc/security/limits.d/99-informix-memlock.conf wird vollständig ersetzt. Inhalt nur noch informix soft memlock unlimited und informix hard memlock unlimited. Vorhandene andere Limits in dieser Datei sind danach weg./etc/profile.d/profile.local.sh wird export IFX_LARGE_PAGES=0 gesetzt oder angehängt. Fehlt die Datei, wird sie nicht angelegt und die Variable bleibt dort ungesetzt./etc/sysctl.d/99-informix-hugepages.conf wird vollständig ersetzt durch vm.nr_hugepages = 0 und vm.hugetlb_shm_group mit der GID von informix. Anschließend lädt sysctl -p diese Datei. Den Rückgabewert wertet das Skript nicht aus.
Bleibt HugePages_Total danach größer als 0, gibt es einen Hinweis auf der Konsole und der Lauf endet trotzdem erfolgreich. Belegte HugePages gibt der Kernel nicht frei, solange Informix sie hält. Das Skript leert keinen Cache und fährt Informix nicht herunter.
Abschlusszeile für den Start:
export IFX_LARGE_PAGES=0 ulimit -l unlimited oninit
memlock aus der Limits-Datei gilt für neue Anmeldungen. Ein bereits laufender oninit bekommt sie nicht. ulimit -l muss in der Startumgebung stehen.
SHMTOTAL 0 ist der Herstellerstandard: keine Obergrenze für Resident-, Virtual-, Communication- und Extension-Anteile.
RESIDENT 1 hält das Resident-Segment im RAM. Darin liegen die Bufferpools. Dafür braucht oninit memlock.
SHMVIRTSIZE ist das erste virtuelle Segment beim Start. Weitere Segmente legt Informix in der Größe SHMADD bzw. EXTSHMADD an.
SHMVIRT_ALLOCSEG 0,3 ist die Vorgabe aus onconfig.std. Die 0 bedeutet laut IBM: der Server legt ein Shared-Memory-Segment an, wenn er es braucht. Ein Wert von 0,40 bis 0,99 wäre ein Füllgrad für eine vorausschauende Anlage, ein Wert von 256 bis 10000000 eine Restmenge in Kilobyte. Die 3 ist nur die Alarmstufe, wenn die Anlage scheitert (Klasse 24, Ereignis 24003). Der Alarm wiederholt sich alle 30 Minuten. Einen onconfig-Wert, der diese Bedarfsanlage abschaltet, gibt es nicht.
Zusammen mit SHMTOTAL 0 hat die Bedarfsanlage keine Informix-Decke. Jedes weitere Segment vergrößert den virtuellen Anteil um 256000 KB bzw. 8192 KB, solange das Betriebssystem den Speicher gibt. Ist der RAM aufgebraucht, kann der OOM-Killer oninit beenden. RESIDENT 1 verschärft das, weil die Bufferpools nicht ausgelagert werden können.
Auch eine nachträglich gesetzte SHMTOTAL-Decke schließt den Pfad nicht. Page Cleaner und Checkpoint dürfen sie überschreiten. Das steckt im Server. Schlägt die Anlage fehl, steht im Nachrichtenlog unter anderem No memory available for page cleaners, und die verursachenden Transaktionen werden zurückgesetzt. Fehlt dann Betriebssystemspeicher, bleibt der OOM-Killer möglich.
IBM Informix 12.10: SHMVIRT_ALLOCSEG. Dieselbe Beschreibung bei HCL: SHMVIRT_ALLOCSEG und Shared-memory size.
grep -E '^(SHMTOTAL|SHMADD|EXTSHMADD|RESIDENT|SHMVIRTSIZE|SHMVIRT_ALLOCSEG|BUFFERPOOL)' \ /opt/IBM/informix/etc/onconfig.local grep -E '^(MemTotal|HugePages_Total):' /proc/meminfo onstat -g seg
Nach dem Neustart trägt das Resident-Segment die beiden festen Pools. Das erste virtuelle Segment hat die Größe von SHMVIRTSIZE. Jedes weitere virtuelle Segment in onstat -g seg ist die Bedarfsanlage und der Weg in den OOM.
Informix, onconfig, SHMTOTAL, SHMADD, EXTSHMADD, SHMVIRTSIZE, SHMVIRT_ALLOCSEG, BUFFERPOOL, RESIDENT, memlock, HugePages, OOM