背景
S3のバケットのバージョニングが有効になっている場合、バケット内のファイルを削除すると論理削除されたことになる。論理削除されたファイルなのでリカバリもできる。
S3の論理削除は、保存されたファイルの最新のバージョンとして削除マーカーを付け加えることで実現している。よって、この最後の削除マーカーを削除すれば、ファイルが復旧する。
その削除マーカーをRubyで消す処理のメモをここに残す。
バージョン
aws-sdk-s3 (1.156.0)
注意点
最新のファイルとその一個前の新しいファイルが両方とも削除マーカーになっていることもあったので、ここに記した手順は常に完全なものでないため注意。どんなバージョンデータがあるかはS3の使い方によるため、そこは個別に判断する必要がある。
処理
# s3:ListBucketVersions などの普通のWEBサーバーでは使わない権限が必要になるはずなので、
# 作業するときは適切な権限のあるキー・トークンが必要になる
Aws.config.update({ credentials: Aws::Credentials.new('キー','トークン') })
resource = Aws::S3::Resource.new(region: 'リージョン名(ex. ap-northeast-1)')
s3_bucket = resource.bucket('バケット名')
# ファイル名までのパス
file_name = 'dir1/dir2/some_file.pdf'
# 対象ファイルの全バージョンを取得する
data = s3_bucket.object_versions(prefix: file_name).map(&:data)
# 最新のバージョンを取得する
last_datum = data.filter { _1.is_latest }.first
if data.count == 0
puts "[WARN] データが見つかりませんでした: #{file_name}"
elsif last_datum.class == Aws::S3::Types::ObjectVersion
# 最新のファイルが ObjectVersion だったらファイルは有効なので復旧する必要はない
puts "既に復旧が終わっています: #{file_name}"
elsif last_datum.class == Aws::S3::Types::DeleteMarkerEntry
# 最新のバージョンが削除マーカーのとき
# 削除マーカーを削除する
s3_bucket.object(file_name).delete(version_id: last_datum.version_id)
puts "復旧しました: #{file_name}"
else
puts "[WARN] 想定外のデータです: #{file_name}"
end