Khôi Phục File S3 Đã Xóa: Hướng Dẫn Thực Tế Khi Bật Versioning
Bạn vừa chạy lệnh aws s3 rm và nhận ra mình vừa xóa nhầm file quan trọng trên S3 — cảm giác đó không dễ chịu chút nào. Tin tốt là nếu bucket đã bật S3 Versioning, file đó chưa thực sự mất: AWS chỉ tạo một 'delete marker' che đi object gốc, toàn bộ các version trước vẫn còn nguyên trong hệ thống.
TL;DR — Khôi Phục File S3 Đã Xóa Nhanh
| Bước | Hành động | Mục đích |
|---|---|---|
| 1 | Xác nhận Versioning đang bật | Đảm bảo version history tồn tại |
| 2 | Liệt kê tất cả versions của object | Tìm version ID cần khôi phục |
| 3 | Xác định delete marker | Hiểu tại sao object 'biến mất' |
| 4 | Xóa delete marker | Khôi phục object về trạng thái hiện hành |
| 5 | Xác nhận object đã trở lại | Kiểm tra kết quả |
S3 Versioning Hoạt Động Như Thế Nào Khi Xóa File
Trước khi bắt tay vào khôi phục, cần hiểu đúng cơ chế — vì đây là điểm mà nhiều người hiểu sai và làm mất thêm data.
Khi Versioning được bật và bạn thực hiện DELETE một object mà không chỉ định version ID, S3 không xóa object đó. Thay vào đó, S3 chèn một 'delete marker' — một object đặc biệt không có nội dung, đóng vai trò như tấm biển 'object này đã bị xóa'. Mọi GET request sau đó sẽ nhận về lỗi 404, nhưng tất cả các version cũ vẫn tồn tại hoàn toàn trong bucket.
Delete marker giống như tờ giấy dán 'Đã đóng cửa' lên cửa hàng — cửa hàng vẫn còn đó với toàn bộ hàng hóa bên trong, chỉ là khách hàng bình thường không thấy nó nữa.
Ngược lại, nếu bạn xóa với --version-id cụ thể, S3 xóa vĩnh viễn đúng version đó. Đây là thao tác không thể hoàn tác.
IsLatest: true"] B --> C["PUT Object lần 2"] C --> D["Version B
IsLatest: true"] D --> E["Version A
IsLatest: false"] D --> F["DELETE không có version ID"] F --> G["Delete Marker
IsLatest: true"] G --> H["Version B ẩn khỏi GET"] G --> I["DELETE delete marker"] I --> J["Version B
IsLatest: true — đã khôi phục"]
- PUT Object: S3 tạo version đầu tiên với một Version ID duy nhất.
- PUT lần 2: S3 giữ nguyên version cũ, tạo thêm version mới — cả hai cùng tồn tại.
- DELETE không có version ID: S3 chèn delete marker, object 'biến mất' khỏi tầm nhìn thông thường.
- DELETE delete marker: Object gốc hiện ra trở lại — đây là bước khôi phục.
- DELETE với version ID cụ thể: Xóa vĩnh viễn, không thể undo.
Bước 1: Xác Nhận S3 Versioning Đang Bật Trên Bucket
Bước này không phải thủ tục — nếu Versioning chưa bật hoặc đang ở trạng thái 'Suspended', các version cũ có thể không tồn tại và toàn bộ quy trình dưới đây sẽ không có tác dụng. Kiểm tra trước để không mất thêm thời gian.
aws s3api get-bucket-versioning \
--bucket ten-bucket-cua-ban \
--region us-east-1
Output mong đợi khi Versioning đang hoạt động:
{
"Status": "Enabled"
}
Nếu output trả về {} (rỗng) hoặc "Status": "Suspended", các version cũ không được bảo toàn theo cơ chế này. Trường hợp đó, hãy kiểm tra xem bucket có cấu hình S3 Replication hoặc AWS Backup không — đó là hướng khôi phục khác.
Bước 2: Liệt Kê Tất Cả Versions Của Object Bị Xóa
Lệnh list-objects-v2 thông thường sẽ không hiển thị object đã bị xóa. Phải dùng list-object-versions để thấy toàn bộ version history bao gồm cả delete markers.
aws s3api list-object-versions \
--bucket ten-bucket-cua-ban \
--prefix duong-dan/ten-file.txt \
--region us-east-1
Output sẽ có hai phần quan trọng:
🔽 Xem ví dụ output đầy đủ
{
"Versions": [
{
"ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"Size": 1024,
"StorageClass": "STANDARD",
"Key": "duong-dan/ten-file.txt",
"VersionId": "abc123XYZ_version_cu",
"IsLatest": false,
"LastModified": "2024-01-15T10:30:00.000Z",
"Owner": {
"ID": "abc123"
}
}
],
"DeleteMarkers": [
{
"Owner": {
"ID": "abc123"
},
"Key": "duong-dan/ten-file.txt",
"VersionId": "xyz789ABC_delete_marker",
"IsLatest": true,
"LastModified": "2024-01-16T08:00:00.000Z"
}
]
}
Chú ý hai thông tin cần ghi lại: VersionId của delete marker (trong mảng DeleteMarkers, có "IsLatest": true) và VersionId của version bạn muốn khôi phục (trong mảng Versions).
Bước 3: Xác Định Đúng Delete Marker Cần Xóa
Đây là bước dễ nhầm nhất — đặc biệt nếu object đã bị xóa và tạo lại nhiều lần. Delete marker luôn có "IsLatest": true và không có trường Size hay ETag. Nếu có nhiều delete markers, hãy chọn cái có LastModified gần nhất với thời điểm bạn xóa nhầm.
IsLatest: true"] -->|che| V1["Version gốc
IsLatest: false"] DEL["delete-object
--version-id DM"] -->|xóa| DM DEL --> RESULT["Version gốc
IsLatest: true"]
- Version gốc (
IsLatest: false) — đây là nội dung cần khôi phục. - Delete marker (
IsLatest: true, không có Size) — đây là thứ cần xóa để khôi phục. - Sau khi xóa delete marker, version gốc tự động trở thành
IsLatest: true.
Bước 4: Xóa Delete Marker Để Khôi Phục Object
Để xóa delete marker, bắt buộc phải chỉ định đúng --version-id của nó. Đây là thao tác xóa một version cụ thể — không phải xóa object thông thường.
aws s3api delete-object \
--bucket ten-bucket-cua-ban \
--key duong-dan/ten-file.txt \
--version-id xyz789ABC_delete_marker \
--region us-east-1
Output thành công sẽ trả về thông tin của delete marker vừa bị xóa, kèm "DeleteMarker": true:
{
"DeleteMarker": true,
"VersionId": "xyz789ABC_delete_marker"
}
Nếu bạn muốn khôi phục về một version cụ thể trong quá khứ (không phải version mới nhất trước khi xóa), cách tiếp cận khác là copy version đó thành một PUT mới:
aws s3api copy-object \
--bucket ten-bucket-cua-ban \
--copy-source ten-bucket-cua-ban/duong-dan/ten-file.txt?versionId=abc123XYZ_version_cu \
--key duong-dan/ten-file.txt \
--region us-east-1
Lệnh này tạo một version mới với nội dung từ version cũ — an toàn hơn vì không xóa bất kỳ version nào hiện có.
Bước 5: Xác Nhận Object Đã Được Khôi Phục
Sau khi xóa delete marker, kiểm tra lại bằng head-object — nếu trả về metadata bình thường thay vì lỗi 404, object đã khôi phục thành công.
aws s3api head-object \
--bucket ten-bucket-cua-ban \
--key duong-dan/ten-file.txt \
--region us-east-1
Output thành công sẽ trả về metadata của object như ContentLength, LastModified, ETag, và VersionId của version hiện tại.
Bài Học Từ Thực Tế: Khi Khôi Phục Vẫn Trả Về 404
Có một tình huống hay gặp: bạn đã xóa delete marker thành công, nhưng head-object vẫn báo 404. Lúc đầu tôi nghĩ lệnh delete bị lỗi — nhưng không phải vậy.
Nguyên nhân thực tế: object có nhiều hơn một delete marker, thường xảy ra khi file bị xóa nhiều lần hoặc có automation job chạy định kỳ. Xóa một delete marker chỉ làm lộ ra delete marker phía dưới — object vẫn bị che.
Cách kiểm tra: chạy lại list-object-versions sau khi xóa delete marker đầu tiên. Nếu mảng DeleteMarkers vẫn còn entry với "IsLatest": true, cần xóa tiếp cái đó.
aws s3api list-object-versions \
--bucket ten-bucket-cua-ban \
--prefix duong-dan/ten-file.txt \
--region us-east-1 \
--query 'DeleteMarkers[?IsLatest==`true`]'
Lặp lại Bước 4 cho đến khi DeleteMarkers[IsLatest=true] không còn tồn tại. Đây là điểm mà nhiều người bỏ sót vì giả định chỉ có một delete marker.
IAM Permissions Cần Thiết Để Thực Hiện Khôi Phục
Nếu bạn đang thực hiện thao tác này với IAM user hoặc role không phải bucket owner, cần đảm bảo có đủ quyền. Thiếu quyền s3:DeleteObjectVersion là lý do phổ biến khiến lệnh xóa delete marker thất bại mà không có thông báo rõ ràng.
🔽 Xem IAM policy tối thiểu để khôi phục file
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListVersions",
"Effect": "Allow",
"Action": [
"s3:ListBucketVersions",
"s3:GetBucketVersioning"
],
"Resource": "arn:aws:s3:::ten-bucket-cua-ban"
},
{
"Sid": "RestoreObject",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:DeleteObjectVersion",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::ten-bucket-cua-ban/*"
}
]
}
Lưu ý: s3:DeleteObjectVersion là action riêng biệt với s3:DeleteObject. Nhiều policy mẫu chỉ cấp s3:DeleteObject — không đủ để xóa delete marker theo version ID.
Phòng Ngừa: Bật MFA Delete Để Tránh Xóa Nhầm
Nếu bucket chứa data quan trọng, cân nhắc bật MFA Delete — tính năng yêu cầu xác thực MFA cho mọi thao tác xóa version hoặc thay đổi trạng thái Versioning. Khi MFA Delete được bật, ngay cả khi credential bị compromise, kẻ tấn công cũng không thể xóa vĩnh viễn các version.
MFA Delete chỉ có thể được bật bởi root account và yêu cầu hardware hoặc virtual MFA device. Tham khảo tài liệu chính thức của AWS về MFA Delete để biết chi tiết cấu hình.
Khôi Phục File S3 Đã Xóa — Tổng Kết và Bước Tiếp Theo
Khi S3 Versioning đang bật, 'xóa nhầm' thực chất chỉ là chèn một delete marker — toàn bộ version history vẫn còn nguyên. Quy trình khôi phục file S3 đã xóa gồm ba bước cốt lõi: tìm đúng delete marker qua list-object-versions, xóa delete marker đó bằng delete-object --version-id, và xác nhận lại bằng head-object.
Bước tiếp theo nên làm:
- Kiểm tra tất cả các bucket production đã bật Versioning chưa:
aws s3api get-bucket-versioning --bucket <bucket-name> - Cân nhắc cấu hình S3 Lifecycle rules để tự động expire các version cũ, tránh chi phí storage tích lũy.
- Với data tier quan trọng nhất, bổ sung AWS Backup cho S3 như một lớp bảo vệ độc lập.
Glossary — Thuật Ngữ Chính
| Thuật ngữ | Giải thích |
|---|---|
| S3 Versioning | Tính năng của S3 lưu giữ nhiều version của cùng một object trong bucket, cho phép khôi phục về version trước đó. |
| Delete Marker | Object đặc biệt không có nội dung, được S3 tạo ra khi xóa object trong bucket có Versioning. Đóng vai trò 'ẩn' object khỏi các request thông thường. |
| Version ID | Chuỗi định danh duy nhất mà S3 gán cho mỗi version của một object khi Versioning được bật. |
| MFA Delete | Tính năng bảo mật yêu cầu xác thực MFA để xóa object version hoặc thay đổi trạng thái Versioning của bucket. |
| IsLatest | Thuộc tính trong version metadata cho biết đây có phải version hiện hành của object hay không. Delete marker có IsLatest=true sẽ che toàn bộ version phía dưới. |
Nhận xét
Đăng nhận xét