Blog de Amazon Web Services (AWS)

Entendiendo el proceso de auto limpieza (autovacuum) en ambientes Amazon RDS PostgreSQL

Por Anuraag Deekonda e
Baji Shaik

 

PostgreSQL se ha convertido en la base de datos relacional de código abierto preferida para muchos desarrolladores y empresas de nueva creación, ya que potencia a las aplicaciones comerciales y móviles. Amazon Web Services (AWS) ofrece Amazon Relational Database Service (Amazon RDS) y Amazon Aurora como servicios de bases de datos relacionales completamente administrados. Amazon RDS para PostgreSQL facilita la configuración, el funcionamiento y el escalado de las implementaciones de PostgreSQL en la nube. Con algunos comandos, usted puede tener su instancia de base de datos de producción lista y ejecutándose en AWS. Una base de datos administrada libera al administrador de la base de datos de muchas tareas de mantenimiento y administración. Sin embargo, hay algunas tareas de mantenimiento, como el proceso de limpieza (VACUUM), que necesitan un monitoreo cercano y una afinación dependiendo del uso de la base de datos. El proceso de auto limpieza (Autovacuum) es el proceso que automatiza la actividad de eliminación definitiva de tuplas marcadas para borrar y reorganiza los datos a nivel físico.

En este articulo, hablaremos del proceso de auto limpieza y su importancia. También cubrimos ajustes del proceso de auto limpieza para un mejor rendimiento y las desventajas de apagarlo.

MVCC en PostgreSQL

PostgreSQL utiliza Control de Concurrencia mediante Versiones Múltiples (Multi-Version Concurrency Control, MVCC) para mantener múltiples versiones de una fila al realizar modificaciones de datos. Durante las operaciones UPDATE y DELETE en una tabla, la base de datos conserva las versiones antiguas de las filas para otras transacciones en ejecución que puedan necesitar una vista consistente de los datos. En PostgreSQL, cada sentencia que modifica la base de datos genera un identificador de transacción, denominado xid. El estado de una fila se rastrea usando el xid en dos columnas ocultas, xmin y xmax.

Considere la tabla mvcc_test con una columna. Para insertar una fila, use el siguiente código:

postgres=# CREATE TABLE mvcc_test(id int);
CREATE TABLE
postgres=# INSERT INTO mvcc_test VALUES(1);
INSERT 0 1
postgres=# SELECT xmin, xmax, id FROM mvcc_test;
 xmin | xmax | id
------+------+----
 100 |    0 |  1
(1 row)

xmin representa el xid a través del cual se insertó la fila, y xmax suele ser 0 para las filas visibles. Si xmax es mayor que 0, representa una fila caducada que no es visible. Sin embargo, en algunos casos, xmax es más de 0 pero la fila sigue siendo visible. Esto ocurre si actualizas o eliminas algo en la transacción y se revierte la transacción.

Si eliminas una fila, una versión de esa fila aun aparece para mantener el MVCC. En este caso, para la fila eliminada, xmin es el xid de la sentencia INSERT a través de la cual se insertó la fila, y xmax se convierte en el xid de la sentencia DELETE a través de la cual se eliminó la fila.

En PostgreSQL, una operación de UPDATE se considera como DELETE e INSERT. Borra la fila anterior e inserta una nueva fila. Ambas filas se mantienen para cumplir el MVCC. En este caso, para la fila antigua, xmin es el xid a través del cual se insertó la fila, y xmax es el xid a través del cual se actualizó la fila. Para una nueva fila, xmin es el xid a través del cual se actualizó la fila, y xmax es 0 porque la fila es visible.

El siguiente diagrama resume el comportamiento de MVCC.

Para obtener más información, consulte Control de concurrencia en el sitio web de PostgreSQL.

Las filas caducadas originadas por UPDATE y DELETE se denominan filas muertas o tuplas muertas. Una tabla con estas tuplas muertas es una tabla inflada. A menos que usted limpie esas filas muertas, no puedes recuperar ni eliminar el espacio que están usando. Para reutilizar estas filas muertas, se utiliza el comando VACUUM.

