Pourquoi ai-je reçu une erreur « No Space Left on Device » (Espace insuffisant sur l'appareil) ou « DiskFull » (Disque plein) sur Amazon RDS for PostgreSQL ?

Dernière mise à jour : 23/06/2022

Je dispose d'un Amazon Relational Database Service (Amazon RDS) réduit pour la base de données PostgreSQL. L'espace de stockage disponible de l'instance 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 ». (Message d'erreur : PG::DiskFull : ERREUR : impossible d'étendre le fichier "base/16394/5139755" : Il ne reste plus d'espace sur l'appareil). PISTE : Vérifiez l'espace disponible sur le disque.

Je souhaite résoudre les erreurs DiskFull (Disque plein) et éviter les problèmes de stockage.

Brève description

Le stockage d'instances de base de données Amazon RDS est utilisé par les éléments suivants :

  • Tables ou fichiers temporaires créés par des transactions PostgreSQL
  • Fichiers de données
  • Journaux en écriture anticipée (journaux WAL)
  • Emplacements de réplication
  • Journaux de base de données (fichiers d'erreur) 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

Solution

1.    Utilisez Amazon CloudWatch pour surveiller votre espace de stockage de base de données à l'aide de la métrique FreeStorageSpace. Lorsque vous configurez une alarme Amazon CloudWatch pour l'espace de stockage disponible, vous recevez une notification lorsque l'espace commence à diminuer. Si vous recevez une alarme, examinez les causes des problèmes de stockage mentionnés précédemment.

2.    Si votre instance de base de données consomme toujours plus d'espace de stockage que prévu, vérifiez les éléments suivants :

  • Taille des fichiers journaux de base de données
  • Présence de fichiers temporaires
  • Augmentation constante de l'utilisation du disque des journaux de transactions
  • Emplacement de réplication :
    • Les emplacements de réplication physique sont créés par des réplicas en lecture entre régions ou des réplicas en lecture de la même région uniquement s'ils sont exécutés sur PostgreSQL 14.1 et les versions ultérieures
    • Les emplacements de réplication logiques sont créés pour un réplica ou un abonné
  • Distension ou suppression incorrecte de lignes inactives
  • Présence de fichiers orphelins

3.    Lorsque votre charge de travail est prévisible, activez la mise à l'échelle automatique du stockage pour l’instance. Avec la mise à l'échelle automatique du stockage activée, lorsque Amazon RDS détecte que vous manquez d'espace libre dans la base de données, votre stockage est automatiquement mis à l'échelle. Amazon RDS démarre une modification du stockage pour une instance de base de données activée par une mise à l'échelle automatique dans les cas suivants :

  • L'espace libre disponible représente moins de 10 % de l'espace de stockage alloué.
  • La condition de faible stockage dure au moins cinq minutes.
  • Au moins six heures se sont écoulées depuis la dernière modification du stockage ou l'optimisation du stockage s'est terminée sur l'instance, selon la durée la plus longue.

Vous pouvez définir une limite pour la mise à l'échelle automatique de votre instance de base de données en définissant le seuil de stockage maximal. Pour plus d’information, consultez Gestion automatique de la capacité avec la mise à l’échelle automatique du stockage Amazon RDS.

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

Par défaut, les fichiers journaux des 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. Vous pouvez modifier la période de rétention des journaux de système à l'aide du 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, une valeur de 1 440 conservera les journaux pendant un jour. Pour plus d'informations, consultez Fichiers journaux de base de données PostgreSQL.

Vous pouvez également modifier les paramètres de rapport d'erreur et de journalisation dans le groupe de paramètres de base de données afin de réduire la journalisation excessive. Ceci a pour effet de réduire la taille du fichier journal. Pour plus d'informations, consultez Rapport d'erreurs et journalisation.

Vérifier les fichiers temporaires

Les fichiers temporaires sont des fichiers stockés par connexion backend ou de session. Ces fichiers sont utilisés comme un groupe de ressources. Examinez les statistiques des fichiers temporaires en exécutant une commande similaire à celle-ci :

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 recueillent des statistiques dans l'ensemble (cumulatif). Ceci est lié à la conception car ces compteurs ne sont réinitialisés que par récupération au démarrage du serveur. C’est-à-dire que les compteurs sont réinitialisés après un arrêt immédiat, un crash du serveur ou une récupération ponctuelle (PITR). Par conséquent, il est recommandé de surveiller l'augmentation du nombre et de la taille de ces fichiers, plutôt que d'examiner uniquement la sortie.

Les fichiers temporaires sont créés pour les tris, les hachages ou les résultats temporaires des requêtes. Pour suivre la création de tables ou fichiers temporaires, définissez le paramètre log_temp_files dans un groupe de paramètres personnalisé. Ce paramètre contrôle la journalisation des noms et des tailles de fichiers temporaires. Si vous définissez la valeur de log_temp_files sur 0, toutes les informations du fichier temporaire sont enregistrées. Si vous définissez le paramètre sur une valeur positive, seuls les fichiers dont la taille est égale ou supérieure au nombre de kilo-octets spécifié sont enregistrés. La valeur par défaut est -1, ce qui désactive la journalisation des fichiers temporaires.

Vous pouvez également utiliser une instruction EXPLAIN ANALYZE de votre requête pour examiner le tri du disque. Lorsque vous examinez la sortie du journal, vous pouvez voir la taille des fichiers temporaires créés par votre requête. Pour plus d'informations, consultez la documentation PostgreSQL relative à la surveillance de l'activité de la base de données.

Détection d'une augmentation constante de l'espace disque utilisé par les journaux de transactions

La métrique CloudWatch pour TransactionLogsDiskUsage représente l'espace disque utilisé par des WAL de transaction. L'utilisation du disque du journal des transactions peut augmenter pour les raisons suivantes :

  • Charges de base de données élevées (écritures et mises à jour qui génèrent des fichiers WAL supplémentaires)
  • Retard de réplica en lecture en streaming (réplicas dans la même région) ou réplica en lecture dans l'état de stockage plein
  • Emplacements de réplication

Les emplacements de réplication peuvent être créés dans le cadre de la fonctionnalité de décodage logique d'AWS Database Migration Service (AWS DMS). 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'ils soient consommés par un consommateur externe. Par exemple, ils peuvent être consommés par pg_recvlogical, des tâches d'extraction, de transformation et de chargement (ETL) ou AWS DMS.

Si vous définissez la valeur du paramètre rds.logical_replication sur 1, AWS RDS définit les paramètres wal_level, max_wal_senders, max_replication_slots, et max_connections. La modification de ces paramètres peut augmenter la génération de WAL. Une bonne pratique consiste à ne définir le paramètre rds.logical_replication que lorsque vous utilisez des emplacements logiques. Si ce paramètre est défini sur 1 et que des emplacements de réplication logique sont présents, mais qu'il n'y a pas de consommateur pour les fichiers WAL retenus par l'emplacement de réplication, l'utilisation du disque des journaux de transactions peut alors augmenter. Cela se traduit également par une diminution constante de l'espace de stockage disponible.

Exécutez cette requête pour confirmer la présence et la taille des emplacements de réplication :

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 posté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 ;

Après avoir identifié l'emplacement de réplication qui n'est pas consommé (avec un état actif dont la valeur est False [Faux]), supprimez l'emplacement de réplication en exécutant cette requête :

psql=> SELECT pg_drop_replication_slot('Your_slotname_name');

Remarque : si une tâche AWS DMS est le consommateur et qu'elle n'est plus nécessaire, supprimez la tâche et supprimez manuellement l'emplacement de réplication.

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

Dans cet exemple, le nom d'emplacement xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d a un état actif qui est False (Faux). Par conséquent, cet emplacement n'est pas activement utilisé et il contribue à 129 Go des fichiers de transaction.

Supprimez la requête en exécutant la commande suivante :

psql=> SELECT pg_drop_replication_slot('xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d');

Vérifiez l'état des réplicas en lecture entre régions

Lorsque vous utilisez la réplication en lecture entre régions, un emplacement de réplication physique est créé sur l'instance principale. Si le réplica en lecture entre régions échoue, l'espace de stockage sur l'instance de base de données principale peut être affecté. Cela se produit parce que les fichiers WAL ne sont pas répliqués dans le réplica en lecture. Vous pouvez utiliser les métriques CloudWatch Oldest Replication Slot Lag et Transaction Logs Disk Usage afin de déterminer le retard du réplica le plus en retard. Vous pouvez également voir la quantité de stockage utilisée pour les données WAL.

Pour vérifier l’état du réplica en lecture entre régions, utilisez pg_replication_slots. Pour plus d'informations, consultez la documentation PostgreSQL relative à pg_replication_slots. Si l'état actif renvoyé est False (Faux), l'emplacement n'est actuellement pas utilisé pour la réplication.

psql=> SELECT * FROM pg_replication_slots;

Vous pouvez également utiliser la vue pg_stat_replication sur l'instance source afin de vérifier les statistiques relatives à la réplication. Pour plus d'informations, consultez la documentation PostgreSQL relative à pg_stat_replication.

Vérifier s'il n'y a pas de gonflement ou suppression incorrecte de lignes inactives (tuples)

Dans les opérations PostgreSQL normales, des tuples qui sont supprimés ou rendus obsolètes par une instruction UPDATE (METTRE À JOUR) ne sont pas supprimés de leur table. Pour les implémentations MVCC (Multi-Version Concurrency Control), lorsqu’une opération DELETE (SUPPRIMER) est effectuée, la ligne n'est pas immédiatement supprimée du fichier de données. Au lieu de cela, la ligne est marquée comme supprimée en définissant le champ xmax dans une en-tête. Les mises à jour marquent d'abord les lignes à supprimer, puis exécutent une opération d'insertion. Cela permet la simultanéité avec un minimum de verrouillage entre les différentes opérations. Par conséquent, les différentes versions de ligne sont conservées dans le cadre du processus de MVCC.

Si les lignes inactives ne sont pas nettoyées, elles peuvent rester invisibles dans les fichiers de données pour toutes les transactions, ce qui affecte l'espace disque. Si une table possède plusieurs opérations DELETE (SUPPRIMER) et UPDATE (METTRE À JOUR), les tuples inactifs peuvent utiliser une grande quantité d'espace disque, ce qui est parfois appelé « bloat » (gonflement) dans PostgreSQL.

L'opération VACUUM peut libérer l’espace de stockage utilisé par les tuples inactifs afin qu'il puisse être réutilisé, mais cela ne libère pas l'espace de stockage libre dans le système de fichiers. L'exécution de VACUUM FULL libère l'espace de stockage dans le système de fichiers. Notez cependant que pendant l'exécution de VACUUM FULL (VACUUM PLEIN), un verrou exclusif d'accès est maintenu sur la table. Cette méthode nécessite également un espace disque supplémentaire car elle écrit une nouvelle copie de la table et ne libère pas l'ancienne copie avant la fin de l'opération. Une bonne pratique consiste à utiliser cette méthode uniquement lorsque vous devez récupérer une quantité importante d'espace dans la table. C'est également une bonne pratique de réaliser des opérations vacuum ou autovacuum périodiques pour les tables qui sont fréquemment mises à jour. Pour plus d'informations, consultez la documentation PostgreSQL relative à VACUUM (VACUUM).

Pour vérifier l'estimation du nombre de tuples inactifs, utilisez la vue pg_stat_all_tables. Pour plus d'informations, consultez la documentation PostgreSQL relative à la vue pg_stat_all_tables. Dans cet exemple, il existe 1 999 952 tuples inactifs (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     | 2018-08-16 04:49:52.399546+00
last_analyze        | 2018-08-09 09:44:56.208889+00
last_autoanalyze    | 2018-08-16 04:50:22.581935+00
vacuum_count        | 0
autovacuum_count    | 1
analyze_count       | 1
autoanalyze_count   | 1


psql => VACUUM TEST;

Rechercher les fichiers orphelins

Des fichiers orphelins peuvent survenir lorsque les fichiers sont présents dans le répertoire de base de données et lorsqu'il n'y a aucun objet qui pointe vers ces fichiers. Cela peut se produire si votre instance manque de stockage ou si le moteur tombe en panne pendant une opération telle que ALTER TABLE (MODIFIER LA TABLE), VACUUM FULL (VACUUM PLEIN) ou CLUSTER (CLUSTER). Pour vérifier la présence de fichiers orphelins, procédez comme suit :

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

2.    Exécutez ces requêtes pour évaluer les tailles utilisées et réelles.

# Size of the database occupied by files
psql=> SELECT pg_size_pretty(pg_database_size('DATABASE_NAME')); 

# Size of database retrieved by summing the objects (real size)
psql=> SELECT pg_size_pretty(SUM(pg_relation_size(oid))) FROM pg_class;

3.    Veuillez noter les résultats. Si la différence est significative, il se peut que des fichiers orphelins utilisent de l'espace de stockage.


Cet article vous a-t-il été utile ?


Avez-vous besoin d'aide pour une question technique ou de facturation ?