Tengo un caso de uso para insertar 100 000 filas por minuto al mismo tiempo en otro extremo, algunos subprocesos tomarán las filas y las eliminarán de mi tabla. Entonces definitivamente creará muchas tuplas muertas en mi tabla.
Mis configuraciones de vacío automático son
autovacuum_max_workers = 3 autovacuum_naptime = 1min utovacuum_vacuum_scale_factor = 0.2 autovacuum_analyze_scale_factor = 0.1 autovacuum_vacuum_cost_delay = 20ms autovacuum_vacuum_cost_limit = -1Desde "pg_stat_user_tables" puedo encontrar que el vacío automático se está ejecutando en mi tabla, pero dentro de unas horas mi disco estará lleno (500 GB) y no puedo insertar ninguna fila nueva.
en el segundo intento, cambié la siguiente configuración
autovacuum_naptime = 60min autovacuum_vacuum_cost_delay = 0Esta vez, mi simulación y el vacío automático funcionan bien y el tamaño máximo del disco es de 180 GB.
Aquí mi duda es, si cambio el "autovacuum_vacuum_cost_delay" a cero ms, ¿cómo va el autovacío liberando el espacio de tuplas muertas y el PG lo reutiliza? ¿Por qué no funciona según lo previsto si configuro el valor en 20 ms?
Aquí mi duda es, si cambio el "autovacuum_vacuum_cost_delay" a cero ms, ¿cómo va el autovacío liberando el espacio de tuplas muertas y el PG lo reutiliza?
El espacio liberado por el vacío se registra en el mapa de espacio libre , desde donde se entrega para su reutilización por futuros INSERT.
Otro detalle para agregar, en 9.6, el mapa de espacio libre solo se aspira una vez que toda la mesa está completamente vacía, por lo que el espacio liberado no se puede encontrar hasta entonces. Si VACUUM nunca llega al final, porque es demasiado lento o se interrumpe, entonces el espacio que está liberando no se reutilizará para INSERT. Esto se mejoró en v11.
¿Por qué no funciona según lo previsto si configuro el valor en 20 ms?
Porque el vacío no puede mantenerse a ese valor. Los valores predeterminados para PostgreSQL a menudo son adecuados solo para servidores más pequeños, que el suyo no parece ser. Es adecuado y aconsejable cambiar los valores predeterminados en esta situación. Tenga en cuenta que en v12, el valor predeterminado se redujo de 20 a 2 (y su tipo se cambió correspondientemente de int a float, por lo que ahora puede especificar el valor con más precisión)
Para resumir, su aplicación crea toneladas de tuplas muertas y el vacío automático no puede seguir el ritmo. Soluciones posibles
maintenance_work_mem también podría ayudar a acelerar el vacío automático. Quizás descubra que ha alcanzado los límites de su disco duro. En ese caso, deberá optimizar el almacenamiento para que pueda acomodar esas costosas operaciones INSERT + DELETE + autovacuum .Bueno, el valor predeterminado es Autovacuum 2 ms . Entonces su valor de 20ms es alto:
autovacuum_vacuum_cost_delay (coma flotante)
"Especifica el valor de retardo de costo que se usará en las operaciones automáticas de VACÍO. Si se especifica -1, se usará el valor normal de vacío_costo_retraso. Si este valor se especifica sin unidades, se toma como milisegundos. El valor predeterminado es 2 milisegundos. Este parámetro solo se puede configurar en el archivo postgresql.conf o en la línea de comando del servidor, pero la configuración se puede anular para tablas individuales cambiando los parámetros de almacenamiento de la tabla".
Como se explica aquí Vacío :
" vacuum_cost_delay (coma flotante)
La cantidad de tiempo que el proceso dormirá cuando se exceda el límite de costo. Si este valor se especifica sin unidades, se toma en milisegundos. El valor predeterminado es cero, lo que desactiva la función de demora de vacío basada en costos. Los valores positivos permiten el aspirado basado en costos.
Cuando se utiliza el vaciado basado en costos, los valores apropiados para vacuum_cost_delay suelen ser bastante pequeños, quizás menos de 1 milisegundo. Si bien vacuum_cost_delay se puede establecer en valores de fracciones de milisegundo, es posible que dichos retrasos no se midan con precisión en plataformas más antiguas. En tales plataformas, aumentar el consumo de recursos limitados de VACUUM por encima de lo que obtienes en 1 ms requerirá cambiar los otros parámetros de costo de vacío. Sin embargo, debe mantener el valor de vacuum_cost_delay tan pequeño como su plataforma pueda medir de manera constante; grandes retrasos no son útiles. "