

# 在存储桶上启用版本控制
<a name="manage-versioning-examples"></a>

您可以使用 S3 版本控制在一个存储桶中保留对象的多个版本。本部分提供了如何使用控制台、REST API、AWS SDK 和 AWS Command Line Interface（AWS CLI）在存储桶上启用版本控制的示例。

**注意**  
首次在存储桶上启用版本控制后，更改可能需要长达 15 分钟才能在 S3 系统中完全传播。在此期间，对启用版本控制后创建或更新的对象的 `GET` 请求可能会导致 `HTTP 404 NoSuchKey` 错误。我们建议在启用版本控制后等待 15 分钟，然后再对存储桶中的对象执行任何写入操作（`PUT` 或 `DELETE`）。此等待期有助于避免在对象可见性和版本跟踪方面可能出现的问题。

有关 S3 版本控制的更多信息，请参阅[使用 S3 版本控制保留对象的多个版本](Versioning.md)。有关使用已启用版本控制的存储桶中的对象的信息，请参阅 [使用启用版本控制的存储桶中的对象](manage-objects-versioned-bucket.md)。

要了解有关如何使用 S3 版本控制保护数据的更多信息，请参阅[教程：使用 S3 版本控制、S3 对象锁定和 S3 复制保护 Amazon S3 上的数据免遭意外删除或应用程序错误](https://aws.amazon.com/getting-started/hands-on/protect-data-on-amazon-s3/?ref=docs_gateway/amazons3/manage-versioning-examples.html)。

您创建的每个 S3 存储桶都具有关联的 *versioning* 子资源。（有关更多信息，请参阅 [通用存储桶配置选项](UsingBucket.md#bucket-config-options-intro)。） 默认情况下，您的存储桶*不受版本控制*，且对子资源进行版本控制会存储空的版本控制配置，如下所示。

```
<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 
</VersioningConfiguration>
```

要启用版本控制，您可以向 Amazon S3 发送一个请求，在请求中指定包含状态的版本控制配置。

```
<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 
  <Status>Enabled</Status> 
</VersioningConfiguration>
```

要暂停版本控制，请将状态值设置为 `Suspended`。

存储桶拥有者和所有授权用户都可以启用版本控制。存储桶拥有者是创建存储存储桶的 AWS 账户（根账户）。有关许可的更多信息，请参阅[Amazon S3 的身份和访问管理](security-iam.md)。

以下部分提供了有关使用控制台、AWS CLI 和 AWS SDK 启用 S3 版本控制的更多详细信息。

## 使用 S3 控制台
<a name="enable-versioning"></a>

请按照以下步骤使用 AWS 管理控制台 在 S3 存储桶上启用版本控制。

**在 S3 通用存储桶上启用或禁用版本控制**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在左侧导航窗格中，选择**通用存储桶**。

1. 在存储桶列表中，选择要为其启用版本控制的存储桶的名称。

1. 请选择**属性**。

1. 在**存储桶版本控制**下，请选择**编辑**。

1. 请选择 **Suspend (暂停)** 或 **Enable (启用)**，然后选择 **Save changes (保存更改)**。

**注意**  
您可以将 AWS Multi-Factor Authentication (MFA) 与版本控制结合使用。将 MFA 与版本控制结合使用时，您必须提供 AWS 账户的访问密钥和账户 MFA 设备中的有效代码，才能永久删除对象版本或暂停或重新激活版本控制。  
要将 MFA 与版本控制结合使用，请启用 `MFA Delete`。但是，您无法使用 AWS 管理控制台 启用 `MFA Delete`。您必须使用 AWS Command Line Interface (AWS CLI) 或 API。有关更多信息，请参阅 [配置 MFA 删除](MultiFactorAuthenticationDelete.md)。

## 使用 AWS CLI
<a name="manage-versioning-examples-cli"></a>

以下示例在 S3 通用存储桶上启用版本控制。

```
aws s3api put-bucket-versioning --bucket {{amzn-s3-demo-bucket1}} --versioning-configuration Status=Enabled
```

以下示例在存储桶上为物理 MFA 设备启用 S3 版本控制和多重身份验证（MFA）删除。对于物理 MFA 设备，在 `--mfa` 参数中，传递 MFA 设备序列号、空格字符和身份验证设备上显示的值的串联。

```
aws s3api put-bucket-versioning --bucket {{amzn-s3-demo-bucket1}} --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa "{{SerialNumber 123456}}"
```

以下示例在存储桶上为虚拟 MFA 设备启用 S3 版本控制和多重身份验证（MFA）删除。对于虚拟 MFA 设备，在 `--mfa` 参数中，传递 MFA 设备 ARN、空格字符和身份验证设备上显示的值的串联。

```
aws s3api put-bucket-versioning --bucket {{amzn-s3-demo-bucket1}} --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa "arn:aws:iam::{{account-id}}:mfa/root-account-mfa-device {{123789}}"
```

**注意**  
使用 MFA 删除需要获得批准的物理或虚拟身份验证设备。有关在 Amazon S3 中使用 MFA 删除的更多信息，请参阅[配置 MFA 删除](MultiFactorAuthenticationDelete.md)。

有关使用 AWS CLI 启用版本控制的更多信息，请参阅《AWS CLI 命令参考》**中的 [put-bucket-versioning](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-versioning.html)。

## 使用 AWS SDK
<a name="manage-versioning-examples-sdk"></a>

以下示例在存储桶上启用版本控制，然后使用 适用于 Java 的 AWS SDK 和 适用于 .NET 的 AWS SDK 检索版本控制状态。有关使用其他 AWS SDK 的信息，请参阅 [AWS 开发人员中心](https://aws.amazon.com/code/)。

------
#### [ .NET ]

有关设置和运行代码示例的信息，请参阅《适用于 .NET 的 AWS SDK 开发人员指南》**中的[适用于 .NET 的 AWS SDK 入门](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。

```
using System;
using Amazon.S3;
using Amazon.S3.Model;

namespace s3.amazon.com.rproxy.govskope.us.docsamples
{
    class BucketVersioningConfiguration
    {
        static string bucketName = "*** bucket name ***";

        public static void Main(string[] args)
        {
            using (var client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1))
            {
                try
                {
                    EnableVersioningOnBucket(client);
                    string bucketVersioningStatus = RetrieveBucketVersioningConfiguration(client);
                }
                catch (AmazonS3Exception amazonS3Exception)
                {
                    if (amazonS3Exception.ErrorCode != null &&
                        (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId")
                        ||
                        amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
                    {
                        Console.WriteLine("Check the provided AWS Credentials.");
                        Console.WriteLine(
                        "To sign up for service, go to http://aws.amazon.com/s3");
                    }
                    else
                    {
                        Console.WriteLine(
                         "Error occurred. Message:'{0}' when listing objects",
                         amazonS3Exception.Message);
                    }
                }
            }

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }

        static void EnableVersioningOnBucket(IAmazonS3 client)
        {

                PutBucketVersioningRequest request = new PutBucketVersioningRequest
                {
                    BucketName = bucketName,
                    VersioningConfig = new S3BucketVersioningConfig 
                    {
                        Status = VersionStatus.Enabled
                    }
                };

                PutBucketVersioningResponse response = client.PutBucketVersioning(request);
        }


        static string RetrieveBucketVersioningConfiguration(IAmazonS3 client)
        {
                GetBucketVersioningRequest request = new GetBucketVersioningRequest
                {
                    BucketName = bucketName
                };
 
                GetBucketVersioningResponse response = client.GetBucketVersioning(request);
                return response.VersioningConfig.Status;
            }
    }
}
```

------
#### [ Java ]

有关如何创建和测试有效示例的说明，请参阅《适用于 Java 的 AWS SDK 开发人员指南》中的[入门](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/getting-started.html)。

```
import java.io.IOException;

import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.amazonaws.services.s3.model.BucketVersioningConfiguration;
import com.amazonaws.services.s3.model.SetBucketVersioningConfigurationRequest;

public class BucketVersioningConfigurationExample {
    public static String bucketName = "*** bucket name ***"; 
    public static AmazonS3Client s3Client;

    public static void main(String[] args) throws IOException {
        s3Client = new AmazonS3Client(new ProfileCredentialsProvider());
        s3Client.setRegion(Region.getRegion(Regions.US_EAST_1));
        try {

            // 1. Enable versioning on the bucket.
        	BucketVersioningConfiguration configuration = 
        			new BucketVersioningConfiguration().withStatus("Enabled");
            
			SetBucketVersioningConfigurationRequest setBucketVersioningConfigurationRequest = 
					new SetBucketVersioningConfigurationRequest(bucketName,configuration);
			
			s3Client.setBucketVersioningConfiguration(setBucketVersioningConfigurationRequest);
			
			// 2. Get bucket versioning configuration information.
			BucketVersioningConfiguration conf = s3Client.getBucketVersioningConfiguration(bucketName);
			 System.out.println("bucket versioning configuration status:    " + conf.getStatus());

        } catch (AmazonS3Exception amazonS3Exception) {
            System.out.format("An Amazon S3 error occurred. Exception: %s", amazonS3Exception.toString());
        } catch (Exception ex) {
            System.out.format("Exception: %s", ex.toString());
        }        
    }
}
```

------
#### [ Python ]

以下 Python 代码示例创建一个 Amazon S3 存储桶，启用它进行版本控制，并配置一个在 7 天后使非当前对象版本过期的生命周期。

```
def create_versioned_bucket(bucket_name, prefix):
    """
    Creates an Amazon S3 bucket, enables it for versioning, and configures a lifecycle
    that expires noncurrent object versions after 7 days.

    Adding a lifecycle configuration to a versioned bucket is a best practice.
    It helps prevent objects in the bucket from accumulating a large number of
    noncurrent versions, which can slow down request performance.

    Usage is shown in the usage_demo_single_object function at the end of this module.

    :param bucket_name: The name of the bucket to create.
    :param prefix: Identifies which objects are automatically expired under the
                   configured lifecycle rules.
    :return: The newly created bucket.
    """
    try:
        bucket = s3.create_bucket(
            Bucket=bucket_name,
            CreateBucketConfiguration={
                "LocationConstraint": s3.meta.client.meta.region_name
            },
        )
        logger.info("Created bucket %s.", bucket.name)
    except ClientError as error:
        if error.response["Error"]["Code"] == "BucketAlreadyOwnedByYou":
            logger.warning("Bucket %s already exists! Using it.", bucket_name)
            bucket = s3.Bucket(bucket_name)
        else:
            logger.exception("Couldn't create bucket %s.", bucket_name)
            raise

    try:
        bucket.Versioning().enable()
        logger.info("Enabled versioning on bucket %s.", bucket.name)
    except ClientError:
        logger.exception("Couldn't enable versioning on bucket %s.", bucket.name)
        raise

    try:
        expiration = 7
        bucket.LifecycleConfiguration().put(
            LifecycleConfiguration={
                "Rules": [
                    {
                        "Status": "Enabled",
                        "Prefix": prefix,
                        "NoncurrentVersionExpiration": {"NoncurrentDays": expiration},
                    }
                ]
            }
        )
        logger.info(
            "Configured lifecycle to expire noncurrent versions after %s days "
            "on bucket %s.",
            expiration,
            bucket.name,
        )
    except ClientError as error:
        logger.warning(
            "Couldn't configure lifecycle on bucket %s because %s. "
            "Continuing anyway.",
            bucket.name,
            error,
        )

    return bucket
```

------