Configurarea opțiunilor kernelului Linux pentru a optimiza PostgreSQL

Configurarea opțiunilor kernelului Linux pentru a optimiza PostgreSQL Performanța optimă PostgreSQL depinde de parametrii sistemului de operare definiți corect. Setările nucleului sistemului de operare prost configurate pot duce la performanțe slabe ale serverului de baze de date. Prin urmare, este imperativ ca aceste setări să fie configurate în funcție de serverul bazei de date și volumul de lucru al acestuia. În această postare, vom discuta despre câțiva parametri importanți ai nucleului Linux care pot afecta performanța serverului de baze de date și modul de configurare a acestora.

SHMMAX / SHMALL

SHMMAX este un parametru de nucleu utilizat pentru a determina dimensiunea maximă a unui singur segment de memorie partajată pe care un proces Linux îl poate aloca. Înainte de versiunea 9.2, PostgreSQL folosea System V (SysV), care necesită setarea SHMMAX. După 9.2, PostgreSQL a trecut la memoria partajată POSIX. Deci acum sunt necesari mai puțini octeți de memorie partajată System V.

Înainte de versiunea 9.3, SHMMAX era cel mai important parametru al nucleului. Valoarea SHMMAX este specificată în octeți.

În mod similar, SHMALL este un alt parametru al nucleului folosit pentru a determina
volumul de pagini cu memorie partajată la nivelul întregului sistem. Pentru a vizualiza valorile curente SHMMAX, SHMALL sau SHMMIN, utilizați comanda ipcs.

Detalii SHM* - Linux

$ ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 1073741824
max total shared memory (kbytes) = 17179869184
min seg size (bytes) = 1

Detalii SHM* - MacOS X

$ ipcs -M
IPC status from  as of Thu Aug 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(max shared memory segment size)
	shmmin:       1	(min shared memory segment size)
	shmmni:      32	(max number of shared memory identifiers)
	shmseg:       8	(max shared memory segments per process)
	shmall:    1024	(max amount of shared memory in pages)

PostgreSQL folosește Sistemul V IPC pentru a aloca memorie partajată. Acest parametru este unul dintre cei mai importanți parametri ai nucleului. Ori de câte ori primiți următoarele mesaje de eroare, înseamnă că aveți o versiune mai veche de PostgreSQL și valoarea dvs. SHMMAX este foarte mică. Se așteaptă ca utilizatorii să ajusteze și să crească valoarea în funcție de memoria partajată pe care intenționează să o utilizeze.

Posibile erori de configurare greșită

Dacă SHMMAX nu este configurat corect, este posibil să primiți o eroare când încercați să inițializați un cluster PostgreSQL folosind comanda initdb.

initdb Eșec
DETAIL: Failed system call was shmget(key=1, size=2072576, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. 
You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 2072576 bytes),
reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration. child process exited with exit code 1

De asemenea, este posibil să primiți o eroare la pornirea serverului PostgreSQL folosind comanda pg_ctl.

