Comment dépanner une tâche AWS DMS qui échoue avec le message d'erreur « ERROR: canceling statement due to statement timeout » (ERREUR : annulation de l'instruction en raison de l'expiration de son délai d'exécution) ?

Lecture de 7 minute(s)
0

Je migre des données vers ou depuis ma base de données PostgreSQL sur site à l'aide d'AWS Database Migration Service (AWS DMS). La tâche AWS DMS s'exécute normalement pendant un certain temps, puis échoue avec un message d'erreur. Comment puis-je dépanner et résoudre ces erreurs?

Brève description

Si la base de données PostgreSQL est la source de votre tâche de migration, alors AWS DMS extrait les données de la table pendant la phase de chargement complet. Ensuite, AWS DMS lit à partir des « write-ahead logs » (WAL) qui sont conservés par l'emplacement de réplication pendant la phase de capture des données modifiées (CDC).

Si la base de données PostgreSQL est la cible, AWS DMS extrait les données de la source et crée des fichiers CSV dans l'instance de réplication. Ensuite, AWS DMS exécute une commande COPY (COPIER) pour insérer ces enregistrements dans la cible pendant la phase de chargement complet.

Toutefois, lors de la phase CDC, AWS DMS exécute les instructions DML exactes à partir des journaux WAL sources en mode d'application transactionnelle. Pour le mode d'application par lots, AWS DMS crée également des fichiers CSV pendant la phase CDC. Ensuite, il exécute une commande COPY pour insérer les modifications réseau dans la cible.

Lorsque AWS DMS tente d’obtenir leurs données de la source ou de placer des données dans la cible, elle utilise le paramètre de délai d'expiration par défaut de 60 secondes. Si la source ou la cible est fortement chargée ou si les tables contiennent des verrous, AWS DMS aura besoin de plus de 60 secondes pour exécuter ces commandes. Par conséquent, la tâche échoue avec une erreur indiquant « canceling statement due to statement timeout » (annulation de l'instruction en raison de l'expiration de son délai d'exécution). Vous voyez alors l'une des entrées suivantes dans le journal :

Messages :

«] E : RetCode : SQL_ERROR SQLState : 57014 NativeError : 1 Message : ERREUR : annulation d'une instruction en raison de l'expiration du délai de l'instruction ; Erreur lors de l'exécution de la requête [1022502] (ar_odbc_stmt.c:2738) »

