AWS AWS DMS CDC migracja bazy danych database

AWS DMS: rosnące opóźnienie CDC i awaria taska replikacyjnego

Naprawa rosnącego opóźnienia CDC i awarii taska AWS DMS: diagnoza CDCLatencySource vs CDCLatencyTarget, tabele bez klucza głównego, obcięcie LOB i sizing instancji replikacyjnej.

Jerzy Kopaczewski ·
Task AWS DMS miał dogonić zmiany przed przełączeniem produkcji, ale opóźnienie CDC rośnie zamiast maleć - cutover nigdy nie zbiega się do zera. Albo task pada w trybie full load na tabeli bez klucza głównego lub cicho ucina dane w kolumnach LOB. Ten runbook pokazuje, jak zdiagnozować przyczynę i przywrócić replikację.

Ten runbook opisuje rozwiązywanie problemów z taskiem AWS DMS podczas migracji bazy danych. Pełny przewodnik po samej usłudze znajdziesz w artykule AWS DMS - przewodnik po migracji baz danych. W kwestii planowania i realizacji migracji umów konsultację.

Objaw

Task DMS jest w stanie „Running”, ale nie zbliża się do końca, albo przechodzi w „Failed”/„Error”. Typowe sygnały:

# Metryki CloudWatch pokazuja rosnace opoznienie CDC (w sekundach)
aws cloudwatch get-metric-statistics \
  --namespace AWS/DMS \
  --metric-name CDCLatencyTarget \
  --dimensions Name=ReplicationInstanceIdentifier,Value=dms-prod \
               Name=ReplicationTaskIdentifier,Value=oracle-to-aurora \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 60 --statistics Maximum \
  --query 'Datapoints | sort_by(@, &Timestamp) | [-10:].[Timestamp,Maximum]'

# Status i statystyki tabel taska (ktore tabele sa w stanie Error)
aws dms describe-table-statistics \
  --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA \
  --query 'TableStatistics[?TableState!=`Table completed`].{schema:SchemaName, table:TableName, state:TableState, fullLoadRows:FullLoadRows}' \
  --output table

# Typowe komunikaty w logach taska (CloudWatch Logs, grupa dms-tasks-*):
# "Some changes from the source database were not applied due to missing primary key"
# "LOB column data was truncated" / "Limited LOB mode"
# "Last Error ... Task error notification received from subtask"

Opóźnienie CDCLatencyTarget narasta w czasie (nie stabilizuje się), albo w statystykach tabel pojawia się stan Table error.

Przyczyna

Rosnące opóźnienie CDC i błędy taska mają zwykle jedną z czterech przyczyn:

  • Instancja replikacyjna za jest mała: przy dużym wolumenie transakcji na źródle instancja nie nadąża z odczytem i aplikowaniem zmian. Reguła kciuka: ~1 vCPU na 50 GB ładowanych danych lub na 100 tabel pod CDC. Zbyt mała klasa (np. dms.t3) pod produkcyjnym obciążeniem to najczęstsza przyczyna narastającego opóźnienia.
  • Tabele bez klucza głównego: CDC identyfikuje wiersze po kluczu. Tabela bez klucza głównego lub unikalnego indeksu powoduje, że operacje UPDATE/DELETE nie mają jak trafić w konkretny wiersz - task zgłasza błąd lub w skrajnym przypadku aplikuje zmiany do wszystkich pasujących wierszy.
  • Obcięcie LOB (Limited LOB mode): domyślny tryb DMS ucina kolumny BLOB/CLOB/BYTEA powyżej ustalonego LobMaxSize. To cicha utrata danych - task nie pada, ale dane docelowe są niekompletne.
  • Rozróżnienie CDCLatencySource vs CDCLatencyTarget: wysoki CDCLatencySource wskazuje problem po stronie źródła (np. brak supplemental logging w Oracle, wolny odczyt logów, LogMiner pod obciążeniem). Wysoki CDCLatencyTarget przy niskim source wskazuje wąskie gardło po stronie aplikowania zmian na celu (rozmiar instancji, indeksy, wyzwalacze).

Rozwiązanie

A) Ustal, po której stronie jest wąskie gardło (source vs target):

# Porownaj obie metryki opoznienia w tym samym oknie czasowym
for M in CDCLatencySource CDCLatencyTarget; do
  echo "=== $M ==="
  aws cloudwatch get-metric-statistics \
    --namespace AWS/DMS --metric-name $M \
    --dimensions Name=ReplicationInstanceIdentifier,Value=dms-prod \
                 Name=ReplicationTaskIdentifier,Value=oracle-to-aurora \
    --start-time $(date -u -d '30 minutes ago' +%Y-%m-%dT%H:%M:%S) \
    --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
    --period 60 --statistics Average \
    --query 'Datapoints | sort_by(@, &Timestamp) | [-5:].[Timestamp,Average]'
done
# Wysoki source -> problem na zrodle (logowanie zmian).
# Wysoki target przy niskim source -> problem na celu (sizing/indeksy).

B) Wysoki CDCLatencySource - napraw logowanie zmian na źródle (Oracle):

