Comment résoudre les problèmes liés aux mises à niveau de versions majeures d'Amazon RDS for PostgreSQL et d'Aurora pour PostgreSQL ?

Date de la dernière mise à jour : 21/11/2022

La mise à niveau de la version de mon moteur pour Amazon Relational Database Service (Amazon RDS) for PostgreSQL ou l'édition compatible avec Amazon Aurora PostgreSQL est bloquée ou a échoué.

Brève description

Une fois qu’Amazon RDS prend en charge une nouvelle version d'un moteur de base de données, vous avez la possibilité de mettre à niveau vos instances de bases de données vers ladite nouvelle version. Vous pouvez effectuer une mise à niveau de version mineure ou une mise à niveau de version majeure de vos instances de base de données.

Les mises à niveau de versions mineures sont utilisées pour la correction des failles de sécurité et des bugs. Ces mises à niveau n'ajoutent généralement aucune nouvelle fonctionnalité et ne modifient pas le format de stockage interne. Elles sont toujours compatibles avec les versions mineures antérieures et ultérieures de la même version majeure. En revanche, les mises à niveau de versions majeures comportent des modifications de base de données qui ne sont pas rétrocompatibles avec les applications existantes. Ces mises à niveau peuvent apporter des modifications au format interne des tables systèmes, des fichiers de données et du stockage de données. Amazon RDS se sert de l'utilitaire PostgreSQL pg_upgrade pour effectuer des mises à niveau de versions majeures.

Lors d'une mise à niveau de version majeure d'une instance PostgreSQL, Amazon RDS exécute une procédure de pré-vérification. Cette procédure identifie tous les problèmes susceptibles d'entraîner l'échec de la mise à niveau. Elle scrute les possibles conditions d'incompatibilités dans toutes les bases de données. Si Amazon RDS identifie un problème au cours du processus de pré-vérification, il crée un événement de journal pour l'échec de la pré-vérification. Pour plus d'informations sur le processus de pré-vérification pour toutes les bases de données, consultez le journal de mise à niveau pg_upgrade_precheck.log. Amazon RDS ajoute un horodatage au nom du fichier. Les événements RDS peuvent également fournir les raisons de l'échec de la mise à niveau. Toutefois, pour les problèmes exclusivement relatifs au moteur, vous devez vérifier les fichiers journaux de base de données.

Pour plus d'informations, consultez Liste et affichage des fichiers journaux de base de données pour RDS pour PostgreSQL. Vous pouvez également consulter Liste et affichage des fichiers journaux de base de données pour Aurora pour PostgreSQL.

Au cours d'une mise à niveau de version majeure, RDS effectue les étapes suivantes :

  1. Création d'un instantané de l'instance en prélude à la mise à niveau. Cela se produit uniquement si vous définissez la période de rétention de sauvegarde de votre instance de bases de données à un nombre supérieur à zéro.
  2. Fermeture de l'instance.
  3. Utilisez l'utilitaire pg_upgrade pour exécuter la tâche de mise à niveau sur l'instance.
  4. Créez un instantané de l'instance après la mise à niveau.

Solution

Bien qu'Amazon RDS gère ces mises à niveau, il peut arriver que vous rencontriez les problèmes ci-dessous lors d'une mise à niveau de version :

  • La mise à niveau prend plus de temps que prévu.
  • La mise à niveau échoue.

La mise à niveau prend beaucoup de temps

Pending maintenance activities (Activités de maintenance en attente) : toutes les activités de maintenance en cours sont automatiquement appliquées lors des mises à niveau de version de moteur. Cela peut inclure l'application d'un correctif du système d'exploitation sur votre instance RDS. Dans ce cas, le correctif du système d'exploitation est d'abord appliqué, puis la version du moteur est mise à niveau. Par conséquent, l'exécution des activités de maintenance du système d'exploitation entraîne une augmentation du temps nécessaire pour effectuer la mise à niveau.

