入门阅读约 2 分钟

把 DynamoDB 表复制到另一个账户或区域

DynamoDB 没有一键的"复制表"命令——AWS CLI 里没有,控制台里也没有。每一次复制其实都是两个半程:把数据从源表取出来,再把它装进目标表。前半程正是图形界面大显身手的地方——一份无损、可筛选、可校验的导出——而后半程永远跑在 AWS 工具上。本指南两个半程都覆盖,还有那些在生产环境里咬人的运维坑。

如何把 DynamoDB 表复制到另一个账户或区域?

没有原生的复制表命令。对取出这半程,拉一份无损的 DynamoDB-JSON 表导出(在 DynoTable 里一键完成,无需脚本),或者用托管的 S3 导出做快照。对装入这半程,挑一个合适的 AWS 侧方案:小型一次性复制用 Scan + BatchWriteItem 脚本,大表用 S3 导出再导入,需要完整保真度的跨账户迁移用 AWS Backup 复制 + 恢复,持续的实时复制用全局表。每次恢复或导入都会创建一张新表。

场景最佳方案
小表、一次性、完全掌控Scan + BatchWriteItem 脚本
大表、能接受快照S3 导出 → 导入(创建新表)
跨账户 / 跨区域、走恢复AWS Backup 复制 + 恢复
持续的实时复制(不是一次性复制)全局表

没有哪种方案放之四海皆准——取决于表的大小、你要的是时间点快照还是实时数据,以及目标是新表还是已有的表。

导出半程:用 DynoTable 把数据拉出来

任何恢复发生之前,数据得先离开源表——而手搓的扫描循环正是一次小型迁移里最容易出错的部分(丢页、数字精度被搅坏、类型标签剥得太早)。DynoTable 一键完成这半程:

  • 无损是设计使然:完整的筛选匹配导出为 marshalled DynamoDB-JSON——带类型包装的线上格式,能保住普通 JSON 会损坏的大数字(> 2⁵³)——或者在目标根本不是 DynamoDB 时导出为 NDJSON/CSV。格式细节见导出为 CSV
  • 有范围,不是全有或全无:托管的 S3 导出快照的是_整张_表;DynoTable 导出的是你的查询匹配到的每一个项,直接从 DynamoDB 流式取出——所以"只把 TENANT#42 的项复制到 staging 环境"是一个筛选条件,不是一段脚本。
  • 大表无压力:导出会脱离页面在后台运行,逐行流式写到磁盘——一次几 GB 的拉取扛得住切换标签页甚至应用重载。
  • 装载之后的校验:目标表建好之后,把源和目标并排浏览、比对项数量(表大小与项数量)、抽查样本记录——不用写校验脚本。

诚实的边界在这里:DynoTable 负责把数据取出来并校验结果——把数据装进目标表那一步跑在 AWS 工具上(写入脚本、S3 导入或 Backup 恢复),下面逐一展开。

方案 1:Scan + BatchWriteItem(脚本路线)

技术含量最低的路径——用 Scan 从源表读出每一个项,再用 BatchWriteItem 写进目标表。只要脚本同时持有两侧的凭证(或在目标账户里代入一个角色),跨账户、跨区域都行得通。

# Sketch — read source, write target (pseudo; use the SDK in real life)
aws dynamodb scan --table-name SourceTable --region us-east-1 \
  > items.json
# transform Items[] into BatchWriteItem RequestItems, then:
aws dynamodb batch-write-item --request-items file://batch.json \
  --region eu-west-1

这些坑真实存在,而且很容易漏掉:

  • BatchWriteItem 每次调用上限 25 个项或 16MB——你必须分块,而且单次调用可能返回_未处理的项_,需要你带指数退避重试(API 参考)。
  • 写入消耗写入容量。容量的目标表上你会很快撞上 ProvisionedThroughputExceededException模式能吸收更多,但每个分区仍有 1,000 WCU / 3,000 RCU 的硬上限。开始之前,先对照目标表的容量估算写入负载。
  • Scan 会读整张表并对每个项计量——经典的 Query 与 Scan 成本问题。大表还意味着要沿 LastEvaluatedKey 分页;参见分页
  • 它不是原子的。扫描进行期间写入的项可能被漏掉——只有源表静止时你才能得到一份一致的快照。

最适合小表,或复制过程中需要转换/筛选的场景——而且如果读取那半程已经以 DynoTable 的 marshalled 导出形式存在,脚本就缩水成只剩分块写入的循环。

方案 2:导出到 S3,再导入到新表

对大表,DynamoDB 托管的导出到 S3 加上从 S3 导入完全避免了对容量的冲击。

导出把表快照到一个 S3 存储桶(工作原理):

  • 要求源表启用时间点恢复(PITR)
  • 不消耗读取容量,对表的性能零影响——它读的是持续备份,不是线上表。
  • 输出 DynamoDB JSON 或 Amazon Ion 格式。(落进 S3 的正是 DynamoDB-JSON 线上格式,类型标签一应俱全。)
  • 可以写入另一个账户拥有的位于不同区域的 S3 存储桶。
  • 支持完整与增量导出(增量导出 2023 年 9 月正式可用)。

