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.