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. VACUUM
finalmente 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 VACUUM
normalmente 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 SELECT
que de repente está creando mucho tráfico de escritura. Ejecutar VACUUM
después de las confirmaciones de inserción evitará eso. Otra distinción importante es queVACUUM
SIEMPRE 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 VACUUM
se 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.
VACUUM
es 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. VACUUM
potencialmente puede marcar esas páginas como todas visibles, pero solo si la transacción en ejecución más antigua cuando se VACUUM
inició 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 FREEZE
en 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_LIVE
caso 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
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 porCOMMIT
oROLLBACK
, ¿verdad?