Configurando los parametros del kernel para PostgreSQL


Una instalación por defecto de PostgreSQL no necesita ninguna configuración especial del sistema operativo Linux donde se ejecuta.

Pero si vamos a utilizar PostgreSQL en sistemas de producción ó con grandes cantidades de datos, tendremos que ajustar ciertos parametros en el fichero de configuración postgresql.conf y estos cambios con gran probabilidad, harán que PostgreSQL deje de funcionar si no se ajustan ciertos parametros del núcleo de Linux.

Existen dos elementos que probablemente necesiten ajustes en el núcleo de vuestro sistema Linux. Estos elementos son usados por PostgreSQL para organizar los recursos compartidos entre procesos PostgreSQL.

  • Memoria compartida (share memory)
  • Semáforos (Semaphore)

Los parámetros del núcleo que se utilizan para configurarlos son:

Memoria compartida

  • SHMMAX: Tamaño máximo de un segmento de memoria compartida (bytes)
  • SHMMIN: Tamaño mínimo de un segmento de memoria compartida (bytes)
  • SHMALL: Cantidad máxima de memoria compartida disponible (bytes ó páfinas)
  • SHMSEG: Número máximo de segmentos de memoria compartida por proceso
  • SHMMNI: Número máximo de segmentos de memoria compartida en todo el sistema

Semáforos

  • SEMMNI: Número máximo de identificadores de semáforos (grupos)
  • SEMMNS: Número máximo de semáforos en todo el sistema
  • SEMMSL: Número máximo de semáforos por grupo
  • SEMMAP: Número de entradas en el mapa de semáforos
  • SEMVMX: Máximo valor de un semáforo
  • SEMOPM: Número máximo de operaciones con semáforos que pueden realizarse por cada llamada del sistema semop
  • SEM: Es igual a “SEMMSL SEMMNS SEMOPM SEMMNI”

Los valores recomendados para estos parámetros para uso con PostgreSQL son los siguientes:

Memoria compartida

  • SHMMAX: Varios MB. El valor por defecto del núcleo es 32MB, un valor muy bajo en muchos casos. Existen varios parametros en postgresql.conf que determinan cuanta memoria compartida necesitaremos, el más importante de ellos y el principal causante de que necesitemos aumentar SHMMAX es shared_buffers.

    El valor de SHMMAX (bytes) no puede ser menor que el valor definido en shared_buffers. PostgreSQL se negará a arrancar si el valor de SHMMAX es muy pequeño.

  • SHMMIN: Como mínimo 1.

  • SHMALL: Como mínimo SHMMAX/PAGE_SIZE. En donde el valor de PAGE_SIZE lo podeis obtener ejecutando el comando getconf PAGESIZE. El valor por defecto del núcleo es 2097152 pages (8192MB)

    Si teneis varios clusters de PostgreSQL ejecutandose en la máquina ó otros programas que usen memoria compartida, tendreis que definir un valor de SHMALL lo suficientemente grande para poder ejecutar todos estos programas a la vez.

  • SHMSEG: Solamente se necesita 1. El valor por defecto es mucho más grande.

  • SHMMNI: Como mínimo SHMSEG + lo necesario por otras aplicaciones. El valor por defecto del núcleo es 4096.

    Pocas veces hay que modificar este valor.

Semáforos

  • SEMMNI: ceil((max_connections + autovacuum_max_workers) / 16). El valor por defecto del núcleo suele ser 128
  • SEMMNS: ceil((max_connections + autovacuum_max_workers) / 16) * 17 + lo necesario por otras aplicaciones. El valor por defecto del núcleo suele ser 32000
  • SEMMSL: Como minimo 17. El valor por defecto del núcleo suele ser 250
  • SEMMAP: En algunos casos tiene que ser igual a SEMMNS
  • SEMVMX: Como mínimo 1000. El valor por defecto del núcleo suele ser 32767
  • SEMOPM: El valor por defecto del núcleo suele ser 32
  • SEM: Es igual a “SEMMSL SEMMNS SEMOPM SEMMNI”

Los casos mas comúnes de usuarios con problemas de arranque de PostgreSQL son:

  • Aumento del parametro shared_buffers en el fichero de configuración postgresql.conf sin cambiar los valores del núcleo de memoria compartida. El error típico registrado es:
      FATAL:  could not create shared memory segment: Invalid argument
      DETAIL:  Failed system call was shmget(key=5440001, size=4011376640, 03600).
    
  • Aumento de los parámetros max_connections y/ó autovacuum_max_workers en el fichero de configuración postgresql.conf sin cambiar los valores del núcleo de semáforos
      FATAL:  could not create semaphores: No space left on device
      DETAIL:  Failed system call was semget(5440126, 17, 03600).
    

