Object Storage Service (OSS) allows you to configure versioning to protect data at the bucket level. After you enable versioning for a bucket, data that is overwritten or deleted in the bucket is saved as a previous version. After you configure versioning for a bucket, you can recover objects in the bucket to a previous version to protect your data from being accidentally overwritten or deleted.

Scenarios

To ensure data security, we recommend that you configure versioning in the following scenarios:

  • Recover deleted data

    OSS does not provide the recycle bin feature. You can configure versioning to recover deleted data.

  • Recover overwritten data

    Online collaborative documents and documents stored in online storage are frequently modified. In online office scenarios, a large number of temporary versions are generated when objects are edited. You can configure versioning to recover the data of a specified object at a point in time.

Usage notes

  • Billing

    If you enable versioning for a bucket, you are charged for the storage of previous versions of objects in the bucket. To reduce storage costs, we recommend that you delete the previous versions of objects that you no longer need. When you download a previous version of an object or recover the previous version to the current version, fees are incurred by the requests and traffic. For more information, see Billing Overview.

  • Required permissions

    Only the bucket owner or RAM users who have the PutBucketVersioning permission can configure versioning for a bucket.

  • Feature conflicts
    • A bucket cannot have versioning and retention policies configured at the same time.
    • If versioning is enabled for a bucket, the x-oss-forbid-overwrite request header that is specified when an object is uploaded to the bucket does not take effect. For more information, see Request headers.
  • OSS-HDFS in versioned buckets

    We recommend that you do not enable the OSS-HDFS service and configure retention policies for a bucket.

    If you enable the OSS-HDFS service, configure a retention policy for a bucket, and then delete data from the .dlsdata/ directory by using the methods that are supported by the OSS-HDFS service, a message that indicates that the data is successfully deleted is displayed. However, OSS still retains the deleted data during the retention period that is specified for the retention policy and OSS cannot recognize and delete the data after the retention period expires.

Versioning states

A bucket can be in one of the following versioning states: disabled, enabled, and suspended.

  • By default, versioning is disabled for a bucket. After versioning is enabled for a bucket, the versioning state of the bucket cannot be set back to Disabled. However, you can suspend versioning for a bucket that has versioning enabled.
  • When an object is uploaded to a bucket for which versioning is enabled, OSS generates a random string as the globally unique version ID of the object. For more information about how to perform operations on objects in a versioned bucket, see Manage objects in a versioning-enabled bucket.
  • When an object is uploaded to a bucket for which versioning is suspended, OSS generates a string null as the version ID of the object. For more information about how to perform operations on objects in a bucket for which versioning is suspended, see Manage objects in a versioning-suspended bucket.
Note In a versioned bucket, all versions of an object are stored. These versions consume storage space and incur storage fees. To reduce storage costs, we recommend that you configure lifecycle rules to delete unnecessary previous versions or convert the storage class of current or previous object versions to Infrequent Access (IA) or Archive. For more information, see Configure lifecycle rules to manage object versions.

Data protection

The following table describes how OSS processes deleted and overwritten data in buckets with different versioning states to help you understand the data protection mechanism of versioning.

Versioning state Object overwriting Object deletion
Disabled The existing object is overwritten and cannot be recovered. Only the current object version can be accessed. The object is deleted and cannot be accessed.
Enabled A new version with a unique ID is generated for the object. The existing object is stored as a previous version. A delete marker with a globally unique version ID is added to the object as the current version. The existing object is stored as a previous version.
Suspended A new version whose version ID is null is generated for the object.

If the object already has a previous version or delete marker whose version ID is null, the previous version or delete marker is overwritten by the new version. Other previous versions or delete markers whose version IDs are not null are not affected.

A delete marker whose version ID is null is added to the object.

If the object already has a previous version or delete marker whose version ID is null, the previous version or delete marker is overwritten by the new version. Other previous versions or delete markers whose version IDs are not null are not affected.

The following examples provide figures to demonstrate how OSS processes data when an object with the same name as an existing object is uploaded to or an object is deleted from a bucket for which versioning is enabled or suspended. For ease of viewing, all version IDs in the figures are in the simple format.

  • Overwrite an object in a versioned bucket

    When you upload an object repeatedly to a versioned bucket, the object is overwritten multiple times. A version with a unique version ID is generated for the object each time when the object is overwritten.

    1
  • Delete an object from a versioned bucket

    When you delete an object from a versioned bucket, the previous versions of the object are not deleted and a delete marker is added to the object as the current version to indicate that the object is deleted. If you upload an object with the same name after the delete marker is added, a new version with a unique version ID is added as the current version.

    2
  • Overwrite an object in a bucket for which versioning is suspended

    When you upload an object to a bucket for which versioning is suspended, a new version whose version ID is null is added and the previous versions of the object are retained. If you upload an object with the same name again, a new version whose version ID is null overwrites the current version whose version ID is null.

    3
  • Delete an object from a bucket for which versioning is suspended

    When you delete an object from a bucket for which versioning is suspended, the previous versions of the object are not deleted and a delete marker is added to the object as the current version to indicate that the object is deleted.

    4

