¿Qué sucede en el punto de control de PostgreSQL?

22

Aquí está parte de mi registro de puntos de control:

2014-03-26 11:51:29.341 CDT,,,18682,,532854fc.48fa,4985,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 15047 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 30 recycled; write=68.980 s, sync=1.542 s, total=70.548 s; sync files=925, longest=0.216 s, average=0.001 s",,,,,,,,,""
2014-03-26 11:56:05.430 CDT,,,18682,,532854fc.48fa,4987,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 16774 buffers (1.6%); 0 transaction log file(s) added, 0 removed, 31 recycled; write=72.542 s, sync=17.164 s, total=89.733 s; sync files=885, longest=3.812 s, average=0.019 s",,,,,,,,,""
2014-03-26 12:01:21.650 CDT,,,18682,,532854fc.48fa,4989,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 14436 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 33 recycled; write=122.350 s, sync=5.212 s, total=127.676 s; sync files=924, longest=3.740 s, average=0.005 s",,,,,,,,,""
2014-03-26 12:06:25.028 CDT,,,18682,,532854fc.48fa,4991,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 13277 buffers (1.3%); 0 transaction log file(s) added, 0 removed, 29 recycled; write=126.217 s, sync=5.733 s, total=131.991 s; sync files=894, longest=1.859 s, average=0.006 s",,,,,,,,,""
2014-03-26 12:10:41.958 CDT,,,18682,,532854fc.48fa,4993,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 20765 buffers (2.0%); 0 transaction log file(s) added, 0 removed, 28 recycled; write=88.015 s, sync=10.818 s, total=98.872 s; sync files=881, longest=2.690 s, average=0.012 s",,,,,,,,,""

Me di cuenta de que a veces nuestra base de datos es muy lenta: puede ver una gran cantidad de consultas normalmente cortas bloqueadas durante mucho más tiempo que ahora. Ocurre regularmente sin un culpable claro.

Pregunta: ¿Podría el punto de control causar esto? ¿Qué sucede en la fase de "sincronización" del punto de control?

Konrad Garus
fuente

Respuestas:

32

Durante su funcionamiento, PostgreSQL registra los cambios en los archivos de registro de transacciones, pero no los vacía inmediatamente en las tablas de la base de datos real. Por lo general, solo guarda los cambios en la memoria y los devuelve de la memoria cuando se solicitan, a menos que la RAM comience a llenarse y tenga que escribirlos.

Esto significa que si se bloquea, las tablas en disco no estarán actualizadas. Tiene que reproducir los registros de transacciones, aplicando los cambios a las tablas en el disco, antes de que pueda comenzar una copia de seguridad. Eso puede llevar un tiempo para una base de datos grande y ocupada.

Por esa razón, y para que los registros de transacciones no sigan creciendo para siempre, PostgreSQL periódicamente realiza un punto de control donde se asegura de que la base de datos esté en un estado limpio. Vacía todos los cambios pendientes en el disco y recicla los registros de transacciones que se estaban utilizando para mantener un registro de recuperación de fallas de los cambios.

Esta descarga ocurre en dos fases:

  • Tampones write()de suciedad shared_buffersa las mesas; y
  • fsync() de los archivos afectados para asegurarse de que los cambios realmente golpeen el disco

Ambos pueden aumentar la carga de E / S del disco. La contención causada por estas escrituras puede ralentizar las lecturas, y también puede ralentizar el vaciado de segmentos WAL que se requiere para confirmar las transacciones.

Ha sido un desafío de larga data, pero está empeorando a medida que vemos sistemas con más y más RAM para que puedan almacenar más datos y tomar más tiempo para escribirlos. Hay una discusión entre las comunidades de Linux y PostgreSQL sobre cómo lidiar con esto en este momento, como se discute en este artículo de LWN.net . (LWN.net no podrá seguir escribiendo este tipo de gran trabajo si las personas no se suscriben. Soy suscriptor y comparto este enlace porque es útil e informativo. Considere suscribirse si desea ver más de esto tipo de cosa.)

