古いバックアップファイルを定期的に削除する (Linux)

SOFTWARE


古いバックアップファイルを削除する

バックアップを cron などを利用して定期的に取得することがあると思います。

今回はそうやって自動的に取得されたバックアップを、特定のタイミングで消去する方法について考えてみたいと思います。

 

一定期間経過したファイルを自動的に削除する方法としては、想定した期間よりも古いファイルを見つけてそれを削除するという処理を定期的に行うという方法が考えられます。

たとえば、バックアップファイルが /var/backup/ ディレクトリーに *.bak というファイル名で保存されているとした場合、このフォルダーから例えば 360 日以上経過したファイルを見つけ出すには、次のコマンドで実行できます。

find /var/backup -name '*.bak' -mtime '+360'

/var/backup ディレクトリーから *.bak という名前の、最後に編集されてから 360 日以上経過したファイルを見つけ出すという意味になります。

 

さらには、この find というコマンドは -exec \; という形で、該当するファイルに対して任意の処理を行うことができるようになっています。このとき、対象のファイル名は {} で取得することが可能です。

つまり、該当するファイルについて、それらを削除したい場合には、次のようにすることで実現することが可能です。

find /var/backup -name '*.bak' -mtime '+360' -exec rm -f {} \;

rm というコマンドは Linux でファイルを削除するときに使用するコマンドです。

find の -exec の中で実行すると "{}" が対象のファイル名に置き換えられて、見つかったファイルの数だけ実行されるので、これで、該当するファイルが全て削除できることになります。-f オプションを指定しているのは、ユーザーへの確認なく削除を自動実行するためです。

なお、このとき -exec で実行したいコマンドの入力を終えた最後に "\;" を指定するのを忘れないようにします。

 

バックアップを定期的に圧縮したい場合

アクセスログなどで、ある程度の間は手軽に見れるようにしておきたいけれど、それ以上は圧縮してディスク領域を節約したいという時にも、上記と同じ方法で実現することができます。

find /var/backup -name '*.bak' -mtime '+360' -exec gzip {} \;

ファイルを削除する rm コマンドの代わりに、ファイルを圧縮する gzip コマンドを指定しています。

gzip の引数としてファイル名 (ここでは "{}" で find が見つけたファイル名) を指定することで、そのファイルを LZ77 圧縮をして、元のファイルをファイル名に拡張子 ".gz" を付加したファイルに置き換えます。

 

SCP を利用して別サーバーに退避する場合

cron と SCP を利用して、SSH 経由で別サーバーへ定期的にファイルを移動することも可能です。

このとき RSA/DSA 鍵による認証をを利用することで、パスワードの入力なしに SCP を利用することもできるようになります。

 

まずはバックアップを実行するサーバー上で、SSH 接続で使用する鍵ペアを生成します。

ここで作成した鍵、特に秘密鍵ファイルは、バックアップ処理を実行する際の実効アカウントが読み込めるようにしておく必要があるので、バックアップを実行するアカウントでログインした状態で鍵を作るのが効率的かもしれません。

バックアップ元のサーバーへログインしたら、次のようにして認証用の鍵を作成します。

ssh-keygen -t rsa

このようにすると、鍵ペアの保存場所及び名前 (~/.ssh/id_rsa) とそれに設定するパスフレーズの入力を求められます。

保存するファイル名としては、今回は例えば ~/.ssh/scp-backup.key としておくと、秘密鍵 "~/.ssh/scp-backup.key" および公開鍵 "~/.ssh/scp-backup.key.pub" が作成されます。ちなみに "~/" は、現在のアカウントのホームディレクトリーです。

また、このときパスフレーズとして何も設定しないことで、パスワードなしでの RSA 鍵による SSH 接続が可能になります。

 

鍵ペアが作成出来たら、公開鍵の内容をバックアップ先のサーバーへ設定します。

そのために、まずはバックアップで使用するユーザーアカウントを転送先のサーバー上に用意します。

ここでは仮に "backup_user" を作成しておくことにしました。今回はパスワードなしで認証鍵による SSH ログインをしようとしていますので、安全のため、バックアップ用のアカウントには最低限の権限のみを与えるように配慮します。

 

アカウントを作成したら、そのアカウントで転送先サーバーへログインして、"~/.ssh/authorized_keys" ファイルに先ほど作成した公開鍵の内容を 1 行で記載しておきます。

既に "authorized_keys" が存在している場合には、新しい行に記載すれば大丈夫です。ファイル内で # で書き始めた行はコメントとして扱われるので、複数の公開鍵を記載する場合には、説明文を入れておくのも良いかもしれません。

このファイルは、かならず SSH 接続する際に使用するアカウントのホームディレクトリーにある .ssh ディレクトリー内に用意する必要があるので注意しましょう。

 

ここまでできれば、バックアップ元のサーバーからバックアップ先のサーバーへ、パスワードなしで scp によるファイル転送ができるようになったと思います。

後は例えば、バックアップ元のサーバーにある "/var/backup" ディレクトリー内の "*.gz" ファイルを、バックアップ先のサーバー (DST_SERVER) にある "~/backup" へ複製したい場合には、次のようなコマンドをバックアップ元のサーバーで実行することになります。

scp -oIdentityFile=~/.ssh/scp-backup.key /var/backup/*.gz backup_user@DST_SERVER:~/backup/

このようにすることで、バックアップ元の "/var/backup/*.gz" ファイルが、バックアップ先のサーバー "DST_SERVER" 上の "backup-user" アカウントのホームディレクトリー上にある "backup/" ディレクトリーへコピーされることになります。

このとき、scp が利用する SSH 接続は "backup_user" アカウントで接続が試みられ、その時の認証として "~/.ssh/scp-backup.key" という秘密鍵が使用されます。

 

これで、パスワードの入力の必要なく、ファイルを別サーバーへコピーすることが出来るようになりました。

このコマンドを cron 等で自動実行させることで、特定のタイミングで別サーバーへ自動的にファイルを退避するといったこともできるようになります。

 

scp でコピーした "/var/backup/*.gz" を転送後に削除したい場合には、"&&" を使って rm コマンドを連結することで、scp が成功後にファイルを削除するという流れを作ることも可能です。

scp -oIdentityFile=~/.ssh/scp-backup.key /var/backup/*.gz backup_user@DST_SERVER:~/backup/ && rm -f /var/backup/*.gz

このように cron や scp を組み合わせることで、さまざまなバックアップの自動化を図ることが出来るようになると思います。

なお、まだ確かめてはいないのですけど、scp の代わりに rsync を利用したい場合にも、rsync に [ -e 'ssh -l backup_user -i ~/.ssh/scp-backup.key' ] というようなオプションをつけてあげることで、鍵ファイルでの認証を行うことができるようでした。