tencent cloud

Cloud Object Storage

문서Cloud Object Storage

Best Practices for Data Accidental Deletion Prevention and Recovery

Download
포커스 모드
폰트 크기
마지막 업데이트 시간: 2026-05-12 16:30:39

Overview

In the field of cloud storage, data security has always been of paramount importance. Tencent Cloud Object Storage Service (COS) has long been committed to the exploration and practice of data security to ensure data confidentiality and integrity. This article details how to prevent accidental data deletion and recovery methods after accidental deletion.

Prevent accidental data deletion

Background

In the daily operations of enterprises, data security faces multiple threats, including misoperations by internal personnel, attacks by malicious software, and even intrusions by external hackers. These risks may lead to the loss or leakage of important data, resulting in immeasurable losses.

Detailed Introduction and Operational Steps

COS builds the first line of defense for data security through features such as access control, object locking, MFA operation protection, version control, bucket replication to reduce the risk of accidental deletion. The introduction and operation steps of related features are detailed below.
Access control ensures that only authorized users are granted permission to perform sensitive operations, such as deleting data;
Object locking ensures that once data is written, it cannot be modified or deleted unless the preset lock period is reached;
MFA operation protection provides an additional layer of security for user-sensitive operations. For sensitive operations, the system requires secondary authentication.
Version control and bucket replication can effectively back up data and prevent accidental deletion incidents in advance;




Access Control

Overview

By default, COS resources (including Buckets and Objects) have private permissions, accessible only to resource owners or authorized users. To specify who can perform what operations on which resources under what conditions, access control can be implemented through various permission settings combined with the principle of least privilege. Based on policy approaches, it can be divided into resource-based and user-based methods, including bucket policies, bucket ACLs, Object ACLs and user policies (CAM policies) respectively. For more information about policies, see Basic Concepts of Access Control.



COS ensures data security and flexibility, enabling you to configure appropriate access permissions for different users and application scenarios based on actual business needs.




Operation Guide

Bucket Policy
You can grant operational permissions for buckets and objects to CAM sub-accounts, other root accounts, or even anonymous users through bucket policies. COS supports adding bucket policies via multiple methods such as the Console, API, and SDK. The following describes the steps for the graphical interface of the Console. For more usage methods and descriptions, see Bucket Policies.
1. Log in to the COS Console.
2. Go to Permission Management of the target bucket, choose Policy Permission Settings > Graphical Settings, click Add Policy, and configure the policy in the pop-up window.
3. Select template (Optional): COS provides you with multiple policy templates to help you quickly configure bucket policies. Choose as needed. For detailed steps and configuration instructions, see Add Bucket Policy.



4. Configure policy: If the recommended templates do not meet your requirements, you can adjust the policy content at this step to add or remove authorized users, resources, operations, and conditions (optional).



bucket ACL and object ACL
ACL uses XML language to describe a list of authorized entities and granted permissions associated with resources, supporting granting basic read and write permissions to anonymous users or other root accounts. The following is a bucket ACL example, describing the full control permission of the bucket owner (User UIN: 100000000001). For more content and examples, refer to 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>
User policies (CAM policies)
Users can grant different permissions to various types of users under the root account in CAM. You can associate and authorize using preset policies or create custom user policies (for policy syntax, see Element Reference) and associate them with specific identities to manage user access. The following describes the steps for associating users via preset policies. For more details, see the User Policies documentation.
1. Log in to the CAM Console.
2. Go to the Policy page, select Preset Policies, search for COS, and click Associate User Group/Role.

3. In the pop-up page, select the users to be associated, and click OK to complete the operation of associating users via policy.


Object Lock

Overview

COS's Object Lock (WORM: Write Once Read Many) feature provides a data protection mechanism for objects in buckets. By setting retention periods, objects are locked in a read-only state during this period, preventing overwrites or deletions. This feature is particularly suitable for protecting critical sensitive data, ensuring that once data is uploaded, its integrity and security are guaranteed for a specified duration, preventing unauthorized modifications or deletions.
Note:
This feature is available on an allowlist basis. To enable it, please contact us.




Operation Guide

To enable Object Lock in the COS Console, follow these steps. For more details and limitations, see Setting Object Lock.
1. Log in to the COS Console.
2. Go to the Security Management of the target bucket, select Object Lock, click Edit and configure retention period, then click Save to enable the Object Lock feature.

