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