AWS DMS do Redshift/S3: błędy aplikowania zmian w pipelinie hurtowni danych
Naprawa błędów aplikowania zmian w ciągłym tasku AWS DMS do Redshift lub S3: diagnoza stl_load_errors, przepełnienia VARCHAR, uprawnień IAM/S3 i sizingu instancji dla strumienia CDC utrzymywanego bezterminowo.
Ten runbook opisuje błędy aplikowania zmian w ciągłym tasku DMS do hurtowni danych. Podstawy samej usługi i trybów replikacji znajdziesz w artykule AWS DMS - przewodnik po migracji baz danych. W kwestii architektury pipeline’u analitycznego i optymalizacji kosztów umów konsultację.
Objaw
Task DMS do celu Redshift lub S3 jest w stanie „Running”, ale statystyki tabel pokazują błędy aplikowania, a dane na hurtowni odbiegają od źródła:
# Statystyki tabel - szukaj bledow aplikowania (DdlErrors / DataErrors)
aws dms describe-table-statistics \
--replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:OLTP2REDSHIFT \
--query 'TableStatistics[?TableState==`Table error` || Ddls>`0`].{schema:SchemaName, table:TableName, state:TableState, inserts:Inserts, updates:Updates, deletes:Deletes}' \
--output table
-- Po stronie Redshift: bledy ladowania z warstwy COPY, ktora DMS wykorzystuje pod spodem
SELECT starttime, filename, colname, type, col_length, err_reason
FROM stl_load_errors
ORDER BY starttime DESC
LIMIT 20;
-- Typowe err_reason:
-- "String length exceeds DDL length" -> przepelnienie VARCHAR
-- "Invalid digit, Value '...', Pos 0" -> niezgodnosc typu (tekst do kolumny numerycznej)
-- "Missing newline: Unexpected character" -> zle ustawienia separatora/escape
W logach taska (CloudWatch Logs) dla celu S3 typowe są też komunikaty o odmowie dostępu: Access Denied przy zapisie do bucketu lub Unable to assume role.
Przyczyna
W ciągłym pipelinie do hurtowni błędy po stronie bazy docelowej mają zwykle jedną z trzech przyczyn:
- Przepełnienie VARCHAR / niezgodność typów w Redshift: DMS mapuje typy źródłowe na docelowe, ale Redshift jest rygorystyczny co do długości
VARCHAR(liczonej w bajtach, nie znakach - znaki wielobajtowe UTF-8 zajmują więcej). Kolumna, która mieści się na źródle, przepełnia węższą kolumnę docelową i cały wiersz jest odrzucany przez COPY. To najczęstsza przyczyna narastającychDataErrors. - Uprawnienia IAM / dostęp do S3: DMS zapisuje do celu S3 (i do bucketu pośredniczącego przy Redshift) przez rolę IAM. Brak
s3:PutObject/s3:DeleteObjectna buckecie, błędna relacja zaufania roli, albo polityka bucketu blokująca zapis - wszystkie kończą sięAccess Deniedi zatrzymaniem aplikowania. - Sizing instancji dla strumienia utrzymywanego bezterminowo: to pipeline działający latami, nie kilkutygodniowa migracja. Wraz ze wzrostem wolumenu transakcji na źródle instancja replikacyjna dobrana pod pierwotny ruch przestaje nadążać - opóźnienie rośnie, a przy celu Redshift dochodzi koszt częstych, małych operacji COPY zamiast wsadowego ładowania.
Rozwiązanie
A) Przepełnienie VARCHAR - rozszerz kolumnę docelową lub wymuś szerszy mapping:
-- W Redshift: znajdz zbyt waska kolumne i porownaj z rzeczywista dlugoscia danych
SELECT col_length, err_reason, count(*)
FROM stl_load_errors
WHERE colname = 'customer_note'
GROUP BY col_length, err_reason;
-- Rozszerz kolumne (VARCHAR w Redshift liczy sie w BAJTACH)
ALTER TABLE analytics.customers ALTER COLUMN customer_note TYPE VARCHAR(2000);
# Alternatywnie wymus szersze typy juz na etapie DMS - transformation rule w table mapping:
# regula typu "change-data-type" lub globalne ustawienie
# w task settings: "TargetMetadata": { "SupportLobs": true } dla kolumn tekstowych o duzej dlugosci.
# Dla Redshift rozwaz tez BatchApplyEnabled dla wydajnosci wsadowej.
B) Access Denied na S3 - napraw rolę i politykę bucketu:
# Sprawdz, jaka role uzywa endpoint docelowy DMS
aws dms describe-endpoints \
--filters Name=endpoint-arn,Values=arn:aws:dms:eu-west-1:123456789012:endpoint:S3TARGET \
--query 'Endpoints[0].S3Settings.ServiceAccessRoleArn'
# Zweryfikuj, ze rola ma uprawnienia do zapisu na buckecie
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:role/dms-s3-target-role \
--action-names s3:PutObject s3:DeleteObject s3:ListBucket \
--resource-arns arn:aws:s3:::my-warehouse-bucket/* arn:aws:s3:::my-warehouse-bucket \
--query 'EvaluationResults[].{action:EvalActionName, decision:EvalDecision}' --output table
# Oczekiwane: decision = allowed dla kazdej akcji
# Jesli brakuje uprawnien - dodaj polityke do roli (przyklad minimalny)
aws iam put-role-policy \
--role-name dms-s3-target-role \
--policy-name dms-s3-write \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:PutObject","s3:DeleteObject","s3:ListBucket","s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::my-warehouse-bucket","arn:aws:s3:::my-warehouse-bucket/*"]
}]
}'
# Upewnij sie, ze relacja zaufania roli pozwala dms.amazonaws.com na sts:AssumeRole
C) Sizing i tryb wsadowy dla strumienia długoterminowego:
# Powieksz instancje replikacyjna, jesli opoznienie rosnie wraz z wolumenem
aws dms modify-replication-instance \
--replication-instance-arn arn:aws:dms:eu-west-1:123456789012:rep:DMSDW \
--replication-instance-class dms.r5.xlarge \
--apply-immediately
# Dla celu Redshift wlacz aplikowanie wsadowe (mniej, wiekszych operacji COPY):
# task settings JSON: "TargetMetadata": { "BatchApplyEnabled": true }
# oraz "BatchApplyTimeoutMin"/"BatchApplyTimeoutMax" i "BatchApplyMemoryLimit" dobrane do wolumenu.
Prewencja: zaprojektuj schemat docelowy Redshift z zapasem długości VARCHAR (pamiętaj o bajtach vs znakach w UTF-8) i włącz zadanie Data Validation w DMS. Monitoruj stl_load_errors alarmem oraz CDCLatencyTarget w CloudWatch. Dla stałego pipeline’u przypisz koszt instancji do Database Savings Plan zamiast płacić on-demand latami.
Walidacja
-- 1. Brak nowych bledow ladowania w Redshift w ostatniej godzinie
SELECT count(*) AS recent_errors
FROM stl_load_errors
WHERE starttime > GETDATE() - interval '1 hour';
-- Oczekiwane: 0
-- 2. Liczba wierszy na celu zgadza sie ze zrodlem dla kontrolnej tabeli
SELECT count(*) FROM analytics.customers;
# 3. Zadna tabela taska nie jest w stanie bledu, opoznienie stabilne
aws dms describe-table-statistics \
--replication-task-arn arn:aws:dms:eu-west-1:123456789012:task:OLTP2REDSHIFT \
--query 'TableStatistics[?TableState==`Table error`].{schema:SchemaName, table:TableName}' \
--output table
# Oczekiwane: pusta lista
# 4. Dla celu S3 - pliki pojawiaja sie w buckecie zgodnie z partycjonowaniem
aws s3 ls s3://my-warehouse-bucket/cdc/analytics/customers/ --recursive | tail -5
# Oczekiwane: swieze pliki z aktualnym timestampem
Jeśli stl_load_errors nie przyrasta, żadna tabela nie jest w stanie błędu, a pliki CDC trafiają do S3 zgodnie z oczekiwanym partycjonowaniem - pipeline aplikuje zmiany poprawnie. Monitoruj przez 24 godziny, aby potwierdzić, że błąd nie wraca przy zmiennym wolumenie.
Pipeline CDC do hurtowni się rozjeżdża?
Umów bezpłatną 30-minutową rozmowę. Przejrzymy konfigurację DMS, schemat docelowy i sizing, i ustabilizujemy pipeline - razem z optymalizacją kosztu strumienia długoterminowego.