¿Cómo soluciono que una tarea de AWS DMS falle y aparezca el mensaje de error «ERROR: canceling statement due to statement timeout»?
Estoy migrando datos hacia o desde mi base de datos local de PostgreSQL con AWS Database Migration Service (AWS DMS). La tarea de AWS DMS se ejecuta de forma normal durante un tiempo y después se produce un error. ¿Cómo puedo solucionar estos errores?
Descripción corta
Si la base de datos de PostgreSQL es el origen de la tarea de migración, AWS DMS obtiene los datos de la tabla durante la fase de carga completa. A continuación, AWS DMS lee los registros de escritura previa (WAL) que se guardan en la ranura de replicación durante la fase de captura de datos modificados (CDC).
Si el destino es la base de datos de PostgreSQL, AWS DMS obtiene los datos del origen y crea archivos CSV en la instancia de replicación. A continuación, AWS DMS ejecuta un comando COPY para insertar esos registros en el destino durante la fase de carga completa.
Sin embargo, durante la fase de CDC, AWS DMS ejecuta las instrucciones DML exactas de los registros WAL de origen en el modo de aplicación transaccional. Para el modo de aplicación por lotes, AWS DMS también crea archivos CSV durante la fase de CDC. A continuación, ejecuta un comando COPY para insertar los cambios netos en el destino.
Cuando AWS DMS intenta obtener datos del origen o colocarlos en el destino, utiliza la configuración de tiempo de espera predeterminada de 60 segundos. Si el origen o el destino están muy cargados o hay bloqueos en las tablas, AWS DMS no podrá terminar de ejecutar esos comandos en 60 segundos. Por lo tanto, la tarea falla y aparece un error que dice «canceling statement due to statement timeout» y aparece una de estas entradas en el registro:
Mensajes:
«]E: RetCode: SQL_ERROR SqlState: 57014 NativeError: 1 Message: ERROR: canceling statement due to statement timeout; Error while executing the query [1022502] (ar_odbc_stmt.c:2738)»
«]E: test_decoding_create_replication_slot(...) - Unable to create slot 'lrcyli7hfxcwkair_00016402_8917165c_29f0_4070_97dd_26e78336e01b' (on execute(...) phase) [1022506] (postgres_test_decoding.c:392))»
Para solucionar estos errores, sigue estos pasos:
- Identifica la causa de la duración prolongada de los tiempos de ejecución de los comandos.
- Aumenta el valor del tiempo de espera y comprueba el valor del tiempo de espera de creación de ranuras.
- Soluciona los problemas con la creación de ranuras.
Resolución
Identificar la causa de la duración prolongada de los tiempos de ejecución de los comandos
Para encontrar el comando que no se pudo ejecutar durante el periodo de tiempo de espera, revisa el registro de tareas de AWS DMS y la sección de estadísticas de la tabla de la tarea. También puedes encontrar esta información en el archivo de registro de errores de PostgreSQL si el parámetro log_min_error_statement está establecido en ERROR o con una gravedad inferior. Tras identificar el comando que falló, podrás buscar los nombres de las tablas con errores. Consulta este ejemplo de mensaje de error del registro de errores de PostgreSQL:
ERROR: canceling statement due to statement timeout STATEMENT: <The statement executed>"
Para buscar bloqueos en las tablas asociadas, ejecuta este comando en el origen o el destino (según dónde aparezca el error):
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 encuentras algún PID bloqueado, detén o finaliza el PID bloqueado ejecutando este comando:
SELECT pg_terminate_backend(blocking_pid);
Dado que las filas muertas pueden aumentar el tiempo de SELECT, comprueba si hay un gran número de filas muertas en las tablas de origen ejecutando este comando:
select * from pg_stat_user_tables where relname= 'table_name';
Comprueba si la tabla de destino que falla tiene claves principales o índices únicos. Si la tabla no tiene claves principales ni índices únicos, se lleva a cabo un análisis completo de la tabla durante la ejecución de cualquier instrucción UPDATE. Este análisis de la tabla puede tardar mucho tiempo.
Aumentar el valor del tiempo de espera
AWS DMS usa el atributo de conexión adicional executeTimeout tanto en los puntos de enlace de origen como en los de destino. El valor predeterminado de executeTimeout es de 60 segundos, por lo que AWS DMS agota el tiempo de espera si una consulta tarda más de 60 segundos en ejecutarse.
Si el error aparece en Source_Unload o Source_Capture, define el valor de tiempo de espera de executeTimeout en el origen. Si el error aparece en Target_Load o Target_Apply, define el valor de tiempo de espera de executeTimeout en el destino. Para aumentar el valor del tiempo de espera, sigue estos pasos:
1. Abre la consola de AWS DMS.
2. Selecciona Puntos de enlace en el panel de navegación.
3. Elige el punto de enlace de PostgreSQL.
4. Elige Acciones y, a continuación, selecciona Modificar.
5. Expande la sección Configuración específica de punto de enlace.
6. En el campo Atributos de conexión adicionales, introduce este valor:
executeTimeout=3600;
7. Selecciona Guardar.
8. En el panel Puntos de enlace, elige el nombre del punto de enlace de PostgreSQL.
9. En la sección Conexiones, el Estado del punto de enlace cambia de Pruebas a Correcto.
Puedes aumentar (en milisegundos) el parámetro statement_timeout en la instancia de base de datos de PostgreSQL. El valor predeterminado es 0, lo que desactiva los tiempos de espera de cualquier consulta. También puedes aumentar el parámetro lock_timeout. El valor predeterminado es 0, lo que desactiva los tiempos de espera de los bloqueos.
Solucionar problemas con la creación de ranuras
Si el tiempo de espera se agotó al crear la ranura de replicación en la base de datos de PostgreSQL, verás entradas de registro similares a las siguientes:
Mensajes
«]E: test_decoding_create_replication_slot(...) - Unable to create slot 'lrcyli7hfxcwkair_00016402_8917165c_29f0_4070_97dd_26e78336e01b' (on execute(...) phase) [1022506] (postgres_test_decoding.c:392)»
Para aumentar este tiempo de espera, configura el parámetro TransactionConsistencyTimeout en la sección Configuración de la tarea. El valor predeterminado es 600 segundos.
PostgreSQL no puede crear la ranura de replicación si hay bloqueos activos en las tablas de usuarios de la base de datos. Comprueba si hay bloqueos ejecutando este comando:
select * from pg_locks;
A continuación, para comprobar si el error se ha resuelto, ejecuta este comando para crear manualmente la ranura de replicación en la base de datos PostgreSQL de origen:
select xlog_position FROM pg_create_logical_replication_slot('<Slot name as per the task log>', 'test_decoding');
Si el comando sigue sin poder crear la ranura, es posible que tengas que trabajar con un administrador de bases de datos de PostgreSQL para identificar el obstáculo y configurar la base de datos. Si el comando se ejecuta correctamente, elimina la ranura que acabas de crear como prueba:
select pg_drop_replication_slot(‘<slot name>');
Por último, reinicia la tarea de migración.
Información relacionada
Documentación de PostgreSQL para los valores predeterminados de conexión de clientes
Atributos de conexión adicionales cuando se utiliza PostgreSQL como destino para AWS DMS
Atributos de conexión adicionales cuando se usa PostgreSQL como origen de DMS
Uso de una base de datos de PostgreSQL como origen de AWS DMS
- Etiquetas
- AWS Database Migration Service
- Idioma
- Español
Vídeos relacionados


Contenido relevante
- Respuesta aceptadapreguntada hace 4 meses
- Respuesta aceptadapreguntada hace 7 meses
- preguntada hace 13 días
- preguntada hace 6 días
OFICIAL DE AWSActualizada hace 2 años
OFICIAL DE AWSActualizada hace 3 años