Documentazione di PostgreSQL 9.0 > Amministrazione del server > Setup e operatività del server > Gestire le risorse del Kernel
PrecedenteStarting the Database ServerArrestare il serverSuccessivo

17.4. Gestire le risorse del Kernel

Un'installazione grande di PostgreSQL™ può esaurire velocemente i limiti di varie risorse del sistema operativo. (Su alcuni sistemi, i valori predefiniti sono talmente bassi che non si ha nemmeno bisogno di un'installazione molto «grande»). Se si è riscontrato questo tipo di problemi, continuare a leggere.

17.4.1. Memoria condivisa e semafori

Ci si riferisce alla memoria condivisa e i semafori collettivamente come IPC (insieme alle code dei messaggi, che non sono rilevanti per PostgreSQL™). Quasi tutti i sistemi operativi moderni forniscono queste caratteristiche, ma molti di loro non le hanno attivate o sufficientemente dimensionate in modo predefinito, specialmente come RAM disponibile quando le richieste delle applicazioni database crescono. (Su Windows, PostgreSQL™ fornisce la propria implementazione come rimpiazzo di queste caratteristiche, quindi la maggior parte di questa sezione può essere trascurata).

La completa mancanza di queste caratteristiche è di solito manifestata da un errore Illegal system call all'avvio del server. In quel caso non c'è alternativa se non riconfigurare il kernel. PostgreSQL™ non funzionerà senza di loro. In ogni caso, questa situazione è rara tra i sistemi operativi moderni.

