Skip to content

Pourquoi ai-je reçu le message d'erreur « No space left on device » ou « DiskFull » sur Amazon RDS for PostgreSQL ?

Lecture de 10 minute(s)
0

Je dispose d’un petit Amazon Relational Database Service (Amazon RDS) pour la base de données PostgreSQL. L'espace de stockage disponible de l'instance de base de données diminue et je reçois l'erreur suivante : « Error message: PG::DiskFull: ERROR: could not extend file "base/16394/5139755": No space left on device. HINT: Check free disk space. »

Résolution

Remarque : Si votre charge de travail est prévisible, activez l’autoscaling du stockage pour votre instance. Grâce à l’autoscaling du stockage, Amazon RDS redimensionne automatiquement votre espace de stockage lorsque l'espace disponible dans la base de données est faible.

Pour surveiller votre espace de stockage, consultez la métrique Amazon CloudWatch FreeStorageSpace. Configurez une alarme CloudWatch pour obtenir de l'espace de stockage disponible afin de recevoir une notification lorsque l'espace commence à diminuer. Si vous recevez une alarme, recherchez les ressources suivantes qui utilisent le stockage d'instance de base de données Amazon RDS :

  • Tables ou fichiers temporaires créés par des transactions PostgreSQL
  • Fichiers de données
  • Journaux de transactions (WAL)
  • Emplacements de réplication
  • Les journaux de base de données tels que les fichiers d'erreurs conservés trop longtemps
  • Autres fichiers de base de données ou Linux prenant en charge l'état cohérent de l'instance de base de données RDS

Si votre instance de base de données consomme plus que le stockage prévu, prenez les mesures de dépannage suivantes.

Vérifiez la taille des fichiers journaux de la base de données

Par défaut, les fichiers journaux d'erreurs Amazon RDS for PostgreSQL ont une valeur de rétention de 4 320 minutes (trois jours). Les fichiers journaux volumineux peuvent utiliser plus d'espace en raison de charges de travail plus élevées ou d'une journalisation excessive. Pour modifier la période de conservation des journaux système, utilisez le paramètre rds.log_retention_period dans le groupe de paramètres de base de données associé à votre instance de base de données. Par exemple, si vous définissez la valeur sur 1 440, Amazon RDS conserve les journaux pendant une journée. Pour plus d'informations, consultez la section Fichiers journaux de base de données RDS for PostgreSQL.

Pour réduire la journalisation excessive, modifiez les paramètres de signalement et de journalisation des erreurs dans le groupe de paramètres de base de données. Cette action entraîne une réduction de la taille du fichier journal. Pour en savoir plus, consultez la page 19.8 Signalement et journalisation des erreurs sur le site Web de PostgreSQL.

Vérifiez la présence de fichiers temporaires

Les fichiers temporaires sont des fichiers qu'Amazon RDS stocke dans chaque connexion de backend ou de session. Amazon RDS utilise ces fichiers comme groupe de ressources. Pour consulter les statistiques des fichiers temporaires, exécutez la commande suivante :

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

Important : Les colonnes temp_files et temp_bytes de la vue pg_stat_database collectent des statistiques agrégées. Amazon RDS réinitialise ces compteurs uniquement après un arrêt immédiat, une panne du serveur ou une reprise ponctuelle (PITR). C'est pourquoi il est recommandé de surveiller l'augmentation du nombre et de la taille de ces fichiers, et pas seulement d’examiner la sortie.

Amazon RDS crée des fichiers temporaires pour les tris, les hachages et les résultats de requêtes temporaires. Pour suivre la création de tables ou de fichiers temporaires, dans un groupe de paramètres personnalisés, définissez log_temp_files sur 0 pour enregistrer toutes les informations relatives aux fichiers temporaires. Par défaut, log_temp_files est défini sur -1, de sorte qu'Amazon RDS ne journalise pas les fichiers temporaires. Si vous définissez log_temp_files sur une valeur positive, Amazon RDS journalise uniquement les fichiers dont la taille est égale ou supérieure à ce nombre de kilo-octets.

