版本化物件
版本化容許單一物件的多個修訂存在於相同的儲存區中。 物件的每一個版本都可以查詢、讀取、從保存狀態還原或刪除。 在儲存區上啟用版本化可以減少使用者錯誤或無意刪除導致的資料流失。 當改寫物件時,會建立新版本,且會自動保留舊版物件。 因此,在啟用版本化的儲存區中,由於意外刪除或改寫而刪除的物件可以透過還原舊版物件輕鬆地回復。 如果刪除物件,則會以 刪除標記 取代該物件,並儲存舊版 (不會永久刪除任何項目)。 若要永久刪除物件的個別版本,刪除要求必須指定 版本 ID。
物件的 GET 要求將擷取最近儲存的版本。 如果現行版本是刪除標記,則 IBM COS 會傳回 404 Not Found 錯誤。
在儲存區已啟用版本化之後,儲存區中的所有物件都會版本化。 所有新物件 (在儲存區上啟用版本化之後建立) 都會收到永久指派的版本 ID。 在啟用版本化之前建立的物件 (在儲存區上) 會獲指派 null 版本。 當改寫或刪除具有 null 版本 ID 的物件時,會指派新的版本 ID 給該物件。 暫停版本化不會變更任何現有物件,但會變更 IBM COS 處理未來要求的方式。 一旦啟用,版本化只能暫停,不能完全停用。 因此,儲存區可以有三種與版本化相關的狀態:
1. 預設值 (未版本化),2. 已啟用,或 3. 暫停。
開始使用版本化
首先,建立已啟用物件版本化的新儲存區。
- 導覽至物件儲存空間實例之後,請按一下 建立儲存區。
- 選擇區域及備援,然後尋找 物件版本化,並將選取器切換為 已啟用。
然後建立版本化物件。
- 導覽新的儲存區,並將檔案拖曳至瀏覽器視窗來上傳檔案。
- 順利上傳物件之後,請上傳另一個同名的物件。 檔案將獲指派 UUID 並儲存為物件的非現行版本,而不是被改寫。
- 切換 檢視版本,以查看物件的替代版本並與之互動。
必須先開啟「檢視版本」,才能看到個別版本或刪除標記,並可選擇刪除。
術語
刪除標記: 容許存取已刪除物件的版本的「隱藏」物件。
版本識別碼:一種採用Unicode編碼、UTF-8 編碼、URL 安全機制且不透明的字串,用以標示物件及其關聯元數據的唯一版本,並用於將請求定向至該特定版本。 版本 ID 長度上限為 1,024 個位元組。
'null': 指派給在儲存區上啟用版本化時存在之物件的特殊版本 ID。
一致性和資料完整性
雖然 IBM COS 為所有資料 IO 作業提供高度一致性,但儲存區配置最終會一致。 在儲存區上第一次啟用版本化之後,配置可能需要一些時間才能在系統中傳播。 儘管版本控制功能看似已啟用,建議在啟用後等待 5 分鐘,再執行任何預期會建立版本或刪除標記的請求。
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.createcloud-object-storage.bucket-versioning.readcloud-object-storage.bucket-versioning.list
版本化儲存區的管理事件包含 requestData.versioning.state 欄位,指出是否在儲存區上啟用或暫停版本化。
處理或建立物件版本的基本 HEAD、GET、PUT 及 DELETE 動作將包括 target.versionId 欄位。 當完成多組件上傳時,以及當複製物件或組件時 (如果因為那些動作而建立新版本),也會出現 target.versionId 欄位。
當刪除物件並建立刪除標記時,會出現 responseData.deleteMarker.created 欄位。
使用情形和會計
所有版本都會被計量,就像它們是相等的物件一樣。 這表示如果儲存區包含具有五個舊版的單一物件,則 資源配置 API 所傳回的 object_count 欄位會是 6,即使它會顯示為儲存區中只有一個物件。 同樣地,累計版本也會影響總用量且可入帳。 除了 讀取儲存區 meta 資料 API 所傳回的 object_count 欄位之外,API 回應內文還包含與版本化相關聯的數個新欄位:
noncurrent_object_count: 儲存區中非現行物件版本的數目,格式為int64。noncurrent_bytes_used: 儲存區中所有非現行物件版本的大小總計,格式為int64。delete_marker_count: 儲存區中的刪除標記總數,格式為int64。
如上所述,版本化只能啟用或暫停。 如果基於任何原因,想要完全停用版本化,則必須將儲存區的內容移轉至未啟用版本化的新儲存區。
互動
IBM COS 對版本控制的 S3 API 實作與版本控制的 AWS S3 API 完全相同,只有少數差異。
保存已版本化的物件並使其到期
已啟用版本的儲存區中允許生命週期配置。 不過,與 Amazon S3不同,新版本遵循保存規則的方式與一般物件相同。 物件會在建立時獲得轉移日期,並在其個別轉移日期保存,不論它們是現行版本還是非現行版本。 改寫物件不會影響舊版的轉移日期,而新 (現行) 版本將獲指派轉移日期。
無法使用 NoncurrentVersionTransition 規則在生命週期配置中 只 保存非現行版本的物件。
不可變更 Object Storage (WORM)
在啟用版本化的儲存區中不允許 Immutable Object Storage (即保留原則) 的 IBM COS 實作。 嘗試建立保留原則會失敗,嘗試在具有保留原則的儲存區上啟用版本化也會失敗。
支援的 S3 API
下列 REST API 集可以透過某種方式與版本化互動:
GET ObjectHEAD ObjectDELETE ObjectGET Object ACLPUT Object ACLUpload Part CopyRestore ObjectDELETE ObjectsList Object VersionsPUT Bucket VersioningGET Bucket VersioningPUT ObjectPOST ObjectCopy ObjectComplete Multipart UploadPUT Object TaggingGET Object TaggingDELETE Object TaggingPUT Bucket LifecycleGET Bucket LifecycleDELETE 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 剖析器無法剖析部分字元,例如 ASCII 值從 0 到 10 的字元。 對於 XML 1.0中不支援的字元,您可以將此參數新增至要求 COS 對回應中的金鑰進行編碼。 有效值: url。
key-marker:指定列出水桶中物件時要從哪個鍵開始。
max-keys: 設定回應中傳回的索引鍵數目上限。 依預設,API 最多會傳回 1,000 個金鑰名稱。 回應可能包含較少的索引鍵,但絕不會包含較多的索引鍵。
prefix: 使用此參數只選取以指定字首開頭的金鑰。
version-id-marker: 指定您要從中開始列出的物件版本。
刪除水桶中物件的版本
一般的 ListObjects 或 ListObjectsV2 呼叫不會回傳版本 ID。 若要取得任何刪除作業所需的版本 ID,您必須使用 ListObjectVersions: 搭配 ?versions 查詢參數的 GET 請求。 這也會回傳刪除標記及其版本 ID。 沒有這個步驟,以下的刪除操作都無法進行。
curl 範例:
curl -X "GET" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?versions" \
-H 'Authorization: bearer $TOKEN'
IBM Cloud CLI 範例:
ibmcloud cos object-versions --bucket $BUCKET
Python 範例:
pythonresponse = cosClient.list_object_versions(Bucket=BUCKET)
for version in response.get('Versions', []):
print(version['Key'], version['VersionId'])
for marker in response.get('DeleteMarkers', []):
print(marker['Key'], marker['VersionId'], '(delete marker)')
刪除特定版本的 CLI 和 SDK 範例。
IBM Cloud CLI 範例:
ibmcloud cos object-delete --bucket $BUCKET --key $OBJECT_KEY --version-id $VERSION_ID
Python 範例:
pythoncosClient.delete_object(
Bucket=BUCKET,
Key='my-object.txt',
VersionId='L4kqtJlcpXroDVBH40Nr8X8gdRQBpUMLUo'
)
Node.js:
javascriptawait cos.deleteObject({
Bucket: 'my-versioning-bucket',
Key: 'my-object.txt',
VersionId: 'L4kqtJlcpXroDVBH40Nr8X8gdRQBpUMLUo'
}).promise();
使用使用者介面刪除目前版本需要先刪除非目前的物件。
移除刪除標記
移除刪除標記是物件意外刪除時的復原工作流程:您可以從 ListObjectVersions 取得刪除標記的版本 ID,然後依據該版本 ID 將其刪除。
刪除 null 版本 ID
預先版本的物件會被指派一個 null 的版本 ID,若要刪除該版本,請在請求中傳入 versionId=null。
curl 範例:
curl -X "DELETE" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/$OBJECT_KEY?versionId=null" \
-H 'Authorization: bearer $TOKEN'
Python 範例:
cosClient.delete_object(
Bucket=BUCKET,
Key='my-object.txt',
VersionId='null'
)
對特定物件版本的作業
數個 API 會使用新的查詢參數 (?versionId=<VersionId>) 來指出您要求的物件版本。 此參數以相同方式用於讀取、刪除、檢查 meta 資料和標籤,以及還原保存物件。 例如,若要讀取版本 ID 為 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
});