IBM Cloud Docs
版本控制对象

版本控制对象

版本控制允许单个对象的多个修订版存在于同一存储区中。 可以查询,读取,从已归档状态复原或删除对象的每个版本。 在存储区上启用版本控制可以减轻因用户错误或无意删除而造成的数据丢失。 覆盖对象时,将创建新版本,并且会自动保留对象的先前版本。 因此,在启用版本控制的存储区中,由于意外删除或覆盖而删除的对象可以通过复原先前版本的对象来轻松恢复。 如果删除了某个对象,那么会将其替换为 删除标记,并保存先前版本 (不会永久删除任何内容)。 要永久删除对象的各个版本,删除请求必须指定 版本标识。 对象的 GET 请求将检索最近存储的版本。 如果当前版本是删除标记,那么 IBM COS 会返回 404 Not Found 错误。

在存储区启用版本控制后,将对存储区中的所有对象进行版本控制。 所有新对象 (在存储区上启用版本控制后创建) 都将接收到永久分配的版本标识。 在启用版本控制之前创建的对象 (在存储区上) 将分配一个版本的 null。 当覆盖或删除具有 null 版本标识的对象时,将为其分配新的版本标识。 暂挂版本控制不会改变任何现有对象,但会改变 IBM COS 处理未来请求的方式。 启用后,只能暂挂版本控制,而不能完全禁用版本控制。 因此,存储区可以具有与版本控制相关的三种状态: 1。 缺省值 (未版本化),2。 已启用,或 3。 已暂挂。

版本控制入门

首先,创建一个启用了对象版本控制的新存储区。

  1. 浏览至对象存储器实例后,单击 创建存储区
  2. 选择区域和弹性,然后查找 对象版本控制,并将选择器切换为 已启用

启用版本控制 "
启用版本控制 "

然后创建版本化对象。

  1. 浏览新存储区,并通过将文件拖到浏览器窗口来上载该文件。
  2. 成功上载对象后,请上载具有相同名称的另一个对象。 文件将被分配 UUID 并保存为非当前版本的对象,而不是被覆盖。
  3. 切换 查看版本 以查看对象的备用版本并与之交互。

查看版本
查看版本

术语

删除标记: 允许访问已删除对象的版本的“不可见”对象。

版本标识: Unicode,UTF-8 编码,URL 安全,不透明的字符串,指示对象和关联元数据的唯一版本,并用于将请求作为该特定版本的目标。 版本标识的最大长度为 1,024 字节。

"null": 分配给在存储区上启用版本控制时存在的对象的特殊版本标识。

一致性和数据完整性

虽然 IBM COS 为所有数据 IO 操作提供了强大的一致性,但存储区配置最终是一致的。 在存储区上首次启用版本控制后,配置可能需要一些时间才能在系统中传播。 虽然可能似乎已启用版本控制,但建议在启用版本控制后等待 15 分钟,以发出期望创建版本或删除标记的任何请求。

IAM 操作

存在与版本控制关联的新 IAM 操作。

与版本管理相关的 IAM 操作
IAM 操作 角色
cloud-object-storage.bucket.put_versioning 管理者和写入者
cloud-object-storage.bucket.get_versioning 管理者、写入者和读取者
cloud-object-storage.object.get_version 经理,作家,读者,内容读者,对象读者
cloud-object-storage.object.head_version 经理,作家,读者,内容读者,对象读者
cloud-object-storage.bucket.delete_version 管理者和写入者
cloud-object-storage.object.get_versions 经理,作家,读者,内容读者,对象读者
cloud-object-storage.object.copy_get_version 管理者、写入者和读取者
cloud-object-storage.object.copy_part_get_version 管理者、写入者和读取者
cloud-object-storage.object.restore_version 管理者和写入者
cloud-object-storage.object.put_tagging_version 经理,写程序,对象写程序
cloud-object-storage.object.get_tagging_version 管理者、写入者和读取者
cloud-object-storage.object.delete_tagging_version 管理者和写入者

Activity Tracker 事件