Par ailleurs, si votre instance RDS est dans un déploiement multi-AZ, la maintenance du système d'exploitation entraînera un basculement. Lorsque vous configurez votre instance dans un déploiement Multi-AZ, la sauvegarde de votre instance est généralement créée sur l'instance secondaire. En cas de basculement, après la mise à niveau, une sauvegarde est créée sur une nouvelle instance secondaire. Cette sauvegarde sur la nouvelle instance secondaire peut ne pas être la dernière sauvegarde. Par conséquent, une sauvegarde complète peut être déclenchée au lieu d'une sauvegarde incrémentielle. La création d'une sauvegarde complète peut être chronophage, surtout si la base de données est très volumineuse.

Pour éviter ce problème, recherchez les pending maintenance activities (activités de maintenance en attente) dans la section Pending maintenance (Maintenance en attente) de votre console RDS. Pour Aurora pour PostgreSQL, consultez Affichage de la maintenance en attente.

Vous pouvez également utiliser la commande describe-pending-maintenance-actions de l'Interface de la ligne de commande AWS (AWS CLI) sur votre instance.

aws rds describe-pending-maintenance-actions --resource-identifier example-arn

Remarque : effectuez ces opérations de maintenance avant d'effectuer les mises à niveau de version du moteur de base de données.

Aucun instantané créé avant la mise à niveau : il est recommandé de créer un instantané de l'instantané du cluster RDS ou Aurora pour PostgreSQL avant la mise à niveau. Si vous avez déjà activé les sauvegardes pour votre instance, un instantané est créé automatiquement au cours du processus de mise à niveau. La création d'un instantané avant la mise à niveau réduit la durée du processus de mise à niveau. En effet, seule une sauvegarde incrémentielle est créée lors du processus de mise à niveau.

Mises à niveau des réplicas en lecture RDS pour PostgreSQL : lorsque vous effectuez une mise à niveau de version majeure de votre instance de base de données principale, tous les réplicas en lecture de la même région sont mis à niveau automatiquement. Après démarrage du flux de mise à niveau, les réplicas en lecture attendent que pg_upgrade se termine correctement sur l'instance de base de données principale. Ensuite, la mise à niveau de l'instance principale attend que les mises à niveau du réplica en lecture soient terminées. Vous rencontrerez une panne tant que toutes les mises à niveau ne sont pas terminées. Si la fenêtre d'indisponibilité de la mise à niveau est limitée, vous pouvez continuer avec votre instance de réplica. Recréez ensuite les réplicas en lecture une fois la mise à niveau terminée.

Pour mettre à niveau en toute sécurité les instances de base de données qui constituent votre cluster, Aurora pour PostgreSQL utilise l'utilitaire pg_upgrade. Une fois la mise à niveau en écriture terminée, chaque instance de lecteur subit une brève interruption pendant la mise à niveau vers la nouvelle version majeure.

Opérations chronophages ou charge de travail élevée avant la mise à niveau : des opérations chronophages ou des charges de travail élevées avant la mise à niveau peuvent augmenter le temps nécessaire à l'arrêt de la base de données et augmenter le temps nécessaire à la mise à niveau.

Exécutez la requête suivante pour identifier les opérations chronophages :

SQL>SELECT pid, datname, application_name, state, 
age(query_start, clock_timestamp()), usename, query 
FROM pg_stat_activity 
WHERE query NOT ILIKE '%pg_stat_activity%' AND 
usename!='rdsadmin' 
ORDER BY query_start desc;

Capacité de calcul insuffisante : l'utilitaire pg_upgrade peut nécessiter une importante capacité de calcul. C'est pourquoi il est recommandé d'effectuer une mise à niveau à blanc avant de mettre à niveau vos bases de données de production. Vous pouvez restaurer un instantané de l'instance de production et effectuer un essai à blanc avec la même classe d'instance que la base de données de production.

Échec de mise à niveau

Classes d'instance de bases de données non prises en charge : la mise à niveau peut échouer si la classe d'instance de votre instance de base de données n'est pas compatible avec la version de PostgreSQL vers laquelle vous effectuez la mise à niveau. Assurez-vous d'avoir vérifié la compatibilité de la classe d'instance avec la version du moteur. Pour plus d'informations, consultez les moteurs de base de données pris en charge pour les classes d'instance de base de données pour RDS pour PostgreSQL. Vous pouvez également consulter les moteurs de base de données pris en charge pour les classes d'instance de base de données pour Aurora pour PostgreSQL.

