バックアップ取ってます
さくらVPSサーバーにあるアプリケーションのバックアップを毎日、さくらのオブジェクトストレージに転送してます。
やりたい事
バケット内に溜まった古いオブジェクト(バックアップファイル)を定期的に削除したい!
ライフサイクルの様な機能がなかった
さくらのオブジェクトストレージはAWSのS3と互換を持ってて、aws cli
で操作出来て割と使い勝手がいいのですが、AWS S3のライフサイクルのような機能を使って定期的に削除するという機能がありませんでした。
そのうち実装されるのかな。。
定期的に削除するShellを作ってみた
日付で特定しやすいようにバックアップファイル名には日付入りで保管してます。
こんな感じ → bkup_20220418.tar.gz
#!/bin/bash
〜〜
# バケットに保管する期限
readonly EXPIRE=`date -d '10 day ago' +"%Y%m%d"`
# バケットにあるオブジェクトのリストを取得します
items=`aws --endpoint-url=https://s3.isk01.sakurastorage.jp/ s3 ls [バケット名] | awk '{print $4}'`
for item in ${items}
do
# ファイル名に含まれた日付の部分を抽出します
item_date=`echo ${item} | sed -e 's/^bkup_\([0-9]\+\).tar.gz/\1/'`
# 日付形式になっているか確認します
`date '+%Y%m%d' -d ${item_date} > /dev/null 2>&1`
# 取得した値が日付形式である事、保管する期間が過ぎたファイルはバケットから削除します
if [ $? -eq 0 ] && [ ${item_date} -lt ${EXPIRE} ]; then
`aws --endpoint-url=https://s3.isk01.sakurastorage.jp/ s3 rm [バケット名]/${item}`
fi
done
これでいけるか?
と、思ったら動きがおかしい。
消したい対象のファイルが1つの場合は正常に削除出来ますが、複数あった場合、for
でちゃんと動かない。
10日より前のファイルがあったら全部消して欲しいので、これはちゃんと動くようにしたい。
どのような動きをするのか?
- 10日より前のファイルが複数ある場合、もっとも古いファイルは削除出来た。
- しかし次のファイルを消そうとすると
delete:: コマンドが見つかりません
と出た。
ちょっと理由は分かりませんでした。
連続して命令が出せない様になっているのか、rm
コマンドはループしない方がいいのか、理由を知ってる方がいらっしゃいましたら教えて欲しいです。
試しに s3api を使ってみた
- S3のAPI経由で削除してみる。
#!/bin/bash
# バケットに保管する期限
readonly EXPIRE=`date -d '10 day ago' +"%Y%m%d"`
# バケットにあるオブジェクトのリストを取得します
items=`aws --endpoint-url=https://s3.isk01.sakurastorage.jp/ s3 ls [バケット名] | awk '{print $4}'`
for item in ${items}
do
# ファイル名に含まれた日付の部分を抽出します
item_date=`echo ${item} | sed -e 's/^bkup_\([0-9]\+\).tar.gz/\1/'`
# 日付形式になっているか確認します
`date '+%Y%m%d' -d ${item_date} > /dev/null 2>&1`
# 取得した値が日付形式である事、保管する期間が過ぎたファイルはバケットから削除します
if [ $? -eq 0 ] && [ ${item_date} -lt ${EXPIRE} ]; then
- `aws --endpoint-url=https://s3.isk01.sakurastorage.jp/ s3 rm [バケット名]/${item}`
+ // 値が空だったら終了 ※
+ if [ -z ${item} ]; then
+ exit 0
+ fi
+ `aws s3api delete-object --endpoint-url=https://s3.isk01.sakurastorage.jp/ --bucket [バケット名] --key ${item}`
fi
done
s3api
だとちゃんとループして複数のファイルを削除出来ました。
ただ注意しないといけないのが、--key
に渡す値が空だと、バケットの中身を全部消しちゃいます。
う〜〜ん。怖い・・・・
なので、事前に値が空だったら終了というようにしています。
↓ ↓
// 値が空だったら終了 ※
if [ -z ${item} ]; then
exit 0
fi
あとは、このスクリプトファイルを Cron で実行させれば、自動削除の完成です。
まとめ
うまく複数のファイルをループして消せましたが、やり方を間違えるとバケットの中身が一瞬で全消しされるので、参考程度で(・ω・;)
使う場合は自己責任でお願いします。
あと、もっと効率よく、さくらオブジェクトストレージで定期的にオブジェクト削除出来るやり方がありましたら教えて下さい!