El proceso de limpieza (VACUUM) escanea todas las páginas de la tabla (también conocidas como montón(heap)) que pueden contener versiones de filas muertas. Una estructura de datos llamada mapa de visibilidad (visibility map) realiza un seguimiento de qué páginas han sido modificadas desde el último proceso de limpieza. El proceso de limpieza elimina las versiones de fila muerta de esas páginas y hace que ese espacio esté disponible para su reutilización.

Introducción al proceso de limpieza

El proceso de auto limpieza (Autovacuum) es un servicio que automatiza la ejecución de los comandos VACUUM y ANALYZE (para recopilar estadísticas). El proceso de auto limpieza comprueba si hay tablas infladas en la base de datos y recupera el espacio para su reutilización.

Flujo de trabajo del proceso de Auto limpieza

El servicio de auto limpieza está diseñado con dos tipos diferentes de procesos: el iniciador (autovacuum launcher) y el ejecutor de auto limpieza (autovacuum worker).

El iniciador de auto limpieza es un proceso predeterminado que el proceso maestro (postmaster) inicia cuando el parámetro auto limpieza está activado. El proceso maestro actúa como mecanismo de procesamiento de solicitudes al sistema PostgreSQL. Todos los programas de interfaz (front-end) envían un mensaje de inicio al servicio maestro, y el servicio maestro usa la información del mensaje e inicia el proceso de fondo (back-end). El proceso iniciador de auto limpieza decide el momento adecuado para iniciar el proceso de trabajo de limpieza para ejecutar las operaciones de limpieza en las tablas.

El ejecutor de auto limpieza es el proceso de trabajo real que ejecuta las operaciones de limpieza en las tablas. Se conecta a la base de datos según lo programado por el iniciador, lee las tablas del catálogo y selecciona una tabla para ejecutar la operación de limpieza.

El proceso iniciador de auto limpieza continua monitoreando las tablas en la base de datos y selecciona la tabla adecuada para un trabajo de limpieza después de que una tabla alcance el límite para auto limpieza. Este limite se basa en parámetros como  autovacuum_vacuum_thresholdautovacuum_analyze_thresholdautovacuum_vacuum_scale_factor, y autovacuum_analyze_scale_factor.

autovacuum_vacuum_threshold y autovacuum_analyze_threshold

Estos parámetros determinan el número mínimo de actualizaciones o eliminaciones en una tabla para que la tabla sea programada para un proceso de auto limpiezay un auto analizador (autoanalyzer), respectivamente. El valor predeterminado para ambos es 50.

autovacuum_vacuum_scale_factor y autovacuum_analyze_scale_factor

Estos parámetros determinan el porcentaje de cambios que una tabla necesita tener para que la tabla sea programada para un proceso de auto limpieza y un proceso auto analizador, respectivamente. El valor predeterminado para autovacuum_vacuum_scale_factor es 0.2 (20%), y autovacuum_analyze_scale_factor es 0.1 (10%).

Ambos valores son adecuados para las tablas si el número de filas en la tabla no es demasiado alto. Sin embargo, para tablas con un gran número de filas, los valores predeterminados para estos parámetros representan una gran cantidad de cambios en filas, lo que es mucho trabajo de limpieza cuando entra en acción. Sin embargo, si las tablas grandes son minoría en la base de datos, es mejor establecer estos parámetros a nivel de la tabla en lugar de en el archivo de configuración.

Para obtener más información sobre estos parámetros, consulte Limpieza automática en el sitio web de PostgreSQL.

Para calcular el limite, utilice la siguiente fórmula:

limite de limpieza (vacuum threshold) = limite base de limpieza + factor de escala de limpieza * número de tuplas vivas. Utilice los siguientes valores:

  • Limite base de limpieza  – autovacuum_vacuum_threshold
  • Factor de escala de limpieza  – autovacuum_vacuum_scale_factor
  • Número de tuplas vivas – El valor de  n_live_tup de la vista pg_stat_all_tables

El iniciador de auto limpieza no puede iniciar el proceso de trabajo de auto limpieza por sí solo; esto lo hace el proceso maestro. El iniciador almacena la información sobre las bases de datos en el área de memoria compartida de auto limpieza, establece una bandera en la memoria compartida y envía una señal al proceso maestro. El proceso maestro inicia el proceso ejecutor de auto limpieza. Este nuevo proceso de trabajo lee la información de la memoria compartida, se conecta a la base de datos requerida y completa el trabajo de limpieza.

