AWS AWS DMS CDC migracja bazy danych walidacja danych

AWS DMS: walidacja danych zgłasza rozbieżności po full load + CDC

Naprawa rozbieżności danych w walidacji AWS DMS po full load + CDC: diagnoza ValidationState i ValidationFailedRecords, niezgodność typów, obcięte LOB, kolacja i kolejność wierszy przed przełączeniem produkcji.

Jerzy Kopaczewski ·
Full load się zakończył, opóźnienie CDC jest bliskie zera, task wygląda na gotowy do przełączenia - ale walidacja danych DMS zgłasza `ValidationFailedRecords` albo liczba wierszy na celu nie zgadza się ze źródłem. Przełączenie produkcji z rozbieżnymi danymi oznacza ciche uszkodzenie danych, które wychodzi dopiero przy reklamacjach użytkowników. Ten runbook pokazuje, jak zdiagnozować i usunąć rozbieżności, zanim przełączysz produkcję.

Ten runbook opisuje rozwiązywanie rozbieżności danych wykrytych przez walidację AWS DMS. Jeśli problemem jest rosnące opóźnienie CDC lub awaria taska, zobacz runbook AWS DMS: opóźnienie CDC i błąd taska. Pełny przewodnik po usłudze: AWS DMS - przewodnik po migracji baz danych, a dla migracji heterogenicznych Migracja Oracle do PostgreSQL na AWS. W kwestii planowania przełączenia produkcji umów konsultację.

Objaw

Task DMS jest w stanie „Running”, full load ukończony, ale walidacja danych nie schodzi do zera błędów. Typowe sygnały:

# Stan walidacji per tabela - ktore tabele maja rozbieznosci
aws dms describe-table-statistics \
  --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA \
  --query 'TableStatistics[?ValidationFailedRecords>`0` || ValidationState!=`Validated`].{schema:SchemaName, table:TableName, valState:ValidationState, failed:ValidationFailedRecords, pending:ValidationPendingRecords, suspended:ValidationSuspendedRecords}' \
  --output table

# Typowe wartosci ValidationState:
#   Validated                 - zgodne (stan docelowy)
#   Mismatched records        - wiersze o roznej zawartosci
#   Suspended validation      - walidacja wstrzymana (np. brak klucza)
#   Error                     - blad procesu walidacji

# Roznica liczby wierszy zrodlo vs cel (szybki sanity check)
# zrodlo Oracle:      SELECT COUNT(*) FROM app_schema.orders;
# cel Aurora PostgreSQL: SELECT COUNT(*) FROM app_schema.orders;

ValidationFailedRecords > 0, ValidationState = "Mismatched records" lub liczba wierszy na celu różni się od źródła. Task nie zgłasza awarii - dane są niekompletne lub niezgodne mimo „zielonego” statusu replikacji.

Przyczyna

Rozbieżności w walidacji DMS po full load + CDC mają zwykle jedną z czterech przyczyn:

  • Obcięte LOB (Limited LOB mode): domyślny tryb DMS ucina kolumny BLOB/CLOB/BYTEA powyżej LobMaxSize. Full load i CDC działają, ale wartości LOB na celu są krótsze niż na źródle - walidacja porównuje treść i wykrywa mismatch. To najczęstsza cicha przyczyna rozbieżności.
  • Niezgodność typów i precyzji po konwersji heterogenicznej: Oracle NUMBER bez skali → PostgreSQL numeric/double precision, DATE z częścią czasową, TIMESTAMP WITH TIME ZONE, mapowanie CHAR z dopełnieniem spacjami. Po konwersji ta sama wartość logiczna zapisuje się inaczej i walidacja raportuje różnicę.
  • Kolacja i porównywanie tekstu: różne reguły sortowania/porównań (case sensitivity, trailing spaces, kolacja bazy) sprawiają, że DMS uznaje wiersze za rozbieżne, choć aplikacyjnie są równoważne. Dotyczy zwłaszcza kluczy tekstowych.
  • Tabele bez klucza głównego lub z niestabilną kolejnością: walidacja DMS dopasowuje wiersze po kluczu. Brak klucza głównego/unikalnego indeksu powoduje Suspended validation, a przy dużych tabelach bez deterministycznego porządku - fałszywe rozbieżności.

Rozwiązanie

A) Ustal charakter rozbieżności - których kolumn dotyczy:

# Wlacz szczegolowe logowanie walidacji w ustawieniach taska (task settings JSON):
# "ValidationSettings": {
#   "EnableValidation": true,
#   "ValidationMode": "ROW_LEVEL",
#   "RecordFailureDelayInMinutes": 5,
#   "TableFailureMaxCount": 1000,
#   "FailureMaxCount": 10000,
#   "ValidationPartialLobSize": 0,      # 0 = waliduj pelne LOB, nie tylko prefiks
#   "PartitionSize": 10000
# }

# Szczegoly rozbieznych wierszy trafiaja do tabeli kontrolnej na celu:
#   awsdms_validation_failures_v1  (schemat kontrolny DMS na docelowej bazie)
# Podejrzyj, ktore kolumny sie roznia:
# SELECT TABLE_NAME, COLUMN_NAME, FAILURE_TYPE, KEY, DETAILS
# FROM awsdms_control.awsdms_validation_failures_v1
# ORDER BY FAILURE_TIME DESC LIMIT 50;

B) Obcięte LOB - przełącz na Full LOB i zwaliduj pełną treść:

