You need to enable JavaScript to run this app.
导航

多版本场景(Go SDK)

最近更新时间2024.02.04 18:31:02

首次发布时间2023.01.18 17:37:39

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

桶多版本管理

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

注意

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

设置桶版本控制状态

package main

import (
    "context"
    "fmt"
    "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
    "github.com/volcengine/ve-tos-golang-sdk/v2/tos/enum"
    "os"
)

func checkErr(err error) {
    if err != nil {
       if serverErr, ok := err.(*tos.TosServerError); ok {
          fmt.Println("Error:", serverErr.Error())
          fmt.Println("Request ID:", serverErr.RequestID)
          fmt.Println("Response Status Code:", serverErr.StatusCode)
          fmt.Println("Response Header:", serverErr.Header)
          fmt.Println("Response Err Code:", serverErr.Code)
          fmt.Println("Response Err Msg:", serverErr.Message)
       } else if clientErr, ok := err.(*tos.TosClientError); ok {
          fmt.Println("Error:", clientErr.Error())
          fmt.Println("Client Cause Err:", clientErr.Cause.Error())
       } else {
          fmt.Println("Error:", err)
       }
       panic(err)
    }
}

func main() {
    var (
       accessKey = os.Getenv("TOS_ACCESS_KEY")
       secretKey = os.Getenv("TOS_SECRET_KEY")
       // Bucket 对应的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com
       endpoint = "https://tos-cn-beijing.volces.com"
       region   = "cn-beijing"
       // 填写 BucketName
       bucketName = "*** Provide your bucket name ***"

       ctx = context.Background()
    )
    // 初始化客户端
    client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey)))
    checkErr(err)

    // 开启多版本
    output, err := client.PutBucketVersioning(ctx, &tos.PutBucketVersioningInput{
       Bucket: bucketName,
       Status: enum.VersioningStatusEnable,
    })

    fmt.Println("PutBucketVersioning Request ID:", output.RequestID)

    // 关闭多版本
    output, err = client.PutBucketVersioning(ctx, &tos.PutBucketVersioningInput{
       Bucket: bucketName,
       Status: enum.VersioningStatusSuspended,
    })

    fmt.Println("PutBucketVersioning Request ID:", output.RequestID)

}

下载多版本对象

package main

import (
   "context"
   "fmt"
   "io/ioutil"

   "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
)

func checkErr(err error) {
   if err != nil {
      if serverErr, ok := err.(*tos.TosServerError); ok {
         fmt.Println("Error:", serverErr.Error())
         fmt.Println("Request ID:", serverErr.RequestID)
         fmt.Println("Response Status Code:", serverErr.StatusCode)
         fmt.Println("Response Header:", serverErr.Header)
         fmt.Println("Response Err Code:", serverErr.Code)
         fmt.Println("Response Err Msg:", serverErr.Message)
      } else if clientErr, ok := err.(*tos.TosClientError); ok {
         fmt.Println("Error:", clientErr.Error())
         fmt.Println("Client Cause Err:", clientErr.Cause.Error())
      } else {
         fmt.Println("Error:", err)
      }
      panic(err)
   }
}

func main() {
   var (
      accessKey = os.Getenv("TOS_ACCESS_KEY")
      secretKey = os.Getenv("TOS_SECRET_KEY")
      // Bucket 对应的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com
      endpoint = "https://tos-cn-beijing.volces.com"
      region   = "cn-beijing"
      // 填写 BucketName
      bucketName = "*** Provide your bucket name ***"
      objectKey = "example_dir/example.txt"
      ctx       = context.Background()
   )
   // 初始化客户端
   client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey)))
   checkErr(err)
   // 下载数据到内存
   // 指定下载对象版本信息
   versionID := "your object version id"
   getOutput, err := client.GetObjectV2(ctx, &tos.GetObjectV2Input{
      Bucket:    bucketName,
      Key:       objectKey,
      VersionID: versionID,
   })
   checkErr(err)
   fmt.Println("GetObjectV2 Request ID:", getOutput.RequestID)
   // 下载数据大小
   fmt.Println("GetObjectV2 Response ContentLength", getOutput.ContentLength)
   defer getOutput.Content.Close()
   body, err := ioutil.ReadAll(getOutput.Content)
   checkErr(err)
   // 完成下载
   fmt.Println("Get Object Content:", body)
}

删除多版本对象

package main

import (
   "context"
   "fmt"

   "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
)
func checkErr(err error) {
   if err != nil {
      if serverErr, ok := err.(*tos.TosServerError); ok {
         fmt.Println("Error:", serverErr.Error())
         fmt.Println("Request ID:", serverErr.RequestID)
         fmt.Println("Response Status Code:", serverErr.StatusCode)
         fmt.Println("Response Header:", serverErr.Header)
         fmt.Println("Response Err Code:", serverErr.Code)
         fmt.Println("Response Err Msg:", serverErr.Message)
      } else if clientErr, ok := err.(*tos.TosClientError); ok {
         fmt.Println("Error:", clientErr.Error())
         fmt.Println("Client Cause Err:", clientErr.Cause.Error())
      } else {
         fmt.Println("Error:", err)
      }
      panic(err)
   }
}

