Come si risolve un'attività AWS DMS che fallisce con il messaggio di errore " ERRORE: annullamento dell'istruzione a causa del timeout dell'istruzione"?

6 minuti di lettura
0

Sto migrando i dati da o verso il mio database PostgreSQL on-premises utilizzando AWS Database Migration Service (AWS DMS). L'attività di AWS DMS viene eseguita normalmente per un po' e poi fallisce con un errore. Come posso individuare e risolvere questi errori?

Breve descrizione

Se il database PostgreSQL è la fonte dell'attività di migrazione, AWS DMS ottiene i dati dalla tabella durante la fase di caricamento completo. Poi, AWS DMS legge dai log write-ahead (WAL) conservati dallo slot di replica durante la fase di acquisizione dei dati di modifica (CDC).

Se il database PostgreSQL è la destinazione, AWS DMS riceve i dati dall'origine e crea file CSV nell'istanza di replica. Quindi, AWS DMS esegue un comando COPY per inserire tali record nella destinazione durante la fase di pieno carico.

Ma durante la fase CDC, AWS DMS esegue esattamente le istruzioni DML dai log WAL di origine in modalità di applicazione transazionale. Per la modalità di applicazione batch, AWS DMS crea anche file CSV durante la fase CDC. Quindi, esegue un comando COPY per inserire le modifiche nette nel target.

Quando AWS DMS cerca di ottenere i dati dall'origine o di inserirli nella destinazione, utilizza il timeout predefinito di 60 secondi. Se l'origine o la destinazione sono molto cariche o ci sono blocchi nelle tabelle, AWS DMS non può terminare l'esecuzione dei comandi entro 60 secondi. Quindi, l'attività fallisce con un errore che dice "annullamento dell'istruzione a causa del timeout dell'istruzione" e vedi una di queste voci nel registro:

Messaggi:

"]E: RetCode: SQL_ERROR SqlState: 57014 NativeError: 1 messaggio: ERRORE: annullamento dell'istruzione a causa del timeout dell'istruzione; errore durante l'esecuzione della query [1022502] (ar_odbc_stmt.c:2738)"

"]E: test_decoding_create_replication_slot(...) - Impossibile creare lo slot 'lrcyli7hfxcwkair_00016402_8917165c\29f0_4070_97dd\26e78336e01b' (in fase execute(...)) [1022506] (postgres_test_decoding.c:392))"

Per risolvere e risolvere questi errori, procedi nel seguente modo:

  • Identifica la causa dei lunghi tempi di esecuzione dei comandi.
  • Aumenta il valore di timeout e controlla il valore di timeout di creazione dello slot.
  • Risolvi i problemi relativi alla creazione degli slot.

Risoluzione

Identifica la causa dei lunghi tempi di esecuzione dei comandi

Per trovare il comando che non è stato eseguito durante il periodo di timeout, consulta il log delle attività di AWS DMS e la sezione relativa alle statistiche della tabella dell'attività. Puoi anche trovare queste informazioni nel file di registro degli errori di PostgreSQL se il parametro log_min_error_statement è impostato su ERROR o su una gravità inferiore. Dopo aver identificato il comando che non ha funzionato, puoi trovare i nomi delle tabelle non funzionanti. Vedi questo messaggio di errore di esempio dal registro degli errori di PostgreSQL:

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

Per trovare i lock sulle tabelle associate, esegui questo comando nell'origine o nella destinazione (a seconda di dove viene visualizzato l'errore):

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;

Se trovi dei PID bloccati, interrompi o termina il PID bloccato eseguendo questo comando:

SELECT pg_terminate_backend(blocking_pid);

Poiché le righe morte, o “tuple”, possono aumentare il tempo di SELEZIONE, controlla la presenza di un numero elevato di righe morte nelle tabelle di origine eseguendo questo comando:

select * from pg_stat_user_tables where relname= 'table_name';

Controlla se la tabella di destinazione fallita ha chiavi primarie o indici unici. Se la tabella non ha chiavi primarie o indici univoci, viene eseguita una scansione completa della tabella durante l'esecuzione di qualsiasi istruzione UPDATE. Questa scansione della tabella può richiedere molto tempo.

Aumentare il valore di timeout

AWS DMS utilizza l'attributo di connessione aggiuntivo executeTimeout sia negli endpoint di origine che di destinazione. Il valore predefinito per executeTimeout è 60 secondi, quindi AWS DMS scade se l'esecuzione di una query richiede più di 60 secondi.

Se l'errore viene visualizzato in Source_Unload o Source_Capture, imposta il valore di timeout per executeTimeout nell'origine. Se l'errore viene visualizzato in Target_Load o Target_Apply, imposta il valore di timeout per executeTimeout nella destinazione. Aumenta l'impostazione del valore di timeout seguendo questi passaggi:

  1. Apri la console AWS DMS.

  2. Scegli Endpoint dal riquadro di navigazione.

  3. Scegli l'endpoint PostgreSQL.

  4. Scegli Azioni e seleziona Modifica.

  5. Espandi la sezione delle Impostazioni specifiche dell'endpoint.

  6. Nel campo per gli Attributi di connessione aggiuntivi, inserisci questo valore:

executeTimeout=3600;
  1. Scegli Salva.

  2. Dal riquadro Endpoint, scegli il nome del tuo endpoint PostgreSQL.

  3. Dalla sezione Connessioni, lo Stato dell'endpoint passa da Testing a Successo.

È possibile aumentare (in millisecondi) il parametro statement_timeout nell'istanza DB di PostgreSQL. Il valore predefinito è 0, che disattiva i timeout per qualsiasi query. Puoi anche aumentare il parametro lock_timeout. Il valore predefinito è 0, che disattiva i timeout per i blocchi.

Risolvi i problemi di creazione degli slot

Se il timeout si è verificato quando hai creato lo slot di replica nel database PostgreSQL, vedrai delle voci di registro simili alle seguenti:

Messaggi

"]E: test_decoding_create_replication_slot(...) - Impossibile creare lo slot 'lrcyli7hfxcwkair_00016402_8917165c\29f0_4070_97dd\26e78336e01b' (in fase execute(...)) [1022506] (postgres_test_decoding.c:392)"

È possibile aumentare questo timeout configurando il parametro TransactionConsistencyTimeout nella sezione Impostazioni attività. Il valore predefinito è 600 secondi.

PostgreSQL non può creare lo slot di replica se ci sono blocchi attivi nelle tabelle degli utenti del database. Controlla i blocchi eseguendo questo comando:

select * from pg_locks;

Quindi, per verificare se l'errore è stato risolto, esegui questo comando per creare manualmente lo slot di replica nel database PostgreSQL di origine:

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

Se il comando non riesce ancora a creare lo slot, potrebbe essere necessario utilizzare un DBA di PostgreSQL per identificare il collo di bottiglia e configurare il database. Se il comando ha esito positivo, elimina lo slot che hai appena creato come test:

select pg_drop_replication_slot(‘<slot name>');

Infine, riavvia l'attività di migrazione.


Informazioni correlate

Documentazione PostgreSQL per le impostazioni predefinite di connessione client

Attributi di connessione aggiuntivi quando si utilizza PostgreSQL come destinazione per AWS DMS

Attributi di connessione aggiuntivi quando si utilizza PostgreSQL come sorgente DMS

Utilizzo di un database PostgreSQL come fonte AWS DMS

AWS UFFICIALE
AWS UFFICIALEAggiornata un anno fa