¿Vale la pena ejecutar VACUUM en una tabla que solo recibe INSERTs?

19

En una charla re: Invent de 2015, AWS mencionó que el vacío debe ejecutarse no solo después de actualizaciones o eliminaciones, sino también después de las inserciones. Aquí está la parte relevante de la charla:

http://www.youtube.com/watch?v=tZXp19q8RFo&t=16m2s

Supuestamente, hay una limpieza que se debe hacer en los bloques, incluso si solo recibieron inserciones, y esta limpieza se puede hacer ya sea la primera vez que se selecciona un bloque (ralentizando las lecturas) o durante el vacío. ¿Es esto cierto y, de ser así, exactamente qué limpieza se debe hacer?

foobar0100
fuente

Respuestas:

15

tl; dr: el primer proceso que lee los datos después de confirmarlos establecerá bits de sugerencia. Eso ensuciará la página, creando actividad de escritura. La otra cosa VACUUM(pero no otros comandos) hace es marcar la página como todo visible, si corresponde. VACUUMfinalmente tendrá que golpear la mesa para congelar las tuplas.

El trabajo que debe hacerse después de un inserto no es realmente una limpieza, al menos no en el sentido del otro trabajo que VACUUMnormalmente hace. Antes de entrar en detalles, tenga en cuenta que esta respuesta se basa en el código 9.6 (inédito) actual y estoy ignorando los efectos de la replicación de transmisión, a pesar de que puede afectar la visibilidad.

Debido a MVCC , cada vez que Postgres evalúa si una tupla debe ser visible para una consulta, debe considerar si la transacción que creó la tupla (registrada en el campo oculto xmin) se confirmó, junto con algunos otros criterios. Esa verificación es costosa, por lo que tan pronto como se sabe que una transacción es visible para todas las transacciones abiertas actualmente, se establece un "bit de sugerencia" en el encabezado de tupla que lo indica. La configuración de ese bit ensucia la página, lo que significa que tendrá que escribirse en el disco. Esto puede ser muy confuso si el siguiente comando para leer los datos es SELECTque de repente está creando mucho tráfico de escritura. Ejecutar VACUUMdespués de las confirmaciones de inserción evitará eso. Otra distinción importante es queVACUUMSIEMPRE indicará tuplas en una página (siempre que tenga el bloqueo de limpieza en la página), pero la mayoría de los otros comandos solo darán una pista si la transacción de inserción se confirmó antes de que comenzara el comando.

Un punto importante sobre la escritura de todos estos bits de sugerencia es que VACUUMse puede limitar (y el vacío automático se regula por defecto). Otros comandos no están limitados y generarán datos sucios lo más rápido posible.

VACUUMes el único método para marcar páginas como todo visible, lo cual es una consideración de rendimiento importante para algunas operaciones (en particular, escaneos de índice solamente). Si hace una inserción grande, es muy probable que haya muchas páginas con nada más que tuplas recién insertadas. VACUUMpotencialmente puede marcar esas páginas como todas visibles, pero solo si la transacción en ejecución más antigua cuando se VACUUMinició fue más nueva que la transacción que insertó los datos .

Debido a cómo funciona MVCC, las tuplas que se insertaron hace más de ~ 2 mil millones de transacciones deben marcarse como " congeladas ". Por defecto, el vacío automático se activará para hacer eso cada 200 millones de transacciones. Ejecutar una aspiradora manual con vacuum_freeze_min_age establecida en 0 después de una inserción masiva puede ayudar a reducir el impacto de eso. De manera más agresiva, puede ejecutar VACUUM FREEZEen la tabla después de insertar. Eso "reiniciaría el reloj" cuando ocurriera la próxima exploración congelada.

Si desea conocer los detalles específicos, eche un vistazo al HEAPTUPLE_LIVEcaso después de la llamada al HeapTupleSatisfiesVacuum()interior lazy_scan_heap(). Ver también a HeapTupleSatisfiesVacuum()sí mismo y compararlo con HeapTupleSatisfiesMVCC().

Hay otras dos presentaciones mías que pueden ser interesantes. El primer video está disponible en http://www.pgcon.org/2015/schedule/events/829.en.html , mientras que el segundo (que creo que fue un poco mejor) en https://www.youtube. com / watch? v = L8nErzxPJjQ

Jim Nasby
fuente
Esto es muy interesante, y también explica algunas páginas sucias en ciertos EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least * COMPROMISOS` y *INVALID) puede (podría) ya estar configurado por COMMITo ROLLBACK, ¿verdad?
dezso
3
COMMIT y ROLLBACK en realidad no tocan páginas de datos, por lo que no, esos comandos específicamente nunca podrían insinuar. Un comando DML aún podría establecer estados de sugerencia xmin y xmax, ya sea para tuplas marcadas por otras transacciones o incluso tuplas marcadas por la transacción actual.
Jim Nasby