Utilisez EXPLAIN ANALYZE sur votre requête pour vérifier le tri des disques. Dans la sortie du journal, vérifiez la taille des fichiers temporaires créés par votre requête. Pour plus d'informations, consultez la section Régler les opérations de tri dans PostgreSQL avec work_mem.

Vérifiez l'augmentation constante de l'utilisation du disque des journaux de transactions

Vérifiez la métrique TransactionLogsDiskUsage pour afficher l'espace disque utilisé par la transaction WAL. L'utilisation du disque du journal de transactions peut augmenter pour les raisons suivantes :

  • Charges de base de données élevées dues aux écritures et aux mises à jour qui génèrent des WAL supplémentaires
  • Retard de réplica en lecture en streaming pour les réplicas situés dans la même région AWS, ou pour un réplica en lecture à l'état complet de stockage
  • Emplacements de réplication

L'AWS Database Migration Service (AWS DMS) peut créer des emplacements de réplication dans le cadre du décodage logique. Pour la réplication logique, le paramètre d'emplacement rds.logical_replication est défini sur 1. Les emplacements de réplication conservent les fichiers WAL jusqu'à ce qu'un consommateur externe consomme ces derniers. Les exemples de consommateurs incluent les tâches pg_recvlogical, d’extraction, de transformation et de chargement (ETL), et AWS DMS.

Si vous définissez rds.logical_replication sur 1, Amazon RDS définit les paramètres wal_level, max_wal_senders, max_replication_slots et max_connections. Ces modifications de paramètres peuvent augmenter la génération WAL. Il est recommandé de définir le paramètre rds.logical_replication uniquement lorsque vous utilisez des emplacements logiques. S'il n'y a pas de consommateur pour les fichiers WAL conservés, l'utilisation du disque des journaux de transactions augmente et l'espace de stockage disponible diminue régulièrement.

Pour vérifier la présence et la taille des emplacements de réplication, exécutez les requêtes suivantes :

  • 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 et versions ultérieures :

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

Exemple de sortie :

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

Les emplacements de réplication dont l'état actif est défini sur f (faux) ne sont pas consommés. Dans cet exemple, l’emplacement xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d présente un état f actif. Cet emplacement n'est pas utilisé activement, mais utilise 129 Go de fichiers de transaction.

Pour supprimer les emplacements inutilisés, exécutez la requête suivante :

psql=> SELECT pg_drop_replication_slot('YOUR_SLOTNAME');

Remarque : Remplacez YOUR_SLOTNAME par le nom de l’emplacement.

Exemple de sortie :

psql=> SELECT pg_drop_replication_slot('xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d');

Si une tâche AWS DMS dont vous n'avez plus besoin est le consommateur, supprimez-la et refermer manuellement l’emplacement de réplication.

Vérifiez l'état des réplicas en lecture entre régions ou dans la même région

Remarque : Vous pouvez utiliser la résolution suivante pour les réplicas en lecture de la même région uniquement s’ils sont exécutés sur PostgreSQL 14.1 ou version ultérieure.

Lorsque vous utilisez un réplica en lecture entre régions ou dans la même région, Amazon RDS crée un emplacement de réplication physique sur l'instance principale. Un échec du réplica en lecture peut affecter l'espace de stockage sur l'instance de base de données principale. Cette situation se produit lorsque les fichiers WAL ne sont pas répliqués dans le réplica en lecture. Vérifiez les métriques OldestReplicationSlotLag et TransactionLogsDiskUsage pour déterminer le degré de retard du réplica présentant le plus grand retard. Vous pouvez également voir la quantité de stockage utilisée par les données WAL.

Pour vérifier le statut du réplica en lecture, exécutez la requête suivante :

psql=> SELECT * FROM pg_replication_slots;

Pour plus d'informations sur pg_replication_slots, consultez la page 52.19 pg_replication_slots sur le site Web de PostgreSQL. Si l'état actif de la sortie est défini sur f, l’emplacement n'est pas utilisé pour la réplication.

