如何立即从Amazon S3上的多个对象中删除删除标记

Dav*_*ern 3 versioning amazon-s3 amazon-web-services

我有一个启用了版本控制的Amazon S3存储桶.由于生命周期策略配置错误,此存储桶中的许多对象都添加了删除标记.

我可以从S3控制台中删除这些标记以恢复这些对象的先前版本,但是有足够的对象可以在Web控制台上手动执行此操作,这非常耗时.

有没有办法在S3存储桶中找到所有删除标记并删除它们,还原该存储桶中的所有文件?理想情况下,我想从控制台本身执行此操作,但我很乐意编写脚本或使用amazon CLI工具执行此操作,如果这是唯一的方法.

谢谢!

Kc *_*key 9

使用此选项可还原特定文件夹中的文件.我在我的脚本中使用了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在脚本中放入正确的位置

  • 这不适用于名称中包含空格的文件夹 (2认同)

Tom*_*asz 9

这是一个示例 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)

如果您需要在版本化的存储桶中恢复文件夹,可以在此处找到我编写的程序的其余部分.


Via*_*lav 7

定义变量

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)

  • 这对我很有用!请注意,如果用户只想删除某些对象,而不是全部对象,则可能需要使用 `--prefix`。(没有`--prefix`的查询在合理大小的存储桶上往往很慢......) (2认同)

Joh*_*ein 5

您需要编写一个程序来:

  • 循环访问 Amazon S3 存储桶中的所有对象
  • 检索每个对象的每个版本的版本 ID
  • 删除删除标记

使用 SDK(例如boto.

也可以使用AWS 命令​​行界面 (CLI),但您必须围绕它构建一个脚本来捕获 ID,然后删除标记。