Si el proceso maestro no inicia un proceso de trabajo, establece un indicador en la memoria compartida y envía una señal al proceso iniciador. Al leer la señal del proceso maestro, el iniciador intenta nuevamente iniciar el proceso de trabajo enviando la señal al proceso maestro (la falla del proceso maestro para iniciar un proceso de trabajo puede deberse a una alta carga y saturación de memoria o a demasiados procesos que ya se están ejecutand).

Cuando el proceso de trabajo de auto limpieza completa las operaciones de limpieza, envía una señal al iniciador. Cuando el iniciador recibe la señal del ejecutor, el iniciador se activa e intenta iniciar otro proceso de trabajo si la lista de tablas a limpiar es demasiado alta en la memoria compartida. Esto es para que los demás ejecutores eviten quedar bloqueados al esperar un bloqueo de limpieza para esa tabla. También actualizan los datos en tabla pgstats justo antes de limpiar cada tabla, para evitar limpiar una tabla que otro proceso ejecutor acaba de limpiar y por lo tanto ya no se registra en la memoria compartida.

Una idea equivocada en PostgreSQL es que el proceso de auto limpieza causa incrementos  en operaciones de E/S (I/O), por lo tanto, muchos optan por apagar completamente el proceso de auto limpieza. Esto podría parecer una solución efectiva en las etapas iniciales del ambiente, pero cuando la base de datos comienza a crecer en tamaño, es posible que exista mucho espacio ocupado por las tuplas muertas, lo que provoca lentitud rápidamente y aumenta el tamaño de su base de datos.

Ventajas del proceso de auto limpieza

En esta sección hablaremos de las cosas importantes que el proceso de auto limpieza cuida cuando está encendido. También explicaremos los problemas que presentarían cuando está apagado.

Actualizando estadísticas

El proceso ANALYZE de PostgreSQL colecta y calcula las estadísticas de las tablas. El planificador de consultas utiliza estas estadísticas para ejecutar un plan de consulta. Esta información es calculada y recopilada por el proceso ANALYZE y guarda las estadísticas en las tablas del catálogo. A continuación, el planificador de consultas crea un plan de consulta para obtener los datos.

En un escenario similar, si el proceso de auto limpieza está desactivado, el proceso ANALYZE no colecta ni calcula las estadísticas. El planificador de consultas no tiene información sobre la tabla, lo que lleva a hacer un mal plan de consulta, lo que no es adecuado.

Prevención del envolvimiento de transacciones

Como se explicó anteriormente, PostgreSQL asigna un número a la transacción como identificador de transacción. Debido a que el identificador de transacción es un número, debe tener límites como los valores máximo y mínimo a permitir (no se pueden generar números infinitos).

PostgreSQL elige un entero de 4 bytes como número definido para el identificador de transacción. Es decir, el número máximo de identificador de transacción que puede generar con 4 bytes es de 2^32 ~ 4294967296, que es de 4 mil millones de identificadores de transacción. Pero PostgreSQL puede manejar un número ilimitado de transacciones con el entero de 4 bytes rotando los identificadores de transacción de 1 a 2^31 ~ 2147483648. Es decir, si PostgreSQL alcanza el identificador de transacción 2147483648, asigna el identificador de transacción de 1 a 2^31 para transacciones entrantes adicionales. En la terminología PostgreSQL, este método de rotación del identificador de transacción se denomina envolvimiento de identificador de transacción (transaction ID wraparound).

Como ejemplo de un caso de uso de envolvimiento de identificador de transacción típico, asuma el identificador de transacción actual como 100. Después de alcanzar el límite de transacción 2^31, el identificador de transacción actual solo puede ver la información confirmada de sus identificadores de transacción anteriores y no las transacciones futuras. Debido a que todos los identificadores de transacción de 101 a 2^31 son identificadores futuros para la transacción actual, el identificador de transacción actual 100 no puede ver ninguna fila en la base de datos cuyo identificador  de transacción sea superior a 100, lo que lleva a la falta de disponibilidad de la base de datos. Para evitar este problema de envolvimiento de identificador de transacción, puede congelar (freeze) el identificador de transacción (transaction ID).

