Comment puis-je identifier l'origine des erreurs « No Space Left on Device » (Espace insuffisant sur l'appareil) ou « DiskFull » (Disque plein) sur Amazon RDS for PostgreSQL ?

Date de la dernière mise à jour : 16/04/2019

Je dispose d'une petite base de données Amazon Relational Database Service (Amazon RDS) for PostgreSQL. L'espace de stockage disponible de l'instance diminue et j'ai reçu 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. » (Message d'erreur : PG : Disque rempli : ERREUR : impossible d'étendre le fichier "base/16394/5139755" : espace insuffisant sur l'appareil. SUGGESTION : vérifiez l'espace disponible sur le disque.)

Comment dépanner les erreurs « DiskFull » (Disque plein) et comment éviter les problèmes de stockage plein ?

Brève description

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

  • Des tables temporaires créées par des transactions PostgreSQL
  • Des fichiers de données
  • Un journal WAL (write-ahead log)
  • Des emplacements de réplication non utilisés
  • Des journaux de base de données (fichiers d'erreur) conservés trop longtemps
  • Une réplication en lecture entre régions arrêtée
  • D'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

Résolution

Utilisez Amazon CloudWatch pour surveiller votre espace de stockage de base de données à l'aide de la métrique FreeStorageSpace. En définissant une alarme Amazon CloudWatch pour l'espace de stockage disponible, vous recevez une notification lorsque l'espace commence à diminuer. Si vous recevez une alarme, vous pouvez alors examiner les causes possibles précédentes des problèmes de stockage. Nous vous recommandons également de surveiller les journaux dans log_temp_files pour voir quand et comment les fichiers temporaires sont créés. Si votre instance de base de données consomme toujours plus d'espace de stockage que prévu, vérifiez les points suivants :

  • Taille des fichiers journaux de base de données
  • Présence de fichiers temporaires
  • Constante augmentation de l'espace disque utilisé par les journaux de transactions
  • Réplicas en lecture entre régions
  • Gonflement ou suppression de lignes mortes
  • Présence de fichiers orphelins

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

Par défaut, les fichiers journaux des erreurs PostgreSQL ont une valeur de rétention de 4 320 minutes (trois jours). Les fichiers journaux volumineux peuvent utiliser une valeur supérieure, ce qui peut entraîner des charges de travail plus élevées. Vous pouvez modifier la période de rétention des fichiers systèmes à 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 la section Fichiers journaux de base de données PostgreSQL.

Vérifier les fichiers temporaires

Les fichiers temporaires sont des fichiers stockés par connexion backend ou de session. Ils sont utilisés en tant que groupe de ressources ou tampon. Ces fichiers sont stockés à l'écart de l'espace de ressource partagée. Vous pouvez consulter ces fichiers en utilisant le delta ou en exécutant une commande similaire à celle qui suit :

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 dans la vue pg_stat_database recueillent des statistiques dans l'ensemble (cumulatif). Ce comportement est voulu, étant donné que ces compteurs sont réinitialisés uniquement par la récupération au démarrage du serveur, comme après une interruption immédiate, une défaillance du serveur et une restauration à un instant dans le passé. Par conséquent, il est recommandé de surveiller l'évolution de ces fichiers au niveau de leur nombre et de leur taille, plutôt que d'examiner uniquement la sortie.

Des fichiers temporaires sont créés pour des tris, des hachages et des résultats de requête temporaires. Une entrée de journal est réalisée pour chaque fichier temporaire lorsque le fichier est supprimé. Pour suivre la création d'espace temporaire utilisé par une seule requête, définissez 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 log_temp_files sur 0, toutes les informations du fichier temporaire sont consignées. Si vous définissez le paramètre sur une valeur positive, seuls les fichiers dont la taille est supérieure ou égale au nombre spécifié de kilo-octets sont consignés. Le paramètre par défaut est -1, ce qui permet de consigner la création de fichiers temporaires et les instructions exécutées. Vous pouvez également utiliser une instruction EXPLAIN ANALYZE de votre requête pour examiner le tri du disque. Si vous examinez la sortie de 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.

Rechercher 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. Les éléments suivants peuvent entraîner une augmentation de l'espace disque utilisé par les journaux de transactions :

  • Charges de base de données élevées (écritures et mises à jour qui génèrent des fichiers WAL supplémentaires).
  • Les réplicas en lecture sont à l'état de stockage complet (conservation des journaux des transactions sur l'instance principale).
  • 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 utilisés en externe par un consommateur, par exemple, par pg_recvlogical, des travaux 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 DMS définit les paramètres wal_level, max_wal_senders, max_replication_slots, et max_connections. Ces modifications de paramètres peuvent accroître la génération de fichiers WAL de sorte que vous ne deviez 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 si des emplacements de réplication logique sont présents, mais s'il n'y a pas de consommateur pour les fichiers WAL conservés par l'emplacement de réplication, vous pouvez constater une augmentation de l'espace disque utilisé par les journaux de transactions. Cela se traduit également par une constante diminution de l'espace de stockage disponible.