MFA Operation Protection

Overview

Operation protection is an additional security layer provided when users perform sensitive operations, and MFA is one type of such protection. When MFA is enabled, users must provide additional verification information when performing sensitive operations, such as deleting data or modifying critical configurations. This adds a crucial security layer to prevent unauthorized access or accidental deletions caused by misoperations. For more details, see Operation Protection and Binding a Virtual MFA Device.

Operation Guide

1. Log in to the Account Center Console and go to the Security Settings page.
2. In the Basic Settings section, find MFA Device, click Bind, and complete identity verification according to the page prompts.

3. Select different MFA devices as needed and complete the account binding process according to the page instructions. Select Operation Protection, then click Submit to complete the binding.
4. Go to the File List page, click Empty Bucket, and the system will prompt for MFA verification for secondary confirmation, further reducing the risk of accidental deletion.

Versioning

Overview

After versioning is enabled, all write operations on files with the same name will create a new version of the file. Deletion operations will add a delete marker. You can query, delete, or restore any historical version by specifying the version ID, enabling data rollback operations. For more details, see Versioning Overview.




Operation Guide

COS supports enabling the versioning feature via the Console, API, or SDK. This document only describes the steps to enable versioning in the Console. For other methods and related information, see Versioning Configuration.
1. Log in to the COS Console.
2. Go to the Fault Tolerance and Disaster Recovery Management of the target bucket, select Versioning, click Edit to enable the status, then click Save to enable versioning. For more detailed steps and limitations, see Setting Versioning.
3. After enabling, go to the File List page, click List History Versions to view all versions and manage them.

Bucket replication

Overview

The bucket replication feature of COS helps users replicate all incremental files to data centers in other cities via dedicated lines, achieving cross-region disaster recovery. It supports both intra-region and cross-region backups. When data in the primary bucket is deleted, it can be restored from the backup bucket through batch copying. For more details, see Bucket Replication Overview.




Operation Guide

1. Log in to the COS Console.
2. Go to the Fault Tolerance and Disaster Recovery Management of the target bucket, select Bucket Replication, click Add Rule. For configuration item descriptions, see Setting Bucket Replication.
3. You can choose to replicate objects in the entire bucket or within a specified range to the destination bucket.
4. Supports both intra-region replication and cross-region replication. Click OK to complete creating a bucket replication rule.
5. Supports viewing configured rules in the List. After configuration, the system will automatically and asynchronously replicate incremental objects from the source bucket to the destination bucket according to the rules.

Accidental Deletion Trace

Even with the primary safeguard for data security, the threat of accidental data deletion remains significant. Data loss caused by operational errors or system failures can severely impact enterprises. In such scenarios, data traceability becomes critical. COS provides the Log Management feature to help users track, record, and analyze every data access in real time, facilitating the tracing of abnormal events and ensuring data traceability.
The following describes how to quickly locate deletion events through Log Search and Inventory. For more details and step-by-step operations, see Setting Log Storage, Setting Log Search, and Setting Inventory.

Tracing through Log Search

1. Log in to the COS Console.
2. Go to the Log Search page, add search conditions, configure reqMethod contains DELETE, and select the time range.
3. Click Search to query the results of DELETE requests. As shown in the following figure, the file txttt was deleted by user 100xxxxxxxxx at 20:22 on May 16.


Trace through inventory

To trace deleted data using the inventory feature, ensure that version control is enabled for your bucket.
1. Log in to the COS Console.
2. Go to the Inventory Settings page, add a new inventory or select an existing one to generate an on-demand inventory. For specific steps, see Generating On-Demand Inventory.
3. The basic configuration information for adding an inventory is as follows. Select the target bucket and inventory report generation path as needed. For an introduction to the path, see Inventory Report Storage Path.



4. In the inventory configuration process, you can fill in filter conditions as needed based on actual scenarios. For Object Version, select "Include all versions". For instructions on other parameter configurations, see Setting Inventory. The following are examples of common scenarios:
If you know that objects with a specified prefix have been deleted, it is recommended to select "Specified File Prefix" for the file scope and enter the corresponding prefix.
If you know that the data deletion occurred after a specific time point or within a specified range, it is recommended to select "all objects after a specified time point" or "objects within a specified time range" for the time filter and enter the corresponding range.