Quando PostgreSQL™ eccede uno dei vari limiti IPC, il server rifiuterà di avviarsi e dovrebbe generare un errore informativo che descrive il problema e cosa fare. (Si veda anche Sezione 17.3.1, «Fallimenti dell'avvio del server»). I parametri rilevanti del kernel sono chiamati consistentemente tra i vari sistemi; Tabella 17.1, «Parametri IPC System V» fornisce una fanoramica. I metodi per impostarli, comunque, variano. Suggerimenti per alcune piattaforme sono presentati sotto.

Tabella 17.1. Parametri IPC System V

NomeDescrizioneValori ragionevoli
SHMMAXDimensione massima del segmento di memoria condivisa (byte)almeno diversi megabyte (si veda text)
SHMMINDimensione minima del segmento di memoria condivisa (byte)1
SHMALLQuantità totale della memoria condivisa disponibile (byte o pagine)se byte, lo stesso di SHMMAX; se pagine, ceil(SHMMAX/PAGE_SIZE)
SHMSEGIl massimo numero di segmenti di memoria condivisa per processosolo 1 segmento è necessario, ma il valore predefinito è molto maggiore
SHMMNIIl massimo numero di segmenti di memeoria condivisa a livello di sistemacome SHMSEG più spazione per altre applicazioni
SEMMNIIl massimo numero di identificatori di semaforo (per es., sets)almeno ceil((max_connections + autovacuum_max_workers) / 16)
SEMMNSIl massimo numero di semafori a livello di sistemaceil((max_connections + autovacuum_max_workers) / 16) * 17 più spazio per altre applicazioni
SEMMSLIl massimo numero di sema Maximum number of semaphores per insiemealmeno 17
SEMMAPNumero di voci nella mappa dei semaforisi veda text
SEMVMXIl massimo valore del semaforoalmeno 1000 (Il valore predefiniro spesso è 32767; non cambiarlo a meno che non sia necessario)

Il parametro più importante riguardante la memoria condivisa è SHMMAX, cioè la dimensione massima, in byte, di un segmento di memoria condivisa. Se si ottiene un messaggio di errore da shmget tipo «Invalid argument», è probabile che questo limite sia stato superato. La dimensione del segmento di memoria condivisa richiesta varia dipendentemente da diveri parametri di configurazione di PostgreSQL™, come mostrato in Tabella 17.2, «Utilizzo della memoria condivisa da parte di PostgreSQL™». (Qualsiasi messaggio di errore che si potrebbe ottenere includeranno la dimensione esatta della richiesta di allocazione fallita). È possibile, come soluzione temporanea, abbassare alcune di queste impostazioni per evitare il fallimento. Mentre è possibile avviare PostgreSQL™ con SHMMAX grande 2 MB, probabilmente si avrà bisogno di più per prestazioni accettabili. Impostazioni auspicabili sono da centinaia di megabyte a pochi gigabyte.

Alcuni sistemi hanno anche un limite sulla quantità totale di memeoria condivisa nel sistema (SHMALL). Assicurarsi che sia grande abbastanza per PostgreSQL™ più qualsiasi altra applicazione che stia usando segmenti di memoria condivisa. Notare che SHMALL viene misurata in pagine invece di byte su molti sistemi.

È meno probabile che a causare problemi sia la dimensione minima per i segmenti di memoria condivisa (SHMMIN), che dovrebbero essere tutt'al più 500 kB approssimativamente per PostgreSQL™ (di solito è 1). Il massimo numero di segmenti a livello di sistema (SHMMNI) o per processo (SHMSEG) probabilmente non causeranno problemi a meno che il sistema non li abbia impostati a zero.

PostgreSQL™ usa un semaforo per ogni connessione permessa (max_connections) e processo worker dell'autovacuum consentito (autovacuum_max_workers), in gruppi di 16. Ognuno di questi gruppi conterrà anche un 17esimo semaforo che contiene un «numero magico», per accorgersi di collisioni con insiemi di semafori usati da altre applicazioni. Il massimo numero di semafori nel sistema è impostato da SEMMNS, che di conseguenza deve essere grande almeno quanto max_connections più autovacuum_max_workers, più uno aggiuntivo per ogni 16 connessioni più worker consentite (si veda la formula in Tabella 17.1, «Parametri IPC System V»). Il parametro SEMMNI determina il limite sul numero di gruppi di semafori che possono esistere nel sistema in un dato istante. Da adesso questo parametro deve essere almeno ceil((max_connections + autovacuum_max_workers) / 16). Abbassare il numero di connessioni permesse è una soluzione temporanea per fallimenti, che di solito sono espressi confusamente come «No space left on device», dalla funzione semget.

In alcuni casi potrebbe essere necessario anche incrementare SEMMAP per essere almeno nell'ordine di SEMMNS. Questo parametro definisce la dimensione della mappa delle risorse del semaforo, nella quale qualsiasi blocco contiguo di semafori disponibili necessita una voce. Quando un insieme di semafori viene liberato o è aggiunto a una voce esistente che è adiacente al blocco liberato oppure viene registrata con una nuova voce di mappa. Se la mappa è piena, i semafori liberati vengono persi (fino al riavvio). La frammentazione dello spazio dei semafori potrebbe portare nel tempo ad avere meno semafori disponibili rispetto a quanti ce ne dovrebbero essere.

Il parametro SEMMSL, che determina quanti semafori possono esserci in un insieme, dev'essere almeno 17 per PostgreSQL™.

Varie altre impostazioni relative a «semaphore undo», tipo SEMMNU and SEMUME, non hanno effetti su PostgreSQL™.

AIX

Almeno dalla versione 5.1, non dovrebbe essere necessario fare nessuna configurazione speciale per parametri come SHMMAX, per come appare questo è configurato per permettere a tutta la memoria di essere usata come memoria condivisa. Che è una sorta di configurazione usata comunemente in altri database tipo DB/2.

potrebbe comunque essere necessario modificare l'informazione globale ulimit in /etc/security/limits, dato che il limite predefinito per la dimensione dei file (fsize) e il numero di file (nofiles) potrebbe essere troppo basso.

BSD/OS

Memoria condivisa.  In modo predefinito, solo 4 MB di memoria condivisa sono supportati. Tenere a mente che la memeoria condivisa non è paginabile; è bloccata in RAM. Per incrementare la quantità di memoria condivisa supportata dal sistema, aggiungere qualcosa di simile al seguente al file di configurazione del kernel:

options "SHMALL=8192"
options "SHMMAX=\(SHMALL*PAGE_SIZE\)"

SHMALL viene misurato in pagine da 4 kB, quindi un valore di 1024 rappresenta 4 MB di memoria condivisa. Inoltre l'esempio sopra aumenta l'area di massima memoria condivisa a 32 MB. Per chi utilizza la versione 4.3 o successive, probabilmente dovrà anche incrementare KERNEL_VIRTUAL_MB, il valore predefinito è 248. Una volta che tutti i cambiamenti sono stati fatti, ricompilare il kernel, e riavviare.

Semafori.  Probabilmente si vorrà incrementare anche il numero di semafori; il valore 60 predefinito di sistema permetterà solo cira 50 connessioni PostgreSQL™. Impostare i valori che si vogliono nel file di configurazione del kernel, per es.:

options "SEMMNI=40"
options "SEMMNS=240"

FreeBSD

Le impostazioni predefinite sono adatte solo a installazioni piccole (per esempio, il valore predefinito di SHMMAX è 32 MB). Possono essere fatti cambiamenti attraverso le interfaccie sysctl o loader. I seguenti parametri possono essere impostati usando sysctl:

$ sysctl -w kern.ipc.shmall=32768
$ sysctl -w kern.ipc.shmmax=134217728
$ sysctl -w kern.ipc.semmap=256

Per rendere queste impostazioni persistenti al riavvio, modificare /etc/sysctl.conf.

Le impostazioni dei semafori rimanenti sono a sola lettura per come è pensato sysctl, ma può essere cambiato prima dell'avvio usando il prompt loader:

(loader) set kern.ipc.semmni=256
(loader) set kern.ipc.semmns=512
(loader) set kern.ipc.semmnu=256

Similmente questi possono essere salvati in /boot/loader.conf.

Si potrebbe anche voler configurare il kernel per bloccare la memoria condivisa nella RAM e prevenire che venga paginata fuori dalla swap. Questo può essere fatto usando l'impostazione kern.ipc.shm_use_phys di sysctl.

If running in FreeBSD jails by enabling sysctl's security.jail.sysvipc_allowed, postmasters running in different jails should be run by different operating system users. Questo incrementa la sicurezza dato che previene che utenti non root interferiscano con la memoria condivisa o i semafori in jail differenti, e permette al codice di pulizia IPC di PostgreSQL di funzionare in modo appropriato. (In FreeBSD 6.0 e successive il codice di pulizia ICP non trova correttamente i processi nelle altre jail, prevenendo l'esecuzione di postmaster sulla stessa porta in jail differenti).

