折腾的起因
之前为了忽悠,在 OSS 上传了 600T 的数据,现在为了继续忽悠,需要把这些数据清空。(天空飘来一首歌:当初忽悠要上传,上传就上传,现在又要来忽悠,把它去清空……)
折腾的步骤
删除文件
首先直接用 aws 命令删除文件,具体参数和之前的一致:
aws s3 rm s3://test/copy_ --recursive --endpoint-url https://obs-xxxx.cucloud.cn --no-verify-ssl
检查文件已经全部删除:
aws s3 ls s3://test/copy_ --recursive --endpoint-url https://obs-xxxx.cucloud.cn --no-verify-ssl
但删除完后,发现存储桶还是不能删除,应该是有版本控制,即其内部有文件的历史版本或删除标记。
删除版本
API
使用 API 来查找历史版本:
aws s3api list-object-versions --bucket test --endpoint-url https://obs-xxxx.cucloud.cn --no-verify-ssl --query '{Objects: [Versions[], DeleteMarkers[] | {Key: Key, VersionId: VersionId}]}' > delete.json
aws s3api delete-objects --bucket test --delete file://delete.json --endpoint-url https://obs-xxxx.cucloud.cn --no-verify-ssl
但通过这两条命令还是无法删除,没办法只能动用 Python了。
Python
让 AI 整理了一下,给出了一个 Python 脚本:
import boto3
from botocore.client import Config
# 1. 抑制 urllib3 的 InsecureRequestWarning
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# 配置参数
ENDPOINT = "https://obs-xxxx.cucloud.cn"
BUCKET_NAME = "test"
ACCESS_KEY = "ACCESS_KEY"
SECRET_KEY = "SECRET_KEY"
# 初始化 S3 客户端
s3 = boto3.client(
's3',
endpoint_url=ENDPOINT,
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
verify=False,
config=Config(signature_version='s3v4')
)
def force_empty_and_delete_bucket(bucket_name):
print(f"--- 开始清空存储桶: {bucket_name} ---")
# 计数器
count = 0
try:
# 使用分页器获取所有版本,处理大容量 Bucket
paginator = s3.get_paginator('list_object_versions')
for page in paginator.paginate(Bucket=bucket_name):
# 处理普通版本和历史版本
versions = page.get('Versions', [])
for v in versions:
key = v['Key']
vid = v['VersionId']
print(f"[删除版本] {key} (ID: {vid})")
s3.delete_object(Bucket=bucket_name, Key=key, VersionId=vid)
count += 1
# 处理删除标记
markers = page.get('DeleteMarkers', [])
for m in markers:
key = m['Key']
vid = m['VersionId']
print(f"[清理标记] {key} (ID: {vid})")
s3.delete_object(Bucket=bucket_name, Key=key, VersionId=vid)
count += 1
# 清理未完成的分段上传碎片
print("正在检查未完成的分段上传碎片...")
uploads = s3.list_multipart_uploads(Bucket=bucket_name)
for u in uploads.get('Uploads', []):
print(f"[中止碎片] {u['Key']}")
s3.abort_multipart_upload(Bucket=bucket_name, Key=u['Key'], UploadId=u['UploadId'])
print(f"--- 清理完成,共处理 {count} 个条目 ---")
# 尝试删除存储桶
try:
s3.delete_bucket(Bucket=bucket_name)
print(f"SUCCESS: 存储桶 {bucket_name} 已成功销毁。")
except Exception as e:
print(f"ERROR: 桶已清空但无法删除,可能是权限或延迟: {e}")
except Exception as e:
print(f"CRITICAL ERROR: {e}")
if __name__ == "__main__":
force_empty_and_delete_bucket(BUCKET_NAME)


