|||||||||||||||||||||

なんぶ電子

- 更新: 

MariaDB 暗号化されたテーブルをdump

MariaDB-Backup

いつもMariaDBデータベースのバックアップを取る時、mysqldumpを使っていました。 この方式だとdumpファイルがプレーンテキストになってしまうため、MariaDBのテーブルを暗号化する意味が薄れてしまうことに気づきました。 その代替を探したところMariadb-Backupというパッケージがあることがわかりました。 これは従来のmysqldumpと違い、/var/lib/mysql 内にあるデータベースを構築するためのファイルを直接コピーするものです。 暗号化されたテーブルはOSベースでそのまま保存されるのでファイルから復元される可能性を低くすることができます。

筆者はDebian13を使用しているので、その環境で話をします。

インストールとバックアップ

関連パッケージなので通常はaptからの追加インストールが必要になると思います。

# apt install mariadb-backup

バックアップを実行する場合には、/var/lib/mysql配下のファイルを操作する権限(管理者権限)が必要です。通常のユーザー権限でもコマンドの実行はできますが、中止 や abort というメッセージで止まります。

OSとは別にデータベースの権限も必要で、LOCK TABLES 等を持ったユーザーを指定する必要があるようです。わからなかったら rootを指定すればいいと思います。

次のコマンドで、ファイルコピーを実行します。バックアップ取得時はデータベースのサービスを停止させる必要はありません。

ファイルコピー実行

mariabackup --backup \
  --target-dir=[バックアップ先DIR] \
  --user=[DBのユーザー] \
  --password=xxxxxxx
  • --target-dir

    --target-dirには、あらかじめ作成しておいた空のディレクトリへのパスを指定します。ここにコピーされたデータベースの設定・データファイルがファイルが入ります。

  • --user

    内部的にデータベースへのアクセスもするので、その再に使うデータベースのユーザーを指定します。権限がないとえらーになります。

  • --password

    データベース接続時のパスワードです。省略すると、パスワードなしではアクセスできないという旨のエラーが出るので、コマンドラインからの入力が必須のようです。気になるようなら history -c 等を実行してあとでコマンド履歴を消しておきます。

実行後 completed OK! のメッセージが出ればコピーは完了です。後続の処理に進みます。

よくあるエラー

InnoDB環境でテーブル毎にファイルを持っていたりすると、ファイルのオープンの上限の都合で、次のようなエラーになることがあります。

[ERROR] InnoDB: Error number 24 means 'Too many open files

現在のファイルオープン数の上限を確認するには ulimit コマンドを使います。ソフトリミットとハードリミットがあり、通常はソフトリミット < ハードリミットとなっているはずです。

筆者の場合ソフトリミットが、1024 ハードリミットが 65535 だったので、一時的にソフトリミットを 65535 にしました。

確認方法

  ulimit -n ←ソフトリミットの確認
  ulimit -Hn ←ハードリミットの確認

一時的な修正をしたいなら、ulimit n [上限数]の形でできます。リーブートしたり、設定し直せば元に戻せます。

mariadb-backup実行後の処理

コピー取得後には後処理をして初めてバックアップとなります。そのままだと例えるならクラッシュ直後の状態で、不整合が起きている可能性があるので、mariadb-backup実行後にそのチェックを行います。

prepare処理

mariabackup --prepare --target-dir=[バックアップ先DIR]

先ほど同様に completed OK! のメッセージが出れば完了です。これでバックアップがとれました。

注意点としては my.cnfや50-server.cnfといった設定ファイルや、ログファイル、SSL化時の暗号化ファイルは対象とならないようです。テーブルを暗号化している時は暗号化キーもコピーの対象になっていないので、個別に処理をするようにしましょう。

正確にはbackup-my.cnfというかたちで、cnfファイルが生成したバックアップ無いに含まれますが、どこの設定をコピーしてきているかいまいち不明なので個別にコピーを取る方がいいです。

また、対象は/var/lib/mysqlのファイルですが、ユーザが任意でそこに保存したものや初期化済みバージョン管理ファイルであるdebian-x.y.flagなどは対象とならないようでした。

圧縮

mysqldumpでは対象のデータベースが複数あっても一つのファイルにまとまっていました。

mariadb-backupではバックアップの構造がディレクトリなので、コピー漏れ等を誘発しそうです。

ディスクの容量的にも、圧縮しておくのがいいと思います。

最近はtar.gzより、zstandard (tar.zst)が使われるようになってきたのでそれで保存します。zstdコマンドでオプションを指定して使うこともできますが、zstandardは圧縮だけでディレクトリ構造は保存しないののでtarが必要になるのに加え、tarにzstandardオプションがあるので tarから操作します。

tar --zstd -cvf mariabkup.tar.zst [バックアップ先DIR]

復元

MariaDB Backupのバージョン間の互換性は、メジャーバージョン間で保証されるようです。ただし注意が必要なのはMariaDBのメジャーバージョンは、10.xと最初の.以下を含むということです。

近辺のバージョンで、下位から上位ならなら自動で行われる mysql_upgrade でうまくいくこともあるようです。

tar.zstにしていた場合は展開します。

