PerconaといえばXtraBackup!! といっても過言ではないこの機能。
バックアップ手法はいくつかあれど、少なくともmysqldumpを使うくらいならXtraBackupを使っとけばいいと思います。手始めに、簡単な使い方から紹介していきます。
はじめに
インストールについては前にまとめてあり、単にパッケージインストールするだけになっています。バージョンは必ず最新を使ってください。だいぶ安定してきたとはいえ、バグフィックスは常にされており、特に v2.0.0 では8GBを超えるデータの際にエラーが起こるため、修正されています(参照:Announcing Percona XtraBackup 2.0.1)。
XtraBackupはmysqldumpと比べると、バックアップ作成速度が遅くなったり、データ容量が大きくなったりする場合がありますが、その代わりに以下のようなメリットがあります。
有償であるMySQL Enterprise Backupと比べても優秀であるとも謳っています。
実際の運用では xtrabackup コマンドではなく、より多様な機能を持たせたラッパースクリプトである innobackupex を使用することになると思いますが、まずは xtrabackup単体で理解してからの方がよいです。
xtrabackupの設定
xtrabackupはログファイルを作成したりするので、MySQLの設定を必要とします。設定は稼働中のMySQLからではなく、全て my.cnf ファイルから読み込むので、変わった書き方をしているとxtrabackupがパースできないかもしれません。xtrabackup –help
これはヘルプだけでなく使用しようとする設定値なども表示されます。my.cnf の読み込み順序
公式の Using Option Files と少し違っていて、こんな感じです。実際のVariables
下部には実行時に利用する値が見れますので、一度確認しておくとよいです。xtrabackup –print-defaults
これで、コマンドライン形式で、実行時の設定値を確認できます。xtrabackup –print-param
中でも、これで表示される設定が、xtrabackupにおいて重要な項目になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# This MySQL options file was generated by XtraBackup. [mysqld] datadir = "/fio/mysql" tmpdir = "/fio/mysql_tmp" innodb_data_home_dir = "/fio/mysql" innodb_data_file_path = "ibdata1:10M:autoextend" innodb_log_group_home_dir = "/fio/mysql" innodb_log_files_in_group = 2 innodb_log_file_size = 104857600 innodb_flush_method = "O_DIRECT" innodb_fast_checksum = 0 innodb_page_size = 16384 innodb_log_block_size = 4096 |
–print-param 以外の設定
innodb_file_per_table が設定されていなければ、データファイルが1ファイルになり、設定されていればテーブル毎のファイルになります。バックアップで抽出したファイル構成も元の構成のままになります。xtrabackupには Partial Backups というテーブル単位の部分的なバックアップ機能がありますが、innodb_file_per_table がONのデータでないと利用できません。
xtrabackup特有のオプションをmy.cnfに記述する
Configuring xtrabackup に記載されていますが、–target-dir といったxtrabackupのオプションは my.cnf に書いておくことができます。
1 2 |
[xtrabackup] target_dir = /fio/mysql_backup/ |
my.cnfで設定しない方がよい項目
通常の運用とも関係しますが、バックアップを取得する
シンプルに取得してみます。log scanned up to の数値が増加している部分は、更新クエリが発行されたタイミングです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# mkdir /fio/mysql_backup # xtrabackup --backup --datadir=/fio/mysql/ --target-dir=/fio/mysql_backup/ xtrabackup version 2.0.2 for Percona Server 5.1.59 unknown-linux-gnu (x86_64) (revision id: undefined) xtrabackup: uses posix_fadvise(). xtrabackup: cd to /fio/mysql/ InnoDB: The log block size is set to 4096. xtrabackup: Target instance is assumed as followings. xtrabackup: innodb_data_home_dir = ./ xtrabackup: innodb_data_file_path = ibdata1:10M:autoextend xtrabackup: innodb_log_group_home_dir = ./ xtrabackup: innodb_log_files_in_group = 2 xtrabackup: innodb_log_file_size = 104857600 xtrabackup: using O_DIRECT 120918 16:02:40 InnoDB: Warning: allocated tablespace 11, old maximum was 9 >> log scanned up to (2701786932) [01] Copying ./ibdata1 to /fio/mysql_backup/ibdata1 [01] ...done [01] Copying ./sbtest/sbtest.ibd to /fio/mysql_backup/./sbtest/sbtest.ibd >> log scanned up to (2701789249) >> log scanned up to (2701789747) [01] ...done >> log scanned up to (2701789747) xtrabackup: The latest check point (for incremental): '2701789249' xtrabackup: Stopping log copying thread. .>> log scanned up to (2701789747) xtrabackup: Transaction log of lsn (2701786932) to (2701789747) was copied. |
出来上がったファイルは
1 2 3 4 5 6 7 |
# ls -hl /fio/mysql_backup/* -rw-r----- 1 root root 218M 2012-09-18 16:02 /fio/mysql_backup/ibdata1 -rw-r----- 1 root root 83 2012-09-18 16:02 /fio/mysql_backup/xtrabackup_checkpoints -rw-r----- 1 root root 24K 2012-09-18 16:02 /fio/mysql_backup/xtrabackup_logfile /fio/mysql_backup/sbtest: -rw-r----- 1 root root 1.0G 2012-09-18 16:02 sbtest.ibd |
チェックポイントファイルの中身は
1 2 3 4 |
backup_type = full-backuped from_lsn = 0 to_lsn = 2701789249 last_lsn = 2701789747 |
この出来上がったファイルがバックアップファイルになります。
圧縮アーカイブでバックアップする
上記の方法だと、容量がそのままだし、1ファイルじゃないから他サーバに転送して管理するのが汚らしかったりするので、ちゃんと圧縮アーカイブするとこうなります。
1 2 |
xtrabackup --backup --datadir=/fio/mysql/ --target-dir=/fio/mysql_backup/ \ --stream=tar | gzip - > /fio/mysql_backup/xtrabackup.tar.gz |
できたファイルがこれ。ついでに mysqldump –all-databases でもとってみた。この例だとmysqldumpの方がかなり小さいですが、圧縮率はどちらも十分です。
1 2 3 4 5 6 7 8 |
# ls -hl /fio/mysql_backup/ -rw-r--r-- 1 root root 12M 2012-09-18 13:39 mysqldump.sql.gz -rw-r--r-- 1 root root 85M 2012-09-18 13:52 xtrabackup.tar.gz # gzip -l /fio/mysql_backup/*.gz compressed uncompressed ratio uncompressed_name 11878715 298130813 96.0% /fio/mysql_backup/mysqldump.sql 88161071 1302364160 93.2% /fio/mysql_backup/xtrabackup.tar |
中身の確認・解凍は -i オプションが必要です。
1 2 3 4 5 |
# tar itzf /fio/mysql_backup/xtrabackup.tar.gz ibdata1 ./sbtest/sbtest.ibd xtrabackup_checkpoints xtrabackup_logfile |
解凍したら通常バックアップと同じファイル群が出てきます。
バックアップエラー例
一息入れて簡単なエラー例。一般ユーザで実行する
mysqlユーザのデータファイルが読めないのでエラーになります。
1 2 3 4 5 6 |
InnoDB: Operating system error number 13 in a file operation. InnoDB: The error means mysqld does not have the access rights to InnoDB: the directory. InnoDB: File name ./ibdata1 InnoDB: File operation call: 'open'. InnoDB: Error in opening ./ibdata1 |
バックアップ済みのディレクトリに再実行する
上書きはできないようになっています。
1 2 3 |
InnoDB: Warning: allocated tablespace 11, old maximum was 9 xtrabackup: Can't create/write to file '/fio/mysql_backup/xtrabackup_logfile' (Errcode: 17) xtrabackup: error: cannot open /fio/mysql_backup/xtrabackup_logfile (errno: 17) |
リストアの準備
取得したバックアップファイルはそのままでは利用できないので、ログファイルを適用して完全なデータファイルにしてあげます。ログファイルの適用
prepareを実行します。この作業は、データファイルを編集するだけなので、バックアップファイルとxtrabackupが存在するサーバであればどこでも実行することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# xtrabackup --prepare --target-dir=/fio/mysql_backup/ ~snip~ InnoDB: Log scan progressed past the checkpoint lsn 2701786932 120918 16:50:00 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace information from the .ibd files... InnoDB: Doing recovery: scanned up to log sequence number 2701789747 (0 %) 120918 16:50:00 InnoDB: Starting an apply batch of log records to the database... InnoDB: Progress in percents: 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 InnoDB: Apply batch completed InnoDB: Last MySQL binlog file position 0 1042, file name /fio/mysql_log/bin/bin.000014 120918 16:50:01 Percona XtraDB (http://www.percona.com) 1.0.17-12.5 started; log sequence number 2701789747 [notice (again)] If you use binary log and don't use any hack of group commit, the binary log position seems to be: InnoDB: Last MySQL binlog file position 0 1042, file name /fio/mysql_log/bin/bin.000014 xtrabackup: starting shutdown with innodb_fast_shutdown = 1 120918 16:50:01 InnoDB: Starting shutdown... 120918 16:50:01 InnoDB: Shutdown completed; log sequence number 2701789747 |
これでデータファイルをリストアする準備ができました。
新規ログファイルの作成
MySQLを起動した時に、InnoDBログファイルが存在しない場合は勝手に作成してくれますが、その時間を省くために予め作成しておくことができます。なので実行は必須ではないですが、完全な準備とすることができます。コマンドは1度目のprepareと全く一緒です。
1 2 3 4 5 6 7 8 9 10 11 |
# xtrabackup --prepare --target-dir=/fio/mysql_backup/ ~snip~ 120918 17:03:04 InnoDB: Log file ./ib_logfile0 did not exist: new to be created InnoDB: Setting log file ./ib_logfile0 size to 100 MB InnoDB: Database physically writes the file full: wait... InnoDB: Progress in MB: 100 120918 17:03:04 InnoDB: Log file ./ib_logfile1 did not exist: new to be created InnoDB: Setting log file ./ib_logfile1 size to 100 MB InnoDB: Database physically writes the file full: wait... InnoDB: Progress in MB: 100 ~snip~ |
my.cnf に書いてあるサイズと数でログファイルが作成されました。
1 2 3 4 |
# ls -l /fio/mysql_backup/ib* -rw-r--r-- 1 root root 104857600 2012-09-18 17:03 /fio/mysql_backup/ib_logfile0 -rw-r--r-- 1 root root 104857600 2012-09-18 17:03 /fio/mysql_backup/ib_logfile1 -rw-r----- 1 root root 228589568 2012-09-18 17:03 /fio/mysql_backup/ibdata1 |
リストアを実行する
別途復旧するファイル
見ての通り、ここまでの方法でできたファイルは ibdata, .ibd, ib_logfile だけであり、以下のファイルが不足しています。これらは、手動でコピーしてくる必要があるのですが、実際には innobackupex を利用することで全て自動で取得してくれます。xtrabackupはあくまでもXtraDBのバックアップ機能という位置付けなのでこのようになっています。
めんどうですが今回は手動でコピーしてきます。
1 2 3 4 5 6 |
/etc/init.d/mysql stop cp -R /fio/mysql/mysql /fio/mysql_backup/ cp -R /fio/mysql/performance_schema /fio/mysql_backup/ cp -R /fio/mysql/sbtest/*.frm /fio/mysql_backup/sbtest/ cp -R /fio/mysql/sbtest/*.MYD /fio/mysql_backup/sbtest/ cp -R /fio/mysql/sbtest/*.MYI /fio/mysql_backup/sbtest/ |
次に権限を変更します。
1 2 3 4 5 6 7 |
chmod -R 660 /fio/mysql_backup/ chown -R mysql:mysql /fio/mysql_backup/ # DBディレクトリだけ実行権限が必要(階層下を見る必要がある) chmod 755 /fio/mysql_backup/mysql chmod 700 /fio/mysql_backup/performance_schema chmod 700 /fio/mysql_backup/sbtest |
最後に元データと入れ替えて起動して完了です。
1 2 3 |
mv /fio/mysql /fio/_mysql-20120908 mv /fio/mysql_backup /fio/mysql /etc/init.d/mysql start |
起動しない場合はエラーログを確認して修正します。
この基本手順でわかりやすいメリットはリストアです。
mysqldumpもxtrabackupでも、実際にはバックアップサーバから転送して~解凍して~は同じですが、リストア処理は、mysqldumpのようなクエリ実行型では遅くて所要時間も予測しづらかったのが、xtrabackupになるとちょいとprepareして丸ごと入れ替えるだけなので圧倒的にわかりやすく速いです。
ただ、ロックは必要ないといっても、可能な限りSLAVEサーバ、しかもできれば参照すらしないバックアップ用サーバで実行することが理想であることは変わりません。また、小さい容量で少アクセスなデータベースの場合はmysqldumpの方が圧倒的に使いやすいですので、環境に応じて適切な箇所で利用するのが肝心です。
次回は、もう少し踏み込んだ機能について紹介します。