Le versioni di FreeBSD precedenti la 4.0 funzionano come NetBSD e OpenBSD (si veda sotto).

NetBSD, OpenBSD

Le opzioni SYSVSHM e SYSVSEM devono essere abilitate quando viene compilato il kernel. (E lo sono in maniera predefinita). La dimensione massima della memoria condivisa è determinata dall'opzione SHMMAXPGS (in pagine). L'esempio seguente mostra un esempio di come impostare i vari parametri su NetBSD (OpenBSD invece usa option):

options        SYSVSHM
options        SHMMAXPGS=4096
options        SHMSEG=256

options        SYSVSEM
options        SEMMNI=256
options        SEMMNS=512
options        SEMMNU=256
options        SEMMAP=256

Si potrebbe voler configurare il kernel anche per bloccare la memoria condivisa nella RAM e prevenire che venga paginata fuori dalla swap. Questo può essere fatto usando l'impostazione kern.ipc.shm_use_phys di sysctl.

HP-UX

Le impostazioni predefinite tendono ad essere sufficenti per installazioni normali. Su HP-UX™ 10, il valore predefinito di SEMMNS è 128, che potrebbe essere troppo basso per database più grandi.

I parametri IPC possono essere impostati nel System Administration Manager (SAM) in Kernel ConfigurationConfigurable Parameters. Scegliere Create A New Kernel quando si è fatto.

Linux

