如何使用AWS CLI按创建时间顺序跨桶迁移S3存储桶的对象?
AWS CLI 按创建时间顺序迁移版本控制S3桶的实现方案
注意不要直接使用
aws s3 sync命令,该命令默认仅同步对象的最新版本,且无法自定义按创建时间的迁移顺序,无法满足版本保留和按时间优先级迁移的需求。
前置准备
- 确保AWS CLI版本 ≥ 2.0,已配置拥有源桶(桶A)的
s3:GetObject*、s3:ListBucketVersions权限,目标桶(桶B)的s3:PutObject*权限的访问凭证 - 确认两个桶均已开启版本控制,可执行以下命令验证:
返回结果中aws s3api get-bucket-versioning --bucket 替换为桶A名称 aws s3api get-bucket-versioning --bucket 替换为桶B名称Status为Enabled即为开启状态。
实现步骤
1. 导出源桶所有版本对象并按创建时间升序排序
执行以下命令拉取源桶所有对象版本(包含删除标记),按创建时间LastModified从早到晚排序后导出到本地文件:
aws s3api list-object-versions --bucket 替换为桶A名称 --output json | \ jq -r '.Versions + .DeleteMarkers | sort_by(.LastModified)[] | [.Key, .VersionId, .LastModified] | @tsv' > sorted_objects.txt
该命令依赖jq工具做JSON解析,未安装的话可先通过系统包管理器安装。
2. 按排序结果顺序迁移对象
单线程迁移(适合对象量不大的场景)
while IFS=$'\t' read -r key version_id last_modified; do echo "正在迁移: ${last_modified} | 对象键: ${key} | 版本ID: ${version_id}" aws s3api copy-object \ --bucket 替换为桶B名称 \ --copy-source "/替换为桶A名称/${key}?versionId=${version_id}" \ --key "${key}" \ --metadata-directive COPY done < sorted_objects.txt
--metadata-directive COPY会保留原对象的元数据、标签、ACL等配置,若需要修改元数据可替换为REPLACE并追加对应的元数据参数- 按创建时间从早到晚复制的逻辑会自动对齐源桶的版本历史顺序,后写入的新版本会自然成为目标桶中同对象键的更高版本
多线程并发迁移(适合对象量较大的场景)
可配合parallel工具提高迁移效率,以下示例为10并发迁移,可根据实际带宽和S3限流阈值调整并发数:
cat sorted_objects.txt | parallel --colsep '\t' -j 10 \ aws s3api copy-object \ --bucket 替换为桶B名称 \ --copy-source "/替换为桶A名称/{1}?versionId={2}" \ --key {1} \ --metadata-directive COPY
3. 迁移结果校验
迁移完成后可对比两个桶的版本总数量验证迁移完整性:
# 统计源桶版本总数(包含删除标记) aws s3api list-object-versions --bucket 替换为桶A名称 --output json | jq '[.Versions[]? + .DeleteMarkers[]?] | length' # 统计目标桶版本总数(包含删除标记) aws s3api list-object-versions --bucket 替换为桶B名称 --output json | jq '[.Versions[]? + .DeleteMarkers[]?] | length'
两个命令返回的数值一致即可确认全量版本迁移完成。
额外注意事项
- 若源桶对象数量超过10万,
list-object-versions会返回截断结果,需要添加--paginate参数,或通过NextToken做分页拉取全量版本 - 超过8MB的对象AWS CLI会自动触发多段复制,无需额外配置
- 若迁移过程中源桶仍有新数据写入,可在全量迁移完成后再次执行上述步骤,筛选出上一次迁移结束时间之后的对象做增量同步即可。
内容的提问来源于stack exchange,提问作者mark86v1
相关产品推荐
相关产品推荐