5. After the inventory task is created, click Preview Inventory.

6. After the date and inventory directory are filtered, locate the desired inventory and click View Inventory Results.



7. Click Download to download the generated inventory file, which needs to be unzipped after downloading.



8. The decompressed CSV file describes object information. You can identify deleted objects based on IsDeleteMarker and LastModifiedDate. The field names corresponding to the CSV file can be viewed in the "fileSchema" of the manifest.json file. For more field meanings and descriptions, see Inventory Parameters.




Recover Accidentally Deleted Data

The recoverability of data is based on versioning to provide bucket replication and a series of features and methods to enhance the accidental deletion recovery system. Even if the latest version is accidentally deleted or overwritten, it can be restored to any previous version. As mentioned above, version control and bucket replication based on versioning have been introduced, so they will not be reiterated here.
COS supports the following features or methods to recover accidentally deleted data: recover data through bucket replication + batch processing, inventory + batch processing, SDK, and API. You can choose as needed based on your actual business scenarios.

Restore using bucket replication + batch processing

After data is accidentally deleted, since bucket replication rules have been previously configured in the source bucket to copy data to the backup bucket, you can create a batch data replication task in the backup bucket to recover the deleted data. For more information, see Batch Processing. The steps are as follows:
1. Log in to the COS Console.
2. Click Batch Processing > Create Batch Task.
3. In the Create Task page, enter the Task Name, select Batch Data Replication for Task Type, and configure other settings as required. For details, see Batch Processing Steps.
4. After the information is confirmed, click Create and Start to complete the creation of the batch data replication task.
5. In the Task List, you can view the status of created tasks and clone or cancel tasks.

Recovery via inventory + batch processing

After identifying the deleted objects via the inventory, you can also recover the deleted data through batch processing. For more information, see Batch Processing. The steps are as follows:
1. Log in to the COS Console.
2. After identifying the deleted objects via the inventory, retain a csv file and upload it to a bucket. The header format of the csv file is as shown in the figure below.
Column A: List the bucket names, for example examplebucket-1250000000.
Column B: List the objects to be recovered in the current bucket, i.e., the object keys, for example image.png.
Column C: List the version IDs corresponding to the objects to be recovered.

3. Click Batch Processing > Create Batch Task.
4. In the Create Task page, enter the Task Name, select Batch Data Replication for Task Type. For Inventory Report, select "Yes", and choose the storage path of the csv file uploaded in Step 2 for Inventory Path. Configure other settings as required. For details, see Batch Processing.
5. After the information is confirmed to be correct, click Create and Start to complete the creation of the batch data replication task.
6. In the Task List, you can view the status of created tasks and clone or cancel tasks.

Restore via SDK

COS SDK provides a method for rapid batch data recovery based on version control. The core logic involves iterating through all target objects to locate the first non-deleted version data object for copying. Therefore, this method requires that the bucket has enabled the version control feature.
Currently, Go SDK, Java SDK, and Python SDK provide sample code for both batch recovery from the source bucket and batch recovery from the backup bucket. More SDKs are being continuously optimized. Stay tuned.

Example Code

Go (Recover from source bucket)
Go (Recovery from Backup Bucket)
Java (recover from source bucket)
Java (Restore from Backup Bucket)
Python (Restore from source bucket)
Python (Restore from backup bucket)
The operation steps are as follows:
1. Ensure that the COS XML Go SDK source code is downloaded and the environment is installed. For details, see Go SDK Quick Start.
2. Copy the following code. To view the Git example, go to GitHub.
package main

