我能恢复从 S3 存储桶中删除的文件吗?
答案1
一旦删除,就无法恢复或取消删除对象。
答案2
如果您启用了版本控制,那么您可以!在版本控制的存储桶上,对文件执行删除操作实际上并不会删除它,但会添加一个带有“删除标记”的版本。您可以使用 AWS CLI 删除删除标记:
aws s3api delete-object --bucket yourbucket-name --key "yourfile" --version-id id_of_the_delete_marker
您可以使用以下命令获取存储桶中的所有文件
aws --output text s3api list-object-versions --bucket yourbucket-name > files.txt
如果您想要取消删除存储桶中的所有文件,您可以尝试:
echo '#!/bin/bash' > undeleteScript.sh && aws --output text s3api list-object-versions --bucket yourbucket-name | grep -E "^DELETEMARKERS" | awk '{FS = "[\t]+"; print "aws s3api delete-object --bucket yourbucket-name --key \42"$3"\42 --version-id "$5";"}' >> undeleteScript.sh && . undeleteScript.sh; rm -f undeleteScript.sh;
答案3
我在寻找答案时刚刚更新了这个问题:
您现在可以将版本控制添加到 S3 存储桶。这将导致 S3 即使在删除后仍保留对象的版本。完整文档:http://docs.amazonwebservices.com/AmazonS3/latest/dev/Versioning.html
答案4
万一您想以更可持续的方式恢复大量 s3 对象,这里有一个 python 版本和 @chris Cinelli 分享的相同解决方案的 bash 版本
Python 版本, 来源于这里
#!/usr/bin/env python
from datetime import datetime, timezone
import boto3
# ######################################
#
# Empty Bucket of all delete markers from all objects.
#
# ######################################
# -----------------------------------
# Enter these values here:
thebucket = "<bucket_name>"
access_key = "<access_key>"
secret_key = "<secret_key>"
region_name = "<region_name>" # us-east-1
# ------------------------------------
s3 = boto3.resource("s3", region_name=region_name, aws_access_key_id=access_key, aws_secret_access_key=secret_key)
s3client = boto3.client("s3", aws_access_key_id=access_key, aws_secret_access_key=secret_key)
# paginate 100000 at a time
page_size = 100000
folder_in_thebucket = "files/invoices"
paginator = s3client.get_paginator("list_object_versions")
pageresponse = paginator.paginate(
Bucket=thebucket, Prefix=folder_in_thebucket, PaginationConfig={"PageSize": page_size}
)
deleted_at = datetime(2019, 10, 22, 20, 0, 0, tzinfo=timezone.utc)
def restore_all(pages):
# iter over the pages from the paginator
for page in pages:
# Find if there are any delmarkers
if "DeleteMarkers" in page.keys():
for each_delmarker in page["DeleteMarkers"]:
if each_delmarker["IsLatest"] is True and each_delmarker["LastModified"] > deleted_at:
restore(each_delmarker)
def restore(delete_marker):
# Create a resource for the version-object
# and use .delete() to remove it.
file_object_version = s3.ObjectVersion(thebucket, delete_marker["Key"], delete_marker["VersionId"])
# I added this output just so I could watch the script run.
print(f"Restoring {delete_marker}")
# Lastly, lets remove the del marker and recover one of many files.
file_object_version.delete()
if __name__ == "__main__":
print(f"Restoring files deleted after {deleted_at} in {thebucket}/{folder_in_thebucket}.")
restore_all(pageresponse)
Bash 版本, 来源于这里
#!/bin/bash
bucket=$1
prefix=$2
set -e
echo "Removing all latest delete markers in $bucket with prefix $prefix"
#versions=`aws s3api list-object-versions --bucket $bucket | jq '.Versions | .[] | select(.IsLatest | not)'`
latest_delete_markers=`aws s3api list-object-versions --bucket $bucket --prefix "$prefix" | jq '.DeleteMarkers | .[] | select(.IsLatest)'`
# echo "latest delete markers:"
# echo "$latest_delete_markers"
# echo "removing delete markers"
for marker in $(echo "${latest_delete_markers}" | jq -r '@base64'); do
marker=$(echo ${marker} | base64 --decode)
# echo "marker:"
# echo "$marker"
key=`echo $marker | jq -r .Key`
versionId=`echo $marker | jq -r .VersionId `
printf "Removing delete marker $key $versionId ... "
aws s3api delete-object --bucket $bucket --key "$key" --version-id $versionId > /dev/null
printf "✓\n"
# echo $cmd
# $cmd
done