Transactions préparées ouvertes : les transactions préparées qui sont ouvertes dans la base de données peuvent entraîner l'échec de la mise à niveau. Assurez-vous de valider ou d'annuler toutes les transactions préparées ouvertes avant tout lancement de mise à niveau.

Exécutez la requête suivante pour vérifier s'il existe des transactions préparées ouvertes sur votre instance :

SELECT count(*) FROM pg_catalog.pg_prepared_xacts;

Dans ce cas, le message d'erreur dans le fichier pg_upgrade.log est similaire à ce qui suit :

------------------------------------------------------------------------
Upgrade could not be run on Wed Apr 4 18:30:52 2018
-------------------------------------------------------------------------
The instance could not be upgraded from 9.6.11 to 10.6 for the following reasons.
Please take appropriate action on databases that have usage incompatible with 
the requested major engine version upgrade and try the upgrade again.

*There are uncommitted prepared transactions. Please commit or rollback 
all prepared transactions.*

Types de données non pris en charge : la mise à niveau échoue avec une notification d'erreur si vous tentez de mettre à niveau la base de données avec des types de données non pris en charge, tels que :

  • regcollation
  • regconfig
  • regdictionary
  • regnamespace
  • regoper
  • regoperator
  • regproc
  • regprocedure

Remarque : les données de type regclass, regrole et regtype sont pris en charge.

L'utilitaire de mise à niveau PostgreSQL pg_upgrade ne prend pas en charge la mise à niveau des bases de données contenant des colonnes de tableau à l'aide des types de données système de référence OID reg. Avant de lancer toute mise à niveau, supprimez toutes les utilisations des types de données reg*, à l'exception de regclass, regrole et regtype.

Exécutez la requête suivante pour vérifier l'utilisation de types de données reg* non pris en charge :

SELECT count(*) FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n, pg_catalog.pg_attribute a
  WHERE c.oid = a.attrelid
      AND NOT a.attisdropped
      AND a.atttypid IN ('pg_catalog.regproc'::pg_catalog.regtype,
                         'pg_catalog.regprocedure'::pg_catalog.regtype,
                         'pg_catalog.regoper'::pg_catalog.regtype,
                         'pg_catalog.regoperator'::pg_catalog.regtype,
                         'pg_catalog.regconfig'::pg_catalog.regtype,
                         'pg_catalog.regdictionary'::pg_catalog.regtype)
      AND c.relnamespace = n.oid
      AND n.nspname NOT IN ('pg_catalog', 'information_schema');

Emplacements de réplication logique : aucune mise à niveau n'est possible si votre instance possède des emplacements de réplication logique. Les emplacements de réplication logique sont généralement utilisés pour la migration AWS Database Migration Service (AMS DMS). Ils sont également utilisés pour répliquer des tables depuis des bases de données vers des lacs de données, des outils de Business Intelligence et d'autres cibles. Avant de procéder à la mise à niveau, assurez-vous de connaître l'objectif des emplacements de réplication logique utilisés et assurez-vous que ces derniers peuvent être supprimés.

Si les emplacements de réplication logiques sont toujours utilisés, vous ne devez pas les supprimer. Dans ce cas, vous ne pouvez pas procéder à la mise à niveau.

L'erreur correspondante dans le fichier journal pg_upgrade ressemble à ce qui suit :

"The instance could not be upgraded because one or more databases have logical replication slots. Please drop all logical replication slots and try again."

Si les emplacements de réplication logique ne sont pas nécessaires, exécutez les requêtes suivantes pour les supprimer :

SELECT * FROM pg_replication_slots;
SELECT pg_drop_replication_slot(slot_name);

Problèmes de stockage : il peut arriver que l'instance manque d'espace pendant l'exécution du script pg_upgrade. Cela entraîne l'échec du script et un message d'erreur similaire au suivant s'affiche :

