Optimizando PostgreSQL para datos transitorios


8

Tengo varias tablas con 100-300 columnas de tipos enteros cada una, que contienen datos altamente volátiles. Los conjuntos de datos están codificados por una o dos claves principales, y cuando se produce la actualización, se elimina todo el conjunto de datos y se insertan datos nuevos en una transacción. El tamaño del conjunto de datos suele ser de unos cientos de filas, pero puede ser de varios miles de filas en casos extremos. La actualización se produce una vez por segundo, y las actualizaciones de conjuntos de datos para diferentes claves generalmente están desarticuladas, por lo que no es posible descartar y volver a crear la tabla.

¿Cómo ajusto Postgres para manejar dicha carga? Puedo usar la última y mejor versión si eso hace alguna diferencia.

Respuestas:


7

Dependiendo de cuántos conjuntos de datos diferentes hay, una opción sería dividir las tablas por conjunto de datos.

Cuando se actualiza un conjunto de datos, BEGINuna nueva transacción, TRUNCATEla tabla, COPYlos nuevos datos en él y COMMIT. PostgreSQL tiene una optimización en COPYing en una tabla que ha sido TRUNCATEd en la misma transacción hace mucho menos de E / S si está utilizando wal_level = minimal(por defecto).

Si no puede particionar y truncar (por ejemplo, si se trata de decenas o cientos de miles de conjuntos de datos, donde habría demasiadas tablas), en su lugar, querrá aumentar el vacío automático para ejecutar todo lo que pueda , asegúrese de tener buenos índices en todo lo que elimine en función de, y esté preparado para un rendimiento algo normal.

Si no necesita protección contra fallas, no le importa que sus tablas estén vacías después de una falla del sistema, también puede crear sus tablas como UNLOGGED, lo que le ahorrará una gran cantidad de costos de E / S.

Si no le importa tener que restaurar toda la configuración desde una copia de seguridad después de un bloqueo del sistema, puede ir un paso más allá y también configurar fsync=off, lo que básicamente le dice a PostgreSQL "no se preocupe por la seguridad del bloqueo, tengo buenas copias de seguridad y no No me importa si mis datos son irrecuperables de forma permanente y total después de un bloqueo, y estoy feliz de poder recuperarlos initdbantes de poder usar mi base de datos nuevamente ".

Escribí algo más sobre esto en un hilo similar en Stack Overflow sobre la optimización de PostgreSQL para pruebas rápidas ; que menciona el ajuste del sistema operativo host, separando WAL en un disco diferente si no está utilizando unloggedtablas, ajustes de puntero de verificación, etc.

También hay información en los documentos de Pg para la carga rápida de datos y configuraciones no duraderas .


Gracias por la sugerencia de partición, nunca pensé en usarlos en este caso. En cuanto a las tablas no registradas, ¿quiere decir que terminan vacías de forma predeterminada después del bloqueo del sistema? No hace ninguna diferencia, solo tengo curiosidad.
Alex Tokarev

1
@AlexTokarev Eso es correcto; después de que PostgreSQL se cierre de manera sucia (postmaster o un backend segfaults, los ciclos de alimentación del sistema de repente, el backend se SIGKILLedita, etc.) cualquier UNLOGGEDtabla puede ser TRUNCATEd, por lo que están vacías al inicio. No se truncan después de un apagado y reinicio limpios, pero no debe confiar en que sean duraderos.
Craig Ringer

Gracias por la explicación. No necesito seguridad de datos para las tablas en cuestión, los datos en ellas son transitorios y se actualizan desde la fuente cada segundo. Sin embargo, desactivar fsync no es una opción, ya que hay otras tablas más tradicionales en el mismo esquema que deben ser seguras y recuperables. Tener la UNLOGGEDopción por mesa es simplemente genial.
Alex Tokarev

Estoy mirando el documento de partición y parece que podría ser una solución (casi) perfecta para el problema. Sin embargo, una pregunta: si voy a tener una tabla principal para el esquema y las tablas secundarias para contener los datos, voy a consultar los datos de la tabla principal, ¿verdad? Si existe una tabla secundaria para ese rango, la consulta la devolverá; de lo contrario, devolverá un conjunto de datos vacío. En ese caso, incluso puedo soltar y volver a crear tablas secundarias para cada lote de datos nuevos. Dadas las circunstancias, ¿qué será más efectivo TRUNCATEo DROP/CREATE TABLEsecuencia?
Alex Tokarev

@AlexTokarev Te recomendaría TRUNCATEpersonalmente. La rotación DDL tiene sus propios costos. Dado que está haciendo cambios con tanta frecuencia, será muy importante asegurarse de activar la agresividad de autovacuum pg_catalog.pg_classy otras tablas del sistema que podrían hincharse bajo esa carga de trabajo.
Craig Ringer
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.