Exécutez une requête similaire à celle qui suit 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 v11

psql=> select slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn)) as replicationSlotLag, 
active from pg_replication_slots ;

Une fois que vous avez identifié l'emplacement de réplication qui n'est pas consommé (avec un état actif dont la valeur est False), vous pouvez supprimer l'emplacement de réplication en exécutant une requête similaire à la suivante :

psql=>select pg_drop_replication_slot('Your_slotname_name');

Remarque : si une tâche AWS DMS est le consommateur et si elle n'est plus nécessaire, vous pouvez la supprimer.

Exemple de sortie :

--------------
                      
slot_name                            | replicationslotlag | active
----------------------------------------------------------------+--------------------+--------
xc36ufspjql35djp_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 xc36ufspjql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d a un état actif qui est False. Par conséquent, cet emplacement n'est pas activement utilisé et il contribue à 129 Go de fichiers de transaction.

Vous pouvez supprimer la requête en exécutant une commande similaire à la suivante :

psql=> select pg_drop_replication_slot('xc36ufspjql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d');

Réplicas en lecture entre régions

Si 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é, car les fichiers WAL ne sont pas répliqués sur le réplica en lecture. Vous pouvez utiliser les métriques CloudWatch pour Oldest Replication Slot Lag et Transaction Logs Disk Usage afin de déterminer la taille du retard du réplica le plus en retard en termes de données WAL reçues et le volume de stockage utilisé pour les données WAL.

Pour déterminer le statut d'un réplica en lecture entre régions, vous pouvez exécuter la requête pg_replication_slots. Pour plus d'informations, consultez la documentation PostgreSQL pour la requête pg_replication_slots. Si l'état actif renvoyé est False, l'emplacement n'est actuellement pas utilisé pour la réplication.

postgres=# select * from pg_replication_slots;

Outre les événements et les métriques CloudWatch relatifs au retard du réplica, vous pouvez 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.

Distension ou suppression de lignes mortes (tuples)

Dans les opérations normales de PostgreSQL, des tuples qui sont supprimés ou rendus obsolètes par une instruction UPDATE ne sont pas supprimés de leur table. Pour les mises en œuvre de MVCC (Multi-Version Concurrency Control), si une opération DELETE 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. En premier lieu, les mises à jour marquent également les lignes en vue de leur suppression, puis effectuent 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 dans les fichiers de données (en étant invisibles pour toute transaction), ce qui affecte l'espace disque. Si une table possède de nombreuses opérations DELETE et UPDATE, les tuples inactifs peuvent utiliser une grande quantité d'espace disque, ce qui est parfois qualifié de distension dans PostgreSQL.

L'opération VACUUM peut récupérer le stockage qui est occupé par des tuples inactifs. Il est recommandé 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.

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 l'exemple suivant, 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;

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 désigne ces fichiers. Ce scénario génère rarement des fichiers orphelins, mais cela peut se produire si votre instance est à court d'espace de stockage pendant une opération telle que ALTER TABLE, VACUUM FULL ou 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 les requêtes suivantes 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. La différence doit être importante.

En cas de différence significative entre la taille de la base de données occupée par le fichier et la taille de la base de données extraite en additionnant les objets, il se peut que des fichiers orphelins utilisent de l'espace de stockage.


Cette page vous a-t-elle été utile ?

Cette page peut-elle être améliorée ?


Vous avez besoin d'aide ?