You need to enable JavaScript to run this app.
导航
多版本场景(Node.js SDK)
最近更新时间:2024.02.04 18:31:09首次发布时间:2023.12.19 18:47:29

版本控制应用于桶中所有对象。通过开启桶的版本控制,您可以在错误删除或者覆盖对象后,将对象回恢复至任意的历史版本。
目前支持多版本的接口包含 getObjectV2、getObjectAcl、copyObject、uploadPartCopy、deleteObject 等。调用相关接口时,您可通过可选参数 versionId 指定操作对象的具体版本。

桶多版本管理

TOS 中桶的版本状态包含未开启、开启版本控制和暂停版本控制三种,本文介绍桶的多版本管理。

注意

  • 设置桶多版本状态前,您必须具备 tos:PutBucketVersioning 权限。
  • 查询桶多版本状态前,您必须具备 tos:GetBucketVersioning 权限。

设置桶版本控制状态

// 导入 SDK, 当 TOS Node.JS SDK 版本小于 2.5.2 请把下方 TosClient 改成 TOS 导入
import { TosClient, TosClientError, TosServerError, VersioningStatusType } from '@volcengine/tos-sdk';

// 创建客户端
const client = new TosClient({
  accessKeyId: process.env['TOS_ACCESS_KEY'],
  accessKeySecret: process.env['TOS_SECRET_KEY'],
  region: "Provide your region", // 填写 Bucket 所在地域。以华北2(北京)为例,则 "Provide your region" 填写为 cn-beijing。
  endpoint: "Provide your endpoint", // 填写域名地址
});

function handleError(error) {
  if (error instanceof TosClientError) {
    console.log('Client Err Msg:', error.message);
    console.log('Client Err Stack:', error.stack);
  } else if (error instanceof TosServerError) {
    console.log('Request ID:', error.requestId);
    console.log('Response Status Code:', error.statusCode);
    console.log('Response Header:', error.headers);
    console.log('Response Err Code:', error.code);
    console.log('Response Err Msg:', error.message);
  } else {
    console.log('unexpected exception, message: ', error);
  }
}

const bucketName = 'node-sdk-test-bucket';
async function main() {
  try {
    // 开启多版本
    const { requestId } = await client.putBucketVersioning({
      bucket: bucketName,
      status: VersioningStatusType.Enabled,
    });
    console.log('putBucketVersioning Request ID: ', requestId);

    // 关闭多版本
    const { requestId: requestId2 } = await client.putBucketVersioning({
      bucket: bucketName,
      status: VersioningStatusType.Suspended,
    });
    console.log('putBucketVersioning Request ID: ', requestId2);
  } catch (error) {
    handleError(error);
  }
}

main();

下载多版本对象

// 导入 SDK, 当 TOS Node.JS SDK 版本小于 2.5.2 请把下方 TosClient 改成 TOS 导入
import { TosClient, TosClientError, TosServerError } from '@volcengine/tos-sdk';

// 创建客户端
const client = new TosClient({
  accessKeyId: process.env['TOS_ACCESS_KEY'],
  accessKeySecret: process.env['TOS_SECRET_KEY'],
  region: "Provide your region", // 填写 Bucket 所在地域。以华北2(北京)为例,则 "Provide your region" 填写为 cn-beijing。
  endpoint: "Provide your endpoint", // 填写域名地址
});

function handleError(error) {
  if (error instanceof TosClientError) {
    console.log('Client Err Msg:', error.message);
    console.log('Client Err Stack:', error.stack);
  } else if (error instanceof TosServerError) {
    console.log('Request ID:', error.requestId);
    console.log('Response Status Code:', error.statusCode);
    console.log('Response Header:', error.headers);
    console.log('Response Err Code:', error.code);
    console.log('Response Err Msg:', error.message);
  } else {
    console.log('unexpected exception, message: ', error);
  }
}

const bucketName = 'node-sdk-test-bucket';
async function main() {
  try {
    // 指定的 objectKey
    const objectKey = '*** Provide your object key ***';
    // objectKey 对象的版本 id
    const versionId = '*** Provide object Version ID ***';
    // 下载数据到内存
    const { data, requestId } = await client.getObjectV2({
      bucket: bucketName,
      dataType: 'buffer',
      key: objectKey,
      versionId,
    });
    console.log('getObjectV2 Request ID: ', requestId);
    console.log('buffer.length: ', data.content.length);
  } catch (error) {
    handleError(error);
  }
}

main();

删除多版本对象

// 导入 SDK, 当 TOS Node.JS SDK 版本小于 2.5.2 请把下方 TosClient 改成 TOS 导入
import { TosClient, TosClientError, TosServerError } from '@volcengine/tos-sdk';