导入随后用那份 S3 数据建一张全新的表(工作原理):

  • 只能导入到一张全新的表——不能导入到已有的表。
  • 新表上不消耗写入容量
  • 接受 CSV、DynamoDB JSON 或 Amazon Ion(可选 GZIP/ZSTD 压缩)。
  • 源 S3 存储桶可以在另一个账户或另一个区域
  • 你可以在导入时定义二级索引,导入一完成即可查询。

对于能接受时间点快照(而非实时数据)的大型跨账户/跨区域迁移,这是最干净的路径。

方案 3:AWS Backup 复制 + 恢复

如果你已经在用 AWS Backup,它可以跨账户、跨区域复制恢复点(跨账户迁移指南):

  1. 把源表备份进一个备份库。
  2. 把备份复制到目标账户/区域的备份库。
  3. 在目标处把它恢复为一张新表。

关键约束:

  • 跨账户复制要求两个账户同属同一个 AWS Organization
  • 恢复总是创建新表——你不能恢复到已有的表上。
  • 默认被保留(可以排除部分或全部以节省恢复时间/成本);恢复时不能_新增_索引。
  • 加密的坑:跨区域恢复要保住同一个 KMS 密钥,需要一个多区域密钥;跨账户则必须把密钥共享给目标账户。AWS 拥有和 AWS 托管的密钥既不能共享,也不能做成多区域(恢复加密说明)。

方案 4:全局表(实时复制,不是一次性复制)

全局表把一张表跨区域复制——现在还可选跨账户(多账户 2026 年 2 月正式可用)——而且是持续进行的。任意副本都能服务读和写(多活),复制是异步的、最后写入者胜(全局表文档)。

不是一个"复制完就走"的工具——它是持续复制。当你希望目标区域无限期保持同步(灾备、低延迟的本地读取)时用它,而不是用于一次干净的一次性迁移。给已有的表添加一个区域,DynamoDB 会把现有数据回填进新副本。

运维坑(所有方案通用)

  • GSI 不是白来的。scan+write 复制不携带索引——你在目标上定义它们,它们单独回填(也单独花钱)。提前规划好目标表的 GSI 与 LSI 布局;LSI 只能在建表时创建(LSI 文档)。
  • 容量模式不会随迁。新表以你设置的模式起步,而不是源表的模式。scan+write 复制之前先估算写入负载——用项大小计算器量一个有代表性的项,再乘以项数量来粗算 WCU。
  • 、自动扩缩和标签是表设置,不是数据——没有哪种复制方法能把它们全部带上。在目标上重新应用。
  • DynamoDB JSON ≠ 普通 JSON。导出和扫描输出的都是带类型标签的 DynamoDB-JSON;如果你要在半路做转换,DynamoDB JSON 转换器可以处理 marshalling。
  • 切换之前先校验。比对两侧的项数量并抽查记录——记住 DescribeTable 的计数最多可能滞后六小时,所以一张刚建的目标表报告为零是正常的。

常见问题

有没有复制 DynamoDB 表的 AWS CLI 命令? 没有。不存在原生的 copy-table 命令。你要么组合 scan + batch-write-item,要么用托管的导出/导入或 AWS Backup 功能。

如何把 DynamoDB 表复制到另一个账户? 三个选项:持有两个账户凭证的 scan+write 脚本、S3 导出/导入(存储桶可以跨账户),或 AWS Backup 复制+恢复(两个账户必须同属同一个 AWS Organization)。

如何把 DynamoDB 表复制到另一个区域? S3 导出/导入和 AWS Backup 都支持跨区域。若要的是_持续的_跨区域同步而不是一次性复制,就在目标区域添加一个全局表副本。

复制表会连索引一起复制吗? S3 导入和 AWS Backup 恢复允许你保留/定义二级索引;scan+write 脚本不行——索引得你自己在目标上创建,并单独回填。

能导入到已有的 DynamoDB 表吗? 不能。DynamoDB 的 S3 导入和 AWS Backup 恢复都会创建一张表。要合并进已有的表,用 scan+write 脚本。

能只复制表的一部分吗? 托管的导出/导入和 Backup 路线都只支持全表。要子集的话,从 DynoTable 导出筛选匹配(无损的 marshalled DynamoDB-JSON),或写一段带筛选的扫描脚本,再把子集写进目标表。


图形界面让切换变得省心:把你要迁移的那些项精确地拉成一份无损导出,然后把源和目标并排浏览,复制完成后校验项数量和几条样本记录,再随手跑些临时检查——全程不用写扫描脚本。下载 DynoTable,跨账户、跨区域跑完一次迁移的导出与校验半程。

更新于