

# Realización de una inmovilización de vacío manual
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze"></a>

Puede ocurrir que desee realizar una operación de vacío manual en una tabla que ya tenga un proceso de vacío en ejecución. Esto resulta útil si se ha identificado una tabla con una antigüedad cercana a dos mil millones de transacciones (o por encima del umbral que esté monitorizando).

Los siguientes pasos son pautas, con varias variaciones en el proceso. Por ejemplo, durante las pruebas, suponga que descubre que el parámetro [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) se definió en un valor demasiado bajo y que tiene que adoptar medidas de forma inmediata en una tabla. Sin embargo, quizás no desea rebotar la instancia en ese momento. Con las consultas de las secciones anteriores, puede determinar qué tabla está causando el problema y comprobar que hay una sesión de autovacuum que lleva mucho tiempo en ejecución. Sabe que tiene que cambiar el ajuste del parámetro `maintenance_work_mem`, pero también tiene que adoptar medidas de inmediato y aplicar el vacío en la tabla afectada. El siguiente procedimiento muestra qué hacer en esa situación.

**Para realizar manualmente una inmovilización de vacío**

1. Abra dos sesiones en la base de datos que contiene la tabla en la que desea ejecutar el vacío. Para la segunda sesión, use "screen" u otra utilidad que mantenga la sesión activa si se interrumpe la conexión.

1. En la sesión uno, obtenga el ID de proceso (PID) de la sesión de autovacuum que se ejecuta en la tabla. 

   Ejecute la siguiente consulta para obtener el PID de la sesión de autovacuum.

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) LIKE '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. En la sesión dos, calcule la cantidad de memoria que necesitará para esta operación. En este ejemplo, determinamos que podemos permitirnos usar un máximo de 2 GB de memoria para esta operación y, por tanto, definimos [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) en 2 GB para la sesión actual.

   ```
   SET maintenance_work_mem='2 GB';
   SET
   ```

1. En la sesión dos, ejecute el comando `vacuum freeze verbose` para la tabla. El ajuste de informe detallado resulta útil porque, aunque PostgreSQL no ofrece actualmente un informe de progreso para esto, se puede ver la actividad.

   ```
   \timing on
   Timing is on.
   vacuum freeze verbose pgbench_branches;
   ```

   ```
   INFO:  vacuuming "public.pgbench_branches"
   INFO:  index "pgbench_branches_pkey" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  index "pgbench_branches_test_index" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  "pgbench_branches": found 0 removable, 50 nonremovable row versions 
        in 43 out of 43 pages
   DETAIL:  0 dead row versions cannot be removed yet.
   There were 9347 unused item pointers.
   0 pages are entirely empty.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   VACUUM
   Time: 2.765 ms
   ```

1. En la sesión uno, si la limpieza automática bloqueaba la sesión de vacío, `pg_stat_activity` muestra que la espera es `T` para la sesión de vacío. En este caso, finalice el proceso de limpieza automática de la siguiente manera.

   ```
   SELECT pg_terminate_backend('the_pid'); 
   ```
**nota**  
Algunas versiones anteriores de Amazon RDS no pueden finalizar un proceso de limpieza automática mediante el comando anterior y producen el siguiente error: `ERROR: 42501: must be a superuser to terminate superuser process LOCATION: pg_terminate_backend, signalfuncs.c:227`. 

   En este punto, comienza la sesión. La limpieza automática se reinicia inmediatamente, ya que esta tabla es probablemente la que ocupa una posición más alta en la lista de trabajo. 

1. Inicie el comando `vacuum freeze verbose` en la sesión dos y luego finalice el proceso de autovacuum en la sesión uno.