Congelar un identificador de transacción significa convertir el valor de un identificador de transacción en un identificador de transacción congelado, que es un valor de 2. Como se mencionó anteriormente, cuando alcanza el identificador de transacción 100 como resultado del envolvimiento de transacción, no puede ver las transacciones adicionales confirmadas desde el identificador de transacción 101 hasta el 2^31. Si cambias todos estos identificadores a 2, PostgreSQL puede mostrar toda la información de los identificadores de transacción confirmados.

La operación de congelamiento realiza un proceso similar en las tablas. Lógicamente convierte todos los identificadores de transacción anteriores a 2. Después de ejecutar el comando VACUUM FREEZE, verá el xmin igual que el identificador anterior pero internamente mantiene el valor congelado:

postgres=# select xmin, xmax, * from freeze_test ;
 xmin | xmax | id | name 
------+------+----+------
 1002 |    0 |  1 | test
(1 row)
postgres=# VACUUM FREEZE freeze_test ;
VACUUM
postgres=# select xmin, xmax, * from freeze_test ;
 xmin | xmax | id | name 
------+------+----+------
 1002 |    0 |  1 | test
(1 row)

El proceso de auto limpieza visita cada fila de cada página y congela los identificadores de transacción. Se puede utilizar esta opción de congelación para evitar el problema envolvimiento cuando la antigüedad de identificador de transacción de base de datos alcanza autovacuum_freeze_max_age. La antigüedad de un identificador de transacción es simplemente cuántas transacciones se realizaron en una tabla o base de datos sin ninguna operación de congelamiento o después de la operación de congelamiento. Siempre que la antigüedad de la transacción de la base de datos alcanza autovacuum_freeze_max_age, PostgreSQL inicia el proceso de auto limpieza instantáneamente para realizar la operación de congelación en toda la base de datos.

Monitoreo del proceso de auto limpieza

Para asegurarse de que el proceso de auto limpieza funcione de manera efectiva, debe monitorear regularmente las filas muertas, el uso de espacio en disco y la última vez que se ejecuto el proceso de auto limpieza o la ejecución del comando ANALYZE.

Tuplas muertas

PostgreSQL ofrece la vista pg_stat_user_tables, que proporciona información sobre cada tabla (relname) y cuántas filas muertas (n_dead_tup) hay en la tabla.

El monitoreo del número de filas muertas en cada tabla, especialmente las tablas que se actualizan con frecuencia, ayuda a determinar si los procesos de auto limpieza las están eliminando periódicamente para que su espacio en disco pueda ser reutilizado para un mejor rendimiento. Puede utilizar la siguiente consulta para verificar el número de tuplas muertas y cuándo se ejecutó el último proceso de auto limpieza en las tablas:

SELECT
relname AS TableName
,n_live_tup AS LiveTuples
,n_dead_tup AS DeadTuples
,last_autovacuum AS Autovacuum
,last_autoanalyze AS Autoanalyze
FROM pg_stat_user_tables;

Disco usado por tablas

El seguimiento de la cantidad de espacio en disco que usa cada tabla es importante porque le permite analizar los cambios en el rendimiento de una consulta a lo largo del tiempo. También puede ayudar a detectar problemas relacionados con la limpieza. Por ejemplo, si recientemente agregó muchos datos nuevos a una tabla y ve un aumento inesperado en el uso del disco de la tabla, esa tabla puede tener un problema de limpieza.

El proceso de limpieza ayuda a marcar filas obsoletas como disponibles para su reutilización, por lo que si el proceso de limpieza no se ejecuta regularmente, los datos recién agregados utilizan espacio en disco adicional en lugar de reutilizar el espacio en disco ocupado por las filas muertas.

Último proceso de auto limpieza y  auto analizador

La vista pg_stat_user_tables le da información sobre la última vez que el proceso de auto limpieza se ejecutó sobre una tabla. Puede verificar si el proceso de auto limpieza está funcionando de manera eficiente mediante el uso de las columnas autovacuum y autoanalyze . La siguiente consulta le da detalles de last_autovacuum y last_autoanalyze ejecutados en las tablas:

SELECT relname, last_autovacuum,last_autoanalyze FROM pg_stat_user_tables;

Habilitar log_autovacuum_min_duration

El parámetro log_autovacuum_min_duration le ayuda a registrar cada acción que ejecutó el proceso de auto limpieza. Las acciones se registran cuando el proceso de auto limpieza es ejecutado en un número especificado de milisegundos o excede los parámetros de almacenamiento de la tabla. Si establece este parámetro en 150 milisegundos, se registran todos los procesos de auto limpieza que se ejecuten en 150 milisegundos o más. Además, cuando este parámetro se establece en cualquier valor que no sea -1, se registra un mensaje si se omite una acción del proceso de auto limpieza debido a un conflicto de bloqueo. También puede proporcionar más información sobre lentitud de los procesos de auto limpieza.

Habilitación de una alerta de Amazon CloudWatch

Usted puede configurar una alerta de Amazon CloudWatch para detectar el envolvimiento de transacciones. Para obtener más información, consulte Implementar un sistema de alerta temprana para envolvimiento de identificador de transacción en Amazon RDS para PostgreSQL.

También puede usar las métricas de CloudWatch para monitorear el uso general de los recursos del sistema y asegurarse de que esté dentro de un rango aceptable cuando las sesiones de auto limpieza se ejecuten simultáneamente.

Problemas comunes relacionados con el proceso de auto limpieza

Si las estadísticas anteriores indican que el servicio de auto limpieza no está funcionando eficientemente en la base de datos, puede ser por varias razones. En la siguiente sección se discuten algunas de las posibles razones.

Ajuste de parámetros de auto limpieza

Si el proceso de auto limpieza no está activando el proceso de limpieza en las tablas regularmente, o no está funcionando de manera eficiente, considere ajustar los parámetros de auto limpieza. El proceso de auto limpieza depende de varios ajustes de configuración para decidir cuándo debe ejecutar automáticamente los comandos VACUUM y ANALYZE en sus tablas.

El siguiente código proporciona la lista de parámetros de auto limpieza que debe considerar ajustar:

select category, name,setting,unit,source,min_val,max_val from pg_settings where category = 'Autovacuum' ;
 
  category |                name                 | setting   | unit |       source       | min_val |  max_val   | boot_val 
------------+-------------------------------------+-----------+------+--------------------+---------+------------+-----------
Autovacuum | autovacuum                          | on        |      | default            |         |            | on
Autovacuum | autovacuum_analyze_scale_factor     | 0.05      |      | configuration file | 0       | 100        | 0.1
Autovacuum | autovacuum_analyze_threshold        | 50        |      | default            | 0       | 2147483647 | 50
Autovacuum | autovacuum_freeze_max_age           | 200000000 |      | default            | 100000  | 2000000000 | 200000000
Autovacuum | autovacuum_max_workers              | 3         |      | default            | 1       | 262143     | 3
Autovacuum | autovacuum_multixact_freeze_max_age | 400000000 |      | default            | 10000   | 2000000000 | 400000000
Autovacuum | autovacuum_naptime                  | 30        | s    | configuration file | 1       | 2147483    | 60
Autovacuum | autovacuum_vacuum_cost_delay        | 20        | ms   | default            | -1      | 100        | 20
Autovacuum | autovacuum_vacuum_cost_limit        | -1        |      | default            | -1      | 10000      | -1
Autovacuum | autovacuum_vacuum_scale_factor      | 0.1       |      | configuration file | 0       | 100        | 0.2
Autovacuum | autovacuum_vacuum_threshold         | 50        |      | default            | 0       | 2147483647 | 50

En el resultado anterior, la columna Settings muestra los valores configurados actuales. La columna boot_val muestra los valores predeterminados para los parámetros de auto limpieza establecidos por PostgreSQL, los cuales son usados si no existen cambios en los parámetros predeterminados. El ajuste de estos parámetros de auto limpieza asegura que su proceso de auto limpieza  funcione de manera frecuente y eficiente en las tablas.

Para obtener más información sobre la afinación del proceso auto limpieza, consulte Un caso de estudio de la afinación del proceso de auto limpieza en Amazon RDS for PostgreSQL.