版本控制将生成新事件。

  • cloud-object-storage.bucket-versioning.create
  • cloud-object-storage.bucket-versioning.read
  • cloud-object-storage.bucket-versioning.list

版本化存储区的管理事件包含 requestData.versioning.state 字段,指示是在存储区上启用还是暂挂版本控制。

对对象执行操作或创建对象版本的基本 HEADGETPUTDELETE 操作将包含 target.versionId 字段。 如果由于这些操作而创建了新版本,那么在完成多重部件上载以及复制对象或部件时,也会显示 target.versionId 字段。

删除对象并创建删除标记时,将存在 responseData.deleteMarker.created 字段。

使用情况和会计

将对所有版本进行计量,就像它们是相同的对象一样。 这意味着,如果存储区包含具有五个先前版本的单个对象,那么 资源配置 API 返回的 object_count 字段将为 6,即使它在存储区中仅显示一个对象也是如此。 同样,累积版本将占总使用量的比例,并且可计费。 除了 读取存储区元数据 API 返回的 object_count 字段外,API 响应主体还包含多个与版本控制关联的新字段:

  • noncurrent_object_count: 存储区中 int64 格式的非当前对象版本数。
  • noncurrent_bytes_used: 存储区中所有非当前对象版本的总大小 (格式为 int64 )。
  • delete_marker_count: 存储区中 int64 格式的删除标记总数。

如上所述,只能启用或暂挂版本控制。 如果出于任何原因想要完全禁用版本控制,那么需要将存储区的内容迁移到未启用版本控制的新存储区。

交互

用于版本控制的 S3 API 的 IBM COS 实现与用于版本控制的 AWS S3 API 完全相同,但存在一些差异。

归档和到期版本化对象

在支持版本的存储区中允许生命周期配置。 但是,与 Amazon S3不同,新版本受归档规则约束的方式与常规对象相同。 创建对象时,将为其提供转换日期,并在其个别转换日期对其进行归档,而不考虑这些对象是当前版本还是非当前版本。 覆盖对象不会影响先前版本的转换日期,并且将为新 (当前) 版本分配转换日期。

无法使用 NoncurrentVersionTransition 规则 归档生命周期配置中对象的非当前版本。

不可变Object Storage(WORM)

在启用了版本控制的存储区中不允许不可变 Object Storage (即,保留时间策略) 的 IBM COS 实现。 尝试创建保留时间策略将失败,尝试在具有保留时间策略的存储区上启用版本控制也将失败。

受支持的 S3 API

以下一组 REST API 可以通过某种方式与版本控制进行交互:

  • GET Object
  • HEAD Object
  • DELETE Object
  • GET Object ACL
  • PUT Object ACL
  • Upload Part Copy
  • Restore Object
  • DELETE Objects
  • List Object Versions
  • PUT Bucket Versioning
  • GET Bucket Versioning
  • PUT Object
  • POST Object
  • Copy Object
  • Complete Multipart Upload
  • PUT Object Tagging
  • GET Object Tagging
  • DELETE Object Tagging
  • PUT Bucket Lifecycle
  • GET Bucket Lifecycle
  • DELETE Bucket Lifecycle

REST API 示例

使用 cURL 显示了以下示例以方便使用。 环境变量用于表示特定于用户的元素,例如 $BUCKET$TOKEN$REGION。 请注意,$REGION 还将包含任何网络类型规范,因此使用专用网络向 us-south 中的存储区发送请求将需要将变量设置为 private.us-south

在存储区上启用版本控制

curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?versioning" \
     -H 'Authorization: bearer $TOKEN' \
     -H 'Content-MD5: 8qj8HSeDu3APPMQZVG06WQ==' \
     -H 'Content-Type: text/plain; charset=utf-8' \
     -d $'<VersioningConfiguration>
            <Status>Enabled</Status>
          </VersioningConfiguration>'

成功的请求返回 200 响应。

暂挂存储区上的版本控制

curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?versioning" \
     -H 'Authorization: bearer $TOKEN' \
     -H 'Content-MD5: hxXDWuCDWB72Be0LG4XniQ==' \
     -H 'Content-Type: text/plain; charset=utf-8' \
     -d $'<VersioningConfiguration>
            <Status>Suspended</Status>
          </VersioningConfiguration>'

成功的请求返回 200 响应。

列出水桶中对象的版本

curl -X "GET" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?versions" \
     -H 'Authorization: bearer $TOKEN'

这将返回 XML 响应主体:

<ListVersionsResult>
   <IsTruncated>boolean</IsTruncated>
   <KeyMarker>string</KeyMarker>
   <VersionIdMarker>string</VersionIdMarker>
   <NextKeyMarker>string</NextKeyMarker>
   <NextVersionIdMarker>string</NextVersionIdMarker>
   <Version>
      <ETag>string</ETag>
      <IsLatest>boolean</IsLatest>
      <Key>string</Key>
      <LastModified>timestamp</LastModified>
      <Owner>
         <DisplayName>string</DisplayName>
         <ID>string</ID>
      </Owner>
      <Size>integer</Size>
      <StorageClass>string</StorageClass>
      <VersionId>string</VersionId>
   </Version>
   ...
   <DeleteMarker>
      <IsLatest>boolean</IsLatest>
      <Key>string</Key>
      <LastModified>timestamp</LastModified>
      <Owner>
         <DisplayName>string</DisplayName>
         <ID>string</ID>
      </Owner>
      <VersionId>string</VersionId>
   </DeleteMarker>
   ...
   <Name>string</Name>
   <Prefix>string</Prefix>
   <Delimiter>string</Delimiter>
   <MaxKeys>integer</MaxKeys>
   <CommonPrefixes>
      <Prefix>string</Prefix>
   </CommonPrefixes>
   ...
   <EncodingType>string</EncodingType>
</ListVersionsResult>

delimiter:分隔符是您指定用于分组键的字符。 在前缀与第一次出现的定界符之间包含相同字符串的所有键都分组在 CommonPrefixes 中的单个结果元素下。 这些组将根据 max-keys 限制作为一个结果进行计数。 这些键不会在响应中的其他位置返回。

encoding-type: 请求 COS 对响应中的对象键进行 URL 编码。 对象键可能包含任何 Unicode 字符; 但是,XML 1.0 解析器无法解析某些字符,例如具有从 0 到 10 的 ASCII 值的字符。 对于 XML 1.0中不支持的字符,您可以添加此参数以请求 COS 对响应中的密钥进行编码。 有效值: url

key-marker:指定在列出数据桶中的对象时要从哪个键开始。

max-keys: 设置响应中返回的最大密钥数。 缺省情况下,API 最多返回 1,000 个密钥名称。 响应可能包含更少的密钥,但永远不会包含更多密钥。

prefix: 使用此参数可仅选择那些以指定前缀开头的键。

version-id-marker: 指定要从其开始列表的对象版本。

对特定对象版本的操作

多个 API 使用新的查询参数 (?versionId=<VersionId>),该参数指示您正在请求哪个版本的对象。 此参数以相同的方式用于读取,删除,检查元数据和标记以及复原归档对象。 例如,要读取版本标识为 L4kqtJlcpXroDVBH40Nr8X8gdRQBpUMLUo 的对象 foo 的版本,请求可能类似于以下内容:

curl -X "GET" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/foo?versionId=L4kqtJlcpXroDVBH40Nr8X8gdRQBpUMLUo" \
     -H 'Authorization: bearer $TOKEN'

以相同方式删除该对象。

curl -X "DELETE" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/foo?versionId=L4kqtJlcpXroDVBH40Nr8X8gdRQBpUMLUo" \
     -H 'Authorization: bearer $TOKEN'

对于已使用查询参数的请求,可以将 versionId 参数添加到末尾。

curl -X "GET" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/foo?tagging&versionId=L4kqtJlcpXroDVBH40Nr8X8gdRQBpUMLUo" \
     -H 'Authorization: bearer $TOKEN'

