はじめに
Discord BotなどでMySQLを利用するようになって結構経ったので、レコード数が増えてきました。そのため、何かの拍子でサーバが壊れてしまったときなどに備え、定期的にMySQLのバックアップをLANDISKに作成しようと考えました。
今回はその方法をまとめようと思います。
環境
- Ubuntu 24.04.4 LTS
また、以下ではsudoユーザーで操作することを仮定します。
LANDISKのマウント
まず、接続するLANDISKのIPアドレスとユーザ名・パスワードを控えておきます。
そして、以下のコマンドでcifs-utilsをインストールします。
apt update && apt install cifs-utils -y
次に、以下のコマンドでマウントポイントを作成します。
mkdir -p /mnt/landisk
先ほど控えたユーザ名・パスワードは以下のファイルに保存します。
vi /root/.smbcreds
ファイルの中身は以下のようにします。
username=your_landisk_user
password=your_landisk_password
このファイルは他のユーザーから読み書きできないようにしておきましょう。
chmod 600 /root/.smbcreds
そして、以下のファイルを編集し、マウントができるようにします。
vi /etc/fstab
このファイルの末尾に以下を追記しましょう。
//www.xxx.yyy.zzz/backup /mnt/landisk cifs credentials=/root/.smbcreds,iocharset=utf8,uid=root,gid=root,file_mode=0700,dir_mode=0700,vers=1.0 0 0
//www.xxx.yyy.zzz/backupの所は実際のIPアドレス・パスに変更しましょう。file_mode=0700,dir_mode=0700の所では、マウントしたディレクトリの権限をrootのみに制限しています。
versの所はLANDISKに合わせて変更します。新しいものだと3.0 0 0で行けますが古いものだと1.0 0 0にする必要があります。接続に失敗するとエラー文が出るので、それを参考に調整すると良いです。
では最後に、マウントできるか確認します。以下のコマンドを実行し、特にエラー文が出なければ接続成功です。
mount -a
マウントが成功すると、以下のコマンドでLANDISKの中身が参照できます。
ls /mnt/landisk/
スクリプトファイルの用意
では次に、バックアップ処理を行うスクリプトを用意しましょう。
事前に、ローカルでバックアップを置いておく場所を用意しましょう。
mkdir -p /root/backup/mysql
次にスクリプトを作成します。
vi /root/backup4mysql.sh
スクリプトの内容は以下のようにします。
#!/bin/sh
# 他のユーザからバックアップを読み込めないようにする
umask 077
# バックアップファイルを何日分残しておくか
period=10
# バックアップを保存するディレクトリ
dirpath='/root/backup/mysql'
# LANDISKのマウントポイントと保存先ディレクトリ
mount_point='/mnt/landisk'
landisk_dirpath="${mount_point}/mysql"
# ファイル名を定義
filename=`date +%y%m%d`
oldfile=`date --date "$period days ago" +%y%m%d`
# ローカルに保存(rootパスワードは適宜変更)
mysqldump --opt --all-databases --events --default-character-set=binary -u root --password="xxx" | gzip > "$dirpath/$filename.sql.gz"
# ローカルの古いファイルを削除
rm -f "$dirpath/$oldfile.sql.gz"
# マウントされているか確認
if mountpoint -q "$mount_point"; then
mounted=true
else
# 外れている場合は再マウントを試みる
mount "$mount_point"
# 再マウント後に再度確認
if mountpoint -q "$mount_point"; then
mounted=true
else
mounted=false
fi
fi
# マウントされている場合のみコピーと削除を実行
if [ "$mounted" = true ]; then
# LANDISKへコピー
cp "$dirpath/$filename.sql.gz" "$landisk_dirpath/"
# LANDISKの古いファイルを削除
rm -f "$landisk_dirpath/$oldfile.sql.gz"
else
# マウントに失敗した場合は、エラーログを残す
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: LANDISK is not mounted. Skipped network backup." >> /var/log/mysql_backup_error.log
fi
処理の流れは以下のようになっています。
- バックアップファイルの名前や保存先を定義
- MySQLのダンプデータを取得・圧縮してローカルに保存
- LANDISKがマウントされているか確認、外れていたら再マウント
- マウントに成功した場合、LANDISKの所定位置にバックアップファイルを保存、エラーの場合はログを残す
ディスク容量の圧迫を防ぐために10日以前のバックアップは自動で削除するようになっています。何日残すかはperiodで設定できます。
たまにLANDISKのマウントが外れてしまう事があるので、実行時に正しくマウントされているかの確認・必要なら再接続を行います。
スクリプトファイルにはrootのパスワードを記載しているので、先ほどと同様にrootユーザ以外から読み書きできないようにしておきます。
chmod 700 /root/backup4mysql.sh
最後に、一連の動作が正しく行われるかスクリプトを直接実行してテストしましょう。
/root/backup4mysql.sh
/root/backup/mysql/及びLANDISKの所定のフォルダに.gzファイルが保存されていれば成功です!
定期実行の設定
最後に、cronを設定して毎日朝3時にバックアップが取得されるようにしておきましょう。
echo "0 3 * * * root /root/backup4mysql.sh" > /etc/cron.d/backup4mysql
取得時間は適宜都合のいいように設定できます。
これにて設定は終了です!
おわりに
ローカルだけでなくLANDISKにもバックアップを作成したことで、重要なデータが失われる可能性が軽減されたので安心しています。冗長性は大事ですね。
今回はMySQLのバックアップを取ったのですが、同じ要領で別のサービスのバックアップも作成できそうですね。それも機会があればやってみたいです。
それではまた。