¿Por qué he recibido el error «No queda espacio en el dispositivo» o «DiskFull» en Amazon RDS para PostgreSQL?

10 minutos de lectura
0

Tengo un Amazon Relational Database Service (Amazon RDS) pequeño para una base de datos de PostgreSQL. El espacio de almacenamiento libre de la instancia está disminuyendo y recibo el siguiente error: «Error message: PG::DiskFull: ERROR: no se pudo extender el archivo "base/16394/5139755": No queda espacio en el dispositivo. SUGERENCIA: Compruebe el espacio libre en disco.»

Solución

Nota: Cuando la carga de trabajo sea predecible, active el escalamiento automático del almacenamiento para la instancia. Con el escalamiento automático del almacenamiento, Amazon RDS escala automáticamente el almacenamiento cuando hay poco espacio libre en la base de datos.

Para supervisar el espacio de almacenamiento, consulte la métrica FreeStorageSpace de Amazon CloudWatch. Configure una alarma de CloudWatch para obtener espacio de almacenamiento libre para así recibir una notificación cuando el espacio comience a disminuir. Si recibe una alarma, compruebe los siguientes recursos que utilizan el ](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html)almacenamiento de instancias de base de datos de Amazon RDS[:

  • Tablas o archivos temporales que se crean mediante transacciones de PostgreSQL
  • Archivos de datos
  • Registros de escritura previa (WAL)
  • Ranuras de replicación
  • Registros de base de datos (como archivos de errores) que se retienen durante demasiado tiempo
  • Otros archivos de base de datos o Linux que admitan el estado coherente de la instancia de base de datos de RDS

Si la instancia de base de datos consume más del almacenamiento esperado, lleve a cabo las siguientes acciones de solución de problemas.

Compruebe el tamaño de los archivos de registro de la base de datos

De forma predeterminada, los archivos de registro de errores de Amazon RDS para PostgreSQL tienen un valor de retención de 4320 minutos (tres días). Los archivos de registro de gran tamaño pueden ocupar más espacio debido al aumento de las cargas de trabajo o al registro excesivo. Para cambiar el período de retención de los registros del sistema, use el parámetro rds.log_retention_period del grupo de parámetros de la base de datos asociado a la instancia de base de datos. Por ejemplo, si establece el valor en 1440, Amazon RDS retendrá los registros durante un día. Para obtener más información, consulte Archivos de registro de bases de datos de RDS para PostgreSQL.

Para reducir el registro excesivo, cambie los parámetros de registro e informe de errores en el grupo de parámetros de la base de datos. Esta acción reduce el tamaño del archivo de registro. Para obtener más información, consulte Error reporting and logging (19.8 Notificación y registro de errores) en el sitio web de PostgreSQL.

Comprobar si hay archivos temporales

Los archivos temporales son archivos que Amazon RDS almacena en cada conexión de backend o sesión. Amazon RDS utiliza estos archivos como grupo de recursos. Para revisar las estadísticas de los archivos temporales, ejecute el siguiente comando:

psql=> SELECT datname, temp_files AS "Temporary files",temp_bytes AS "Size of temporary files" FROM pg_stat_database ;

Importante: Las columnas temp_files y temp_bytes de la vista pg_stat_database recopilan estadísticas agregadas. Amazon RDS restablece estos contadores solo después de un apagadp inmediato, un bloqueo del servidor o una recuperación a un momento dado (PITR). Por este motivo, se recomienda supervisar el crecimiento de estos archivos en número y tamaño, no revisar solo el resultado.

Amazon RDS crea archivos temporales para las clasificaciones, los hashes y los resultados de consultas temporales. Para hacer un seguimiento de la creación de tablas o archivos temporales, en un grupo de parámetros personalizado, establezca log_temp_files en 0 para registrar toda la información de los archivos temporales. De forma predeterminada, log_temp_files está establecido en -1, por lo que Amazon RDS no registra archivos temporales. Si le asigna un valor positivo a log_temp_files, Amazon RDS solo registrará los archivos que sean iguales o superiores a esa cantidad de kilobytes.

Use EXPLAIN ANALYZE en su consulta para revisar la clasificación de los discos. En el resultado del registro, compruebe el tamaño de los archivos temporales que crea la consulta. Para obtener más información, consulte Tune sorting operations in PostgreSQL with work_mem (Ajuste de operaciones de clasificación en PostgreSQL con work_mem).

Comprobar si hay un aumento constante en el uso del disco en los registros de transacciones

Comprueba la métrica TransactionLogsDiskUsage para ver el espacio en disco que utiliza la transacción WAL. El uso del disco del registro de transacciones puede aumentar por los siguientes motivos:

  • Cargas elevadas de base de datos de escrituras y actualizaciones que generan más registros WAL
  • Retraso en la transmisión de réplicas de lectura para réplicas en la misma región de AWS o en una réplica de lectura en estado de almacenamiento lleno
  • Ranuras de replicación

AWS Database Migration Service (AWS DMS) puede crear ranuras de replicación como parte de la decodificación lógica. Para la replicación lógica, el parámetro de ranura rds.logical_replication se establece en 1. Las ranuras de replicación retienen los archivos WAL hasta que un consumidor externo los consuma. Algunos ejemplos de consumidores son los trabajos pg_recvlogical, los trabajos de extracción, transformación y carga (ETL) y AWS DMS.

Si estableces el valor del parámetro rds.logical_replication en 1, Amazon RDS establece los parámetros wal_level, max_wal_senders, max_replication_slots y max_connections. Estos cambios en los parámetros pueden aumentar la generación de WAL. Se recomienda configurar el parámetro rds.logical_replication solo cuando utilice ranuras lógicas. Si no hay un consumidor para los archivos WAL retenidos, el uso del disco de los registros de transacciones aumenta y el espacio de almacenamiento libre disminuye constantemente.

Para comprobar la presencia y el tamaño de las ranuras de replicación, use las siguientes consultas:

  • PostgreSQL v9:

    psql=> SELECT slot_name, pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(),restart_lsn)) AS replicationSlotLag, active FROM pg_replication_slots ;
  • PostgreSQL v10 y versiones posteriores:

    psql=> SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn)) AS replicationSlotLag, active FROM pg_replication_slots ;