«] E : test_decoding_create_replication_slot (...) - Impossible de créer le slot 'lrcyli7hfxcwkair_00016402_8917165c_29f0_4070_97dd_26e78336e01b' (lors de la phase d'exécution (...)) [1022506] (postgres_test_decoding.c:392)) »

Procédez comme suit pour dépanner et résoudre ces erreurs :

  • Identifiez la cause de longs délais d'exécution des commandes.
  • Augmentez la valeur du délai d'exécution et vérifiez la valeur du délai de création de l'emplacement.
  • Dépannez les problèmes de création de l'emplacement.

Résolution

Identifiez la cause de longs délais d'exécution des commandes

Pour rechercher la commande qui n'a pas pu être exécutée pendant la période d'exécution, consultez le journal des tâches AWS DMS et la section des statistiques de table de la tâche. Vous pouvez également trouver ces informations dans le fichier du journal des erreurs PostgreSQL si le paramètre log_min_error_statement est défini sur ERROR ou a une gravité inférieure. Après avoir identifié la commande qui a échoué, vous pouvez trouver les noms des tables ayant échoué. Consultez l'exemple de message d'erreur suivant tiré du journal des erreurs PostgreSQL :

ERROR: canceling statement due to statement timeout 
STATEMENT: <The statement executed>"

Pour trouver des verrous sur les tables associées, exécutez la commande suivante dans la source ou la cible (selon l'endroit où l'erreur s'affiche) :

SELECT blocked_locks.pid AS blocked_pid,
 blocked_activity.usename AS blocked_user,
 blocking_locks.pid AS blocking_pid,
         blocking_activity.usename AS blocking_user, 
         blocked_activity.query    AS blocked_statement,
         blocking_activity.query   AS current_statement_in_blocking_process
   FROM  pg_catalog.pg_locks         blocked_locks 
    JOIN pg_catalog.pg_stat_activity blocked_activity  ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks         blocking_locks 
        ON blocking_locks.locktype = blocked_locks.locktype 
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid 
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
   WHERE NOT blocked_locks.GRANTED;

Si vous trouvez des PID bloqués, arrêtez ou stoppez le PID bloqué en exécutant la commande suivante :

SELECT pg_terminate_backend(blocking_pid);

Comme les lignes mortes ou les « tuples » peuvent augmenter le temps de SELECT, recherchez un grand nombre de lignes mortes dans les tables sources en exécutant la commande suivante :

select * from pg_stat_user_tables where relname= 'table_name';

Vérifiez si la table cible ayant échoué comporte ou non des clés primaires ou des index uniques. Si la table ne possède pas de clés primaires ou d'index uniques, une analyse complète de la table est effectuée lors de l'exécution de toute instruction UPDATE. Cette analyse du tableau peut prendre du temps.

Augmentation de la valeur du délai d'exécution

AWS DMS utilise l'attribut de connexion supplémentaire executeTimeout dans les points de terminaison source et cible. La valeur par défaut de executeTimeout est 60 secondes. AWS DMS expire donc si l'exécution d'une requête prend plus de 60 secondes.

Si l'erreur s'affiche dans Source_Unloadou Source_Capture, définissez la valeur de délai pour executeTimeout dans la source. Si l'erreur s'affiche dans Target_Load ou Target_Apply, définissez la valeur de délai d'expiration pour executeTimeout dans la cible. Procédez comme suit pour augmenter le paramètre de valeur de délai d'exécution :

1.    Ouvrez la console AWS DMS.

2.    Choisissez Endpoints (Points de terminaison) dans le panneau de navigation.

3.    Choisissez le point de terminaison PostgreSQL.

4.    Choisissez Actions, puis sélectionnez « Modify » (Modifier).

5.    Développez la section « Endpoint specific settings » (Paramètres spécifiques aux points de terminaison).

6.    Dans le champ Extra connection attributes (Attributs de connexion supplémentaires), entrez la valeur suivante :

executeTimeout=3600;

7.    Choisissez Enregistrer.

8.    Dans le panneau Endpoints (Points de terminaison), choisissez le nom de votre point de terminaison PostgreSQL.

9.    Dans la section Connections (Connexions) le Statut du point de terminaison passe de Testing (Test en cours) à Successful (Réussite).

Vous pouvez augmenter (en millisecondes) le paramètre statement_timeout dans l'instance de base de données PostgreSQL. La valeur par défaut est 0, ce qui désactive les délais d'attente pour n'importe quelle requête. Vous pouvez également augmenter le paramètre lock_timeout . La valeur par défaut est 0, ce qui désactive les délais d'attente pour les verrous.

Résoudre les problèmes de création de l'emplacement

Si l'expiration s'est produite lorsque vous avez créé l'emplacement de réplication dans la base de données PostgreSQL, vous voyez des entrées de journal semblable à ce qui suit :

Messages

«] E : test_decoding_create_replication_slot (...) - Impossible de créer le slot 'lrcyli7hfxcwkair_00016402_8917165c_29f0_4070_97dd_26e78336e01b' (lors de la phase d'exécution (...)) [1022506] (postgres_test_decoding.c:392) »

Vous pouvez augmenter ce délai en configurant le paramètre TransactionConsistencyTimeout dans la section Task settings (Paramètres de tâche). La valeur par défaut est de 600 secondes.

PostgreSQL ne peut pas créer l'emplacement de réplication s'il y a des verrous actifs dans les tables d'utilisateur de base de données. Vérifiez la présence de verrous en exécutant cette commande :

select * from pg_locks;

Ensuite, pour tester si l'erreur a été résolue, exécutez la commande suivante pour créer manuellement l'emplacement de réplication dans la base de données PostgreSQL source :

select  xlog_position FROM pg_create_logical_replication_slot('<Slot name as per
    the task log>', 'test_decoding');

Si la commande ne parvient toujours pas à créer l'emplacement, vous devrez peut-être utiliser un administrateur de base de données PostgreSQL DBA pour identifier le point de blocage et configurer votre base de données. Si la commande aboutit, supprimez l'emplacement que vous venez de créer comme test:

select pg_drop_replication_slot(‘<slot name>');

Enfin, redémarrez votre tâche de migration.


Informations connexes

Documentation PostgreSQL pour les paramètres par défaut de connexion client

Attributs de connexion supplémentaires lors de l'utilisation de PostgreSQL comme cible pour AWS DMS

Attributs de connexion supplémentaires lors de l'utilisation de PostgreSQL comme source DMS

Utilisation d'une base de données PostgreSQL comme source AWS DMS

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 2 ans