Auto limpieza omitida debido a conflictos de bloqueo

Si ya optimizó sus ajustes de auto limpieza y observa que el servicio de auto limpieza omite la limpieza de algunas tablas, podría deberse a bloqueos EXCLUSIVOS en las tablas.

Para ejecutar una limpieza sobre una tabla, el proceso de auto limpieza tiene que adquirir un bloqueo SHARE UPDATE EXCLUSIVE, que entra en conflicto con otros bloqueos porque dos transacciones no pueden contener un bloqueo SHARE UPDATE EXCLUSIVE al mismo tiempo. Esto es lo mismo para otros modos de bloqueo como SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, y ACCESS EXCLUSIVE .

 

El bloqueo SHARE UPDATE EXCLUSIVE no bloquea operaciones de SELECT, UPDATE, INSERT, o DELETE. Solo bloquea las transacciones con los siguientes bloqueos:

  • SHARE UPDATE EXCLUSIVE — Adquirido por VACUUM (sin FULL), ANALYZE, CREATE INDEX CONCURRENTLY, REINDEX CONCURRENTLY, CREATE STATISTICS, y ciertas variantes ALTER INDEX y ALTER TABLE.
  • SHARE — Adquirido por CREATE INDEX (sin CONCURRENTLY).
  • SHARE ROW EXCLUSIVE — Adquirido por CREATE TRIGGER y algunas formas de ALTER TABLE.
  • EXCLUSIVE — Adquirido por REFRESH MATERIALIZED VIEW CONCURRENTLY.
  • ACCESS EXCLUSIVE — Adquirido por los comandos DROP TABLE, TRUNCATE, REINDEX, CLUSTER, VACUUM FULL, y REFRESH MATERIALIZED VIEW (sin CONCURRENTLY). Muchas formas de ALTER INDEX y ALTER TABLE también adquieren un bloqueo en este nivel.

Por lo tanto, si alguna transacción viene con una solicitud para mantener uno de estos modos de bloqueo sobre una tabla, y si el servicio de auto limpieza ya está ejecutando un trabajo de limpieza en una de esas tablas, inmediatamente cancela el trabajo de limpieza para que la otra transacción pueda tomar los bloqueos. De igual manera, si alguna transacción ya tiene un bloqueo ACCESS EXCLUSIVE en una tabla, el proceso de auto limpieza evita que esas tablas pasen por el proceso de limpieza. El proceso de auto limpieza mantiene las tablas omitidas para ejecutar un trabajo de limpieza en la siguiente iteración.

Acción de auto limpieza omitida debido a transacciones de larga duración

Debido a que PostgreSQL se basa en el concepto de Control de Concurrencia mediante Versiones Múltiples (MVCC), el proceso de auto limpieza no limpia las tuplas muertas si una o más transacciones están accediendo a la versión desactualizada de los datos. Si alguna transacción está trabajando en una imagen de los datos (snapshot) que se tomaron antes de que los datos fueran eliminados o actualizados, el proceso de auto limpieza omite esas tuplas muertas, y esas tuplas muertas se limpian en la siguiente iteración. Esto suele ocurrir con transacciones de larga duración en su base de datos. Para encontrar las transacciones de larga duración en su base de datos, ingrese el siguiente código:

SELECT now()-query_start as Running_Since, pid, datname, usename, application_name, client_addr , left(query,60) FROM pg_stat_activity WHERE state in ('active','idle in transaction') AND (now() - query_start) > interval '5 minutes';

Es una buena práctica incluir el valor idle in transaction  como parte del monitoreo porque esas podrían hacer que el proceso de auto limpieza omita filas muertas.

Mejores prácticas de auto limpieza

En esta sección hablaremos de las mejores prácticas para ejecutar el proceso de auto limpieza.

Asignación de Memoria para el proceso de auto limpieza

El parámetro maintenance_work_mem es un parámetro importante que influye en el rendimiento del proceso de auto limpieza. Decide cuánta memoria usar para el proceso de auto limpieza para escanear las tablas en una base de datos y contiene los identificadores de filas que necesitan limpieza.

