Uno de mis servidores PostgreSQL aloja varias (1-3) bases de datos que reciben un flujo constante de datos. Los datos no están particularmente estructurados, equivalen al tiempo actual y a una variedad de datos observados para ese instante en particular. La velocidad de datos es bastante alta; Resulta aproximadamente un gigabyte por día para una base de datos, aproximadamente una décima parte de eso para otra. No espero que esta tasa aumente. El rendimiento de lectura es una prioridad mucho menor y actualmente es aceptable.
En los registros tengo este mensaje:
LOG: checkpoints are occurring too frequently (15 seconds apart)
HINT: Consider increasing the configuration parameter "checkpoint_segments".
Este valor está configurado actualmente en 16, que es cortesía de pgtune
.
¿Cuáles son las configuraciones que debo considerar para mejorar el rendimiento de escritura? Preferiría mantener la mayor seguridad posible. Teniendo en cuenta el volumen de datos que ingresa, podría aceptar perder algunos datos recientes en una falla, siempre y cuando la mayor parte de los datos estén intactos.
Editar: estoy usando PostgreSQL 9.0 por ahora, pero planeo actualizar a 9.1. No publico los detalles del hardware porque, aunque reconozco su importancia, en última instancia necesitaré hacer esta optimización en varias máquinas con hardware muy diverso. Si el hardware es esencial para la respuesta, proporcione la información general para que pueda aplicar la respuesta a máquinas con diferentes configuraciones de hardware.
fuente
checkpoint_segments
según lo recomendado? ¿Que pasó?Respuestas:
1 gigabyte al día no es tan alto de una carga de escritura. Se extiende a lo largo del día, lo que equivale a unos 50kbytes por segundo. Una memoria USB lenta podría manejar eso. Aunque supongo que es más explosivo. Como sugiere a_horse_with_no_name, aumente los segmentos del punto de control. Más o menos 100 no está fuera de lo común.
Luego, aumente su tiempo
checkpoint_timeout
a 1 hora, y considere aumentarlocheckpoint_completion_target
a algo más cercano a 1.0 (100%). El objetivo de finalización le dice a PostgreSQL qué tan agresivamente escribir en segundo plano para que esté x% completado antes de ejecutar un punto de control, lo que obliga a que todos los datos se escriban de una vez desde el WAL y ralentizará el sistema hasta que se arrastre mientras está sucediendo.La razón por la que generalmente no lo configura al 100% es que es bastante común escribir en el mismo bloque más de una vez, y al retrasar las escrituras de WAL en la tienda principal, evita que el mismo bloque se escriba dos veces sin ninguna razón.
Si es poco probable que escriba en el mismo bloque más de una vez antes de que se agote el tiempo de espera, es decir, todo lo que debe hacer es insertarlo y luego configurarlo bastante alto tiene sentido elevarlo a 0.9 más o menos. Lo peor que sucederá es que escribirás un poco más a menudo de lo que podrías necesitar, pero el impacto de los puntos de control se reducirá considerablemente.
fuente
En un sistema muy 'pesado de escritura', es probable que esté limitado por la tasa de WAL que se puede escribir durante la actividad pico.
Si realmente puede "aceptar perder algunos datos recientes en una falla", puede desactivar la confirmación sincrónica que:
Si puede cambiar su hardware, puede considerar cualquiera de estos para optimizar las escrituras:
--editar
Según su comentario sobre la excelente respuesta de @ Scott : "El volumen de escritura es en realidad casi completamente uniforme", y la velocidad de datos implícita de "50kbytes por segundo", dudo que necesite hacer algo que arriesgue la pérdida de datos. Quizás sería útil saber en qué están configurados algunos de sus otros parámetros de configuración.
fuente
También puede verificar la frecuencia / tamaño de sus confirmaciones: recientemente me encontré con un problema en el que estaba tratando de actualizar> 1 millón de registros en una sola transacción. Recibí mensajes de registro similares a los descritos por OP, pero la transacción no pudo completarse incluso después de varias horas. Cuando dividí la escritura en varias transacciones más pequeñas (aproximadamente 10,000 registros), el tiempo total requerido se redujo a aproximadamente 15 minutos.
Lo que creo que sucedió fue que Postgres pasó tanto tiempo escribiendo los registros que checkpoint_timeout transcurrió antes de que pudiera hacer un progreso sustancial al guardar los registros. No estoy seguro si esa explicación se sostiene. Todavía recibo las advertencias, pero todas las escrituras finalmente se procesan. Sin embargo, necesitaba (y encontré) una solución programática en lugar de una que requiera la reconfiguración de la base de datos.
Ver también http://www.postgresql.org/docs/9.3/static/wal-configuration.html
fuente