清理存储桶

折腾的起因

之前为了忽悠,在 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)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注