func main() {
   var (
      accessKey = os.Getenv("TOS_ACCESS_KEY")
      secretKey = os.Getenv("TOS_SECRET_KEY")
      // Bucket 对应的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com
      endpoint = "https://tos-cn-beijing.volces.com"
      region   = "cn-beijing"
      // 填写 BucketName
      bucketName = "*** Provide your bucket name ***"

      // 指定的 objectKey
      objectKey = "example_dir/example.txt"
      ctx       = context.Background()
      versionID = "*** Provide object Version ID"
   )
   // 初始化客户端
   client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey)))
   checkErr(err)
   // 删除存储桶中指定对象指定版本
   output, err := client.DeleteObjectV2(ctx, &tos.DeleteObjectV2Input{
      Bucket:    bucketName,
      Key:       objectKey,
      VersionID: versionID,
   })
   checkErr(err)
   fmt.Println("DeleteObjectV2 Request ID:", output.RequestID)

}

清空开启多版本的桶

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

package main

import (
    "context"
    "fmt"
    "os"

    "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
)

func checkErr(err error) {
    if err != nil {
       if serverErr, ok := err.(*tos.TosServerError); ok {
          fmt.Println("Error:", serverErr.Error())
          fmt.Println("Request ID:", serverErr.RequestID)
          fmt.Println("Response Status Code:", serverErr.StatusCode)
          fmt.Println("Response Header:", serverErr.Header)
          fmt.Println("Response Err Code:", serverErr.Code)
          fmt.Println("Response Err Msg:", serverErr.Message)
       } else if clientErr, ok := err.(*tos.TosClientError); ok {
          fmt.Println("Error:", clientErr.Error())
          fmt.Println("Client Cause Err:", clientErr.Cause.Error())
       } else {
          fmt.Println("Error:", err)
       }
       panic(err)
    }
}

func main() {
    var (
       accessKey = os.Getenv("TOS_ACCESS_KEY")
       secretKey = os.Getenv("TOS_SECRET_KEY")
       // Bucket 对应的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com
       endpoint = "https://tos-cn-beijing.volces.com"
       region   = "cn-beijing"
       // 填写 BucketName
       bucketName = "*** Provide your bucket name ***"

       ctx = context.Background()
    )
    // 初始化客户端
    client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey)))
    checkErr(err)

    // 删除桶中所有对象
    truncated := true
    marker := ""
    versionIdMarker := ""

    for truncated {
       listOutput, err := client.ListObjectVersionsV2(ctx, &tos.ListObjectVersionsV2Input{
          Bucket: bucketName,
          ListObjectVersionsInput: tos.ListObjectVersionsInput{
             MaxKeys:         1000,
             KeyMarker:       marker,
             VersionIDMarker: versionIdMarker,
          },
       })
       checkErr(err)
       for _, obj := range listOutput.Versions {
          // 删除多版本对象
          output, err := client.DeleteObjectV2(ctx, &tos.DeleteObjectV2Input{
             Bucket:    bucketName,
             Key:       obj.Key,
             VersionID: obj.VersionID,
          })
          checkErr(err)
          fmt.Printf("Delete %s, Request ID: %s\n", obj.Key, output.RequestID)

       }
       // 删除标记信息
       for _, deleteMarker := range listOutput.DeleteMarkers {
          output, err := client.DeleteObjectV2(ctx, &tos.DeleteObjectV2Input{
             Bucket:    bucketName,
             Key:       deleteMarker.Key,
             VersionID: deleteMarker.VersionID,
          })
          checkErr(err)
          fmt.Printf("Delete deleteMarker %s, Request ID: %s\n", deleteMarker.Key, output.RequestID)
       }
       truncated = listOutput.IsTruncated
       marker = listOutput.NextKeyMarker
       versionIdMarker = listOutput.NextVersionIDMarker
    }

    truncated = true
    marker = ""
    uploadIDMarker := ""
    for truncated {

       output, err := client.ListMultipartUploadsV2(ctx, &tos.ListMultipartUploadsV2Input{
          Bucket:         bucketName,
          MaxUploads:     1000,
          KeyMarker:      marker,
          UploadIDMarker: uploadIDMarker,
       })
       checkErr(err)
       for _, upload := range output.Uploads {
          abortUpload, err := client.AbortMultipartUpload(ctx, &tos.AbortMultipartUploadInput{
             Bucket:   bucketName,
             Key:      upload.Key,
             UploadID: upload.UploadID,
          })
          checkErr(err)
          fmt.Println("AbortMultipartUpload Upload ID:", upload.UploadID, " Request ID:", abortUpload.RequestID)
       }
       truncated = output.IsTruncated
       marker = output.NextKeyMarker
       uploadIDMarker = output.NextUploadIDMarker
    }

}