支持对象版本的服务器端复制,但使用的语法略有不同。 查询参数不会添加到 URL 本身,而是会附加到 x-amz-copy-source 头。 这与从源对象为多部分创建部分的语法相同。

curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/<new-object-key>"
 -H "Authorization: bearer $TOKEN"
 -H "x-amz-copy-source: /<source-bucket>/<object-key>?versionId=L4kqtJlcpXroDVBH40Nr8X8gdRQBpUMLUo"

CLI 示例

您可以将 IBM Cloud CLI 与 cos 插件配合使用,以在存储区上启用版本控制。

cos bucket-versioning-put --bucket $BUCKET --versioning-configuration file://vers.json

在本例中,vers.json 是一个简单文档:

{
    "Status": "Enabled"
}

SDK 示例

以下示例使用 IBM COS SDK for Python 和 Node.js,尽管对象版本控制的实现应该与允许设置定制端点的任何 S3-compatible 库或工具完全兼容。 使用第三方工具需要 HMAC 凭证才能计算 AWS V4 特征符。 有关 HMAC 凭证的更多信息,请参阅 文档

Python

可以使用 高级资源低级客户机 语法来启用使用 IBM COS SDK for Python 的版本控制。

使用资源:

#!/usr/bin/env python3

import ibm_boto3
from ibm_botocore.config import Config
from ibm_botocore.exceptions import ClientError

#Define constants
API_KEY = os.environ.get('IBMCLOUD_API_KEY')
SERVICE_INSTANCE = os.environ.get('SERVICE_INSTANCE_ID')
ENDPOINT = os.environ.get('ENDPOINT')

BUCKET = "my-versioning-bucket" # The bucket that will enable versioning.

#Create resource client with configuration info pulled from environment variables.
cos = ibm_boto3.resource("s3",
                         ibm_api_key_id=API_KEY,
                         ibm_service_instance_id=SERVICE_INSTANCE,
                         config=Config(signature_version="oauth"),
                         endpoint_url=ENDPOINT
                         )

versioning = cos.BucketVersioning(BUCKET)

versioning.enable()

然后,可以使用 versioning.suspend() 暂挂存储区的版本控制

通过使用同一 cos 资源,可以使用以下命令列出对象的所有版本:

versions = s3.Bucket(BUCKET).object_versions.filter(Prefix=key)

for version in versions:
    obj = version.get()
    print(obj.get('VersionId'), obj.get('ContentLength'), obj.get('LastModified'))

使用客户机:

#!/usr/bin/env python3

import ibm_boto3
from ibm_botocore.config import Config
from ibm_botocore.exceptions import ClientError

#Define constants
API_KEY = os.environ.get('IBMCLOUD_API_KEY')
SERVICE_INSTANCE = os.environ.get('SERVICE_INSTANCE_ID')
ENDPOINT = os.environ.get('ENDPOINT')

BUCKET = "my-versioning-bucket" # The bucket that will enable versioning.

#Create resource client with configuration info pulled from environment variables.
cosClient = ibm_boto3.client("s3",
                         ibm_api_key_id=API_KEY,
                         ibm_service_instance_id=SERVICE_INSTANCE,
                         config=Config(signature_version="oauth"),
                         endpoint_url=ENDPOINT
                         )

response = cosClient.put_bucket_versioning(
    Bucket=BUCKET,
    VersioningConfiguration={
        'Status': 'Enabled'
    }
)

使用同一客户机列出对象的版本:

resp = cosClient.list_object_versions(Prefix='some-prefix', Bucket=BUCKET)

请注意,Python API 非常灵活,并且有许多不同的方法来完成同一任务。

Node.js

使用 IBM COS SDK for Node.js 启用版本控制:

const IBM = require('ibm-cos-sdk');

var config = {
    endpoint: '<endpoint>',
    apiKeyId: '<api-key>',
    serviceInstanceId: '<resource-instance-id>',
};

var cos = new IBM.S3(config);

var params = {
    Bucket: 'my-versioning-bucket', /* required */
    VersioningConfiguration: { /* required */
    Status: 'Enabled'
   },
};

s3.putBucketVersioning(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
});