版本控制应用于桶中所有对象。通过开启桶的版本控制,您可以在错误删除或者覆盖对象后,将对象回恢复至任意的历史版本。
目前支持多版本的接口包含 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();