Vamos a ver un ejemplo de como ajustar los valores del núcleo cuando cambiamos algunos valores en postgresql.conf. Vamos a cambiar los valores de shared_buffers, max_connections y autovacuum_max_workers:

shared_buffers = 2048MB
max_connections = 300
autovacuum_max_workers = 6

Probablemente, si intentamos arrancar PostgreSQL con los valores por defecto del núcleo, fallará el arranque. Vamos a ver que valores tenemos definidos en nuestro sistema:

root@server:~# getconf PAGESIZE
4096

root@server:~# cat /proc/sys/kernel/shmall 
2097152

root@server:~# cat /proc/sys/kernel/shmmax 
33554432

root@server:~# cat /proc/sys/kernel/shmmni 
4096

root@server:~# cat /proc/sys/kernel/sem 
250     32000   32      128

A continuación calculamos los valores que vamos a necesitar y actualizamos, si es necesario, el fichero /etc/sysctl.conf con los mismos.

  • Con un valor de 2048MB en shared_bufferes necesitamos como mínimo:
    • shmmax = 2147483648 (bytes = 2048MB * 1024 * 1024)
    • shmall = shmmax / 4096 = 524288
  • Con un valor de 300 en max_connections y 6 en autovacuum_max_workers necesitamos como mínimo:
    • semmsl = 17
    • semmns = ceil((300 + 6) / 16) * 17 = 340
    • semmni = ceil((300 + 6) / 16) = 20

Si comparamos los valores que tenemos definidos por defecto y los que necesitamos para que PostgreSQL funcione, solamente necesitamos alterar SHMMAX, ya que este es el único parametro con un valor definido por debajo del valor que necesitamos.

Para cambiar el valor de este parametro permanentemente tenemos que editar el fichero /etc/sysctl.conf, y añadir la linea:

kernel.shmmax = 2147483648

Para instalar los cambios tenemos que ejecutar el comando

sysctl -p /etc/sysctl.conf

Despues de este cambio deberiais de poder arrancar PostgreSQL sin problemas.

Desde la linea de comandos podeis ver la memoria compartida y los semáforos usados por postgreSQL en vuestro sistema. Aqui teneis un ejemplo de como podeis consultar la memoria compartida y los semáforos usados por postgreSQL

postgres@bserver:~$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x0052e2c1 983040     postgres  600        219332608  5                       


postgres@server:~$ ipcs -mi 983040

Shared memory Segment shmid=983040
uid=1000        gid=1000        cuid=1000       cgid=1000
mode=0600       access_perms=0600
bytes=219332608 lpid=10125      cpid=22498      nattch=5
att_time=Wed Apr 22 10:33:12 2009  
det_time=Wed Apr 22 10:33:13 2009  
change_time=Wed Apr 15 21:29:27 2009  


postgres@server:~$ ipcs -s

------ Semaphore Arrays --------
key        semid      owner      perms      nsems     
0x0052e2c1 10944512   postgres  600        17        
0x0052e2c2 10977281   postgres  600        17        
0x0052e2c3 11010050   postgres  600        17        
0x0052e2c4 11042819   postgres  600        17        
0x0052e2c5 11075588   postgres  600        17        
0x0052e2c6 11108357   postgres  600        17        
0x0052e2c7 11141126   postgres  600        17        

postgres@server:~$ ipcs -si 10944512

Semaphore Array semid=10944512
uid=1000         gid=1000        cuid=1000       cgid=1000
mode=0600, access_perms=0600
nsems = 17
otime = Wed Apr 15 21:29:27 2009  
ctime = Wed Apr 15 21:29:27 2009  
semnum     value      ncount     zcount     pid       
0          1          0          0          22498     
1          1          0          0          22498     
2          1          0          0          22498     
3          1          0          0          22498     
4          1          0          0          22498     
5          1          0          0          22498     
6          1          0          0          22498     
7          1          0          0          22498     
8          1          0          0          22498     
9          1          0          0          22498     
10         1          0          0          22498     
11         1          0          0          22498     
12         1          0          0          22498     
13         1          0          0          22498     
14         1          0          0          22498     
15         1          0          0          22498     
16         537        0          0          22498     

Bueno esto es todo lo que tenia pensado decir sobre los parametros del kernel y PostgreSQL. Para más información pasaros por la sección 17.4. Managing Kernel Resources de la documentación oficial.