pg_ctl Eșec
DETAIL: Failed system call was shmget(key=5432001, size=14385152, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.

You can either reduce the request size or reconfigure the kernel with larger SHMMAX.; To reduce the request size (currently 14385152 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration.

Înțelegerea diferențelor dintre definiții

Definirea parametrilor SHMMAX/SHMALL este ușor diferită pe Linux și MacOS X:

  • Linux: kernel.shmmax, kernel.shmall
  • MacOS X: kern.sysv.shmmax, kern.sysv.shmall

Echipă sysctl poate fi folosit pentru a modifica temporar valoarea. Pentru a seta valori constante, adăugați o intrare la /etc/sysctl.conf. Detaliile sunt mai jos.

Modificarea setărilor kernelului pe MacOS X

# Get the value of SHMMAX
sudo sysctl kern.sysv.shmmax
kern.sysv.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kern.sysv.shmall 
kern.sysv.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kern.sysv.shmmax=16777216
kern.sysv.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kern.sysv.shmall=16777216
kern.sysv.shmall: 4096 -> 16777216

Modificarea parametrilor kernelului pe Linux

# Get the value of SHMMAX
sudo sysctl kernel.shmmax
kernel.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kernel.shmall
kernel.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kernel.shmmax=16777216
kernel.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kernel.shmall=16777216
kernel.shmall: 4096 -> 16777216

Nu uita: Pentru a face modificările permanente, adăugați aceste valori la /etc/sysctl.conf

Pagini uriașe

Linux folosește pagini de memorie de 4 KB în mod implicit, BSD folosește pagini de memorie de XNUMX KB. Super Pagini, iar pe Windows - Pagini mari. O pagină este o bucată de memorie RAM alocată unui proces. Un proces poate avea mai multe pagini în funcție de cerințele de memorie. Cu cât un proces necesită mai multă memorie, cu atât este alocată mai multe pagini. Sistemul de operare menține un tabel de alocare a paginilor pentru procese. Cu cât dimensiunea paginii este mai mică, cu atât tabelul este mai mare, cu atât este nevoie de mai mult pentru a găsi o pagină în acel tabel de pagini. Prin urmare, paginile mari permit utilizarea unor cantități mari de memorie cu o supraîncărcare redusă; mai puține vizualizări de pagină, mai puține erori de pagină, operațiuni de citire/scriere mai rapide pe buffer-uri mai mari. Rezultatul este o performanță îmbunătățită.

PostgreSQL acceptă numai pagini mari pe Linux. În mod implicit, Linux folosește pagini de memorie de 4 KB, așa că în cazurile în care sunt prea multe operații de memorie, este necesar să setați pagini mai mari. Se observă creșterea performanței atunci când se utilizează pagini mari de 2 MB și până la 1 GB. Dimensiunea mare a paginii poate fi setată în momentul pornirii. Puteți verifica cu ușurință parametrii paginii mari și utilizarea lor pe mașina dvs. Linux folosind comanda cat /proc/meminfo | grep -i imens.

Obținerea de informații despre paginile mari (numai Linux)

Note: This is only for Linux, for other OS this operation is ignored$ 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

În acest exemplu, deși dimensiunea paginii mari este setată la 2048 (2 MB), numărul total de pagini mari este setat la 0. Aceasta înseamnă că paginile mari sunt dezactivate.

Script pentru determinarea numărului de pagini mari

Acest script simplu returnează numărul necesar de pagini mari. Rulați scriptul pe serverul dvs. Linux în timp ce PostgreSQL rulează. Asigurați-vă că pentru variabila de mediu $PGDATA Directorul de date PostgreSQL este specificat.

Obținerea numărului de pagini mari necesare

#!/bin/bash
pid=`head -1 $PGDATA/postmaster.pid`
echo "Pid:            $pid"
peak=`grep ^VmPeak /proc/$pid/status | awk '{ print $2 }'`
echo "VmPeak:            $peak kB"
hps=`grep ^Hugepagesize /proc/meminfo | awk '{ print $2 }'`
echo "Hugepagesize:   $hps kB"
hp=$((peak/hps))
echo Set Huge Pages:     $hp

Ieșirea scriptului arată astfel:

Ieșire script

Pid:            12737
VmPeak:         180932 kB
Hugepagesize:   2048 kB
Set Huge Pages: 88

Valoarea recomandată pentru paginile mari este 88, așa că ar trebui să o setați la 88.

Instalarea paginilor mari

sysctl -w vm.nr_hugepages=88

Verificați paginile mari acum, veți vedea că paginile mari nu sunt folosite (HugePages_Free = HugePages_Total).

Pagini mari revizuite (numai Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       88
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

Acum setați parametrul huge_pages la „on” în $PGDATA/postgresql.conf și reporniți serverul.

Încă o dată, informații despre paginile mari (numai Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       81
HugePages_Rsvd:       64
HugePages_Surp:        0
Hugepagesize:       2048 kB

Acum puteți vedea că sunt folosite foarte puține pagini mari. Să încercăm acum să adăugăm câteva date în baza de date.

Unele operațiuni de bază de date pentru reciclarea paginilor mari

postgres=# CREATE TABLE foo(a INTEGER);
CREATE TABLE
postgres=# INSERT INTO foo VALUES(generate_Series(1,10000000));
INSERT 0 10000000

Să vedem dacă acum folosim pagini mai mari decât înainte.

Mai multe informații pe paginile mari (numai Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       18
HugePages_Rsvd:        1
HugePages_Surp:        0
Hugepagesize:       2048 kB

Acum puteți vedea că majoritatea paginilor mari sunt folosite.

Notă: Valoarea estimată pentru HugePages utilizată aici este foarte mică, ceea ce nu este o valoare normală pentru o mașină care rulează un mediu de produs. Estimați numărul necesar de pagini pentru sistemul dvs. și setați-le în consecință în funcție de încărcare și resurse.

vm.schimbări

vm.schimbări este un alt parametru al nucleului care poate afecta performanța bazei de date. Această opțiune este folosită pentru a controla comportamentul swappiness (schimbarea paginilor în și în afara memoriei) în Linux. Valoarea variază de la 0 la 100. Determină câtă memorie va fi paginată sau paginată. Zero înseamnă nici un schimb și 100 înseamnă schimb agresiv.

Puteți obține performanțe bune setând valori mai mici.

Setarea acestuia la 0 pe nucleele mai noi poate determina OOM Killer (procesul de curățare a memoriei Linux) să distrugă procesul. Prin urmare, este sigur să îl setați la 1 dacă doriți să minimizați schimbarea. Valoarea implicită în Linux este 60. O valoare mai mare face ca MMU (unitatea de gestionare a memoriei) să utilizeze mai mult spațiu de swap decât RAM, în timp ce o valoare mai mică păstrează mai multe date/cod în memorie.

O valoare mai mică este un pariu bun pentru o performanță îmbunătățită în PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Aplicațiile dobândesc memorie și o eliberează atunci când nu mai este necesară. Dar, în unele cazuri, aplicația primește prea multă memorie și nu o eliberează. Acest lucru poate provoca un criminal OOM. Iată valorile posibile ale parametrilor vm.overcommit_memory cu o descriere pentru fiecare:

  1. Supracompunere euristică (implicit); euristică bazată pe nucleu
  2. Permiteți oricum supraangajarea
  3. Nu exagerați, nu depășiți rata de supracompunere.

URL: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

vm.overcommit_ratio — procentul de RAM disponibil pentru supraîncărcare. O valoare de 50% pe un sistem cu 2 GB RAM poate aloca până la 3 GB RAM.

O valoare de 2 pentru vm.overcommit_memory oferă performanțe mai bune pentru PostgreSQL. Această valoare maximizează utilizarea RAM a procesului serverului fără niciun risc semnificativ de a fi ucis de procesul ucigaș OOM. Aplicația se va putea reîncărca, dar numai în limitele depășirii, ceea ce reduce riscul ca un criminal OOM să distrugă procesul. Prin urmare, o valoare de 2 oferă performanțe mai bune decât valoarea implicită de 0. Cu toate acestea, fiabilitatea poate fi îmbunătățită asigurându-vă că memoria în afara intervalului nu este supraîncărcată. Acest lucru elimină riscul ca procesul să fie ucis de un criminal OOM.

Pe sistemele fără schimbare, poate apărea o problemă cu vm.overcommit_memory egală cu 2.

https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMIT

vm.dirty_background_raport / vm.dirty_background_bytes

vm.dirty_background_ratio este procentul de memorie umplut cu pagini murdare care trebuie scrise pe disc. Flush-ul pe disc are loc în fundal. Valoarea acestui parametru variază de la 0 la 100; cu toate acestea, o valoare sub 5 poate fi ineficientă și unele nuclee nu o acceptă. 10 este implicit pe majoritatea sistemelor Linux. Puteți îmbunătăți performanța pentru operațiunile intensive de scriere cu un factor mai mic, ceea ce va însemna că Linux va șterge paginile murdare în fundal.

Trebuie să setați valoarea vm.dirty_background_bytes în funcție de viteza de deplasare.

Nu există valori „bune” pentru acești doi parametri, deoarece ambii sunt dependenți de hardware. Cu toate acestea, setarea vm.dirty_background_ratio la 5 și vm.dirty_background_bytes la 25% din viteza discului îmbunătățește performanța la ~25% în majoritatea cazurilor.

vm.dirty_ratio/dirty_bytes

Aceasta este la fel ca vm.dirty_background_raport/dirty_background_bytes, cu excepția faptului că resetarea este efectuată într-o sesiune de lucru, blocând aplicația. Prin urmare, vm.dirty_ratio ar trebui să fie mai mare decât vm.dirty_background_ratio. Acest lucru asigură că procesele de fundal încep mai devreme pentru a evita blocarea aplicației cât mai mult posibil. Puteți ajusta diferența dintre aceste două rapoarte în funcție de încărcarea I/O pe disc.

Total

Puteți modifica alte setări pentru a îmbunătăți performanța, dar îmbunătățirile vor fi minime și nu veți vedea prea multe beneficii. Trebuie să ne amintim că nu toate opțiunile se aplică tuturor tipurilor de aplicații. Unele aplicații funcționează mai bine atunci când ajustăm unele setări, iar altele nu. Trebuie să găsiți echilibrul potrivit între configurarea acestor setări pentru volumul de lucru așteptat și tipul de aplicație și, de asemenea, trebuie să luați în considerare comportamentul sistemului de operare la reglare. Configurarea parametrilor kernelului nu este la fel de ușoară precum configurarea parametrilor bazei de date; este mai dificil să se facă recomandări.

Sursa: www.habr.com

Adauga un comentariu