pg_restore: [archiver (db)] Error while PROCESSING TOC: 
pg_restore: [archiver (db)] could not execute query: ERROR: could not create file "base/12345/12345678": No space keyword" left  on device

Pour résoudre ce problème, assurez-vous que l'instance dispose d'un espace de stockage libre suffisant avant de démarrer la mise à niveau.

Types de données inconnues : les versions 10 et ultérieures de PostgreSQL ne prennent pas en charge les types de données unknown (inconnues). Si une base de données PostgreSQL version 9.6 utilise le type de données unknown (inconnues), une mise à niveau vers la version 10 affichera un message d'erreur similaire à ce qui suit :

"The instance could not be upgraded because the 'unknown' data type is used in user tables. Please remove all usages of the 'unknown' data type and try again."

Il s'agit d'une limitation de PostgreSQL, et l'automatisation de RDS ne modifie pas les colonnes utilisant le type de données unknown (inconnues). Vous devrez peut-être modifier ces colonnes manuellement avant la mise à niveau.

Exécutez la requête suivante pour rechercher les colonnes de votre base de données dont le type est unknown (inconnues) :

SELECT DISTINCT data_type FROM information_schema.columns WHERE data_type ILIKE 'unknown';

Après avoir identifié les colonnes, vous pouvez les supprimer ou les modifier selon un type de données pris en charge.

Échec de la mise à niveau du réplica en lecture (RDS pour PostgreSQL uniquement) : si l'instance RDS possède des réplicas en lecture, les échecs de mise à niveau du réplica en lecture peuvent entraîner le blocage de votre instance principale. L'échec de la mise à niveau du réplica en lecture peut également entraîner l'échec de la mise à niveau de l'instance principale. Un réplica en lecture ayant échoué passe à l'état incompatible-restore (restauration incompatible) et la réplication est arrêtée sur l'instance de base de données.

La mise à niveau d'un réplica en lecture peut échouer pour l'une des raisons suivantes :

  • Le réplica en lecture ne rattrape pas l'instance de base de données principale même après épuisement du temps d'attente.
  • Le réplica en lecture est dans un état terminal ou de cycle de vie incompatible, tel qu'une restauration avec capacité de stockage pleine ou une restauration incompatible.
  • Lorsque la mise à niveau de l'instance de base de données principale est lancée, une mise à niveau de version mineure distincte est en cours d'exécution.
  • Le réplica en lecture utilise des paramètres incompatibles.
  • Le réplica en lecture ne peut pas communiquer avec l'instance de base de données principale pour la synchronisation du dossier de données.

Pour résoudre ce problème, supprimez le réplica en lecture. Ensuite, recréez un réplica en lecture basé sur l'instance principale mise à niveau une fois l'instance principale mise à niveau.

Nom d'utilisateur principal incorrect : si le nom d'utilisateur principal commence par « pg_ », la mise à niveau échoue et le message d'erreur suivant s'affiche :

PreUpgrade checks failed: The instance could not be upgraded because one or more role names start with 'pg_'. Please rename  all roles with names that start with 'pg_' and try again

Pour résoudre ce problème, créez un autre utilisateur avec le rôle rds_superuser. Vous pouvez contacter AWS Support pour mettre à jour cet utilisateur en tant que nouvel utilisateur principal.

Erreur de paramètre incompatible : cette erreur se produit si un paramètre lié à la mémoire, tel que shared_buffer ou work_memory, est défini sur une valeur supérieure. Cela peut entraîner l'échec du script de mise à niveau. Pour résoudre le problème, réduisez les valeurs de ces paramètres, puis essayez d'exécuter à nouveau la mise à niveau.

Extensions non mises à jour avant la mise à niveau : une mise à niveau de version majeure n'inclut pas la mise à niveau des extensions PostgreSQL. Si vous n'avez pas mis à jour les extensions avant d'effectuer une mise à niveau de version majeure, le message d'erreur suivant s'affiche dans le fichier pg_upgrade.log :

