AWS DMS 数据迁移:Replication Task、全量 CDC、验证与停止位点
任务显示 running,为什么切换后仍然丢订单
某团队用 AWS Database Migration Service 把自建 MySQL 迁往新的托管数据库。复制任务一直显示 running,全量进度也达到完成状态,于是大家把应用写流量切到目标端。切换后,账务对账出现缺口:一张没有主键的历史表在全量阶段报错,几笔大事务仍堆积在 replication instance 到目标库之间,数据验证因为表缺少主键处于无法验证状态。团队只看了任务总状态,没有看 Table statistics、CDCLatencySource、CDCLatencyTarget 和 validation state。
AWS DMS 的完整名称是 AWS Database Migration Service。这里的 DMS 只指 AWS 的数据库迁移服务,不与阿里云数据管理服务或其他产品缩写混称。它的任务可以执行 full-load、cdc 或 full-load-and-cdc,但“任务在运行”只说明控制面没有整体停止,不代表每张表都加载成功、每条变更都已提交到目标端,也不代表目标数据已经通过校验。
在线迁移必须回答五个水位问题:全量从哪个一致性基线读取;全量期间的变更在哪里缓存;源端日志读取到哪里;目标端提交到哪里;任务在什么停止位点结束。再加上对象级状态与差异校验,团队才有资格把唯一写入权交给目标库。
四个核心对象组成一条数据链
AWS DMS 的经典 provisioned 形态由 replication instance、source endpoint、target endpoint 和 replication task 组成。AWS 也提供 Serverless replication 等形态,选型时应按当前区域、端点和能力文档确认;不要把某个控制台默认选项写成所有迁移的固定架构。
DMS 资源属于创建它的 AWS Region,endpoint、task、replication instance 或 Serverless replication 不能因为 ARN 看起来相似就跨 Region 复用。先从官方 DMS 区域端点表 确认目标 Region 提供 DMS 控制面,再分别核对该 Region 的实例类别、Serverless、源目标引擎、引擎版本与功能支持。服务在某 Region 有 API endpoint,只证明控制面可用,不证明任意端点组合、CDC、validation-only、Multi-AZ 或 Serverless 都可用;跨 Region 数据路径仍要单独承担路由、延迟、传输费用、KMS 与数据驻留责任。
Replication instance 是运行全量读取、缓存、转换和 CDC 应用的复制计算资源。它位于 VPC 中,需要同时到达源端和目标端。CPU、内存、交换空间、存储、网络和可用性配置会直接改变吞吐与恢复能力。
Endpoint 保存数据库引擎、地址、端口、认证方式、TLS 和引擎专属设置。Test connection 证明从指定复制资源能够建立连接,但不证明源账号有日志读取权限、目标账号能创建全部对象,也不证明数据类型兼容。
Replication task 才是迁移工作的执行对象。官方 任务说明 将任务过程分为 full load、应用缓存变更和 ongoing CDC,并允许通过 task settings 与 table mappings 控制日志、错误处理、对象选择和转换。
Assessment、monitoring 与 validation 是三组不同证据。迁移前评估找已知不兼容或缺失条件;CloudWatch 与表统计解释运行时吞吐、延迟和失败对象;data validation 比较源目标记录。任何一组都不能替代另外两组。
这条链路刻意把控制面和数据面分开:IAM 允许某人创建任务,不等于数据库账号有读取 binlog/WAL 的权限;endpoint 测试成功,不等于 table mapping 正确;full load 完成,不等于缓存变化已经应用;CDC 延迟归零,也不等于没有 validation failure。
部署不是安装客户端,而是放置复制资源
AWS DMS 是托管服务,无需在开发机安装 DMS daemon。开发机可以安装 AWS CLI 用于可审查的资源创建和查询,也可以通过控制台操作。真正的“部署”是选择 VPC、replication subnet group、安全组、复制资源形态和可达路径,并为源目标创建 endpoint。
复制实例应放在能到达两端的子网中。源库在本地机房时,通常通过 Site-to-Site VPN、Direct Connect 或受控公网路径接入;源目标位于不同 VPC 时,需要明确路由、VPC peering、Transit Gateway 或其他网络连接。安全组是有状态规则,网络 ACL、路由表、数据库防火墙和 DNS 又是独立层次。一个方向开放端口不代表返回路径、域名解析和 TLS 都正常。
官方 DMS VPC endpoint 指南 说明,私有子网中的复制实例或 Serverless replication 访问部分 AWS 托管目标以及 Secrets Manager 时,需要配置相应 VPC endpoint;从 DMS 版本 3.4.7 起,文档对私网访问相关服务给出了明确要求。使用 Secrets Manager 时,接口端点、子网、安全组、私有 DNS 和访问策略共同决定能否取到凭证,不能只创建 secret 就认为网络闭环完成。
网络验证分三步。先从数据库侧确认监听地址、端口和授权 host;再用 endpoint 的 Test connection 验证复制资源到数据库的会话;最后在数据库审计或连接视图中确认连接来自预期路径并使用迁移账号。连接超时优先查路由、安全组和 NACL,认证失败查 secret、账号与 host,TLS 错误查证书链、端点 SSL mode 与服务器配置。
IAM 权限与数据库权限必须分开治理
IAM 管理谁能创建、修改、启动、停止和删除 DMS 资源;数据库账号决定 DMS 在源目标内部可执行哪些数据库动作。官方 AWS DMS 安全说明 还涉及 VPC、TLS 与 KMS:复制实例存储和 endpoint 连接信息可由 KMS 密钥保护,端点连接可以使用 TLS。不要把一个管理员 IAM role 与一个数据库超级账号绑定成永久共享身份。
源端权限与日志参数按数据库引擎变化。以 MySQL 兼容源为例,需要启用适合 CDC 的 binary logging,并向 DMS endpoint 用户授予读取迁移对象和复制日志所需权限;实际版本、托管形态和 XA 使用情况应逐项核对官方 MySQL source 指南。PostgreSQL 走逻辑复制链路,publication/slot、WAL 保留、DDL 捕获工件和权限要求不同,应依据 PostgreSQL source 指南 配置,不能照搬 MySQL 授权。
-- 合成 MySQL 实验账号。生产权限必须按源类型、DMS 版本和迁移模式收敛。
CREATE USER 'dms_source'@'10.%' IDENTIFIED BY '<source-password>';
GRANT SELECT, SHOW VIEW, TRIGGER ON shop_demo.* TO 'dms_source'@'10.%';
GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'dms_source'@'10.%';
CREATE USER 'dms_target'@'10.%' IDENTIFIED BY '<target-password>';
GRANT ALL PRIVILEGES ON shop_demo.* TO 'dms_target'@'10.%';
SHOW GRANTS FOR 'dms_source'@'10.%';
SHOW GRANTS FOR 'dms_target'@'10.%';推荐用 Secrets Manager 保存受支持 endpoint 的数据库凭证,并把 secret ARN 与访问 role ARN交给 endpoint,而不是把密码写入 CLI 历史或仓库。官方 DMS 使用 Secrets Manager 说明,创建或修改 endpoint 的操作者还需要对访问 role 与 secret 执行验证所需的 IAM 权限;RDS/Aurora 托管 master credential 因缺少 DMS 建连所需的 host/port 信息,不能直接作为这类 endpoint secret 使用。
账号准备还包括服务角色,而不只是操作者的 dms:*。官方 DMS IAM 指南 要求经典控制台、CLI 或 API 场景准备 dms-vpc-role 与 dms-cloudwatch-logs-role,Redshift 目标还需要对应 endpoint access role;Serverless 会使用服务关联角色。自定义策略若替代 AWS 托管策略,团队还要跟踪托管策略新增的权限,否则一次 DMS 版本或网络能力变化可能让旧模板突然无法创建 ENI、写日志或读取 endpoint 资源。
凭证轮换前应验证 DMS 对当前引擎和任务的连接恢复行为。CloudTrail 记录 DMS API 操作,CloudWatch Logs 可能包含库表名、失败 SQL 或数据片段;两者的访问和保留应按数据敏感级别治理。secret、KMS key、日志组和 replication task 还应使用标签绑定 owner、环境和到期时间。
从 endpoint 到 task:配置字段如何改变语义
创建任务前需要已有 source endpoint、target endpoint 和 replication instance,官方 创建任务指南 对这三个对象与迁移方法有明确说明。低停机在线迁移通常选择 full-load-and-cdc:全量搬历史记录,同时捕获迁移期间的新变化,随后应用缓存变化并进入持续增量迁移。
资源配额也是预检查的一部分。官方 DMS 配额表 当前默认按账号、按 Region 统计:60 个 replication instances、1,000 个 endpoints、600 个 tasks、100 个 Serverless replications,以及所有 replication instances 合计 30,000 GB 存储;单实例还有 endpoint 与 task 上限。多数资源配额可申请提高,但 API 节流不能靠临时扩容绕过。上线前应在目标 Region 查询 Service Quotas 和现有占用,并为自动化的 DescribeTableStatistics 等轮询使用退避与抖动,避免迁移正常却被控制面限流误判为故障。
table mappings 决定哪些 schema/table 被选择、排除、重命名或转换。规则应显式选择业务 schema,不要用 % 粗暴包含系统库。官方 MySQL source 文档特别提醒,通配数据库名可能把系统数据库带入迁移并因权限或目标兼容问题失败。映射 JSON 的大小也有服务限制,复杂对象清单应拆分并通过当前 table mapping 文档 检查。
{
"rules": [
{
"rule-type": "selection",
"rule-id": "1",
"rule-name": "include-orders",
"object-locator": {
"schema-name": "shop_demo",
"table-name": "orders"
},
"rule-action": "include"
}
]
}task settings 控制 full load 并发、目标元数据、LOB、日志、错误处理、change processing tuning 与 validation。LOB 选择尤其影响准确性和吞吐:limited LOB mode 需要明确最大尺寸,超过限制可能截断或报错;full LOB mode 以分块方式处理,通常更完整但吞吐和资源代价更高。BatchApplyEnabled 会改变目标应用方式和约束行为,不能为了追吞吐盲目打开;官方 Target metadata settings 列出了批应用、目标 schema 与 LOB 参数的约束。
下面是与本实验配套、可保存为 task-settings.json 的完整文件,而不是省略关键段落的片段。它选择保守的全 LOB、持续 validation、CloudWatch 日志和遇到数据冲突即停任务;并发值是教学基线,生产仍要按源目标容量压测。
{
"TargetMetadata": {
"TargetSchema": "",
"SupportLobs": true,
"FullLobMode": true,
"LobChunkSize": 64,
"LimitedSizeLobMode": false,
"LobMaxSize": 0,
"InlineLobMaxSize": 0,
"BatchApplyEnabled": false,
"TaskRecoveryTableEnabled": false
},
"FullLoadSettings": {
"TargetTablePrepMode": "DO_NOTHING",
"CreatePkAfterFullLoad": false,
"StopTaskCachedChangesApplied": false,
"StopTaskCachedChangesNotApplied": false,
"MaxFullLoadSubTasks": 8,
"TransactionConsistencyTimeout": 600,
"CommitRate": 10000
},
"Logging": {
"EnableLogging": true,
"DeleteTaskLogs": false,
"LogComponents": [
{ "Id": "SOURCE_UNLOAD", "Severity": "LOGGER_SEVERITY_DEFAULT" },
{ "Id": "SOURCE_CAPTURE", "Severity": "LOGGER_SEVERITY_DEFAULT" },
{ "Id": "SORTER", "Severity": "LOGGER_SEVERITY_DEFAULT" },
{ "Id": "TARGET_LOAD", "Severity": "LOGGER_SEVERITY_DEFAULT" },
{ "Id": "TARGET_APPLY", "Severity": "LOGGER_SEVERITY_DEFAULT" },
{ "Id": "TABLES_MANAGER", "Severity": "LOGGER_SEVERITY_DEFAULT" },
{ "Id": "TASK_MANAGER", "Severity": "LOGGER_SEVERITY_DEFAULT" },
{ "Id": "VALIDATOR", "Severity": "LOGGER_SEVERITY_DEFAULT" }
]
},
"ErrorBehavior": {
"DataErrorPolicy": "STOP_TASK",
"DataTruncationErrorPolicy": "STOP_TASK",
"DataMaskingErrorPolicy": "STOP_TASK",
"DataErrorEscalationPolicy": "STOP_TASK",
"DataErrorEscalationCount": 0,
"TableErrorPolicy": "STOP_TASK",
"TableErrorEscalationPolicy": "STOP_TASK",
"TableErrorEscalationCount": 0,
"RecoverableErrorCount": 6,
"RecoverableErrorInterval": 5,
"RecoverableErrorThrottling": true,
"RecoverableErrorThrottlingMax": 1800,
"ApplyErrorDeletePolicy": "STOP_TASK",
"ApplyErrorInsertPolicy": "STOP_TASK",
"ApplyErrorUpdatePolicy": "STOP_TASK",
"ApplyErrorEscalationPolicy": "STOP_TASK",
"ApplyErrorEscalationCount": 0,
"ApplyErrorFailOnTruncationDdl": true,
"FullLoadIgnoreConflicts": false,
"FailOnNoTablesCaptured": true
},
"ValidationSettings": {
"EnableValidation": true,
"ValidationOnly": false,
"ThreadCount": 5,
"PartitionSize": 10000,
"FailureMaxCount": 10000,
"TableFailureMaxCount": 1000,
"SkipLobColumns": false,
"ValidationPartialLobSize": 0,
"ValidationQueryCdcDelaySeconds": 0
}
}这些值中有几项具有破坏性或显著代价。DO_NOTHING 不会清空已有目标数据,目标表非空时会发生冲突;改成 DROP_AND_CREATE 会删除并重建目标表,改成 TRUNCATE_BEFORE_LOAD 会清空现有数据,两者都只能在确认目标可销毁后使用。full LOB 会迁移完整大对象但更慢、更占网络和内存;limited LOB 若上限小于真实值会截断。validation 会增加两端查询负载,日志会产生 CloudWatch 成本并可能记录对象名和失败上下文。这里把截断、记录错误、表错误和 apply 冲突设为 STOP_TASK,是为了让不一致阻断实验;改成 LOG_ERROR、IGNORE_RECORD 或 SUSPEND_TABLE 会允许整体任务继续,不能再用 running 代表完整。ApplyErrorFailOnTruncationDdl=true 还会让捕获到的 TRUNCATE 主动失败,避免一次破坏性 DDL 静默传播。
CDC 起点与停止点是迁移协议,不是普通时间备注。CdcStartPosition 可以接受引擎原生位点、checkpoint 或时间形式,但不同源的安全语义不同;若以时间或位点启动时仍有未提交长事务,可能漏掉其最终结果。CdcStopPosition 支持 server_time: 或 commit_time: 形式,表示任务应在复制服务器时间或源事务提交时间达到指定点后停止。官方 ReplicationTask API 还暴露 RecoveryCheckpoint,可用于从最近 CDC checkpoint 创建恢复路径。
迁移前评估要进入启动门禁
endpoint 测试通过之后,先运行 premigration assessment。官方 迁移前评估指南 区分旧的 data type assessment 与更完整的 premigration assessment run;后者包含多类 individual assessment,使用它时无需再单独选择旧的数据类型评估。
评估运行针对已配置任务及其源目标组合,帮助发现会让任务不按预期运行的缺失要求、数据类型和已知限制。它承担比普通连接测试更完整的迁移预检查职责。结果可写入指定 S3 bucket,因此 bucket policy、KMS、访问日志、保留与清理都要预先设置。评估报告中可能出现 schema、table、column、type 与对象样本,它不是可以公开传播的普通构建产物。
处理评估结果时,不要只看“有多少条”。每条发现都要形成决策:修复源端结构、预建目标对象、增加 transformation、排除并由其他工具迁移,或接受有证据的兼容损失。接受项必须带业务 owner 与补偿方案。任务配置改变后重新运行 assessment,因为旧结果不再代表当前 table mappings 和 task settings。
评估无法替代真实负载测试。它不会替团队证明复制实例容量、源端全量扫描压力、目标索引策略、长事务峰值和切换冻结是否可行。把它当静态门禁,而不是性能验收。
正向实验:跑通 full load 与 CDC 接续
下面是待执行实验设计,本次复审未创建 AWS 资源、未连接数据库,也未执行 CLI 或 SQL。真正演练时使用临时源目标数据库、临时 replication instance 与合成 shop_demo:先在源库创建基线表和两行数据,再启动 full-load-and-cdc;full load 运行期间提交一次更新和一次新增。下面只展示数据库动作,云资源 ARN 使用占位符,不把任何真实账号写进文档。
CREATE DATABASE IF NOT EXISTS shop_demo;
USE shop_demo;
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
status VARCHAR(32) NOT NULL,
version INT NOT NULL,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
);
INSERT INTO orders(id, status, version) VALUES
(2001, 'CREATED', 1),
(2002, 'PAID', 2);
-- full load 启动后提交,用于验证缓存变化和 ongoing CDC。
UPDATE orders SET status = 'PAID', version = 2 WHERE id = 2001;
INSERT INTO orders(id, status, version) VALUES (2003, 'CREATED', 1);创建任务的 CLI 形态如下。ARN、KMS、subnet 与安全组都应由 IaC 或受控参数注入;table mappings 与 task settings 文件进入代码评审。命令只说明对象关系,不代表云端实验已经执行。
aws dms create-replication-task \
--replication-task-identifier shop-demo-migration \
--source-endpoint-arn '<source-endpoint-arn>' \
--target-endpoint-arn '<target-endpoint-arn>' \
--replication-instance-arn '<replication-instance-arn>' \
--migration-type full-load-and-cdc \
--table-mappings file://table-mappings.json \
--replication-task-settings file://task-settings.json
aws dms start-replication-task \
--replication-task-arn '<replication-task-arn>' \
--start-replication-task-type start-replication预期状态链不是简单的 running -> stopped。Table statistics 中,orders 应经历 full load 并到达 completed,加载错误为零;CDC 更新后,目标端出现 2003,2001 达到 PAID/2;CDCLatencySource 与 CDCLatencyTarget 在源端停止写入后回落;validation state 最终为 Validated,没有 pending、mismatched 或 suspended records。
-- 在源端和目标端分别执行,保存同一业务冻结水位后的结果。
SELECT COUNT(*) AS row_count,
SUM(status = 'PAID') AS paid_count,
MAX(id) AS max_id,
SUM(version) AS version_sum
FROM shop_demo.orders;
SELECT id, status, version
FROM shop_demo.orders
WHERE id IN (2001, 2002, 2003)
ORDER BY id;这里仍然不把总行数当完整校验。version_sum 能帮助发现更新遗漏,逐主键查询能确认 CDC 覆盖值;生产应补充分块 checksum 和订单金额、支付状态、库存守恒等业务不变量。
主键同样决定 CDC 是否能稳定识别一行。AWS 官方故障排查明确指出,full-load-and-CDC 迁移到没有主键或唯一索引的目标表时可能产生重复记录;任务恢复或重放会放大这一风险。validation 也要求主键或唯一索引。遇到无键表时,应在源目标补上语义真实且非空的键并重跑评估与实验,或把它从任务中排除后采用带去重键和独立对账的迁移方案,不能把重复风险留到切换后清洗。
反向实验:制造一张 Table error
为了证明团队能从“整体 running”下钻到对象错误,可在临时目标库把 status 缩短,再从源库提交超长值。这个破坏性反例本次同样未执行,只能在可重建环境按审批后的实验单运行。
-- 临时目标库
ALTER TABLE shop_demo.orders MODIFY status VARCHAR(4) NOT NULL;
-- 临时源库
UPDATE shop_demo.orders
SET status = 'REFUND_PENDING', version = version + 1
WHERE id = 2002;应预期看到目标应用错误、表统计或日志中的失败证据,CDCLatencyTarget 可能上升,而 CDCLatencySource 仍较低。目标端 2002 保持旧值,validation 可能进入 mismatched、pending、suspended 或 table error 等状态。官方 DMS 数据验证 说明,验证失败详情可在目标端 awsdms_control.awsdms_validation_failures_v1 控制表中定位;无主键表会显示 No primary key,表本身迁移失败则可能是 Table error。
修复过程要保留顺序:停止制造新差异;恢复目标列兼容定义;根据任务状态恢复或重载受影响表;等待缓存变化应用;查看表错误归零;重新运行 validation 与业务查询。不要只把错误处理策略改成忽略并继续,忽略会让任务“前进”,却把不一致留给切换日。
用两类 CDC 延迟定位瓶颈
官方 DMS 监控指南 将 CDCLatencySource 定义为源端事件捕获到 replication instance 的延迟,将 CDCLatencyTarget 定义为等待目标确认的最老事件与复制实例当前时间之间的差。两者要成对观察:
两者都高且接近时,先查源端日志读取、长事务、源库负载和源到复制实例网络。CDCLatencyTarget 明显高于 CDCLatencySource 时,优先查目标端索引、锁、资源、网络和复制实例应用能力。源端空闲时 source latency 可能回到零,不能据此推导历史变更全部正确。
大事务在提交前会让源延迟持续增长,短暂尖峰应结合事务与批处理事件解释。
复制实例侧还要组合看 FreeableMemory、SwapUsage、CPU、磁盘队列、CDCChangesMemorySource/Target、CDCChangesDiskSource/Target 与吞吐。FreeableMemory 包含可回收缓存,不应被简单理解为真正空闲内存;它接近零且 swap 持续上升,才更像资源压力证据。目标无主键或索引时,UPDATE/DELETE 应用可能退化为扫描,扩大 target latency。
告警阈值不应写成所有系统通用的固定秒数。先在代表性流量下建立基线,再按 RTO、源日志保留、切换窗口和增长斜率设置。比“超过某值告警”更有用的是组合条件:目标延迟持续增长、磁盘缓存积压单调上升、目标写吞吐低于源变化速率,并且预计在日志保留窗口内无法追平。
Validation 能发现什么,不能证明什么
开启 validation 后,DMS 在表级提供 ValidationState、pending、failed、suspended 等统计。Validated 表示当前可验证记录一致;表继续更新后状态还会变化。No primary key 不是一个可以忽略的黄色提示,而是该表无法用常规机制可靠定位记录;这张表需要补键、改用其他校验方式或明确排除。
validation 会增加源端读取、目标端读取、网络和复制实例工作量。大表、LOB、持续高写入和无合适索引时,校验可能反过来影响迁移吞吐。应在演练中测量它与业务负载的资源竞争,并决定在线持续校验、切换前集中校验或独立 validation-only task 的组合。官方文档说明,较新的 DMS 引擎支持 full-load validation-only task;是否适用于当前引擎、端点与区域,仍要在创建资源时核对当前支持矩阵。
差异修复必须遵循权威侧。切换前由源库重放或重新加载;切换后目标已产生新写入,不能让旧源覆盖。控制表中的主键、失败原因和时间信息可能暴露敏感数据,查询权限只给迁移排障角色,导出的差异报告应加密、脱敏并设置到期删除。
停止位点决定迁移何时真正结束
手工点 Stop 只是控制动作,不是业务水位。计划性切换更可靠的方式是先定义源端提交水位,再让任务在可解释的 stop position 停止。AWS DMS 的 CdcStopPosition 可使用 server_time: 或 commit_time: 前缀:前者按 DMS 服务端时间判断,后者按源事务提交时间判断。迁移团队必须统一时间语义和时区,避免把应用日志时间、数据库提交时间和复制实例时间混为一谈。
对于 CDC-only 恢复或分阶段任务,CdcStartPosition 与 RecoveryCheckpoint 可以连接上一段复制水位。官方 持续复制任务指南 解释了不同源的原生 CDC 起点;位点格式与开放事务风险依赖数据库引擎。任何从时间启动的任务都应检查长事务,否则一个在起点前开始、起点后提交的事务可能落在选择缝隙中。
已运行的任务不能在 running 状态直接修改。官方任务修改约束要求它先进入 stopped 或 failed;计划性修改应主动停止并等待 stopped,再设置停止位点,然后以 resume-processing 恢复原任务。不要使用 reload-target,否则会重新加载目标表。
# 示例时间只表示一次演练中的语义占位,生产由冻结流程生成。
aws dms stop-replication-task \
--replication-task-arn '<replication-task-arn>'
aws dms wait replication-task-stopped \
--filters Name=replication-task-arn,Values='<replication-task-arn>'
aws dms modify-replication-task \
--replication-task-arn '<replication-task-arn>' \
--cdc-stop-position 'commit_time:<cutover-commit-time>'
aws dms start-replication-task \
--replication-task-arn '<replication-task-arn>' \
--start-replication-task-type resume-processing
aws dms wait replication-task-stopped \
--filters Name=replication-task-arn,Values='<replication-task-arn>'
aws dms describe-replication-tasks \
--filters Name=replication-task-arn,Values='<replication-task-arn>' \
--query 'ReplicationTasks[0].{Status:Status,StopReason:StopReason,Checkpoint:RecoveryCheckpoint,Failure:LastFailureMessage}'预期证据包括:源端写入已经冻结;第一次 waiter 结束后任务确为 stopped,修改操作才发生;恢复后停止位点对应的提交已被目标确认;任务最终因 STOPPED_AT_COMMIT_TIME 或所选时间语义对应的计划原因停止,而不是因错误停止;LastFailureMessage 为空;表错误为零;validation 与业务不变量在该水位后一致。若 waiter 超时或 StopReason 指向故障,不能继续修改或把 stopped 当作计划完成。
切换与回切:先转移权威,再恢复流量
切换开始前,源库仍是唯一写入权威,目标只允许 DMS 与校验角色写入。先停发布和非必要 DDL,再冻结 API、消费者、定时任务、数据修复脚本等所有写入口。记录最终业务水位后等待 CDC 追平,到达停止位点并完成最终 validation。随后用只读影子流量验证目标查询,最后灰度恢复写入并把目标设为唯一权威。
观察期内保留旧源为只读,不要立即删除 replication task、endpoint 和日志。回切能否无损,取决于目标端新写入是否已通过反向链路回到旧源。没有反向同步时,回切只能接受丢弃观察期数据或执行经过验证的补偿迁移。双写也不是免费保险:没有全局版本、幂等键与冲突裁决的双写,会制造两个都“成功”却不一致的权威侧。
失败回滚分三类处理。切换前发现积压或差异,保持源端权威并取消切换;刚切换但尚未开放写入,可把读连接退回旧源;目标已经接受新写入后,必须先决定新数据如何回灌,不能直接改回连接串。每类动作都要由明确决策人触发并留下 CloudTrail、任务状态、数据库水位和发布记录。
DMS 的基础设施自动恢复也不能代替迁移灾备。官方 DMS 产品说明 描述了复制服务器故障时的自动 failover,但只有选择并验证相应高可用部署,才能把复制计算节点故障纳入这一恢复路径;它不会替你恢复已经从源端清除的 binlog/WAL,也不会修复 endpoint 权限、路由或不兼容 DDL。灾备演练应分别注入复制资源故障、源端短暂不可达和目标端拒写,保存 RecoveryCheckpoint、任务状态、两类 CDC 延迟、表状态与恢复后校验结果,确认恢复没有重载错误基线或制造重复。
清理资源时别留下凭证、工件和持续费用
观察期结束后,先停止并归档任务状态、table statistics、assessment、validation、CloudWatch 指标与必要日志;再删除 replication task、endpoints 和不再共享的 replication instance。随后撤销数据库迁移账号,删除临时 Secrets Manager secret 或移交到正式 owner,移除安全组和路由中的临时规则,清理 assessment S3 对象、CloudWatch log group 与测试 schema。PostgreSQL source 若为 DDL capture 创建了额外工件,还要按官方引擎指南确认并清理。
-- 合成环境清理。共享或生产数据库必须逐对象审批。
DROP USER IF EXISTS 'dms_source'@'10.%';
DROP USER IF EXISTS 'dms_target'@'10.%';
DROP DATABASE IF EXISTS shop_demo;资源删除要按依赖顺序执行并等待状态稳定,避免 replication instance 仍被任务引用。KMS key 不应因一次任务结束就立即删除,因为日志、secret 或其他资源可能仍依赖它。清理证据至少包括资源 ARN、删除状态、网络规则差异、账号撤权结果和保留数据的到期策略。
费用治理关注驱动项而不是固定金额。官方 AWS DMS 定价 按 provisioned replication instance 或 Serverless capacity 的使用时长计费,并另列额外存储、跨可用区/跨 Region/出 AWS 数据传输和公网 IPv4 等成本;DMS 节点本身的进出流量免费,不等于整条跨地域链路免费。CloudWatch Logs、Secrets Manager、KMS、assessment S3 对象和源目标临时扩容还按各自服务计费。停止 replication task 不会自动删除仍在运行的 replication instance、endpoint、日志组或公网地址,任务 owner 应给每项资源设置标签、预算提醒和销毁时间,并用账单维度确认清理后不再增长。
选型与团队治理:DMS 不是所有迁移的默认答案
AWS DMS 适合需要托管复制运行时、异构端点、full load 加 CDC、对象映射和在线迁移的场景。对于同构数据库迁移,原生备份恢复、快照、物理复制或 AWS 的 homogeneous data migrations 可能获得更高保真度或吞吐;官方 MySQL source 文档也建议同构 MySQL 场景评估 homogeneous data migrations。选择依据应是停机窗口、数据量、日志保留、Schema 兼容、LOB、事务语义、目标写能力、校验要求、团队运维能力和退出路径,而不是只看“能否创建 task”。
Provisioned replication instance 适合需要明确容量、网络和长期运行控制的团队;Serverless 形态减少实例规格管理,但仍需评估支持端点、网络、容量边界、可观测性和费用模型。跨区域、跨账号和本地机房迁移还会增加 IAM trust、KMS、DNS、路由与数据合规责任。版本与端点支持持续变化,实施时应从官方 支持的数据源 和对应 target 文档核对引擎版本、CDC、数据类型与限制,不把文章中的示例版本当永久承诺。
团队可以把 DMS 迁移能力沉淀成一组受审查资产:IaC 定义 subnet group、security group、replication resource、endpoint 与标签;仓库保存 table mappings、task settings 和业务校验 SQL;流水线运行静态检查并触发 assessment;仪表盘同时展示 source/target latency、缓存积压、表错误和 validation;切换单记录冻结水位、stop position、权威侧与回切裁决;退出单负责删除资源、撤权和停止费用。
最后保留一个朴素判断:DMS 负责搬运并提供证据入口,业务团队负责解释证据。只有对象状态、全量基线、CDC 水位、延迟趋势、validation、业务不变量、停止原因和回切数据路径同时清楚,目标库才从“有一份副本”变成“可以接管生产”。
