简介
在云存储领域,数据的安全性始终是悬在头顶的达摩克利斯之剑。长期以来,腾讯云对象存储服务(COS)一直致力于数据安全的探索和实践,以保障数据的安全性和完整性。本文将详细介绍如何防止误删数据以及误删后的恢复手段。
数据防误删
背景
在企业的日常运营中,数据的安全性面临着多种威胁,包括内部人员的误操作、恶意软件的攻击,甚至是外部黑客的入侵。这些风险可能导致重要数据的丢失或泄露,带来不可估量的损失。
详细介绍和操作步骤
COS 通过访问控制、对象锁定、MFA 操作保护、版本控制、存储桶复制、回收站等功能,构建了数据安全的第一道防线,以降低误删风险。相关功能的介绍和操作步骤详见下文。
访问控制确保只有授权用户才能执行敏感操作,如删除数据;
对象锁定则保证了一旦数据被写入,就不能被修改或删除,除非达到了预设的锁定期限;
MFA 操作保护为用户的敏感操作提供了一层额外的安全保障,对敏感操作系统会要求二次确认;
版本控制和存储桶复制可以有效地备份数据,并提前预防误删事件的发生;
回收站就像一个临时存储站点,可以拦截并保留下来被误删的文件,误删后支持一键回滚,进一步降低数据丢失风险。
访问控制
概述
默认情况下,COS 资源(包括 Bucket 和 Object)都是私有权限,只有资源拥有者或者被授权的用户允许访问。若希望规定什么人在什么条件下可以对什么资源进行什么操作,可以结合 最小权限原则 通过多种设置权限的方式实现访问控制。按照策略出发点,可划分为基于资源和基于用户两种方式,分别包括存储桶策略、存储桶 ACL 、对象 ACL 和用户策略(CAM 策略)。关于策略的更多介绍请参见 访问控制基本概念。
通过下述操作,COS 确保了数据的安全性和灵活性,让您能够根据实际业务需求,为不同的用户和应用场景配置合适的访问权限。
操作指南
存储桶策略
您可以通过存储桶策略为 CAM 子账号、其他主账号、甚至匿名用户授权存储桶和对象的操作权限。COS 支持使用控制台、API、SDK 等多种方式添加存储桶策略。以下介绍控制台图形化界面的操作步骤,更多使用方法和描述请参见 存储桶策略。
1. 登录 对象存储控制台。
2. 进入目标存储桶的权限管理,选择 Policy 权限设置 > 图形设置,单击添加策略,在弹窗中进行策略配置。
3. 选择模版(可选):COS 为您提供了多种策略模板,帮助您快速配置存储桶策略,可按需选择。详细操作步骤和配置说明参见 添加存储桶策略。
4. 配置策略:若推荐模板不符合您的需求,可在此步骤对策略内容进行调整,添加、删除被授权用户、资源和操作、条件(可选)。
存储桶 ACL 和对象 ACL
ACL 使用 XML 语言描述,是与资源关联的一个指定被授权者和授予权限的列表,支持向匿名用户或其他主账号授予基本的读写权限。以下是一个存储桶 ACL 示例,描述存储桶拥有者(用户 UIN:100000000001)的完全控制权限,更多内容和示例可参考 ACL。
<AccessControlPolicy><Owner><ID>qcs::cam::uin/100000000001:uin/100000000001</ID></Owner><AccessControlList><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="RootAccount"><ID>qcs::cam::uin/100000000001:uin/100000000001</ID></Grantee><Permission>FULL_CONTROL</Permission></Grant></AccessControlList></AccessControlPolicy>
用户策略(CAM 策略)
用户可以在 访问管理 中,对于主账号名下的不同类型用户,授予不同的权限。您可以 使用预设策略进行关联授权,也可以自行撰写用户策略(策略写法请参见 元素参考)后关联到指定的身份,来实现对名下用户的访问管理。以下介绍通过预设策略关联用户的操作步骤,更多内容请参见 用户策略 文档。
1. 登录 CAM控制台。
2. 进入策略页面,选择预设策略,搜索筛选 COS,单击关联用户组/角色。
3. 在弹出页面勾选要关联的用户,单击确定即可完成通过策略关联用户操作。
对象锁定
概述
COS 的对象锁定(WORM:Write Once Read More)功能为存储桶内的对象提供了一种数据保护机制。通过设定保留时间,将对象在该期限内锁定为只读状态,禁止覆盖写或删除。这一特性十分适用于保护关键敏感数据,确保一旦数据被上传,其完整性和安全性得到一定期限的保障,防止未授权的变更或删除。
说明:
操作指南
1. 登录 对象存储控制台。
2. 进入目标存储桶的安全管理,选择对象锁定,单击编辑并配置保留时间,点击保存即可开启对象锁定功能。
MFA 操作保护
概述
操作保护是一种在用户执行敏感操作时提供的额外安全层,MFA 是其中一种保护类型。通过启用MFA,用户在执行敏感操作,如删除数据或更改关键配置时,需要提供额外的验证信息。这增加了一个重要的安全层,以防止未授权的访问或误操作导致的误删。更多内容请参见 操作保护 和 绑定虚拟 MFA 设备。
操作指南
2. 在基本设置栏中,找到 MFA 设备,单击绑定,根据页面提示完成身份验证。
3. 按需选择不同的 MFA 设备,并根据页面指引完成安装操作,勾选操作保护,单击提交即可完成绑定。
4. 进入文件列表页,单击 清空存储桶 ,此时会弹出 MFA 校验二次确认,进一步降低误删的风险。
版本控制
概述
开启版本控制后,所有同名文件的写操作都会视同新增不同版本的同名文件,删除操作等同于新增一项 删除标记,可通过指定版本 ID 查询、删除或还原过去任意版本的数据,实现数据的回滚操作。更多介绍请参见 版本控制概述。
操作指南
1. 登录 对象存储控制台。
2. 进入目标存储桶的容错容灾管理,选择版本控制,单击编辑开启状态,保存即可开启版本控制。更详细的操作步骤和限制说明请参见 设置版本控制。
3. 开启后,进入文件列表页,单击列出历史版本,可查看所有版本并对其进行管理。
存储桶复制
概述
COS 的存储桶复制功能,帮助用户将所有增量文件通过专线复制到其他城市的数据中心,实现异地容灾的作用,支持同地域和跨地域备份。当主存储桶中的数据被删除时,可从备份存储桶中通过批量拷贝的方式恢复数据,更多介绍请参见 存储桶复制概述。
操作指南
1. 登录 对象存储控制台。
2. 进入目标存储桶的容错容灾管理,选择存储桶复制,单击新增规则,配置项说明请参见 设置存储桶复制。
3. 您可以选择复制整个存储桶或指定范围内的对象到目标桶。
4. 支持同地域复制和跨地域复制,点击确定即可完成创建存储桶复制规则。
5. 支持在列表查看已配置的规则,配置后系统将按照规则对源存储桶中的增量对象进行自动、异步地复制到的目标存储桶中。
回收站
数据误删追溯
即使数据安全有了第一道防线保障,数据误删除的威胁依旧不可忽视。无论是操作失误还是系统故障引发的数据丢失,都可能对企业带来严重影响。在这种情况下,数据的可追溯性变得至关重要。COS 提供日志管理功能帮助用户实时追踪、记录和分析每一次数据访问,方便对异常事件进行追溯,确保数据的可追溯性。
通过日志检索追溯
1. 登录 对象存储控制台。
2. 进入日志检索页面,添加检索条件,配置 reqMethod 包含 DELETE,并选择好时间范围。
3. 单击搜索即可查询出执行了 DELETE 请求的结果。如下图所示,txttt 文件于5月16日20点22分被用户100xxxxxxxxx执行了删除操作。
通过清单追溯
1. 登录 对象存储控制台。
2. 进入清单设置页面,添加清单或选择已有清单去生成一份即时清单,操作步骤请参见 生成即时清单。
3. 其中,添加清单的基础配置信息如下,按需选择目标存储桶和清单报告生成路径,关于路径介绍请参见 清单报告存储路径。
4. 在清单配置过程中,您可根据实际场景按需填写筛选条件,对象版本需要选择“包括所有版本”,其他参数配置说明请参见 设置清单。以下为几种常用场景示例:
若您已知删除了指定前缀对象,文件范围建议选择“指定文件前缀”并填写对应前缀。
若您已知数据删除动作是发生在某时间点之后或指定范围内,筛选时间建议选择“指定时间点之后的所有对象”或“指定时间范围内的对象”并填写范围。
5. 清单导出后,单击预览清单。
6. 筛选日期和清单目录之后,找到所需清单,单击查看清单结果。
7. 单击下载,即可下载生成的清单文件信息,下载后需要进行解压缩。
8. 解压之后的 CSV 文件描述了对象信息,您可以根据 IsDeleteMarker 和 LastModifiedDate 确定被删除的对象。其中,CSV 文件对应的字段名称可在 manifest.json 文件的“fileSchema”中查看,更多字段含义和描述请参见 清单参数。
数据误删恢复
数据的可恢复性是基于多版本提供回收站、存储桶复制等一系列功能和方法来健全误删恢复体系。即使最新版本被误删除或覆盖,也可以恢复到之前的任何一个版本。上面已经介绍了基于多版本的 版本控制、存储桶复制,这里就不再赘述。
COS支持使用以下功能或方法恢复被误删的数据:通过回收站、存储桶复制+批量处理、清单+批量处理、SDK、API实现恢复数据,您可以根据实际业务场景按需选择。
通过回收站恢复
1. 登录 对象存储控制台。
2. 进入目标存储桶的回收站列表,确保已开启回收站功能,支持清空历史版本和批量还原。
3. 按需选择对应的文件,单击批量还原,即可完成数据恢复。
4. 若您需要定期清理回收站内的历史版本和无历史版本的删除标记,请先 设置生命周期 进行删除。
5. 除此之外,进入回收站管理页面,COS 也支持对多个存储桶开启回收站功能。
通过存储桶复制+批量处理恢复
1. 登录 对象存储控制台。
2. 进入批量处理,单击创建批量任务。
3. 填写任务名称,任务类型选择批量数据复制,其他配置项请参见 批量处理操作步骤 按需进行配置,单击下一步。
4. 在操作配置页进行更详细的操作配置,配置说明请参见 批量处理操作步骤 按需进行配置,单击下一步。
5. 在其他配置页进行更详细的操作配置,配置说明请参见 批量处理操作步骤 按需进行配置,单击下一步。
6. 最后,确认信息无误后,单击创建并启动即可完成创建批量数据复制任务。
7. 在任务列表中可查看已创建任务状态,并支持克隆或取消任务。
通过清单+批量处理恢复
1. 登录 对象存储控制台。
2. 经过清单确定被删除的对象之后,保留一份 csv 文件,上传至某个存储桶。
3. 进入批量处理,单击创建批量任务。
4. 填写任务名称,任务类型选择批量数据复制。
5. 清单报告选择“有”,清单路径选择第 2 步已上传的 csv 文件存储路径。其他配置项请参见 批量处理操作步骤 按需进行配置,单击下一步。
6. 最后,确认信息无误后,单击创建并启动即可完成创建批量数据复制任务。
7. 在任务列表中可查看已创建任务状态,并支持克隆或取消任务。
通过 SDK 恢复
目前 Go SDK 已提供从原桶批量恢复、从备份桶批量恢复这两种方式的示例代码,Java SDK 提供从备份桶批量恢复的示例代码,更多 SDK 持续优化中,敬请期待。
示例代码
操作步骤如下:
1. 确保已下载 COS 的 XML Go SDK 源码,并且安装好环境,详情请参见 Go SDK快速入门。
2. 复制以下代码,如需查看 Git示例请前往 GitHub。
package mainimport ("context""fmt""os""net/url""net/http""github.com/tencentyun/cos-go-sdk-v5""github.com/tencentyun/cos-go-sdk-v5/debug")func log_status(err error) {if err == nil {return}if cos.IsNotFoundError(err) {// WARNfmt.Println("WARN: Resource is not existed: %v", err)} else if e, ok := cos.IsCOSError(err); ok {fmt.Printf("ERROR: Code: %v\\n", e.Code)fmt.Printf("ERROR: Message: %v\\n", e.Message)fmt.Printf("ERROR: Resource: %v\\n", e.Resource)fmt.Printf("ERROR: RequestId: %v\\n", e.RequestID)// ERROR} else {fmt.Printf("ERROR: %v\\n", err)// ERROR}}var (srcBucket = "test-1259654469"srcBucketRegion = "ap-guangzhou"srcCosClient *cos.ClientcopyObjs = map[string]struct{}{})func newClient(bucket, region string) *cos.Client {u, _ := url.Parse(fmt.Sprintf("https://%v.cos.%v.myqcloud.com", bucket, region))b := &cos.BaseURL{BucketURL: u,}return cos.NewClient(b, &http.Client{Transport: &cos.AuthorizationTransport{SecretID: os.Getenv("COS_SECRETID"),SecretKey: os.Getenv("COS_SECRETKEY"),Transport: &debug.DebugRequestTransport{RequestHeader: false,RequestBody: false,ResponseHeader: false,ResponseBody: false,},},})}func recoverObj(key, versionId string) {sourceURL := fmt.Sprintf("%v.cos.%v.myqcloud.com/%v?versionId=%v", srcBucket, srcBucketRegion, key, versionId)_, _, err := srcCosClient.Object.MultiCopy(context.Background(), key, sourceURL, nil)if err != nil {log_status(err)}}func main() {srcCosClient = newClient(srcBucket, srcBucketRegion)keyMarker := ""versionIdMarker := ""isTruncated := trueopt := &cos.BucketGetObjectVersionsOptions{EncodingType: "url",}for isTruncated {opt.KeyMarker = keyMarkeropt.VersionIdMarker = versionIdMarkerv, _, err := srcCosClient.Bucket.GetObjectVersions(context.Background(), opt)if err != nil {log_status(err)break}for _, vc := range v.DeleteMarker {if vc.IsLatest {// 对象被删除,需要恢复copyObjs[vc.Key] = struct{}{}}}for _, vc := range v.Version {// 按最新恢复if _, ok := copyObjs[vc.Key]; ok {delete(copyObjs, vc.Key)key, _ := cos.DecodeURIComponent(vc.Key)fmt.Printf("key: %v, versionId: %v\\n", key, vc.VersionId)recoverObj(key, vc.VersionId)}}keyMarker = v.NextKeyMarkerversionIdMarker = v.NextVersionIdMarkerisTruncated = v.IsTruncated}}
3. 根据实际情况填写指定参数:包括原桶名称、原桶的 region、secretId 和 secretKey。
注意:
原桶需要开启版本控制功能。
4. 运行object_recover2.go文件,运行成功后即可恢复被删除的数据。
操作步骤如下:
1. 确保已下载 COS 的 XML Go SDK 源码,并且安装好环境,详情请参见 Go SDK快速入门。
2. 复制以下代码,如需查看 Git示例请前往 GitHub。
package mainimport ("context""fmt""os""net/url""net/http""github.com/tencentyun/cos-go-sdk-v5""github.com/tencentyun/cos-go-sdk-v5/debug")func log_status(err error) {if err == nil {return}if cos.IsNotFoundError(err) {// WARNfmt.Println("WARN: Resource is not existed: %v", err)} else if e, ok := cos.IsCOSError(err); ok {fmt.Printf("ERROR: Code: %v\\n", e.Code)fmt.Printf("ERROR: Message: %v\\n", e.Message)fmt.Printf("ERROR: Resource: %v\\n", e.Resource)fmt.Printf("ERROR: RequestId: %v\\n", e.RequestID)// ERROR} else {fmt.Printf("ERROR: %v\\n", err)// ERROR}}var (srcBucket = "test-1259654469"dstBucket = "test2-1259654469"srcBucketRegion = "ap-guangzhou"dstBucketRegion = "ap-guangzhou"srcCosClient *cos.ClientdstCosClient *cos.Client)func newClient(bucket, region string) *cos.Client {u, _ := url.Parse(fmt.Sprintf("https://%v.cos.%v.myqcloud.com", bucket, region))b := &cos.BaseURL{BucketURL: u,}return cos.NewClient(b, &http.Client{Transport: &cos.AuthorizationTransport{SecretID: os.Getenv("COS_SECRETID"),SecretKey: os.Getenv("COS_SECRETKEY"),Transport: &debug.DebugRequestTransport{RequestHeader: false,RequestBody: false,ResponseHeader: false,ResponseBody: false,},},})}func recoverObj(key, versionId string) {sourceURL := fmt.Sprintf("%v.cos.%v.myqcloud.com/%v?versionId=%v", srcBucket, srcBucketRegion, key, versionId)_, _, err := dstCosClient.Object.MultiCopy(context.Background(), key, sourceURL, nil)if err != nil {log_status(err)}}func main() {srcCosClient = newClient(srcBucket, srcBucketRegion)dstCosClient = newClient(dstBucket, dstBucketRegion)keyMarker := ""versionIdMarker := ""isTruncated := trueopt := &cos.BucketGetObjectVersionsOptions{EncodingType: "url",}var preKey stringfor isTruncated {opt.KeyMarker = keyMarkeropt.VersionIdMarker = versionIdMarkerv, _, err := srcCosClient.Bucket.GetObjectVersions(context.Background(), opt)if err != nil {log_status(err)break}for _, vc := range v.Version {// 最新非deletemarker对象if preKey != vc.Key {preKey = vc.Keykey, _ := cos.DecodeURIComponent(vc.Key)fmt.Printf("key: %v, versionId: %v, lastest: %v\\n", key, vc.VersionId, vc.IsLatest)recoverObj(key, vc.VersionId)}}keyMarker = v.NextKeyMarkerversionIdMarker = v.NextVersionIdMarkerisTruncated = v.IsTruncated}}
3. 根据实际情况填写指定参数:包括备份桶名称、目标桶名称、备份桶的 region、目标桶的 region、secretId 和 secretKey。
注意:
备份桶和目标桶均需要开启版本控制功能。
4. 运行object_recover.go文件,运行成功后即可恢复被删除的数据。
操作步骤如下:
1. 确保已下载 COS 的 XML Java SDK 源码,并且安装好环境,详情请参见 Java SDK快速入门。
2. 复制以下代码,如需查看 Git示例请前往 GitHub。
import com.qcloud.cos.COSClient;import com.qcloud.cos.ClientConfig;import com.qcloud.cos.auth.BasicCOSCredentials;import com.qcloud.cos.auth.COSCredentials;import com.qcloud.cos.exception.CosClientException;import com.qcloud.cos.exception.CosServiceException;import com.qcloud.cos.http.HttpProtocol;import com.qcloud.cos.model.COSVersionSummary;import com.qcloud.cos.model.CopyObjectRequest;import com.qcloud.cos.model.CopyObjectResult;import com.qcloud.cos.model.ListVersionsRequest;import com.qcloud.cos.model.VersionListing;import com.qcloud.cos.region.Region;import java.util.List;import java.util.Objects;public class RecoverObjectsDemo {private static String secretId = "AKIDXXXXXXXX";private static String secretKey = "1A2Z3YYYYYYYYYY";private static String bucketName = "examplebucket-12500000000";private static String bucketRegion = "ap-guangzhou";private static COSClient cosClient = createCli();public static void main(String[] args) {listAndRecoverObjs();}private static COSClient createCli() {// 1 初始化用户身份信息(secretId, secretKey)COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);// 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224ClientConfig clientConfig = new ClientConfig(new Region(bucketRegion));clientConfig.setHttpProtocol(HttpProtocol.https);// 生成cos客户端return new COSClient(cred, clientConfig);}private static void listAndRecoverObjs() {ListVersionsRequest listVersionsRequest = new ListVersionsRequest();listVersionsRequest.setBucketName(bucketName);listVersionsRequest.setPrefix("");listVersionsRequest.setMaxResults(1000);VersionListing versionListing = null;String recover_key = "";String recover_versionid = "";boolean has_recovered = false;do {try {versionListing = cosClient.listVersions(listVersionsRequest);} catch (CosServiceException e) {e.printStackTrace();return;} catch (CosClientException e) {e.printStackTrace();return;}List<COSVersionSummary> cosVersionSummaries = versionListing.getVersionSummaries();for (COSVersionSummary cosVersionSummary : cosVersionSummaries) {String key = cosVersionSummary.getKey();String versionId = cosVersionSummary.getVersionId();boolean isDeleteMarker = cosVersionSummary.isDeleteMarker();boolean isLatest = cosVersionSummary.isLatest();String msg = String.format("list obj, Key[%s], Version[%s], isDeleteMarker[%s], isLatest[%s]", key, versionId, isDeleteMarker, isLatest);System.out.println(msg);if (isDeleteMarker && isLatest) {// 只恢复最新 versionid 为删除标记的对象recover_key = key;has_recovered = false;} else if (!isDeleteMarker && !isLatest && Objects.equals(key, recover_key) && !has_recovered) {// 既不是最新版本,也不是删除标记,如果key等于recover_key,那么说明找到了要恢复的数据版本,执行恢复逻辑recover_versionid = versionId;recoverObj(recover_key, recover_versionid);has_recovered = true;}}String keyMarker = versionListing.getNextKeyMarker();String versionIdMarker = versionListing.getNextVersionIdMarker();listVersionsRequest.setKeyMarker(keyMarker);listVersionsRequest.setVersionIdMarker(versionIdMarker);} while (versionListing.isTruncated());}private static void recoverObj(String srcKey, String srcVersionId) {String dstKey = srcKey;CopyObjectRequest copyObjectRequest = new CopyObjectRequest(new Region(bucketRegion), bucketName, srcKey, bucketName, dstKey);copyObjectRequest.setSourceVersionId(srcVersionId);try {CopyObjectResult result = cosClient.copyObject(copyObjectRequest);String msg = String.format("finish recover by copying obj, srcKey[%s], srcVersion[%s], dstKey[%s], dstVersion[%s]", srcKey, srcVersionId, dstKey, result.getVersionId());System.out.println(msg);} catch (CosServiceException cse) {cse.printStackTrace();} catch (CosClientException cce) {cce.printStackTrace();}}}
3. 根据实际情况填写指定参数:包括原桶名称、原桶的 region、secretId 和 secretKey。
注意:
原桶需要开启版本控制功能。
4. 运行RecoverObjectsDemo.java文件,运行成功后即可恢复被删除的数据。
操作步骤如下:
1. 确保已下载 COS 的 XML Java SDK 源码,并且安装好环境,详情请参见 Java SDK快速入门。
2. 复制以下代码,如需查看 Git示例请前往 GitHub。
import com.qcloud.cos.COSClient;import com.qcloud.cos.ClientConfig;import com.qcloud.cos.auth.BasicCOSCredentials;import com.qcloud.cos.auth.COSCredentials;import com.qcloud.cos.exception.CosClientException;import com.qcloud.cos.exception.CosServiceException;import com.qcloud.cos.http.HttpProtocol;import com.qcloud.cos.model.CopyObjectRequest;import com.qcloud.cos.model.CopyObjectResult;import com.qcloud.cos.model.COSVersionSummary;import com.qcloud.cos.model.ListVersionsRequest;import com.qcloud.cos.model.VersionListing;import com.qcloud.cos.region.Region;import java.util.ArrayList;import java.util.List;public class RecoverObjectsDemo2 {private static String secretId = "AKIDXXXXXXXX";private static String secretKey = "1A2Z3YYYYYYYYYY";private static String srcbucketName = "examplebucket-backup-12500000000";private static String dstbucketName = "examplebucket-dest-12500000000";private static String srcbucketRegion = "ap-guangzhou";private static String dstbucketRegion = "ap-shanghai";private static List<String> copyobjs = new ArrayList<>();private static COSClient srcCosClient = createCli(srcbucketRegion);private static COSClient dstCosClient = createCli(dstbucketRegion);public static void main(String[] args) {listAndRecoverObjs();}private static COSClient createCli(String region) {// 1 初始化用户身份信息(secretId, secretKey)COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);// 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224ClientConfig clientConfig = new ClientConfig(new Region(region));clientConfig.setHttpProtocol(HttpProtocol.https);// 生成cos客户端return new COSClient(cred, clientConfig);}private static void recoverObj(String srcKey, String srcVersionId) {String dstKey = srcKey;CopyObjectRequest copyObjectRequest = new CopyObjectRequest(new Region(srcbucketRegion), srcbucketName, srcKey, dstbucketName, dstKey);copyObjectRequest.setSourceVersionId(srcVersionId);try {CopyObjectResult result = dstCosClient.copyObject(copyObjectRequest);String msg = String.format("finish recover by copying obj, srcBucket[%s], srcKey[%s], srcVersion[%s], dstBucket[%s], dstKey[%s], dstVersion[%s]",srcbucketName, srcKey, srcVersionId, dstbucketName, dstKey, result.getVersionId());System.out.println(msg);copyobjs.add(srcKey);} catch (CosServiceException cse) {cse.printStackTrace();} catch (CosClientException cce) {cce.printStackTrace();}}private static void listAndRecoverObjs() {ListVersionsRequest listVersionsRequest = new ListVersionsRequest();listVersionsRequest.setBucketName(srcbucketName);listVersionsRequest.setPrefix("");VersionListing versionListing = null;do {try {versionListing = srcCosClient.listVersions(listVersionsRequest);} catch (CosServiceException e) {e.printStackTrace();return;} catch (CosClientException e) {e.printStackTrace();return;}List<COSVersionSummary> cosVersionSummaries = versionListing.getVersionSummaries();for (COSVersionSummary cosVersionSummary : cosVersionSummaries) {String key = cosVersionSummary.getKey();String versionId = cosVersionSummary.getVersionId();boolean isDeleteMarker = cosVersionSummary.isDeleteMarker();boolean isLatest = cosVersionSummary.isLatest();if (!isDeleteMarker) {if (isLatest) {System.out.println("latest object, will copy " + "key:" + key + ", versionId:" + versionId);recoverObj(key, versionId);} else {if (!copyobjs.contains(key)) {System.out.println("not latest object, will copy " + "key:" + key + ", versionId:" + versionId);recoverObj(key, versionId);}}}}String keyMarker = versionListing.getNextKeyMarker();String versionIdMarker = versionListing.getNextVersionIdMarker();listVersionsRequest.setKeyMarker(keyMarker);listVersionsRequest.setVersionIdMarker(versionIdMarker);} while (versionListing.isTruncated());System.out.println("--------------------------------------");}}
3. 根据实际情况填写指定参数:包括备份桶名称、目标桶名称、备份桶的 region、目标桶的 region、secretId 和 secretKey。
注意:
备份桶和目标桶均需要开启版本控制功能。
4. 运行 RecoverObjectsDemo2.java 文件,运行成功后即可恢复被删除的数据。
通过 API 恢复
开启版本控制后,删除请求并不会真实的删除对象,而是生成一个删除标记作为最新版本。因此,恢复被删除后的历史版本,就是需要让历史版本重新成为最新版本。方法有2个:
1. 删除“删除标记”。调用 DeleteObject 接口,将最上层的删除标记删掉,历史版本就会成为最新版本。单击 快捷跳转 至操作指引。
2. 将历史版本重新复制一份。调用 PutObject-Copy接口,将需要的历史版本重新复制一次,就会产生一个新的版本。单击 快捷跳转 至操作指引。
方法一:删除“删除标记”
调用 DeleteObject 接口,将最上层的删除标记删掉,历史版本就会成为最新版本。
注意:
调用 DeleteObject 接口时,一定要携带 versionid 参数,并输入删除标记的版本号。
以下分别介绍使用 API 和使用 SDK 两种方式:
1. 使用 API,接口文档可参考 永久删除标记,下面是一个 API 示例:
请求
DELETE /exampleobject?versionId=MTg0NDUxNzgyODk2ODc1NjY0NzQ HTTP/1.1Host: examplebucket-1250000000.cos.ap-beijing.myqcloud.comDate: Wed, 14 Aug 2019 12:00:42 GMTAuthorization: q-sign-algorithm=sha1&q-ak=AKID8A0fBVtYFrNm02oY1g1JQQF0c3JO****&q-sign-time=1565784042;1565791242&q-key-time=1565784042;1565791242&q-header-list=date;host&q-url-param-list=versionid&q-signature=14e18786f25e762fb11560ea788d5e07c375****Connection: close
响应
HTTP/1.1 204 No Content Content-Length: 0 Connection: close Date: Wed, 14 Aug 2019 12:00:42 GMT Server: tencent-cos x-cos-delete-marker: true x-cos-request-id: NWQ1M2Y3ZWFfNzljMDBiMDlfMjkyMDJfMWRjNjVm**** x-cos-version-id: MTg0NDUxNzgyODk2ODc1NjY0NzQ
2. 使用 SDK,以 python 为例,示例代码如下。注意一定要指定删除标记的 versionid,详见 Python SDK文档。
python
response = client.delete_object( Bucket='examplebucket-1250000000', Key='exampleobject', VersionId='string' )
3. 最终效果如下图,删除标记被彻底删除,原先的历史版本自动成为最新版本,达到恢复的效果。
方法二:将历史版本重新复制一次
调用 PutObject-Copy 接口,将需要的历史版本重新复制一次,就会产生一个新的版本,这个新版本会在最上层,达到恢复的效果。注意:调用复制接口的时候,x-cos-copy-source 中一定要明确指定要复制的历史版本的版本号。以下分别介绍使用 API 和使用 SDK 两种方式:
1. 使用 API,接口文档可参考:复制时指定源对象的版本。注意 copy-source一定要携带上版本号,请求示例如下:
请求
PUT /exampleobject HTTP/1.1 Host: destinationbucket-1250000000.cos.ap-beijing.myqcloud.com Date: Sat, 11 Apr 2020 17:51:35 GMT x-cos-copy-source: sourcebucket-1250000001.cos.ap-shanghai.myqcloud.com/example.jpg?versionId=MTg0NDUxNTc0NDYyMjQ2MzUzMjQ Content-Length: 0 Authorization: q-sign-algorithm=sha1&q-ak=AKID8A0fBVtYFrNm02oY1g1JQQF0c3JO****&q-sign-time=1586627495;1586634695&q-key-time=1586627495;1586634695&q-header-list=content-length;date;host;x-cos-copy-source&q-url-param-list=&q-signature=da80bd079b2c1fdb0dd961dea8568ee8d998**** Connection: close
响应
HTTP/1.1 200 OK Content-Type: application/xml Content-Length: 219 Connection: close Date: Sat, 11 Apr 2020 17:51:35 GMT Server: tencent-cos x-cos-copy-source-version-id: MTg0NDUxNTc0NDYyMjQ2MzUzMjQ x-cos-request-id: NWU5MjAzYTdfMWZjMDJhMDlfNTE4N18zNGU2**** <?xml version="1.0" encoding="UTF-8"?> <CopyObjectResult> <ETag>"ee8de918d05640145b18f70f4c3aa602"</ETag> <CRC64>16749565679157681890</CRC64> <LastModified>2020-04-11T17:51:35Z</LastModified> </CopyObjectResult>
2. 使用 SDK,以 python 为例,示例代码如下。注意一定要指定需要恢复的版本的 versionid,详见 Python SDK文档。
python
response = client.copy( Bucket='examplebucket-1250000000', Key='exampleobject', CopySource={ 'Bucket': 'examplebucket-1250000000', 'Key': 'exampleobject', 'Region': 'ap-guangzhou', 'VersionId': 'String' } )
3. 最终的效果如下图所示,会产生一个新的版本出现在最上层,达到恢复的效果。
总结
对象存储服务(COS)通过访问控制、对象锁定、MFA操作保护、版本控制、存储桶复制、日志管理、清单、回收站、批量处理等功能等为您提供了一个丰富的数据保护解决方案。从防误删到误删恢复,我们致力于将数据丢失的风险降到最低,确保企业能够在安全可靠的环境中蓬勃发展。如果您在使用过程中有任何建议或问题,欢迎 联系我们。