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.
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
NUMBERbez skali → PostgreSQLnumeric/double precision,DATEz częścią czasową,TIMESTAMP WITH TIME ZONE, mapowanieCHARz 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.
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.