hatenob

プログラムって分からないことだらけ

一人Web開発~第14夜 MariaDBバックアップ

バックアップを取る時に、その目的は大体2つ。

  • 障害復旧用
  • 調査、解析、監査等の保存用

障害復旧の場合は、物理障害対策であれば1世代前まであれば十分で、論理障害対策であれば最大何世代前まで戻したいかによります。
調査、解析、監査用であればそれぞれどの程度過去の情報まで遡って参照できる必要があるかを決める必要があります。障害調査なら前日くらい、性能分析なら1ヶ月サマリレポート作れるくらい、アクセス・操作履歴は単なる分析用であればそれほどいらいないけれど、セキュリティ事故発生時の調査に使う監査目的であれば1年とか3年とか5年とか。ただしいずれも、サーバ上に残す期間と、別媒体やバックアップサーバ等の保存先に残す期間は整合性を保ったうえで別々に決める必要があります。

バックアップの目的

MariaDBのバックアップは障害復旧目的で取得します。
今回は運用をしていくわけではないので、1世代残れば十分です。

バックアップ方式

MariaDBでは標準で論理バックアップ(mysqldump)と、物理バックアップ(mysqlhotcopy)が使用できます。物理バックアップにしようと思っていたら、MyISAMしか取れないっぽい?というわけで、論理バックアップにしました。
取得したSQLダンプはbz2で圧縮gzipでもいいんだけれども、bzcatとかbzlessとかで簡単に中身を見れるのでという理由で選びました。
あと、取得したSQLには生データが入るので、うっかり他のユーザから見れないように、オーナー以外の権限を取っておきましょう。
というわけでこれをシェルにしました。
色々使ってる関数とかはGithubを参照ください。

. /opt/shell/lib/constants.env
. /opt/shell/lib/functions.env

MARIADB_DATA=/var/lib/mysql
MARIADB_DATA_BACKUP=${BK_HOME}/mariadb/data/
MARIADB_DATA_BACKUP_COMPRESS=${MARIADB_DATA_BACKUP}/mariadb_dump.sql.bz2

LOG_INFO "00001"

# logical backup
cp /dev/null ${MARIADB_DATA_BACKUP_COMPRESS}
chmod 600 ${MARIADB_DATA_BACKUP_COMPRESS}

mysqldump -u root -x --all-databases | bzip2 > ${MARIADB_DATA_BACKUP_COMPRESS}
if [ 0 -eq $(bzcat ${MARIADB_DATA_BACKUP_COMPRESS} | wc -l) ]
then
  LOG_ERROR "00003" "${MARIADB_DATA_BACKUP_COMPRESS}"
  exit 1
fi

LOG_INFO "00002"
exit 0

テスト

正常系と異常系だけやっておきます。
異常系はMariaDBを停止して実行するという、ちょっと荒っぽいことをやっています。
ローカルでUTレベルならこれでいいけど、CI回す時にこれはちょっとやり過ぎかなぁとも思います。
まぁ今回はよしとしときます。

. /opt/shell/lib/constants.env
. /opt/shell/lib/functions.env
. /opt/shell/lib/test_functions.env

# test
## init
## complete
TEST="backup complete"
UTIL_LOG_SWITCH
${SH_BIN}/mariadb_backup.sh
ASSERT_EQUALS "$?" "0"
ASSERT_FILE_NOT_ZERO_BYTE  "/var/backup/mariadb/data/mariadb_dump.sql.bz2"
ASSERT_FILE_PERMISSION "/var/backup/mariadb/data/mariadb_dump.sql.bz2" "600"
ASSERT_FILE_OWNER      "/var/backup/mariadb/data/mariadb_dump.sql.bz2" "root"

ASSERT_LOG 1 "00001" "INFO"
ASSERT_LOG 2 "00002" "INFO"
UTIL_LOG_BACK

## fail
TEST="backup fail"
UTIL_LOG_SWITCH
UTIL_MESSAGE "mysql shutdown"
service mysql stop
${SH_BIN}/mariadb_backup.sh
ASSERT_EQUALS "$?" "1"
ASSERT_EQUALS "$(bzcat /var/backup/mariadb/data/mariadb_dump.sql.bz2 | wc -l)" "0"
ASSERT_FILE_PERMISSION "/var/backup/mariadb/data/mariadb_dump.sql.bz2" "600"
ASSERT_FILE_OWNER      "/var/backup/mariadb/data/mariadb_dump.sql.bz2" "root"

ASSERT_LOG 1 "00001" "INFO"
ASSERT_LOG 2 "00003" "ERROR"

UTIL_MESSAGE "mysql restart"
service mysql start

UTIL_LOG_BACK

バックアップ処理を書くのよりも、シェルのベースを作るのに随分と時間を使ってしまいました。
次は調査等保存用ログのバックアップ&ハウスキーピング。
そこまでできたらいったん完了にしたいと思います。
というわけで次回が第一期最終回の予定。