The Logs indicates that the RDS instance ''xxxx'' has older version of PostGIS extension or its dependent extensions (address_standardizer,address_standardizer_data_us, postgis_tiger_geocoder, postgis_topology, postgis_raster) installed as against the current version required for the upgrade.

Ce message d'erreur indique un problème relatif à l'extension PostGIS.

Exécutez la requête suivante pour vérifier les versions par défaut installées pour PostGIS et ses extensions dépendantes :

SELECT name, default_version, installed_version
FROM pg_available_extensions WHERE installed_version IS NOT NULL AND
name LIKE 'postgis%' OR name LIKE 'address%';

Si la valeur installed_version est inférieure à la valeur default_version, vous devez mettre à jour la version de PostGIS vers la version par défaut. Pour ce faire, exécutez cette requête :

ALTER EXTENSION extension_name UPDATE TO 'default_version_number';

Pour plus d'informations, consultez Mise à niveau des extensions PostgreSQL pour RDS pour PostgreSQL ou Mise à niveau des extensions PostgreSQL pour Aurora PostgreSQL.

Problème relatif aux vues, en raison de la modification du catalogue système de la version cible : les colonnes de certaines vues varient selon les versions de PostgreSQL.

Par exemple, vous pouvez voir un message d'erreur similaire au suivant :

PreUpgrade checks failed: The instance could not be upgraded because one or more databases have views or materialized views which depend on 'pg_stat_activity'. Please drop them and try again.

Cette erreur survient lorsque vous mettez à niveau la base de données de la version 9.5 vers la version 9.6. Cette erreur est causée la vue pg_stat_activity car la colonne en attente est remplacée par les colonnes wait_event_type et wait_event dans la version 9.6.

pg_restore: from TOC entry xxx; xxx xxxx VIEW sys_user_constraints art 
pg_restore: error: could not execute query: ERROR: column c.consrc does not exist LINE 18: "c"."consrc" AS "search_condition", ^ HINT: Perhaps you meant to reference the column "c.conkey" or the column "c.conbin".

Cette erreur survient parce que la structure du catalogue pg_constraint a changé dans PostgreSQL version 12.

Vous pouvez résoudre ces problèmes en supprimant les vues basées sur les catalogues système de la version cible.

Remarque : faites attention lorsque vous supprimez ces vues. Veillez à consulter votre administrateur de bases de données.

Autres éléments à prendre en compte

  • L'utilitaire pg_upgrade produit deux journaux : pg_upgrade_internal.log et pg_upgrade_server.log. Amazon RDS ajoute un horodatage au nom du fichier pour ces journaux. Consultez ces journaux pour obtenir plus d'informations sur les problèmes et les erreurs rencontrés lors de la mise à niveau. Pour plus d'informations, consultez Surveillance des fichiers journaux Amazon RDS pour RDS pour PostgreSQL ou Surveillance des fichiers journaux Amazon Aurora pour Aurora pour PostgreSQL.
  • Lorsque la mise à niveau est terminée, mettez à niveau la table pg_statistics en exécutant ANALYZE sur toutes les bases de données utilisateur. La mise à niveau de version majeure ne déplace pas le contenu de la table pg_statistics vers la nouvelle version. L'omission de cette étape peut entraîner un ralentissement dans l'exécution des requêtes.
  • Si vous avez effectué une mise à niveau vers la version 10 de PostgreSQL, exécutez REINDEX sur tous les index de hachage que vous possédez. Les index de hachage ont été modifiés dans la version 10 et doivent être recréés. Afin de localiser les index de hachage non valides, exécutez le code SQL suivant pour chaque base de données contenant des index de hachage :
SELECT idx.indrelid::regclass AS table_name, 
   idx.indexrelid::regclass AS index_name 
FROM pg_catalog.pg_index idx
   JOIN pg_catalog.pg_class cls ON cls.oid = idx.indexrelid 
   JOIN pg_catalog.pg_am am ON am.oid = cls.relam 
WHERE am.amname = 'hash' 
AND NOT idx.indisvalid;

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


Besoin d'aide pour une question technique ou de facturation ?