import (
"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) {
// WARN
fmt.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.Client

copyObjs = 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 := true
opt := &cos.BucketGetObjectVersionsOptions{
EncodingType: "url",
}
for isTruncated {
opt.KeyMarker = keyMarker
opt.VersionIdMarker = versionIdMarker
v, _, err := srcCosClient.Bucket.GetObjectVersions(context.Background(), opt)
if err != nil {
log_status(err)
break
}
for _, vc := range v.DeleteMarker {
if vc.IsLatest {
// The object has been deleted and needs to be restored.
copyObjs[vc.Key] = struct{}{}
}
}
for _, vc := range v.Version {
// Restore to the latest 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.NextKeyMarker
versionIdMarker = v.NextVersionIdMarker
isTruncated = v.IsTruncated
}
}
3. Fill in the specified parameters based on your actual scenario: including source bucket name, source bucket region, secretId, and secretKey.
Note:
The source bucket needs to have the version control feature enabled.
4. Run the object_recover2.go file. Once executed successfully, the deleted data will be restored.
The operation steps are as follows:
1. Ensure that the COS XML Go SDK source code is downloaded and the environment is installed. For details, see Go SDK Quick Start.
2. Copy the following code. To view the Git example, go to GitHub.
package main

import (
"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) {
// WARN
fmt.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.Client
dstCosClient *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 := true
opt := &cos.BucketGetObjectVersionsOptions{
EncodingType: "url",
}
var preKey string
for isTruncated {
opt.KeyMarker = keyMarker
opt.VersionIdMarker = versionIdMarker
v, _, err := srcCosClient.Bucket.GetObjectVersions(context.Background(), opt)
if err != nil {
log_status(err)
break
}
for _, vc := range v.Version {
// Latest non-deletemarker object
if preKey != vc.Key {
preKey = vc.Key
key, _ := cos.DecodeURIComponent(vc.Key)
fmt.Printf("key: %v, versionId: %v, lastest: %v\\n", key, vc.VersionId, vc.IsLatest)
recoverObj(key, vc.VersionId)
}
}
keyMarker = v.NextKeyMarker
versionIdMarker = v.NextVersionIdMarker
isTruncated = v.IsTruncated
}
}
3. Fill in the specified parameters based on your actual scenario: including backup bucket name, target bucket name, backup bucket region, target bucket region, secretId, and secretKey.
Note:
Both the backup bucket and the target bucket need to have the version control feature enabled.
4. Run the object_recover.go file. Once executed successfully, the deleted data will be restored.
The operation steps are as follows:
1. Ensure that the COS XML Java SDK source code is downloaded and the environment is set up. For details, see Java SDK Quick Start.
2. Copy the following code. To view the Git example, go to 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 = "************************************";
private static String secretKey = "************************************";
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 Initializing user identity information (secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);

// 2 Setting the region of the bucket. For the abbreviations of COS regions, refer to https://www.qcloud.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(bucketRegion));

clientConfig.setHttpProtocol(HttpProtocol.https);
// Generate the cos client
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) {
// Only restore the object with the latest versionid as the delete marker
recover_key = key;
has_recovered = false;
} else if (!isDeleteMarker && !isLatest && Objects.equals(key, recover_key) && !has_recovered) {
// Neither the latest version nor the delete marker. If the key equals recover_key, it means the data version to be restored is found, then execute the restore logic
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. Fill in the specified parameters based on your actual scenario: including source bucket name, source bucket region, secretId, and secretKey.
Note:
The source bucket needs to have the version control feature enabled.
4. Run the RecoverObjectsDemo.java file. Once the operation is successful, the deleted data will be restored.
The operation steps are as follows:
1. Ensure that the COS XML Java SDK source code is downloaded and the environment is set up. For details, see Java SDK Quick Start.
2. Copy the following code. To view the Git example, go to 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 = "************************************";
private static String secretKey = "************************************";
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 Initializing user identity information (secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);

// 2 Setting the region of the bucket. For the abbreviations of COS regions, refer to https://www.qcloud.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(region));

clientConfig.setHttpProtocol(HttpProtocol.https);
// Generate the cos client
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. Fill in the specified parameters based on your actual scenario: including backup bucket name, target bucket name, backup bucket region, target bucket region, secretId, and secretKey.
Note:
Both the backup bucket and the target bucket need to have the version control feature enabled.
4. Run the RecoverObjectsDemo2.java file. Once the operation is successful, the deleted data will be restored.
The operation steps are as follows:
1. Ensure that the COS XML Python SDK source code is downloaded and the environment is set up. For details, see Python SDK Quick Start.
2. Copy the following code. To view the Git example, go to GitHub.

# -*- coding=utf-8

from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import sys
import os
import logging

# logging.basicConfig(level=logging.INFO, stream=sys.stdout)


def _recover_main(src_region, src_bucket, secret_id, secret_key, prefix):

src_client = CosS3Client(CosConfig(Region=src_region, SecretId=secret_id, SecretKey=secret_key))

# Pagination parameters for listing operations
key_marker = ''
versionId_marker = ''
recovered_keys = set() # Used to record recovered objects

while True:
response = src_client.list_objects_versions(
Bucket=src_bucket,
Prefix=prefix,
KeyMarker=key_marker,
VersionIdMarker=versionId_marker,
)
delete_marker_keys = set()
# Retrieve the deleted object from the DeleteMarker
if 'DeleteMarker' in response:
for version in response['DeleteMarker']:
if version['IsLatest'] == 'true':
delete_marker_keys.add(version['Key'])
if len(delete_marker_keys) == 0:
print('no delete markers found, no data to recover, continue listing')

# Retrieve the object version for recovery from Version
if 'Version' in response:
for version in response['Version']:
key = version['Key']
versionId = version['VersionId']
if key in delete_marker_keys and not key in recovered_keys:
print('recover from object: {src_bucket}/{key}(versionId:{versionId})'.format(
src_bucket=src_bucket, key=key, versionId=versionId))
try:
src_client.copy(
Bucket=src_bucket,
Key=key,
CopySource={
'Bucket': src_bucket,
'Key': key,
'Region': src_region,
'VersionId': versionId,
}
)
recovered_keys.add(key)
print("success recover object: {src_bucket}/{key}(versionId={versionId}) => {src_bucket}/{key}".format(
src_bucket=src_bucket, key=key, versionId=versionId))
except Exception as e:
print(e)
pass

if response['IsTruncated'] == 'false':
break

key_marker = response['NextKeyMarker']
versionId_marker = response['NextVersionIdMarker']


if __name__ == '__main__':
# Use Cases:
# Restore files from historical versions based on the delete marker in the source bucket src_bucket

# Source Bucket Information
src_region = 'ap-guangzhou' # Source region
src_bucket = 'bucket-1250000000' # Source bucket name

# Obtain the secret key from environment variables
secret_id = os.environ['COS_SECRET_ID']
secret_key = os.environ['COS_SECRET_KEY']

prefix = '' # Set the object prefix to restore, e.g., 'docs/'. Default empty string means restore all objects.

_recover_main(
src_region=src_region,
src_bucket=src_bucket,
secret_id=secret_id,
secret_key=secret_key,
prefix=prefix
)
3. Fill in the specified parameters based on your actual scenario: including source bucket name, source bucket region, secretId, and secretKey.
Note:
The source bucket needs to have the version control feature enabled.
4. Run the disaster_recovery_demo.py file. After it runs successfully and no exception logs are output, you can restore the deleted data.
The operation steps are as follows:
1. Ensure that the COS XML Python SDK source code is downloaded and the environment is set up. For details, see Python SDK Quick Start.
2. Copy the following code. To view the Git example, go to GitHub.

# -*- coding=utf-8

from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import sys
import os
import logging

# logging.basicConfig(level=logging.INFO, stream=sys.stdout)


def _recover_main(src_region, src_bucket, dst_region, dst_bucket, secret_id, secret_key, prefix):

src_client = CosS3Client(CosConfig(Region=src_region, SecretId=secret_id, SecretKey=secret_key))
dst_client = CosS3Client(CosConfig(Region=dst_region, SecretId=secret_id, SecretKey=secret_key))

# Pagination parameters for listing operations
key_marker = ''
versionId_marker = ''

recovered_keys = set() # Record recovered objects

while True:
response = src_client.list_objects_versions(
Bucket=src_bucket,
Prefix=prefix,
KeyMarker=key_marker,
VersionIdMarker=versionId_marker,
)

# Retrieve the object version for recovery from Version
if 'Version' in response:
for version in response['Version']:
key = version['Key']
versionId = version['VersionId']
if not key in recovered_keys:
print('recover from object: {src_bucket}/{key}(versionId={versionId})'.format(
src_bucket=src_bucket, key=key, versionId=versionId))
try:
dst_client.copy(
Bucket=dst_bucket,
Key=key,
CopySource={
'Bucket': src_bucket,
'Key': key,
'Region': src_region,
'VersionId': versionId,
}
)
recovered_keys.add(key)
print("success recover object: {src_bucket}/{key}(versionId={versionId}) => {dst_bucket}/{key}".format(
src_bucket=src_bucket, key=key, versionId=versionId, dst_bucket=dst_bucket))
except Exception as e:
print(e)
pass
if response['IsTruncated'] == 'false':
break

key_marker = response['NextKeyMarker']
versionId_marker = response['NextVersionIdMarker']


if __name__ == '__main__':
# Use Cases:
# src_bucket: Backup bucket
# dst_bucket: Destination bucket
# When objects in the destination bucket (dst_bucket) are accidentally deleted, traverse the objects in the backup bucket (src_bucket), select the current version objects without delete markers, and copy them to the destination bucket (dst_bucket) to complete the recovery.

# Backup Bucket Information
src_region = 'ap-guangzhou'
src_bucket = 'bucket-backup-1250000000'

# Destination Bucket Information
dst_region = 'ap-guangzhou'
dst_bucket = 'bucket-1250000000'

# Obtain the secret key from environment variables
secret_id = os.environ['COS_SECRET_ID']
secret_key = os.environ['COS_SECRET_KEY']

prefix = '' # Set the object prefix to restore, e.g., 'docs/'. Default empty string means restore all objects.

_recover_main(
src_region=src_region,
src_bucket=src_bucket,
dst_region=dst_region,
dst_bucket=dst_bucket,
secret_id=secret_id,
secret_key=secret_key,
prefix=prefix
)
3. Fill in the specified parameters based on your actual scenario: including backup bucket name, target bucket name, backup bucket region, target bucket region, secretId, and secretKey.
Note:
Both the backup bucket and the target bucket need to have the version control feature enabled.
4. Run the disaster_recovery_demo2.py file. After it runs successfully with no exception log output, you can recover the deleted data.

Restore via API

After versioning is enabled, a delete request does not actually remove the object but instead generates a delete marker as the latest version. Therefore, restoring a deleted historical version requires making that historical version the latest again. There are two methods:
1. Delete the "delete marker". Call the DeleteObject API to remove the topmost delete marker, which will make the historical version become the latest version. Click Quick Jump to access the operation guide.
2. Make a new copy of the historical version. Call the PutObject-Copy API to replicate the required historical version, which will create a new version. Select Quick Jump to access the operation guide.


Method 1: Delete the "delete marker"

Call the DeleteObject API to remove the topmost delete marker, thus making the historical version become the latest version.
Note:
When the DeleteObject API is called, be sure to carry the versionId parameter and enter the version number of the delete marker.
The following describes two methods: using APIs and using SDKs.
1. Using API, API documentation can refer to permanent delete marker, below is an API example:
2. Using SDK, taking Python as an example, the sample code is as follows. Be sure to specify the versionId of the delete marker; refer to Python SDK Documentation for details.
3. The final result is shown in the figure below: the delete marker is completely removed, and the original historical version automatically becomes the latest version, achieving the restoration effect.




Method 2: Replicate the historical version again, which will create a new version

Call the PutObject-Copy API to replicate the required historical version, which will create a new version at the topmost level, achieving restoration. Note: When the copy API is called, the version number of the historical version to be copied must be explicitly specified in the x-cos-copy-source. The following describes two methods: using APIs and using SDKs.
1. When the API is used, API documentation can refer to: Specifying the version of the source object when copying. Note: copy-source must carry the version number. The request example is as follows:
2. Using SDK, taking Python as an example, the sample code is as follows. Be sure to specify the versionId of the version to be restored; refer to Python SDK Documentation for details.
3. The final result is shown in the figure below: a new version will be generated at the topmost level, achieving the restoration effect.




Summary

COS (Cloud Object Storage) provides a comprehensive data protection solution through features such as access control, object locking, MFA operation protection, version control, bucket replication, log management, inventory, and batch processing. From prevention against accidental deletion to recovery after accidental deletion, we are committed to minimizing the risk of data loss, ensuring enterprises can thrive in a secure and reliable environment. If you have any suggestions or questions during use, please contact us.

도움말 및 지원

문제 해결에 도움이 되었나요?

피드백