// 创建客户端
const client = new TosClient({
  accessKeyId: process.env['TOS_ACCESS_KEY'],
  accessKeySecret: process.env['TOS_SECRET_KEY'],
  region: "Provide your region", // 填写 Bucket 所在地域。以华北2(北京)为例,则 "Provide your region" 填写为 cn-beijing。
  endpoint: "Provide your endpoint", // 填写域名地址
});

function handleError(error) {
  if (error instanceof TosClientError) {
    console.log('Client Err Msg:', error.message);
    console.log('Client Err Stack:', error.stack);
  } else if (error instanceof TosServerError) {
    console.log('Request ID:', error.requestId);
    console.log('Response Status Code:', error.statusCode);
    console.log('Response Header:', error.headers);
    console.log('Response Err Code:', error.code);
    console.log('Response Err Msg:', error.message);
  } else {
    console.log('unexpected exception, message: ', error);
  }
}

const bucketName = 'node-sdk-test-bucket';
async function main() {
  try {
    // 指定的 objectKey
    const objectKey = '*** Provide your object key ***';
    // objectKey 对象的版本 id
    const versionId = '*** Provide object Version ID ***';
    // 删除存储桶中指定对象指定版本
    const { requestId } = await client.deleteObject({
      bucket: bucketName,
      key: objectKey,
      versionId,
    });
    console.log('deleteObject Request ID: ', requestId);
  } catch (error) {
    handleError(error);
  }
}

main();

清空开启多版本的桶

以下代码用于清空整个开启多版本桶的示例代码,包括删除所有对象的多个版本、删除删除标记的多个版本、删除所有未合并的对象。

// 导入 SDK, 当 TOS Node.JS SDK 版本小于 2.5.2 请把下方 TosClient 改成 TOS 导入
import { TosClient, TosClientError, TosServerError } from '@volcengine/tos-sdk';

// 创建客户端
const client = new TosClient({
  accessKeyId: process.env['TOS_ACCESS_KEY'],
  accessKeySecret: process.env['TOS_SECRET_KEY'],
  region: "Provide your region", // 填写 Bucket 所在地域。以华北2(北京)为例,则 "Provide your region" 填写为 cn-beijing。
  endpoint: "Provide your endpoint", // 填写域名地址
});

function handleError(error) {
  if (error instanceof TosClientError) {
    console.log('Client Err Msg:', error.message);
    console.log('Client Err Stack:', error.stack);
  } else if (error instanceof TosServerError) {
    console.log('Request ID:', error.requestId);
    console.log('Response Status Code:', error.statusCode);
    console.log('Response Header:', error.headers);
    console.log('Response Err Code:', error.code);
    console.log('Response Err Msg:', error.message);
  } else {
    console.log('unexpected exception, message: ', error);
  }
}

async function main() {
  try {
    const bucketName = 'node-sdk-test-bucket';

    // 删除桶中所有对象
    for (let isTruncated = true, keyMarker = '', versionIdMarker = ''; isTruncated; ) {
      const { data } = await client.listObjectVersions({
        maxKeys: 1000,
        bucket: bucketName,
        keyMarker,
        versionIdMarker,
      });

      // 删除多版本对象
      for (const object of data.Versions) {
        const { requestId } = await client.deleteObject({
          bucket: bucketName,
          key: object.Key,
          versionId: object.VersionId,
        });
        console.log('deleteObject %s Request ID:', object.Key, requestId);
      }

      // 删除标记信息
      for (const markers of data.DeleteMarkers) {
        const { requestId } = await client.deleteObject({
          bucket: bucketName,
          key: markers.Key,
          versionId: markers.VersionId,
        });
        console.log('deleteObject DeleteMarker %s Request ID:', markers.Key, requestId);
      }
      isTruncated = data.IsTruncated;
      keyMarker = data.NextKeyMarker;
      versionIdMarker = data.NextVersionIdMarker;
    }

    // 删除所有未合并的对象
    for (let isTruncated = true, keyMarker = '', uploadIdMarker = ''; isTruncated; ) {
      const { data } = await client.listMultipartUploads({
        bucket: bucketName,
        maxUploads: 1000,
        keyMarker,
        uploadIdMarker,
      });
      for (const upload of data.Uploads) {
        const { requestId } = await client.abortMultipartUpload({
          bucket: bucketName,
          key: upload.Key,
          uploadId: upload.UploadId,
        });
        console.log('abortMultipartUpload uploadId: %s, requestId: %s', upload.UploadId, requestId);
      }
      isTruncated = data.IsTruncated;
      keyMarker = data.NextKeyMarker;
      uploadIdMarker = data.NextUploadIdMarker;
    }
  } catch (error) {
    handleError(error);
  }
}

main();