Resultado de ejemplo:

slot_name                                                      | replicationslotlag | active---------------------------------------------------------------+--------------------+--------
xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d    | 129 GB             | f
7pajuy7htthd7sqn_00013322_a27bcebf_7d0f_4124_b336_92d0fb9f5130 | 704 MB             | t
zp2tkfo4ejw3dtlw_00013322_03e77862_689d_41c5_99ba_021c8a3f851a | 624 MB             | t

Las ranuras de replicación que tienen un estado activo establecido en f (false) no se están consumiendo. En este ejemplo, la ranura xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d tiene un estado activo f. Esta ranura no se usa activamente, pero usa 129 GB de archivos de transacciones.

Para eliminar las ranuras no utilizadas, ejecute la siguiente consulta:

psql=> SELECT pg_drop_replication_slot('YOUR_SLOTNAME');

Nota: Sustituya YOUR_SLOTNAME por el nombre de la ranura.

Resultado de ejemplo:

psql=> SELECT pg_drop_replication_slot('xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d');

Si una tarea de AWS DMS que ya no necesita es el consumidor, elimine la tarea y elimine manualmente la ranura de replicación.

Comprobar el estado de las réplicas de lectura entre regiones o en la misma región

Nota: Puede usar la siguiente resolución para réplicas de lectura de la misma región solo si se procesan en PostgreSQL 14.1 o versiones posteriores.

Cuando utiliza una replicación de lectura entre regiones o en la misma región, Amazon RDS crea una ranura de replicación física en la instancia principal. Un error de réplica de lectura puede afectar al espacio de almacenamiento de la instancia de base de datos principal. Esta situación se produce cuando los archivos WAL no se replican en la réplica de lectura. Revise las métricas OldestReplicationSlotLag y TransactionLogsDiskUsage para determinar qué tan atrasada está la réplica con más retraso. También puede ver cuánto almacenamiento utilizan los datos de WAL.

Para comprobar el estado de la réplica de lectura, use la siguiente consulta:

psql=> SELECT * FROM pg_replication_slots;

Para obtener más información acerca de pg_replication_slots, consulte 52.19 pg_replication_slots en el sitio web de PostgreSQL. Si el resultado tiene el estado activo establecido en f, la ranura no se usa para la replicación.

También puede usar la vista pg_stat_replication en la instancia de origen para comprobar las estadísticas de la replicación. Para obtener más información, consulte Table 27.14. pg_stat_replication view (Tabla 27.14. Vista pg_stat_replication) en el sitio web de PostgreSQL.

Comprobar si hay tablas infladas o si la eliminación de filas muertas es incorrecta