Vous pouvez également utiliser la vue pg_stat_replication sur l'instance source pour vérifier les statistiques de la réplication. Pour plus d'informations, consultez la page Tableau 27.14. Vue pg_stat_replication sur le site Web de PostgreSQL.

Vérifiez l’existence éventuelle d’un gonflement ou d’une élimination inappropriée de lignes mortes

Dans les opérations PostgreSQL standard, PostgreSQL n’élimine pas les lignes mortes (tuples) que les utilisateurs suppriment ou qu'une MISE À JOUR rend obsolètes dans leur table. Pour les implémentations MVCC (Multi-Version Concurrency Control), lorsque vous effectuez une opération DELETE, la ligne n'est pas immédiatement supprimée du fichier de données. PostgreSQL définit plutôt le champ xmax dans un en-tête pour marquer la ligne comme supprimée. Les mises à jour marquent d'abord les lignes à supprimer, puis effectuent une opération d'insertion. Cela permet la simultanéité avec un verrouillage minimal entre les différentes transactions. Par conséquent, PostgreSQL conserve différentes versions de lignes dans le cadre du processus MVCC.

Les lignes mortes qui ne sont pas nettoyées demeurent dans les fichiers de données, mais restent invisibles pour les transactions. Ces lignes peuvent entraîner des problèmes d'espace disque. Si une table comporte de nombreuses opérations DELETE et UPDATE, les tuples morts peuvent utiliser une grande quantité d'espace disque (gonflement).

Utilisez l'opération VACUUM pour libérer le stockage utilisé par les tuples morts. Notez que VACUUM ne libère pas l'espace de stockage disponible dans le système de fichiers. Pour libérer le stockage dans le système de fichiers, utilisez VACUUM FULL. Notez que lorsque vous exécutez VACUUM FULL, PostgreSQL applique un verrouillage exclusif d'accès à la table. Cette méthode nécessite de l'espace disque supplémentaire car VACUUM FULL écrit une nouvelle copie de table et ne libère pas la copie existante tant que l'opération n'est pas terminée. Il est recommandé d'utiliser VACUUM FULL uniquement lorsque vous devez récupérer une quantité importante d'espace de la table. Il est également recommandé d'effectuer des opérations vacuum ou autovacuum périodiques sur les tables que vous mettez fréquemment à jour. Pour en savoir plus, consultez la page VACUUM sur le site Web de PostgreSQL.

Pour vérifier le nombre estimé de tuples morts, utilisez la vue pg_stat_all_tables. Pour plus d'informations, consultez la page Tableau 27.29. Vue pg_stat_all_tables le site Web de PostgreSQL. Dans l’exemple de table suivant, l'enregistrement n_dead_tup contient 1 999 952 tuples morts :

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;

Vérifiez l’existence de fichiers orphelins

Les fichiers orphelins peuvent apparaître lorsqu'aucun objet ne pointe vers un fichier présent dans le répertoire de la base de données. Ce scénario se produit lorsque votre instance manque de stockage ou que le moteur tombe en panne lors d'une opération telle que ALTER TABLE, VACUUM FULL ou CLUSTER. Pour vérifier l’existence de fichiers orphelins, procédez comme suit :

  1. Connectez-vous à PostgreSQL dans chaque base de données.

  2. Pour obtenir la taille utilisée de la base de données, exécutez la requête suivante :

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

    Remarque : Remplacez DATABASE_NAME par le nom de votre base de données.

  3. Pour obtenir la taille réelle de la base de données, exécutez la requête suivante :

    psql=> SELECT pg_size_pretty(SUM(pg_relation_size(oid))) FROM pg_class;
  4. Comparez la taille réelle et utilisée de la base de données à partir des sorties des commandes précédentes. Si la différence est significative, il se peut que des fichiers orphelins utilisent de l'espace de stockage.

Informations connexes

Utilisation de réplicas en lecture pour Amazon RDS for PostgreSQL

Outils de surveillance automatisée