Establecer el parámetro con un valor bajo hace que el proceso de limpieza escanee la tabla varias veces para completar el trabajo de limpieza, lo cual afecta negativamente el rendimiento de la base de datos.

Si tiene muchas tablas pequeñas, asigne más autovacuum_max_workers y menos maintenance_work_mem. Si tiene tablas grandes (más de 100 GB), asigne más memoria y menos procesos de trabajo. Debe tener suficiente memoria asignada para una ejecución de limpieza exitosa en su tabla más grande. Cada autovacuum_max_workers puede usar la memoria que asigne. Por lo tanto, debe de asegurarse que la combinación de procesos de trabajo y memoria sea igual a la memoria total que desea asignar.

Para instancias más grandes, configure maintenance_work_mem en al menos 1 GB, mejorará significativamente el rendimiento del proceso de auto limpieza de las tablas con una gran cantidad de tuplas muertas. Sin embargo, tenga en cuenta que el proceso de limpieza limita el uso de memoria a 1 GB, lo cual es suficiente para procesar alrededor de 179 millones de tuplas muertas en una sola pasada. Limpiar una tabla con más tuplas muertas que eso requerirá múltiples pasadas a través de los índices de las tablas, lo que puede provocar que la limpieza tarde significativamente más. Se puede calcular cuántas tuplas muertas puede procesar el proceso de limpieza en una sola pasada dividiendo maintenance_work_mem (en bytes) entre 6.

Al establecer los parámetros autovacuum_work_mem o maintenance_work_mem se establece el tamaño máximo de memoria que cada proceso de trabajo de auto limpieza deberá de usar. Por defecto, autovacuum_work_mem se establece en -1, lo que indica que para la asignación de memoria para el proceso de trabajo de auto limpieza deberá de usar la configuración maintenance_work_mem.

Amazon RDS ha actualizado su valor predeterminado para que este parámetro sea en KBs calculados como

GREATEST({DBInstanceClassMemory/63963136*1024},65536).

Para obtener más información, consulte Asignación de memoria para auto limpieza y Un caso de estudio de afinación de auto limpieza en Amazon RDS para PostgreSQL.

Reducir las posibilidades de envolvimiento de identificador de transacción

En algunos casos, los ajustes de auto limpieza no son lo suficientemente agresivos como para evitar el envolvimiento de identificador de transacción. Para abordar este problema, Amazon RDS cuenta con un mecanismo que ajusta automáticamente los valores de los parámetros de auto limpieza.

Con el parámetro adaptativo para auto limpieza habilitado, Amazon RDS comienza ajustar los parámetros de auto limpieza cuando la métrica de CloudWatch MaximuMusedTransactionIds alcanza los 750.000.000 o el parámetro autovacuum_freeze_max_age, lo que sea mayor.

Amazon RDS continúa ajustando los parámetros para el proceso de auto limpieza cuando una tabla continúa con una tendencia hacia el envolvimiento de identificador de transacción. Cada ajuste dedica más recursos al proceso de auto limpieza para evitar envolvimiento. Amazon RDS actualiza los siguientes parámetros relacionados con el proceso de auto limpieza:

  • autovacuum_vacuum_cost_delay — La cantidad de tiempo especificada en milisegundos que el proceso de auto limpieza se suspende cuando excede el límite. El valor predeterminado es 20 milisegundos.
  • autovacuum_vacuum_cost_limit — El costo acumulado que hace que el proceso de auto limpieza se suspenda. El valor predeterminado es 200.
  • autovacuum_work_mem — La cantidad máxima de memoria utilizada por cada proceso de trabajo de auto limpieza. Por defecto es -1, lo que indica que se debe usar el valor de maintenance_work_mem.
  • autovacuum_naptime — Especifica el retraso mínimo entre las ejecuciones del proceso de auto limpieza en una base de datos. En cada ciclo, el servicio examina la base de datos y usa los comandos VACUUM y ANALYZE según sea necesario para las tablas de esa base de datos. El retraso se mide en segundos, y el valor predeterminado es de 1 minuto. Sólo se puede establecer este parámetro en el archivo conf o en la línea de comandos del servidor.