En las operaciones estándar de PostgreSQL, PostgreSQL no elimina de la tabla las filas muertas (tuplas) que los usuarios eliminan o que una acción UPDATE hace obsoletas. Para las implementaciones del Control de concurrencia multiversión (MVCC), cuando se lleva a cabo una operación DELETE, la fila no se elimina inmediatamente del archivo de datos. En su lugar, PostgreSQL establece el campo xmax en un encabezado para marcar la fila como eliminada. Las actualizaciones marcan primero las filas para eliminarlas y, a continuación, llevan a cabo una operación de inserción. Esto permite la concurrencia con un bloqueo mínimo entre las diferentes transacciones. Como resultado, PostgreSQL conserva diferentes versiones de la fila como parte del proceso de MVCC.

Las filas muertas que no se eliminen permanecen en los archivos de datos, pero serán invisibles para las transacciones. Estas filas pueden provocar problemas de espacio en disco. Si una tabla tiene muchas operaciones DELETE y UPDATE, las filas muertas pueden ocupar una gran cantidad de espacio en disco (inflación).

Usa la operación VACUUM para liberar el almacenamiento utilizado por las tuplas muertas. Ten en cuenta que VACUUM no libera el almacenamiento gratuito en el sistema de archivos. Para liberar el almacenamiento en el sistema de archivos, utilice VACUUM FULL. Ten en cuenta que cuando usa VACUUM FULL, PostgreSQL aplica un bloqueo de acceso exclusivo a la tabla. Este método requiere más espacio en disco porque VACUUM FULL escribe una nueva copia de la tabla y no libera la copia existente hasta que se complete la operación. Se recomienda utilizar VACUUM FULL solo cuando deba recuperar una cantidad significativa de espacio de la tabla. También se recomienda hacer operaciones periódicas de «vacuum» o «autovacuum» en tablas que actualice con frecuencia. Para obtener más información, consulte VACUUM en el sitio web de PostgreSQL.

Para comprobar el número estimado de filas muertas, utilice la vista pg_stat_all_tables. Para obtener más información, consulte Table 27.29. pg_stat_all_tables view (Tabla 27.29. Vista pg_stat_all_tables) en el sitio web de PostgreSQL. En la siguiente tabla de ejemplo, hay 1 999 952 tuplas muertas en el registro n_dead_tup:

psql => SELECT * FROM pg_stat_all_tables WHERE relname='test';
-[ RECORD 1 ]-------+------------------------------
relid               | 16395
schemaname          | public
relname             | test
seq_scan            | 3
seq_tup_read        | 5280041
idx_scan            |
idx_tup_fetch       |
n_tup_ins           | 2000000
n_tup_upd           | 0
n_tup_del           | 3639911
n_tup_hot_upd       | 0
n_live_tup          | 1635941
n_dead_tup          | 1999952
n_mod_since_analyze | 3999952
last_vacuum         |
last_autovacuum     | 2024-08-16 04:49:52.399546+00
last_analyze        | 2024-08-09 09:44:56.208889+00
last_autoanalyze    | 2024-08-16 04:50:22.581935+00
vacuum_count        | 0
autovacuum_count    | 1
analyze_count       | 1
autoanalyze_count   | 1


psql => VACUUM TEST;

Comprobar si hay archivos huérfanos

Los archivos huérfanos pueden aparecer cuando ningún objeto apunta a un archivo que está presente en el directorio de la base de datos. Esto puede ocurrir si la instancia se queda sin espacio de almacenamiento o si el motor se bloquea durante una operación como ALTER TABLE, VACUUM FULL o CLUSTER. Para comprobar si hay archivos huérfanos, siga estos pasos:

  1. Inicie sesión en PostgreSQL en cada base de datos.

  2. Para obtener el tamaño usado de la base de datos, use la siguiente consulta:

    psql=> SELECT pg_size_pretty(pg_database_size('DATABASE_NAME'));

    Nota: Sustituya DATABASE_NAME por el nombre de la base de datos.

  3. Para obtener el tamaño real de la base de datos, use la siguiente consulta:

    psql=> SELECT pg_size_pretty(SUM(pg_relation_size(oid))) FROM pg_class;
  4. Compare el tamaño real y usado de la base de datos con los resultados de los comandos anteriores. Si la diferencia es significativa, es posible que los archivos huérfanos estén utilizando espacio de almacenamiento.

Información relacionada

Trabajar con réplicas de lectura para Amazon RDS para PostgreSQL

Herramientas de supervisión automatizadas

Sin comentarios