Postgresql que se muere

Alvaro Herrera alvherre en alvh.no-ip.org
Mie Jul 14 12:39:48 CLT 2010


Excerpts from Ricardo Munoz's message of mar jul 13 16:51:29 -0400 2010:

> da para pensar como tanta gente hizo la pega (buscar en Google) del autor
> del primer mail y/o respondieron a la rapida y mal. cualquier usuario de un
> motor de base de datos debe saber que
> 
> - el resultado de un SELECT nunca puede ser un mensaje de error de memoria

Te equivocas, sí puede darse este caso.  En Postgres, posibles motivos
hay varios (de menos a más probable):

- el SELECT invoca alguna función con efectos secundarios que ocupa
  mucha memoria.  Normalmente las funciones que uno pone en un SELECT no
  tienen efectos secundarios.  Esto es hipotético; yo no lo he visto
  nunca en el mundo real.

- un plan de ejecución resulta más caro en memoria de lo que el
  optimizador determinó.  Esto es raro pero se ve; la causa más
  frecuente es que tienes un valor de work_mem demasiado grande.  La
  mayoría de los nodos de ejecución sólo ocupan work_mem de memoria como
  máximo, y por lo tanto en un sistema bien configurado no debería
  pasar.  La única excepción es agregación usando hash (HashAggregate),
  que el optimizador puede *estimar* que va a necesitar X memoria (y lo
  limita a work_mem), pero si la estimación de la cantidad de valores
  distintos (es decir, tamaño de la tabla de hash) es mala por cualquier
  motivo, entonces puede terminar ocupando más memoria.

- El proceso tiene un límite de memoria (ulimit) menor al que el
  optimizador quiere ocupar.

- Existe otro proceso que está ocupando memoria, y el servidor se queda
  corto de memoria física y swap.  (Creo que tienes que tener overcommit
  deshabilitado para que esto se reporte; de lo contrario lo que sucede
  es que entra en acción el OOM-killer, y los síntomas son muy
  diferentes).  Por ej. si tienes uno o más procesos vacuum corriendo y
  tu maintenance_work_mem es muy alto.  Esto es medianamente frecuente
  (hay como un reporte cada dos o tres meses en las listas pgsql)

Y finalmente, la causa más probable ya la mencioné en una respuesta
anterior:

- Existen datos corruptos que hacen que el sistema intente emplazar una
  cantidad ridícula de memoria; particularmente un puntero TOAST
  corrupto.  Los punteros TOAST incluyen el tamaño total del dato
  almacenado; si esto está corrupto, el resultado es que el software
  puede intentar hacer malloc() de cualquier valor (hasta 2^32-1 si mal
  no recuerdo).

> - el resultado de un servicio mal optimizado nunca puede ser un mensaje de
> error de memoria durante su operacion (instruccion SELECT), sino solo al
> momento de subir el servicio

Hmm, no necesariamente ...

> por lo tanto, la unica explicacion logica al problema es que
> 
> - se trata de un bug de Postgres, donde la solucion es actualizar ojala
> usando el metodo ofrecido por la distro de Linux
> - se trata de un error de hardware (memoria o disco), donde la solucion es
> reemplazar el hardware malo o cambiar el servicio a otra maquina

También puede ser un error de configuración; por ejemplo si los discos
tienen cache de escritura activo y ocurre una caída, puede resultar que
una de las últimas escrituras no haya alcanzado a grabarse.  Esto no
sucede en un sistema bien configurado.  (Alternativamente, si quieres
tener muy buen rendimiento, puedes poner un controlador RAID con cache
respaldado por baterías, para protegerte en caso de corte abrupto de
energía).


Más información sobre la lista de distribución Linux