19

我曾經嘗試都s3cmd如何使用CLI在AWS S3中刪除版本化存儲桶?

$ s3cmd -r -f -v del s3://my-versioned-bucket/ 

而且AWS CLI:

$ aws s3 rm s3://my-versioned-bucket/ --recursive 

但是這兩個命令只需添加DELETE標記到S3。刪除存儲桶的命令也不起作用(來自AWS CLI):

$ aws s3 rb s3://my-versioned-bucket/ --force 
Cleaning up. Please wait... 
Completed 1 part(s) with ... file(s) remaining 
remove_bucket failed: s3://my-versioned-bucket/ A client error (BucketNotEmpty) occurred when calling the DeleteBucket operation: The bucket you tried to delete is not empty. You must delete all versions in the bucket. 

好的......怎麼樣? their documentation沒有這方面的信息。 S3Cmd表示這是一個「全功能」的S3命令行工具,但它使得no reference to versions不是它自己的。有沒有辦法做到這一點,而不使用Web界面,這將永遠需要,並要求我保持我的筆記本電腦?

+0

據我所知,您需要遍歷對象版本並將它們批量刪除1000 ... –

+0

如果有某處有示例Java代碼,那就太好了。 AWS文檔真的很糟糕...... – NobleUplift

回答

3

一種方法是遍歷版本並刪除它們。了一下就CLI棘手,但正如你所說的Java,這將是更直截了當:

AmazonS3Client s3 = new AmazonS3Client(); 
String bucketName = "deleteversions-"+UUID.randomUUID(); 

//Creates Bucket 
s3.createBucket(bucketName); 

//Enable Versioning 
BucketVersioningConfiguration configuration = new BucketVersioningConfiguration(ENABLED); 
s3.setBucketVersioningConfiguration(new SetBucketVersioningConfigurationRequest(bucketName, configuration)); 

//Puts versions 
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("some-bytes".getBytes()), null); 
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("other-bytes".getBytes()), null); 

//Removes all versions 
for (S3VersionSummary version : S3Versions.inBucket(s3, bucketName)) { 
    String key = version.getKey(); 
    String versionId = version.getVersionId();   
    s3.deleteVersion(bucketName, key, versionId); 
} 

//Removes the bucket 
s3.deleteBucket(bucketName); 
System.out.println("Done!"); 

您還可以批量如果需要刪除效率的呼叫。

+1

我實際上會嘗試讓一個多線程程序運行來刪除我的S3存儲桶中的每個「文件夾」(其中有四個文件夾),並且如果需要的話,將線程拆分爲較大的文件夾到'first/1',...,'first/9'等......但是一個同事,我最終刪除了所有使用Web界面和Cyber​​duck的版本。感謝您的幫助,但我需要它! – NobleUplift

6

您可以刪除版本化s3存儲桶中的所有對象。 但我不知道如何刪除指定的對象。 aws s3api delete-objects --bucket <value> --delete "$(aws s3api list-object-versions --bucket <value> | jq '{Objects: [.Versions[] | {Key:.Key, VersionId : .VersionId}], Quiet: false}')"

希望它對你有幫助。

+0

這個工程,但我不得不將對象更改爲對象和安靜。這顯然是區分大小寫的。 –

+1

這可惜不適用於1000多個對象.. –

+0

任何方式來解決1000+對象限制? –

19

我遇到了AWS CLI的相同限制。我發現最簡單的解決方案是使用Python和boto3

BUCKET = 'your-bucket-here' 

import boto3 

s3 = boto3.resource('s3') 
bucket = s3.Bucket(BUCKET) 
bucket.object_versions.delete() 

# if you want to delete the now-empty bucket as well, uncomment this line: 
#bucket.delete() 

這個答案的先前版本使用boto但解決方案必須具有大量鍵性能問題輕笑指出。

+0

絕對有效! –

4
  1. 用於使用jq過濾器刪除指定對象。
  2. 您可能需要清理'DeleteMarkers'而不僅僅是'版本'。
  3. 使用$()而不是``,可以爲bucket-name和key-value嵌入變量。
aws s3api delete-objects --bucket bucket-name --delete "$(aws s3api list-object-versions --bucket bucket-name | jq -M '{Objects: [.["Versions","DeleteMarkers"][]|select(.Key == "key-value")| {Key:.Key, VersionId : .VersionId}], Quiet: false}')" 
+0

此oneliner(以及上面的http://stackoverflow.com/a/31086407/465684)外觀和工作很好,但它們不適合有超過1000個對象要刪除的情況(嚴格限制s3api刪除對象調用)。 –

+0

@ tiger-peng在調用DeleteObjects操作時出現錯誤「發生錯誤(MalformedXML):您提供的XML格式不正確或未針對我們發佈的模式進行驗證」。任何想法發生了什麼? –

1

這裏是一個班輪你可以剪切並粘貼到命令行刪除所有版本和刪除標記(它需要AWS工具,它與鬥名稱替換yourbucket名備份)

echo '#!/bin/bash' > deleteBucketScript.sh && aws --output text s3api list-object-versions --bucket yourbucket-name-backup | grep -E "^VERSIONS" | awk '{print "aws s3api delete-object --bucket yourbucket-name-backup --key "$4" --version-id "$8";"}' >> deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh; echo '#!/bin/bash' > deleteBucketScript.sh && aws --output text s3api list-object-versions --bucket yourbucket-name-backup | grep -E "^DELETEMARKERS" | grep -v "null" | awk '{print "aws s3api delete-object --bucket yourbucket-name-backup --key "$3" --version-id "$5";"}' >> deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh; 

那麼你可以使用:

aws s3 rb s3://bucket-name --force

+0

我的同事設置了生命週期規則,將在接下來的幾天內慢慢刪除版本控制桶。你的回答很具有諷刺意味,因爲它永遠會在我們的系統中完成S3版本的終結。 – NobleUplift

5

我遇到了Abe's solution問題,因爲list_buckets生成器用於創建一個名爲all_keys的大規模列表,我花了一個小時沒有完成它。這種調整似乎對我更好,我的桶裏有近百萬個物體,並且數着!

import boto 

s3 = boto.connect_s3() 
bucket = s3.get_bucket("your-bucket-name-here") 

chunk_counter = 0 #this is simply a nice to have 
keys = [] 
for key in bucket.list_versions(): 
    keys.append(key) 
    if len(keys) > 1000: 
     bucket.delete_keys(keys) 
     chunk_counter += 1 
     keys = [] 
     print("Another 1000 done.... {n} chunks so far".format(n=chunk_counter)) 

#bucket.delete() #as per usual uncomment if you're sure! 

希望這有助於任何人遇到這個S3噩夢!

+0

謝謝你這個幫助我的例子,有一件事是在for循環之後缺少一個最終的bucket.delete_keys(keys),以便根據你的批處理邏輯來捕獲任何零碎的東西。 – Sean

12

使用boto3它比與建議boto的解決方案來刪除一個S3桶中的所有對象版本更容易:

#!/usr/bin/env python 
import boto3 

s3 = boto3.resource('s3') 
bucket = s3.Bucket('your-bucket-name') 
bucket.object_versions.all().delete() 

正常工作也非常大量的對象版本,雖然它可能需要一些時間那種情況。

相關問題