更新时间:2026-06-30 GMT+08:00

清理多段上传任务碎片

开发过程中,您有任何问题可以在GitHub上提交issue接口参考文档详细介绍了每个接口的参数和使用方法。

清理碎片是指删除未完成的多段上传任务产生的分片数据。当多段上传任务中断或失败时,会在桶中遗留未合并的分片数据,占用存储空间和产生费用。通过清理碎片功能可以删除这些无用的分片数据。建议定期清理7天以上未完成的多段上传任务,避免不必要的存储费用。

OBS SDK提供以下清理碎片的方式:

  1. 单次清理:通过取消多段上传任务接口清理单个未完成的上传任务。
  2. 批量清理:通过列举多段上传任务接口列出所有未完成的上传任务,然后批量清理。

本示例用于批量中止未完成的多段上传任务,列举桶中所有未完成的多段上传并逐个取消,以清理碎片:

<?php

// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
// 创建ObsClient实例
$obsClient = new ObsClient ( [
      //推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
      //您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/intl/zh-cn/usermanual-ca/ca_01_0003.html
      'key' => getenv('ACCESS_KEY_ID'),
      'secret' => getenv('SECRET_ACCESS_KEY'),
      // endpoint填写Bucket对应的Endpoint, 此处以中国-香港为例,其他地区请按实际情况填写。
       'endpoint' => "obs.ap-southeast-1.myhuaweicloud.com",
      'signature' => 'obs'
] );

$bucketName = 'bucketname';
$concurrency = 5;

// 分页列举所有多段上传
// 如需仅清理指定前缀下的碎片,请在listMultipartUploads中设置Prefix参数
$isTruncated = true;
$keyMarker = null;
$uploadIdMarker = null;
$uploads = [];

while ($isTruncated) {
       $listResp = $obsClient->listMultipartUploads ( [
              'Bucket' => $bucketName,
              'KeyMarker' => $keyMarker,
              'UploadIdMarker' => $uploadIdMarker
       ] );
       if (empty($listResp['Uploads'])) {
              break;
       }
       foreach ($listResp['Uploads'] as $upload) {
              // 如需仅清理7天前的碎片,可添加过滤条件:
              // if (strtotime($upload['Initiated']) > time() - 7*86400) continue;
              $uploads[] = ['Key' => $upload['Key'], 'UploadId' => $upload['UploadId'], 'Initiated' => $upload['Initiated']];
       }
       $isTruncated = $listResp['IsTruncated'];
       $keyMarker = $listResp['NextKeyMarker'];
       $uploadIdMarker = $listResp['NextUploadIdMarker'];
}

printf("Found %d uploads to abort\n\n", count($uploads));

// 并发中止多段上传任务
$successCount = 0;
$failCount = 0;

$promiseGenerator = function () use ($obsClient, $bucketName, $uploads, &$successCount, &$failCount) {
       foreach ($uploads as $upload) {
              printf("Key:%s, UploadId:%s, Initiated:%s\n", $upload['Key'], $upload['UploadId'], $upload['Initiated']);
              yield $obsClient->abortMultipartUploadAsync ( [
                     'Bucket' => $bucketName,
                     'Key' => $upload['Key'],
                     'UploadId' => $upload['UploadId']
              ], function ($exception, $resp) use ($upload, &$successCount, &$failCount) {
                     if ($exception === null) {
                            printf("AbortSuccess: Key:%s, RequestId:%s\n", $upload['Key'], $resp['RequestId']);
                            $successCount++;
                     } else {
                            printf("AbortFailed: Key:%s, Status:%d, Message:%s\n", $upload['Key'], $exception->getStatusCode(), $exception->getExceptionMessage());
                            $failCount++;
                     }
              } );
       }
};

$eachPromise = new EachPromise($promiseGenerator(), [
       'concurrency' => $concurrency
]);

$eachPromise->promise()->wait();

printf("\nResult: success=%d, fail=%d\n", $successCount, $failCount);