Amazon RDS modifica estos parámetros solo si los valores existentes no son lo suficientemente agresivos. Estos parámetros se modifican en la memoria de la instancia de base de datos y no se cambian en el grupo de parámetros.

Siempre que Amazon RDS modifique alguno de estos parámetros de auto limpieza, genera un evento para la instancia de base de datos afectada, esto se puede ver en la consola de administración de AWS a través de la API de Amazon RDS. Después de que la métrica MaximuMusedTransactionIds de CloudWatch regresa abajo del limite, Amazon RDS restablece los parámetros relacionados con el proceso de auto limpieza en la memoria a los valores especificados en el grupo de parámetros.

Ajuste de auto limpieza a nivel de tabla

En un entorno de PostgreSQL en crecimiento basado en la configuración global del proceso de auto limpieza, es probable que vea que las tablas grandes no se limpian de manera efectiva y las tablas pequeñas se limpian con frecuencia. Para evitar estos escenarios, puede establecer sus parámetros de auto limpieza a nivel de tabla con los siguientes pasos:

  1. Enumere las tablas grandes en sus ambientes.
  2. Enumere las tablas que tienen un alto número de cambios.
  3. Vea qué tablas tienen un alto número de ‘n_dead_tup.
  4. Vea cuándo las tablas han sido auto analizadas y auto limpiadas por última vez.
  5. Cambie el parámetro auto limpieza y auto análisis a nivel de tabla.

Resumen

Las tuplas muertas pueden comprometer el rendimiento de una base de datos PostgreSQL porque continúan ocupando espacio y pueden provocar inflación de la tabla. Puede utilizar el proceso de limpieza (VACUUM) para eliminar tuplas muertas y reutilizar el espacio para futuras inserciones y actualizaciones. También puede usar ANALYZE en la tabla, lo cual actualiza las estadísticas de la tabla para que el optimizador pueda elegir planes de ejecución óptimos para una sentencia SQL. El proceso de auto limpieza le ayuda a eliminar la inflación de la tabla, reducir el uso del espacio en disco de la tabla y actualizar las estadísticas de tabla regularmente para que el planificador de consultas funcione de manera adecuada.

Existe la idea errónea de que el proceso de auto limpieza provoca lentitud a la base de datos porque causa muchas operaciones E/S, sin embargo, aunque genere un poco de operaciones de E/S, si la afinación es correcta y sigue las mejores prácticas, puede ser muy beneficioso para su entorno de Amazon RDS para PostgreSQL. Desactivar el proceso de auto limpieza causa problemas de rendimiento y problemas de envolvimiento de transacciones, lo que provoca que su base de datos deje de funcionar, por lo que nunca debe apagarlo.

 

Este artículo fue traducido del Blog de AWS en Inglés.

 


Acerca de los autores

Anuraag Deekonda es Consultor Asociado del equipo de AWS ProServe en India. Como especialista en migración, trabaja en estrecha colaboración con clientes que están migrando sus cargas de trabajo de sus entornos locales (on-premise) a la nube de AWS. Él ha ayudado a clientes a reconfigurar sus aplicaciones y bases de datos en el proceso de migración. Él apoya a los clientes para que construyan soluciones altamente escalables, disponibles y seguras. Es un apasionado de PostgreSQL, MySQL y otras bases de datos de código abierto.

 

 

 

 

Baji Shaik es Consultor Asociado del equipo de AWS ProServe en India. Su experiencia abarca una amplia profundidad y amplitud de conocimientos y experiencia en tecnologías de bases de datos SQL/NoSQL. Ha diseñado muchas soluciones de bases de datos exitosas que abordan los desafiantes requisitos del negocio. Ha proporcionado soluciones utilizando PostgreSQL para informes, inteligencia de negocios, almacenamiento de datos, aplicaciones y soporte de desarrollo. También tiene un buen conocimiento de automatización, orquestación y DevOps en entornos de nube.

 

 

 

 

Traductor

Sergio Nuñez es especialista en bases de datos en el Equipo de Aceleración de la Nube de Amazon Web Services. Sergio se enfoca en liderar los esfuerzos de migración de bases de datos a AWS, así como de proporcionar orientación técnica que incluye optimización de costos, monitoreo y experiencia en modernización a los clientes de Amazon.