-- Sprawdz supplemental logging (wymagane dla CDC z Oracle)
SELECT supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui
FROM v$database;

-- Wlacz, jesli wylaczone
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;

-- Dla MySQL: binlog w formacie ROW; dla PostgreSQL: wal_level = logical

C) Wysoki CDCLatencyTarget - zwiększ instancję replikacyjną lub zrównoleglij:

# Powieksz klase instancji replikacyjnej (bez odtwarzania taska)
aws dms modify-replication-instance \
  --replication-instance-arn arn:aws:dms:eu-west-1:123456789012:rep:DMSPROD \
  --replication-instance-class dms.r5.2xlarge \
  --apply-immediately

# W ustawieniach taska zwieksz rownoleglosc aplikowania (task settings JSON):
# "TargetMetadata": { "ParallelApplyThreads": 8, "ParallelApplyBufferSize": 1000 }
# oraz dla full load: "FullLoadSettings": { "MaxFullLoadSubTasks": 8 }

D) Tabele bez klucza głównego - dodaj klucz lub migruj tylko w full load:

-- Zidentyfikuj tabele bez klucza glownego na zrodle (Oracle)
SELECT t.owner, t.table_name
FROM all_tables t
WHERE NOT EXISTS (
  SELECT 1 FROM all_constraints c
  WHERE c.table_name = t.table_name AND c.owner = t.owner
    AND c.constraint_type = 'P')
  AND t.owner = 'APP_SCHEMA';

-- Dodaj klucz glowny przed migracja (preferowane) LUB
-- oznacz te tabele do migracji wylacznie w trybie Full Load (bez CDC) w table mapping.

E) Obcięcie LOB - przełącz na Full LOB lub dobierz LobMaxSize:

# W ustawieniach taska (task settings JSON) dla tabel z duzymi LOB:
# "TargetMetadata": {
#   "SupportLobs": true,
#   "FullLobMode": true,          # pelne LOB (wolniej, ale bez obciecia)
#   "LobChunkSize": 64,
#   "LimitedSizeLobMode": false
# }
# LUB tryb Inline/Limited z odpowiednio dobranym LobMaxSize (KB) do najwiekszego LOB.

# Po zmianie ustawien - task wymaga zatrzymania i wznowienia
aws dms stop-replication-task  --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA
aws dms start-replication-task --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA \
  --start-replication-task-type resume-processing

Prewencja: monitoruj CDCLatencyTarget od pierwszego dnia migracji, nie w dniu cutoveru. Włącz zadanie Data Validation w DMS, żeby wychwycić rozbieżności danych (w tym obcięte LOB). Dla dużych baz dobierz instancję replikacyjną z zapasem i skonfiguruj alarm CloudWatch na CDCLatencyTarget powyżej progu (np. 300 s).

Walidacja

# 1. Opoznienie CDC spada i stabilizuje sie blisko zera
aws cloudwatch get-metric-statistics \
  --namespace AWS/DMS --metric-name CDCLatencyTarget \
  --dimensions Name=ReplicationInstanceIdentifier,Value=dms-prod \
               Name=ReplicationTaskIdentifier,Value=oracle-to-aurora \
  --start-time $(date -u -d '15 minutes ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 60 --statistics Average
# Oczekiwane: trend malejacy, docelowo < 5 s

# 2. Zadna tabela nie jest w stanie bledu
aws dms describe-table-statistics \
  --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA \
  --query 'TableStatistics[?TableState==`Table error`].{schema:SchemaName, table:TableName}' \
  --output table
# Oczekiwane: pusta lista

# 3. Walidacja danych (jesli wlaczona) nie zglasza rozbieznosci
aws dms describe-table-statistics \
  --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA \
  --query 'TableStatistics[].{table:TableName, validation:ValidationState, pending:ValidationPendingRecords, failed:ValidationFailedRecords}' \
  --output table
# Oczekiwane: ValidationState = "Validated", failed = 0

Jeśli opóźnienie CDC jest stabilnie niskie, żadna tabela nie jest w stanie błędu, a walidacja danych przechodzi bez rozbieżności - task jest gotowy do cutoveru. Utrzymuj replikację do momentu przełączenia i monitoruj opóźnienie aż do wstrzymania zapisu na źródle.

Rosnące opóźnienie CDC oznacza, że nie możesz wykonać czystego przełączenia produkcji - okno cutoveru nigdy się nie domyka. Przy migracji z wymogiem minimalnego przestoju to bezpośrednie ryzyko przesunięcia terminu. Obcięcie LOB jest groźniejsze: task nie zgłasza awarii, a niekompletne dane docierają na produkcję niezauważone aż do reklamacji użytkowników. Dlatego walidację danych i monitoring opóźnienia wdraża się od początku, nie w dniu przełączenia.

 

Jerzy Kopaczewski

Migracja bazy danych z DMS się przeciąga?

Umów bezpłatną 30-minutową rozmowę. Przejrzymy konfigurację DMS, dobierzemy tryb i sizing, i doprowadzimy migrację do czystego cutoveru.

Umów rozmowę