# W ustawieniach taska dla tabel z duzymi LOB:
# "TargetMetadata": {
#   "SupportLobs": true,
#   "FullLobMode": true,          # pelne LOB bez obciecia
#   "LobChunkSize": 64,
#   "LimitedSizeLobMode": false
# }
# oraz w ValidationSettings ustaw "ValidationPartialLobSize": 0.

# Po zmianie zatrzymaj i wznow task; dla pewnosci przeladuj dotkniete tabele:
aws dms start-replication-task \
  --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA \
  --start-replication-task-type reload-target

C) Niezgodność typów - dopnij mapowanie w regułach transformacji:

-- Zweryfikuj konkretny rozjazd na przykladowym kluczu (zrodlo vs cel)
-- Oracle:
SELECT order_id, DUMP(amount) FROM app_schema.orders WHERE order_id = 4711;
-- PostgreSQL:
SELECT order_id, amount, pg_typeof(amount) FROM app_schema.orders WHERE order_id = 4711;

-- Typowe poprawki:
--  * NUMBER bez skali -> wymus numeric(p,s) zamiast double precision (SCT / DDL na celu)
--  * CHAR(n) -> przytnij trailing spaces regula transformacji DMS lub zmien na VARCHAR
--  * DATE Oracle z czasem -> upewnij sie, ze cel to timestamp, nie date
# Reguly transformacji DMS (table mapping) - przyklad: przytnij spacje w kluczu tekstowym
# {
#   "rule-type": "transformation",
#   "rule-action": "convert-lowercase",   # lub rtrim przez expression w SQL na celu
#   "rule-target": "column",
#   "object-locator": { "schema-name": "APP_SCHEMA", "table-name": "CUSTOMERS", "column-name": "CODE" }
# }

D) Kolacja i tabele bez klucza - dopasuj porównywanie lub zawęź walidację:

# Dla tabel bez klucza glownego: dodaj klucz na zrodle przed migracja (preferowane),
# albo wskaz DMS kolumny tworzace unikalny klucz walidacji w table mapping:
# {
#   "rule-type": "validation",
#   "rule-action": "override-validation-function",
#   "object-locator": { "schema-name": "APP_SCHEMA", "table-name": "EVENTS" },
#   "rule-settings": { "validate-function": "NONE" }   # ostatecznosc: wylacz dla tej tabeli
# }

# Dla rozbieznosci wynikajacych z kolacji tekstu - ujednolic kolacje kolumny na celu
# (PostgreSQL): ALTER TABLE app_schema.customers ALTER COLUMN code TYPE text COLLATE "C";

Prewencja: włączaj walidację danych od początku migracji, nie w dniu przełączenia - ValidationState i tabela awsdms_validation_failures_v1 pokazują problemy, gdy jest jeszcze czas na poprawki. Dla migracji heterogenicznych przejrzyj raport SCT pod kątem typów o niepełnym mapowaniu, zanim uruchomisz task (patrz runbook o błędach konwersji SCT). Dla dużych tabel z LOB od razu planuj Full LOB mode i większą instancję replikacyjną.

Walidacja

# 1. Zadna tabela nie ma rozbieznosci i nic nie jest w stanie innym niz Validated
aws dms describe-table-statistics \
  --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA \
  --query 'TableStatistics[?ValidationState!=`Validated` || ValidationFailedRecords>`0`].{table:TableName, state:ValidationState, failed:ValidationFailedRecords}' \
  --output table
# Oczekiwane: pusta lista

# 2. Podsumowanie walidacji per tabela (liczby zerowe w failed/pending/suspended)
aws dms describe-table-statistics \
  --replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:ORACLE2AURORA \
  --query 'TableStatistics[].{table:TableName, valid:ValidationState, failed:ValidationFailedRecords, pending:ValidationPendingRecords, suspended:ValidationSuspendedRecords}' \
  --output table
# Oczekiwane: ValidationState = "Validated", failed = pending = suspended = 0

# 3. Sanity check liczby wierszy na krytycznych tabelach (zrodlo vs cel)
# Oracle:            SELECT COUNT(*) FROM app_schema.orders;
# Aurora PostgreSQL: SELECT COUNT(*) FROM app_schema.orders;
# Oczekiwane: identyczne liczby (przy zatrzymanym zapisie na zrodle w oknie przelaczenia)

Jeśli walidacja zgłasza Validated dla wszystkich tabel, ValidationFailedRecords = 0, a liczby wierszy się zgadzają - dane są spójne i task jest gotowy do przełączenia. Utrzymuj replikację i powtórz sanity check tuż przed przełączeniem, po wstrzymaniu zapisu na źródle.

Rozbieżność danych, którą wykryje walidacja DMS, to problem, który da się naprawić przed przełączeniem - obcięte LOB, niezgodne typy czy kolacja. Groźne jest przełączenie produkcji mimo tych sygnałów: task pokazuje „zielono", a niekompletne lub niezgodne dane docierają na produkcję niezauważone aż do reklamacji użytkowników albo błędów rozliczeń. Dlatego walidację danych traktuje się jako bramkę kontrolną przed przełączeniem, nie jako opcjonalny dodatek.

 

Jerzy Kopaczewski

Walidacja DMS zgłasza rozbieżności przed przełączeniem?

Umów bezpłatną 30-minutową rozmowę. Przejrzymy ustawienia walidacji, mapowanie typów i tryb LOB, i doprowadzimy dane do spójności przed przełączeniem.

Umów rozmowę