Therefore, deleted and overwritten data is stored as previous versions in a versioned bucket. After you configure versioning for a bucket, you can recover objects in the bucket to a previous version to protect your data from being accidentally overwritten or deleted.

Enable versioning

Use the OSS console

When versioning is enabled for a bucket, OSS specifies a unique ID for each version of an object stored in the bucket.

  • Enable versioning when you create a bucket
    1. Log on to the OSS console.
    2. In the left-side navigation pane, click Buckets. On the Buckets page, click Create Bucket.
    3. In the Create Bucket panel, configure the parameters.

      Set Versioning to Activate. For more information about how to configure other parameters, see Create buckets.

    4. Click OK.
  • Enable versioning for an existing bucket
    1. In the left-side navigation pane, click Buckets. On the Buckets page, click the name of the bucket for which you want to enable versioning.
    2. In the left-side navigation pane, choose Redundancy for Fault Tolerance > Versioning.
    3. Click Configure. Set Versioning to Enabled.
    4. Click Save.

After versioning is enabled for a bucket, you can view all versions of objects in the bucket on the Files page. If you want to view only the current versions of objects, set Display Previous Versions to Hide. Hiding previous versions of objects does not increase the response speed when you list objects. If the response speed is slow when you list objects, see Low response speed to troubleshoot and fix the problem.

Use OSS SDKs

The following code provides examples on how to enable versioning for a bucket by using OSS SDKs for common programming languages. For more information about how to enable versioning for a bucket by using OSS SDKs for other programming languages, see Overview.

// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";

// Create an OSSClient instance. 
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// Set the versioning state of the bucket to Enabled. 
BucketVersioningConfiguration configuration = new BucketVersioningConfiguration();
configuration.setStatus(BucketVersioningConfiguration.ENABLED);
SetBucketVersioningRequest request = new SetBucketVersioningRequest(bucketName, configuration);
ossClient.setBucketVersioning(request);

// Shut down the OSSClient instance. 
ossClient.shutdown();
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\OssClient;
use OSS\Core\OssException;

// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
$accessKeyId = "<yourAccessKeyId>";
$accessKeySecret = "<yourAccessKeySecret>";
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";

$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

try {
    // Set the versioning state of the bucket to Enabled. 
    $ossClient->putBucketVersioning($bucket, "Enabled");
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}

print(__FUNCTION__ . ": OK" . "\n");
const OSS = require('ali-oss');

const client = new OSS({
  bucket: '<Your BucketName>',
  // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to oss-cn-hangzhou. 
  region: '<Your Region>',
  // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>'
});

async function putBucketVersioning() {
  // Set the versioning state of the bucket to Enabled. 
  const status = 'Enabled';
  const result = await client.putBucketVersioning('<Bucket Name>', status);
  console.log(result);
}
putBucketVersioning();
# -*- coding: utf-8 -*-
import oss2
from oss2.models import BucketVersioningConfig

# The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')

# Initialize the versioning configurations for the bucket. 
config = BucketVersioningConfig()
# Set the versioning state of the bucket to Enabled. 
config.status = oss2.BUCKET_VERSIONING_ENABLE

# Configure versioning for the bucket. 
result = bucket.put_bucket_versioning(config)
# Display the HTTP status code. 
print('http response code:', result.status)
using Aliyun.OSS;
// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
var endpoint = "yourEndpoint";
// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
var accessKeyId = "yourAccessKeyId";
var accessKeySecret = "yourAccessKeySecret";
// Specify the name of the bucket. Example: examplebucket. 
var bucketName = "examplebucket";
// Initialize an OSSClient instance. 
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    // Set the versioning state of the bucket to Enabled. 
    client.SetBucketVersioning(new SetBucketVersioningRequest(bucketName, VersioningStatus.Enabled));;
    Console.WriteLine("Create bucket Version succeeded");
}
catch (Exception ex)
{
    Console.WriteLine("Create bucket Version failed. {0}", ex.Message);
}
package main

import (
  "fmt"
  "os"

  "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
  // Create an OSSClient instance. 
  client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }

  // Create a bucket. 
  err = client.CreateBucket("<yourBucketName>")
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
  // Set the versioning state of the bucket to Enabled. 
  config := oss.VersioningConfig{Status: "Enabled"}
  err = client.SetBucketVersioning("<yourBucketName>", config)
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    std::string Endpoint = "yourEndpoint";
    std::string BucketName = "yourBucketName";

    /* Initialize resources such as networks. */
    InitializeSdk();

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);

    /* Set the versioning state of the bucket to Enabled. */
    SetBucketVersioningRequest setrequest(BucketName, VersioningStatus::Enabled);
    auto outcome = client.SetBucketVersioning(setrequest);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "SetBucketVersioning fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* Release resources such as networks. */
    ShutdownSdk();
    return 0;
}