La dimensione massima predefinita del segmento è 32 MB, che è adeguata solo per installazioni molto piccole di PostgreSQL™. La dimensione massima totale è 2097152 pagine. Una pagina è quasi sempre 4096 byte ad eccezione di configurazioni del kernel insolite con «pagine enormi» (usare getconf PAGE_SIZE per verificare). Questo genera un limite predefinito di 8 GB, che spesso è sufficiente, ma non sempre.

Le impostazioni per la dimensione della memoria condivisa possono essere cambiate attraverso l'interfaccia sysctl. Per esempio, per permettere 16 GB:

$ sysctl -w kernel.shmmax=17179869184
$ sysctl -w kernel.shmall=4194304

In più queste impostazioni possono essere preservate nel file /etc/sysctl.conf. Farlo è altamente raccomandato.

Distribuzioni molto vecchie potrebbero non avere il programma sysctl, ma le modifiche equivalenti possono essere fatte manipolando il file system /proc:

$ echo 17179869184 >/proc/sys/kernel/shmmax
$ echo 4194304 >/proc/sys/kernel/shmall

I valori predefiniti rimanenti sono abbastanza grandi, e di solito non richiedono cambiamenti.

MacOS X

Il metodo raccomandato per configurare la memoria condivisa in OS X è di creare un file chiamato /etc/sysctl.conf, contenente assegnamenti di variabili tipo:

kern.sysv.shmmax=4194304
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.sysv.shmall=1024

Si noti che in alcune versioni di OS X, tutti e cinque i parametri della memoria condivisa devono essere impostati in /etc/sysctl.conf, altrimenti i valori saranno ignorati.

Fare attenzione al fatto che le versioni recenti di OS X ignoraro i tentativi di impostare SHMMAX a un valore che non è un multiplo esatto di 4096.

SHMALL è misurato in pagine da 4 kB su questa piattaforma.

In vecchie versioni di OS X, si dovrà riavviare per rendere effettivi i cambiamenti ai parametri della memoria condivisa. Dalla 10.5 è possibile cambiare tutto tranne SHMMNI al volo, usando sysctl. Ma è sempre meglio impostare i valori preferiti attraverso /etc/sysctl.conf, in modo che i valori saranno mantenuti anche dopo i riavvi.

Il file /etc/sysctl.conf viene considerato solo in OS X 10.3.9 e successivi. Se si sta eseguendo una versione precedente alla 10.3.x, si deve modificare il file /etc/rc e cambiare i valori nei seguenti comandi:

sysctl -w kern.sysv.shmmax
sysctl -w kern.sysv.shmmin
sysctl -w kern.sysv.shmmni
sysctl -w kern.sysv.shmseg
sysctl -w kern.sysv.shmall

Si noti che /etc/rc di solito viene sovrascritto da aggiornamenti di OS X, quindi ci si dovrebbe aspettare di diver rifare queste modifiche dopo ogni aggiornamento.

In OS X 10.2 e precedenti, modificare questi comandi nel file /System/Library/StartupItems/SystemTuning/SystemTuning.

SCO OpenServer

Nella configurazione predefinita, sono permessi solo 512 kB per segmento. Per aumentare l'impostazione, entrare nella directory /etc/conf/cf.d. Per visualizzare il valore corrente di SHMMAX, lanciare:

./configure -y SHMMAX

Per impostare un nuovo valore per SHMMAX, eseguire:

./configure SHMMAX=value

dove value è il nuovo valore che si vuole usare (in byte). Dopo aver impostato SHMMAX, ricompilare il kernel:

./link_unix

e riavviare.

Solaris

Almeno nella versione 2.6, la dimensione massima predefinita di un segmento di memoria condivisa è troppo basso per PostgreSQL™. Le impostazioni rilevanti possono essere cambiate in /etc/system, per esempio:

set shmsys:shminfo_shmmax=0x2000000
set shmsys:shminfo_shmmin=1
set shmsys:shminfo_shmmni=256
set shmsys:shminfo_shmseg=256

