Dav*_*ern 3 versioning amazon-s3 amazon-web-services
我有一个启用了版本控制的Amazon S3存储桶.由于生命周期策略配置错误,此存储桶中的许多对象都添加了删除标记.
我可以从S3控制台中删除这些标记以恢复这些对象的先前版本,但是有足够的对象可以在Web控制台上手动执行此操作,这非常耗时.
有没有办法在S3存储桶中找到所有删除标记并删除它们,还原该存储桶中的所有文件?理想情况下,我想从控制台本身执行此操作,但我很乐意编写脚本或使用amazon CLI工具执行此操作,如果这是唯一的方法.
谢谢!
使用此选项可还原特定文件夹中的文件.我在我的脚本中使用了aws cli命令.提供输入为:sh scriptname.sh bucketname path/to/a/folder
**Script:**
#!/bin/bash
#please provide the bucketname and path to destination folder to restore
# Remove all versions and delete markers for each object
aws s3api list-object-versions --bucket $1 --prefix $2 --output text |
grep "DELETEMARKERS" | while read obj
do
KEY=$( echo $obj| awk '{print $3}')
VERSION_ID=$( echo $obj | awk '{print $5}')
echo $KEY
echo $VERSION_ID
aws s3api delete-object --bucket $1 --key $KEY --version-id $VERSION_ID
done
Run Code Online (Sandbox Code Playgroud)
编辑:$VERSION_ID
在脚本中放入正确的位置
这是一个示例 Python 实现:
import boto3
import botocore
BUCKET_NAME = 'BUCKET_NAME'
s3 = boto3.resource('s3')
def main():
bucket = s3.Bucket(BUCKET_NAME)
versions = bucket.object_versions
for version in versions.all():
if is_delete_marker(version):
version.delete()
def is_delete_marker(version):
try:
# note head() is faster than get()
version.head()
return False
except botocore.exceptions.ClientError as e:
if 'x-amz-delete-marker' in e.response['ResponseMetadata']['HTTPHeaders']:
return True
# an older version of the key but not a DeleteMarker
elif '404' == e.response['Error']['Code']:
return False
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
有关此答案的一些上下文,请参阅:https : //docs.aws.amazon.com/AmazonS3/latest/dev/DeleteMarker.html
如果您尝试获取对象并且其当前版本是删除标记,则 Amazon S3 会响应:
- 404(未找到对象)错误
- 一个响应头,x-amz-delete-marker: true
响应头告诉您访问的对象是删除标记。此响应标头从不返回 false;如果值为 false,则 Amazon S3 不会在响应中包含此响应标头。
列出删除标记(和对象的其他版本)的唯一方法是在 GET Bucket 版本请求中使用版本子资源。简单的 GET 不会检索删除标记对象。
不幸的是,尽管在https://github.com/boto/botocore/issues/674 中有写,检查是否ObjectVersion.size is None
不是确定版本是否为删除标记的可靠方法,因为对于以前删除的版本也是如此文件夹键。
目前,boto3 缺少确定 anObjectVersion
是否为 DeleteMarker的直接方法。见https://github.com/boto/boto3/issues/1769
然而,ObjectVersion.head()
和.Get()
操作将抛出一个异常ObjectVersion
是一个DeleteMarker。捕获此异常可能是确定 anObjectVersion
是否为 DeleteMarker的唯一可靠方法。
小智 7
我刚写了一个程序(使用boto)来解决同样的问题:
from boto.s3 import deletemarker
from boto.s3.connection import S3Connection
from boto.s3.key import Key
def restore_bucket(bucket_name):
bucket = conn.get_bucket(bucket_name)
for version in bucket.list_versions():
if isinstance(version, deletemarker.DeleteMarker) and version.is_latest:
bucket.delete_key(version.name, version_id=version.version_id)
Run Code Online (Sandbox Code Playgroud)
如果您需要在版本化的存储桶中恢复文件夹,可以在此处找到我编写的程序的其余部分.
定义变量
PROFILE="personal"
REGION="eu-west-1"
BUCKET="mysql-backend-backups-prod"
Run Code Online (Sandbox Code Playgroud)
立即删除 DeleteMarkers
aws --profile $PROFILE s3api delete-objects \
--region $REGION \
--bucket $BUCKET \
--delete "$(aws --profile $PROFILE s3api list-object-versions \
--region $REGION \
--bucket $BUCKET \
--output=json \
--query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}')"
Run Code Online (Sandbox Code Playgroud)
一次删除版本
aws --profile $PROFILE s3api delete-objects \
--region $REGION \
--bucket $BUCKET \
--delete "$(aws --profile $PROFILE s3api list-object-versions \
--region $REGION \
--bucket $BUCKET \
--output=json \
--query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
Run Code Online (Sandbox Code Playgroud)
然后删除 S3 存储桶
aws --profile $PROFILE s3api delete-bucket \
--region $REGION \
--bucket $BUCKET
Run Code Online (Sandbox Code Playgroud)
您需要编写一个程序来:
使用 SDK(例如boto
.
也可以使用AWS 命令行界面 (CLI),但您必须围绕它构建一个脚本来捕获 ID,然后删除标记。