使用版本控制恢复被覆盖的报表

AWSBeginner
立即练习

介绍

将草稿上传到财务团队的报表对象键,会替换读者看到的已批准内容。你将启用版本控制,重现这个错误,恢复已批准内容,并在确认恢复后删除练习历史。

请先完成 使用对象键和元数据组织文档,掌握对象键、属性、下载和清理。这个全新 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 登录。

官方 S3 Console 启用了 Show versions

来源: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,并通过读取旧版本、发布已验证的字节来恢复被覆盖的报表。随后,你创建并移除了删除标记,无需上传另一个版本就恢复了普通访问。

版本控制保留历史,但不能让显式版本删除变得可撤销。最后,你查看并永久删除了全部实验版本,确认没有剩余标记,并删除了空存储桶。