介绍
将草稿上传到财务团队的报表对象键,会替换读者看到的已批准内容。你将启用版本控制,重现这个错误,恢复已批准内容,并在确认恢复后删除练习历史。
请先完成 使用对象键和元数据组织文档,掌握对象键、属性、下载和清理。这个全新 VM 已提供 CLI 连接和已批准文件及草稿文件;存储桶由你创建。使用 Terminal 执行命令,并在旁边的 AWS View 标签页比较当前对象和历史记录。
发布前启用版本控制
在本步骤中,你将创建一个空存储桶,并在上传任何报表前启用版本控制。
使用 cd(更改目录)进入工作目录:
cd /home/labex/project
使用 mb(创建存储桶)创建报表桶:
aws s3 mb s3://labex-report-history
你应看到 make_bucket: labex-report-history。版本控制是存储桶设置:启用后,向对象键的后续写入会创建版本 ID,而不是丢弃之前存储的内容。它有助于恢复意外覆盖,但不能阻止显式删除某个特定版本。
aws s3api 提供单个 S3 API 操作。put-bucket-versioning 更新这个设置;--bucket 标识容器,--versioning-configuration Status=Enabled 请求启用状态:
aws s3api put-bucket-versioning --bucket labex-report-history --versioning-configuration Status=Enabled
成功更新不会打印正文。读取配置,不要只依赖没有输出这一现象:
aws s3api get-bucket-versioning --bucket labex-report-history
{
"Status": "Enabled"
}
AWS View 现在在存储桶上显示 Versioning: Enabled。桶仍为空:启用版本控制不会上传报表或创建历史版本。请在写入要保护的数据前启用这个设置。
创建原始版本和覆盖版本
在本步骤中,你将发布已批准报表,再用草稿覆盖当前内容,同时在历史中保留原件。
使用打印内容的 cat 查看已准备好的文件:
cat report-approved.txt
Monthly revenue: 42000
cat report-draft.txt
Monthly revenue: 00000
将已批准文件发布到对象键 report.txt。源文件名与对象键可以不同:
aws s3 cp report-approved.txt s3://labex-report-history/report.txt
在 AWS View 中打开 report.txt,确认已批准的收入。历史中包含一个版本,标记为 Current。
现在重现错误:将草稿上传到同一个对象键:
aws s3 cp report-draft.txt s3://labex-report-history/report.txt
预览变为 Monthly revenue: 00000。当前仍只有一个对象键,但历史中已有两个存储版本。两个文件大小相同;版本控制跟踪写入,而不只是根据大小判断变化。
list-object-versions 读取历史记录及当前版本:
aws s3api list-object-versions --bucket labex-report-history
Versions 数组包含两个条目,对象键均为 report.txt,但 VersionId 不同。IsLatest: true 表明草稿是当前版本;更早的已批准版本为 IsLatest: false。ID 和时间戳会有所不同。普通对象列表显示当前对象键,因此调查覆盖时应使用版本列表。
在官方 S3 Console 中,Show versions 在对象列表中显示这些历史条目。这个示例展示不同的对象和更多写入;用它认识 Version ID 列即可。本实验不需要 Console 登录。

来源:AWS Storage 博客。
读取并发布已批准版本
在本步骤中,你将下载更早的已批准版本,检查字节内容,并在不删除历史的情况下使该内容重新成为当前内容。
此时 report.txt 恰好有两个版本。在之前的列表中,找到 IsLatest: false 的条目:它是已批准原件。复制它的 VersionId。
将这个 ID 保存到 Shell 变量中,以便复用。将下面的 PASTE_APPROVED_VERSION_ID 替换为复制的值,保留引号。变量赋值的 = 两侧不能有空格:
OLD_VERSION='PASTE_APPROVED_VERSION_ID'
使用前检查值:
echo "$OLD_VERSION"
你应看到更早版本的 ID,而不是占位符。$OLD_VERSION 读取变量;双引号将该值保持为一个命令参数。
get-object 将对象正文下载到最后指定的本地路径。--version-id 选择历史副本,而不是当前草稿:
aws s3api get-object --bucket labex-report-history --key report.txt --version-id "$OLD_VERSION" recovered-report.txt
JSON 输出描述读取到的副本。查看内容:
cat recovered-report.txt
Monthly revenue: 42000
cmp 比较文件字节。&& 只在比较成功后运行后面的消息命令:
cmp report-approved.txt recovered-report.txt && echo 'Approved historical content verified'
读取旧版本不会使它成为当前版本;不指定版本读取对象键的读者仍会收到草稿。将恢复的字节发布到该对象键:
aws s3 cp recovered-report.txt s3://labex-report-history/report.txt
这会创建包含已批准报表的第三个版本。旧的已批准版本和草稿都保留,可供调查。AWS View 显示已批准内容为当前内容,并显示三条版本记录。列出历史进行确认:
aws s3api list-object-versions --bucket labex-report-history
新条目为 IsLatest: true。你通过写入新的当前版本恢复了数据,而没有擦除错误的证据。
这个示例展示恢复的报表为当前版本,以及三条不同的历史记录。所显示的版本 ID 是该会话中的示例:

删除标记出现后恢复访问
在本步骤中,你将观察删除标记如何隐藏启用版本控制的对象,然后移除标记,使之前的当前版本重新可见。
示意图:删除会添加一个当前标记,而三个存储的报表版本仍保留。v1–v3 标签表示写入顺序,不是实际版本 ID。

在已启用版本控制的存储桶中,不带版本 ID 的删除请求会创建删除标记(delete marker)。这是一个表示对象键已删除的当前历史条目;它不包含文件字节,也不会擦除旧版本。使用常用文件命令删除当前对象键:
aws s3 rm s3://labex-report-history/report.txt
普通列表现在不显示当前对象:
aws s3 ls s3://labex-report-history/
在 AWS View 中,当前对象消失,而历史中仍有三行 Version 和一个当前 Delete marker。
尝试不选择版本下载对象键:
aws s3 cp s3://labex-report-history/report.txt unavailable-report.txt
这个命令预期会失败,出现未找到错误。当前删除标记让普通读取表现为对象不存在。这不能证明历史字节已被擦除。
读取完整历史:
aws s3api list-object-versions --bucket labex-report-history
响应现在既包含 DeleteMarkers,也包含 Versions。找到 DeleteMarkers 中唯一的条目,复制其 VersionId。这个 ID 标识标记,不是存储的报表。
将下面占位符替换为该标记 ID:
MARKER_VERSION='PASTE_DELETE_MARKER_ID'
使用 delete-object 移除这个准确标记。提供 --version-id 会删除选中的历史条目,而不是再创建一个标记:
aws s3api delete-object --bucket labex-report-history --key report.txt --version-id "$MARKER_VERSION"
响应标识已删除的标记。之前的已批准版本重新成为当前版本;这个操作不会上传另一个报表版本。下载对象键,确认普通访问已恢复:
aws s3 cp s3://labex-report-history/report.txt accessible-report.txt
cmp report-approved.txt accessible-report.txt && echo 'Current report accessible again'
比较成功。AWS View 再次显示 report.txt,内容为已批准内容,并有三个版本。移除标记会恢复访问;永久删除数据版本则会擦除那个特定副本。
删除历史版本和存储桶
在本步骤中,你将在删除空存储桶前,移除全部实验数据版本。
即使普通对象列表为空,版本历史仍占用存储。普通 aws s3 rm 会再创建一个删除标记,因此不足以清空启用版本控制的桶。上一步的标记已移除;三个数据版本仍存在。
永久清理前,列出历史:
aws s3api list-object-versions --bucket labex-report-history
你应看到 Versions 中有三个条目,没有 DeleteMarkers。全部条目都属于这个一次性报表练习。
三个条目都属于 report.txt。你已经用 delete-object --version-id 删除过标记;同一操作也可以永久删除数据版本。
从列表复制一个 VersionId,替换下面占位符。对三个不同 ID 中的每一个各运行一次命令。永久删除无法撤销,因此每次都要核对存储桶、对象键和 ID:
aws s3api delete-object --bucket labex-report-history --key report.txt --version-id 'PASTE_VERSION_ID'
成功响应标识已删除版本。版本 ID 选择一个历史副本,不会删除该对象键的所有版本。删除三个版本后,确认没有剩余版本或标记:
aws s3api list-object-versions --bucket labex-report-history
成功响应中没有 Versions 或 DeleteMarkers 条目。现在使用 rb 删除空桶:
aws s3 rb s3://labex-report-history
输出为 remove_bucket: labex-report-history。确认存储仍响应:
aws s3 ls
没有剩余存储桶,AWS View 显示 No buckets。本地报表文件仍可使用;只删除了实验 S3 资源及历史。
总结
你在发布前启用了存储桶版本控制,区分了当前对象键及其历史版本 ID,并通过读取旧版本、发布已验证的字节来恢复被覆盖的报表。随后,你创建并移除了删除标记,无需上传另一个版本就恢复了普通访问。
版本控制保留历史,但不能让显式版本删除变得可撤销。最后,你查看并永久删除了全部实验版本,确认没有剩余标记,并删除了空存储桶。