$tar --zstd -xvf backup.tar.zst

復元時はデータベースを止め、データベース設定・データディレクトリを消します。デフォルトの場合は/var/lib/mysqlとなると思いますが、これをディレクトリごと消去します。

 # systemctl stop mariadb
 # rm -r /var/lib/mysql
 削除が心配ならリネームにします。データベースを止めてますのでこちらは差分を考える必要はないです。
 # mv /var/lib/mysql /var/lib/mysql.bak

mariadb-backupの復元コマンドを実行します。バックアップ生成時もそうでしたが、/var/lib/mysqlディレクトリを操作するのでOSの管理者権限が必要です。

ファイル復元後、一連のファイルの権限と所有権の見直しが必要です。

わからない場合は元の環境を確認しておくのが一番だと思いますが、筆者の場合は、所有権はすべて mysql:mysqlとなっていました。

ログはバックアップの対象でないですが、mariadb-backupはどうやら/var/log/mysql/lib/logfile0を書き出そうとするようです。root権限で復元するとこのファイルの所有権がrootになってしまい後でMariaDBを起動できなくなります。ですので、このファイルの所有権をmysql:admにする修正する必要もあります。存在するとエラーになりますので、/var/log/mysql/の中身を削除します。

log側のmysqlは親ディレクトリの権限がdrwxr-s--となっています。sは新規作成時親ディレクトリのグループを設定するビット(setgid ビット)ですもし消してしまったら、2750と設定し所有権はmysql:admです。

中身は、slowlogとerrorlogだけは権限が640で他は、660です。所有権はmysql:admです。

 # mariabackup --copy-back --target-dir=[バックアップ先DIR]
 所有権をすべてmysql:mysqlに
 # chown -R mysql:mysql /var/lib/mysql
 # chown -R mysql:mysql /var/lib/mysql
 # 権限の修正ディレクトリ750(mysqlディレクトリだけは755) ファイル660
 # find /var/lib/mysql -type d -exec chmod 750 {} \;
# chmod 755 /var/lib/mysql

必要に応じて設定(cnf)ファイルや、ログ(バイナリログ)、暗号化キー等をあわせて復元させます。

データベースを起動させ、無事起動できれば成功です。

# systemctl stop mariadb

参考までに元権限と所有権と、バックアップの対象か否かはこんな感じでした。

/var/lib/mysql

drwxr-xr-x 12 mysql mysql mysql

/var/lib/mysql/*

-rw-rw---- 1 mysql mysql aria_log.00000001
-rw-rw---- 1 mysql mysql aria_log_control
-rw-r--r-- 1 root  root  debian-10.5.flag×
-rw-rw---- 1 mysql mysql ib_buffer_pool×
-rw-rw---- 1 mysql mysql ib_logfile0
-rw-rw---- 1 mysql mysql ib_logfile1×
-rw-rw---- 1 mysql mysql ibdata1
-rw-rw---- 1 mysql mysql ibtmp1×
-rw-rw---- 1 mysql mysql multi-master.info×
drwx------ 2 mysql mysql mysql
-rw-r--r-- 1 mysql mysql mysql_upgrade_info×
drwx------ 2 mysql mysql performance_schema
drwx------ 2 mysql mysql [データベースdir]

[データベースdir]の中のテーブル構造とデータは権限660 所有権mysql:mysql でした。

×:筆者の確認したところではバックアップには含まれませんでした。

メジャーバーバージョンの違いは保証されないとの事でしたが、debian-10.5 から debian-11.8 の移行で、とりあえず稼働することができました。

レプリケーションにも対応

レプリケーションを動かしている場合は、mariadb-backupがバックアップ時に バイナリログ座標(レプリケーションの位置情報)を保存してくれます。これを使えば、レプリカを復元する際に どの位置からレプリケーションを再開するか が分かります。

バックアップディレクトリの中にある xtrabackup_binlog_info というファイルがそれです。

xtrabackup_binlog_info

uuid =xxxxxxx
name =
tool_name = mariabackup
...  
binlog_pos = filename 'mysql-bin.000123', position '456789012'
...

レプリケーション作成のために設定ファイルをコピーして使う際は、IDの重複に注意してください。

直接関係ないですけど、新しいバージョンレプリケーションの設定はデフォルトでSSL接続をするようで、筆者の場合次のエラーに悩まされました。

SSL connection error: SSL is required but the server doesn't support it

これは、親側がSSL接続をうけつけない状態で、SSL接続を試みると出るエラーで、change masterのコマンドで、SSL接続を試みないように設定可能です。

MariaDBコンソール

CHANGE MASTER TO
  MASTER_HOST='192.168.1.100',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl_pass',
  MASTER_PORT=3306,
  MASTER_SSL=0 '0でSSL接続をしない 1はする
  MASTER_SSL_CA='/etc/mysql/ssl/server-selfsigned.pem', -- ← サーバの自己署名証明書を配る
  MASTER_SSL_VERIFY_SERVER_CERT=1; //証明書の検証の有無

作業時にchatGPTの回答を参考にしいます。実際に試して確認のとりながら記事しておりますが、一部鵜呑みの部分もあります。あらかじめご了承ください。

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告