Lo principal que puede hacer para reducir el impacto de los puntos de control en este momento es difundir la actividad del punto de control aumentando checkpoint_completion_targetpara que se hayan escrito más datos cuando llegue el punto de control final. Sin embargo, esto tiene un costo: si actualiza una página (digamos) diez veces, podría escribirse en el disco varias veces antes del punto de control con un objetivo de finalización alto, aunque solo tuvo que escribirse estrictamente una vez para evitar accidentes. Un objetivo de finalización más alto hace que los patrones de E / S sean más suaves, pero más sobrecarga general de E / S.

La otra cosa que puede hacer para ayudar es decirle a su sistema operativo que comience a escribir datos inmediatamente cuando se escriben en el búfer. Esto es como el lado del kernel de la configuración checkpoint_completion_targety tiene una compensación similar. Ver la documentación VM Linux , en particular dirty_background_bytes, dirty_background_ratio, dirty_expire_centisecs.

Craig Ringer
fuente
La escritura se extiende durante mucho tiempo y no creo que esté causando problemas. ¿Qué pasa con la sincronización, es por casualidad un tipo de operación para detener el mundo?
Konrad Garus
@KonradGarus La sincronización no debería ser un tipo de operación para detener el mundo, pero a menudo lo es de todos modos. Lea el artículo al que me vinculé anteriormente, es un resumen muy oportuno y útil de los problemas, aunque desde un punto de vista bastante técnico. La versión corta es "fsync () en Linux tiende a arruinar completamente el rendimiento de cualquier E / S concurrente con fsync ()". Puede mitigar eso con las opciones de ajuste enumeradas anteriormente, para reducir la cantidad que debe ser eliminada por un fsync.
Craig Ringer
1

¡Vaciar los buffers sucios del sistema de archivos del sistema operativo causados ​​por exceder dirty_byteso dirty_ratio es una operación de bloqueo en primer plano!

Los elementos ajustables del núcleo dirty_bytes, dirty_background_bytes, dirty_ratio, dirty_background_ratioy dirty_centisecscontrol de lavado de buffers del sistema de archivos del sistema operativo modificados al disco. dirty_byteses el umbral en bytes, dirty_ratioes el umbral como una relación de la memoria total. dirty_background_bytesy dirty_background_ratioson umbrales similares, pero el vaciado ocurre en segundo plano y no bloquea otras operaciones de lectura / escritura hasta que se completa. dirty_centisecses cuántos centisegundos pueden pasar antes de que se inicie una descarga.

Recientemente, los valores predeterminados para estos ajustables se redujeron en Linux, ya que el tamaño de la memoria para las máquinas modernas ha aumentado dramáticamente. Incluso las proporciones de 5 y 10% para dirty_background_ratioy dirty_ratioen una máquina de 256 GB pueden inundar un sistema de E / S.

Poner a punto dirty_background_byteso dirty_background_ratiocomenzar a enjuagar buffers sucios en el fondo es complicado. Afortunadamente, puede ajustar esta configuración sin tener que detener PostgreSQL o el host haciendo eco de los nuevos valores en los archivos apropiados:

$ sudo echo [int value of bytes] > /proc/sys/vm/dirty_background_bytes

por ejemplo, para establecer el número de bytes sucios para activar un vaciado de fondo. Si está utilizando un condensador tarjeta RAID con respaldo, o una memoria flash con respaldo de batería (que no desea mantener sus datos en caso de un accidente, ¿verdad?) Iniciar sintonizando dirty_background_bytesa 1/2 del tamaño de caché de escritura del buffer y dirty_bytesa 3/4 de ese tamaño. Supervise su perfil de E / S con iostatos y si todavía ve problemas de latencia, eso significa que la carga de escritura de su base de datos sigue abrumando los vaciamientos de caché del búfer de archivos. Baje los valores hasta que mejore la latencia o considere actualizar su subsistema de E / S. Las tarjetas FusionIO y las SSD son dos posibilidades para un rendimiento extremo de E / S.

¡Buena suerte!

bobl
fuente
Su comentario sobre datos "sucios" es un punto relevante para la lentitud. Esencialmente: cuanto mayor es la proporción de suciedad, se asigna más búfer para datos sucios antes de que se inicie la descarga. Por lo tanto, minimizar los retrasos de descarga significa aumentar el búfer sucio o aumentar el tiempo que los datos sucios pueden permanecer en la memoria.
Peter Teoh