set semsys:seminfo_semmap=256
set semsys:seminfo_semmni=512
set semsys:seminfo_semmns=512
set semsys:seminfo_semmsl=32

Si deve riavviare per rendere effettive le modifiche.

Si veda anche http://sunsite.uakom.sk/sunworldonline/swol-09-1997/swol-09-insidesolaris.html per informazioni sulla memoria condivisa su Solaris™.

UnixWare

Su UnixWare™ 7, la dimensione massima per i segmenti di memoria condivisa è solamente 512 kB nella configurazione predefinita. Per visualizzare il valore corrente di SHMMAX, eseguire:

/etc/conf/bin/idtune -g SHMMAX

che mostra i valori attuale, predefinito, minimo e massimo. Per impostare un nuovo valore per SHMMAX, eseguire:

/etc/conf/bin/idtune SHMMAX value

dove value è il nuovo valore che si vuole usare (in byte). Dopo aver impostato SHMMAX, ricompilare il kernel:

/etc/conf/bin/idbuild -B

e riavviare.

Tabella 17.2. Utilizzo della memoria condivisa da parte di PostgreSQL

UtilizzoByte di memoria condivisa approssimati richiesti (dalla 8.3)
Connessioni(1800 + 270 * max_locks_per_transaction) * max_connections
Worker autovacuum(1800 + 270 * max_locks_per_transaction) * autovacuum_max_workers
Transazioni preparate(770 + 270 * max_locks_per_transaction) * max_prepared_transactions
Buffer disco condivisi(block_size + 208) * shared_buffers
Buffer WAL(wal_block_size + 8) * wal_buffers
Richieste fisse di spazio770 kB

17.4.2. Limiti delle risorse

I sistemi operativi della famiglia Unix stabiliscono vari tipi di limiti di risorse che potrebbero interferire con le operazioni del server PostgreSQL™. I limiti sul numero di processi per utente, sul numero di file aperti per processo e sulla quantità di memoria disponibile per ogni processo sono di particolare importanza. Ognuno di questi ha un limite «hard» e uno «soft». Il limite soft è quello che conta effettivamente ma può essere cambiato dall'utente fino al limite hard. Il limite hard può essere cambiato solo dall'utente root. La chiamata di sistema setrlimit è responsabile di impostare questi parametri. Il comando ulimit incorporato della shell (shell Bourne) o limit (csh) è usato per controllare i limiti delle risorse dalla linea di comando. Su sistemi derivati da BSD il file /etc/login.conf controlla i vari limiti delle risorse impostati durante il login. Si veda la documentazione del sistema operativo per dettagli. I parametri rilevanti sono maxproc, openfiles e datasize. Per esempio:

default:\
...
        :datasize-cur=256M:\
        :maxproc-cur=256:\
        :openfiles-cur=256:\
...

(-cur è il limite soft. Aggiungere -max per impostare il limite hard).

Il kernel può avere anche limiti a livello di sistema su alcuni risorse.

  • Su Linux/proc/sys/fs/file-max determina il numero masssimo di file aperti che il kernel supporterà. Può essere cambiato scrivendo un numero diverso nel file o aggiungendo un assegnazione in /etc/sysctl.conf. Il limite massimo di file per processo è specificato nel momento in cui il kernel viene compilato; si veda /usr/src/linux/Documentation/proc.txt per maggiori informazioni.

Il server PostgreSQL™ usa un processo per connessione quindi si dovrebbe fornire un numero di processi almeno quanto il numero di connessioni permesse, in aggiunta a quello di cui si ha bisogno per il resto del sistema. Questo di solito non è un problema ma se si eseguono diversi server su una macchina le cose potrebbero diventare strettine.

Il limite predefinito sui file aperti spesso è impostato a valori «socialmente amichevoli» che permettono a molti utenti di coesistere su una macchina senza usare una frazione inappropriata di risorse di sistema. Se si eseguono molti server su una macchina forse è quello che si vuole, ma su server dedicati si potrebbe voler incrementare questo limite.