Use ossutil

For more information about how to enable versioning for a bucket by using ossutil, see Configure the versioning status of a bucket.

Use RESTful APIs

If your business requires a high level of customization, you can directly call RESTful APIs. To directly call an API, you must include the signature calculation in your code. For more information, see PutBucketVersioning.

Suspend versioning

Use the OSS console

You can suspend versioning for a versioned bucket to stop OSS from generating new versions for objects. If a new version is generated for an object in a versioning-suspended bucket, OSS sets the ID of the new version to null and retains the previous versions of the object.

To suspend versioning for a bucket, perform the following steps:

  1. In the left-side navigation pane, click Buckets. On the Buckets page, click the name of the bucket for which you want to suspend versioning.
  2. In the left-side navigation pane, choose Redundancy for Fault Tolerance > Versioning.
  3. Click Configure and then set the versioning state to Suspended.
  4. Click Save.

Use OSS SDKs

The following code provides examples on how to suspend versioning for a bucket by using OSS SDKs for common programming languages. For more information about how to suspend versioning for a bucket by using OSS SDKs for other programming languages, see Overview.

// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";

// Create an OSSClient instance. 
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// Set the versioning state of the bucket to Suspended. 
BucketVersioningConfiguration configuration = new BucketVersioningConfiguration();
configuration.setStatus(BucketVersioningConfiguration.SUSPENDED);
SetBucketVersioningRequest request = new SetBucketVersioningRequest(bucketName, configuration);
ossClient.setBucketVersioning(request);

// Shut down the OSSClient instance. 
ossClient.shutdown();
                
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\OssClient;
use OSS\Core\OssException;

// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
$accessKeyId = "<yourAccessKeyId>";
$accessKeySecret = "<yourAccessKeySecret>";
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";

$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

try {
    // Set the versioning state of the bucket to Suspended. 
    $ossClient->putBucketVersioning($bucket, "Suspended");
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}

print(__FUNCTION__ . ": OK" . "\n");
const OSS = require('ali-oss');

const client = new OSS({
  bucket: '<Your BucketName>',
  // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to oss-cn-hangzhou. 
  region: '<Your Region>',
  // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>'
});

async function putBucketVersioning() {
  // Set the versioning state of the bucket to Suspended. 
  const status = 'Suspended'; 
  const result = await client.putBucketVersioning('<Bucket Name>', status);
  console.log(result);
}
putBucketVersioning();
# -*- coding: utf-8 -*-
import oss2
from oss2.models import BucketVersioningConfig

# The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')

# Initialize the versioning configurations for the bucket. 
config = BucketVersioningConfig()
# Set the versioning state of the bucket to Suspended. 
config.status = oss2.BUCKET_VERSIONING_SUSPEND

# Configure versioning for the bucket. 
result = bucket.put_bucket_versioning(config)
# Display the HTTP status code. 
print('http response code:', result.status)
using Aliyun.OSS;
var endpoint = "<yourEndpoint>";
var accessKeyId = "<yourAccessKeyId>";
var accessKeySecret = "<yourAccessKeySecret>";
var bucketName = "<yourBucketName>";
// Initialize an OSSClient instance. 
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    // Set the versioning state of the bucket to Suspended. 
    client.SetBucketVersioning(new SetBucketVersioningRequest(bucketName, VersioningStatus.Suspended));;
    Console.WriteLine("Create bucket Version succeeded");
}
catch (Exception ex)
{
    Console.WriteLine("Create bucket Version failed. {0}", ex.Message);
}
package main

import (
  "fmt"
  "os"

  "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
  // Create an OSSClient instance. 
  client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }

  // Create a bucket. 
  err = client.CreateBucket("<yourBucketName>")
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
  // Set the versioning state of the bucket to Suspended. 
  config := oss.VersioningConfig{Status: "Suspended"}
  err = client.SetBucketVersioning("<yourBucketName>", config)
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    std::string Endpoint = "yourEndpoint";
    std::string BucketName = "yourBucketName";

    /* Initialize resources such as networks. */
    InitializeSdk();

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);

    /* Set the versioning state of the bucket to Suspended.*/
    SetBucketVersioningRequest setrequest(BucketName, VersioningStatus::Suspended);
    auto outcome = client.SetBucketVersioning(setrequest);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "SetBucketVersioning fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* Release resources such as networks. */
    ShutdownSdk();
    return 0;
}

Use ossutil

For more information about how to suspend versioning for a bucket by using ossutil, see Configure the versioning status of a bucket.

Use RESTful APIs

If your business requires a high level of customization, you can directly call RESTful APIs. To directly call an API, you must include the signature calculation in your code. For more information, see PutBucketVersioning.