入門閱讀時間 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,跨帳戶、跨區域跑完一次遷移的匯出與校驗半程。

已更新