Dall'altro lato della medaglia, alcuni sistemi permettono a processi individuali di aprire un grande numero di file; se più di pochi processi fanno questo allora il limite a livello di sistema può facilmente essere superato. Se si scopre che succede ciò, e non si vuole modificare il limite a livello di sistema, si può impostare il parametro di configurazione max_files_per_process di PostgreSQL™ per limitare il consumo di file aperti.

17.4.3. Linux Memory Overcommit

In Linux 2.4 e successivi, il comportamento predefinito della memoria virtuale non è ottimale per PostgreSQL™. A causa del modo in cui il kernel implementa l'overcommit della memoria, il kernel potrebbe terminare il serve PostgreSQL™ (il processo server principale) se le richieste di memoria di un altro processo causano che il sistema ecceda la memoria virtuale.

Se succede questo, si vedrà un messaggio del kernel che somiglia a questo (consultare la documentazionei e la configurazione del proprio sistema per vedere dove cercare tale messaggio):

Out of Memory: Killed process 12345 (postgres).

Questo indica che il processo postgres è stato terminato a causa della memoria. Anche se le connessioni al database esistenti continueranno a funzionare normalmente, nessuna nuova connessione sarà accettata. Per risolvere la situazione, PostgreSQL™ dovrà essere riavviato.

Un modo di evitare questo problema è di lanciare PostgreSQL™ su una macchina dove si può essere sicuri che altri processi non daranno problemi di memoria. Se la memoria è stretta, incrementare lo spazio di swap del sistema operativo può aiutare a evitare il problema, dato che il killer out-of-memory (OOM) viene invocato solo quando la memoria fisica e lo spazio di swap sono terminati.

Su Linux 2.6 e successivi, è possibile modificare il comportamento del kernel così che non faccia l'«overcommit» della memoria. Anche se quest'impostazione non preverrà del tutto l'invocazione di OOM killer, abbasserà significativamente tale possibilità e porterà inoltre a una maggiore robustezza del sistema. Questo è fatto selezionando la modalità strict per l'overcommit con sysctl:

sysctl -w vm.overcommit_memory=2

o posizionando una voce equivalente in /etc/sysctl.conf. Si potrebbe desiderare anche modificare l'impostazione correlata vm.overcommit_ratio. Per dettagli si veda il file di documentazione del kernel Documentation/vm/overcommit-accounting.

Un altro approccio, che può essere usato modificando o meno vm.overcommit_memory, è di impostare il valore oom_adj specifico del processo postmaster a -17, garantendo in tal modo che non sarà considerato dal killer OOM. Il modo più semplice per fare ciò è di eseguire

echo -17 > /proc/self/oom_adj

nello script di avvio di postmaster appena prima di invocare il postmaster. Notare che questa azione deve essere fatta come root, altrimenti non avrà effetti; quindi uno script di avvio in possesso di root è il posto più semplice dove farlo. Se si fa questo, si potrebbe voler anche compilare PostgreSQL™ con -DLINUX_OOM_ADJ=0 aggiunta a CFLAGS. Questo farà si che i processi figli di postmaster andranno in esecuzione con il valore normale (zero) di oom_adj, quindi il killer OOM può ancora riferirsi a loro se necessario.

[Nota]

Nota

Some vendors' Linux 2.4 kernels are reported to have early versions of the 2.6 overcommit sysctl parameter. However, setting vm.overcommit_memory to 2 on a 2.4 kernel that does not have the relevant code will make things worse, not better. Si raccomanda di ispezionare l'effettivo codice sorgente del kernel (si veda la funzione vm_enough_memory nel file mm/mmap.c) per verificare cosa è supportato nel proprio kernel prima di provarlo in una installazione si 2.4. La presenza del file di documentazione overcommit-accounting non dovrebbe essere presa come prova che la caratteristica sia presente. Se in dubbio, consultare un esperto del kernel o il proprio fornitore del kernel.

Documentazione di PostgreSQL 9.0 > Amministrazione del server > Setup e operatività del server > Gestire le risorse del Kernel
PrecedenteStarting the Database ServerArrestare il serverSuccessivo