MYSQLDUMPを利用する時のOPTION確認とDUMPした後にバイナリーログを適用して、
最新のデータをリカバリーする方法の再確認。

以下のようなOPTIONでDB全体の整合性とバイナリーログのロールフォワードに必要なデータをダンプする。

–master-dataオプションと対象ロック

mysqldump --lock-all-tables --flush-logs --master-data=2 --databases test > DB_DUMP.sql -u root -p
mysqldump --single-transaction --flush-logs --master-data=2 --databases test > DB_DUMP.sql -u root -p

–lock-all-tablesと–single-transactionは同時に利用する事が出来ません。HELPを読むと–lock-all-tablesを利用すると
自動的に–single-transactionはOFFにされるようです。–single-transactionはトランザクションをサポートする
InnoDBにのみ利用可能なのでMyISAMなどには有効では無いようです。同時にオプションを指定すると以下のようなエラーになる。
また–master-dataオプションを指定している場合は自動的に–lock-all-tablesがONになるようです。
暗黙的にONになるので運用者が明確にしておく為に意図的に指定しておいても良いかもしれません。
但し、–single-transactionが指定されていると–master-dataを指定していても–lock-all-tablesはONにならない様です。

[root@HOME002 data]# mysqldump --single-transaction --lock-all-tables --flush-logs --master-data=2 --databases test > /home/mysql/MYSQL_dump20130125.sql -u root -p
mysqldump: You can't use --single-transaction and --lock-all-tables at the same time.
[root@HOME002 data]#

こちらのバックアップオプションで特定データベースもしくはDB全体をバックアップ
InnoDBやMYISAMを含む全てのデータベースをDumpする場合
(–lock-all-tablesはあえて残してあります)
例)

 mysqldump --lock-all-tables --flush-logs --master-data=2 --databases test > DB_DUMP.sql -u root -p
 mysqldump --lock-all-tables --flush-logs --master-data=2 --all-databases >  ALL_DB_DUMP.sql -u root -p

InnoDBのみ利用していて整合性の取れたデータをDumpする場合
例)

 mysqldump --single-transaction --flush-logs --master-data=2 --databases test > DB_DUMP.sql -u root -p
 mysqldump --single-transaction --flush-logs --master-data=2 --all-databases >  ALL_DB_DUMP.sql -u root -p

—————————————————
以下のHELP抜粋
—————————————————
-x, –lock-all-tables
Locks all tables across all databases. This is achieved
by taking a global read lock for the duration of the
whole dump. Automatically turns –single-transaction and
–lock-tables off.

–single-transaction
Creates a consistent snapshot by dumping all tables in a
single transaction. Works ONLY for tables stored in
storage engines which support multiversioning (currently
only InnoDB does); the dump is NOT guaranteed to be
consistent for other storage engines. While a
–single-transaction dump is in process, to ensure a
valid dump file (correct table contents and binary log
position), no other connection should use the following
statements: ALTER TABLE, DROP TABLE, RENAME TABLE,
TRUNCATE TABLE, as consistent snapshot is not isolated
from them. Option automatically turns off –lock-tables.

–master-data[=#] This causes the binary log position and filename to be
appended to the output. If equal to 1, will print it as a
CHANGE MASTER command; if equal to 2, that command will
be prefixed with a comment symbol. This option will turn
–lock-all-tables on, unless –single-transaction is
specified too (in which case a global read lock is only
taken a short time at the beginning of the dump; don’t
forget to read about –single-transaction below). In all
cases, any action on logs will happen at the exact moment
of the dump. Option automatically turns –lock-tables
off.

-F, –flush-logs Flush logs file in server before starting dump. Note that
if you dump many databases at once (using the option
–databases= or –all-databases), the logs will be
flushed for each database dumped. The exception is when
using –lock-all-tables or –master-data: in this case
the logs will be flushed only once, corresponding to the
moment all tables are locked. So if you want your dump
and the log flush to happen at the same exact moment you
should use –lock-all-tables or –master-data with
–flush-logs.

-A, –all-databases Dump all the databases. This will be same as –databases
with all databases selected.

–dump-date Put a dump date to the end of the output.
(Defaults to on; use –skip-dump-date to disable.)

-q, –quick Don’t buffer query, dump directly to stdout.
(Defaults to on; use –skip-quick to disable.)
—————————————————


MYISAMを含むデータもあるのでFULLをあえて–lock-all-tablesで取得して、
InnoDBしか含まないtestデータベースを–single-transactionで取得してます。

※本番環境では状況によって使い分けして下さい。

[root@HOME001 backup]# dumpdate=`date '+%F'`
[root@HOME001 backup]# dumpfile=MYSQL_DUMP_$dumpdate
[root@HOME001 backup]# dumpfile_dir=/home/mysql/backup/
[root@HOME001 backup]# mysqldump --lock-all-tables --flush-logs --master-data=2 --all-databases >  $dumpfile_dir$dumpfile\_ALL.sql -u root -p
Enter password:
[root@HOME001 backup]# 
[root@HOME001 backup]# mysqldump --single-transaction --flush-logs --master-data=2 --databases test > $dumpfile_dir$dumpfile\_test.sql -u root -p
Enter password:
[root@HOME001 backup]# ls -l /home/mysql/backup/MYSQL_DUMP_*                                                          
-rw-r--r--. 1 root root 516386  1月 26 11:00 2013 /home/mysql/backup/MYSQL_DUMP_2013-01-26_ALL.sql
-rw-r--r--. 1 root root   4000  1月 26 11:03 2013 /home/mysql/backup/MYSQL_DUMP_2013-01-26_test.sql
[root@HOME001 backup]#


FULLバックアップを取得したので先ずはデータの確認して、
データを追記した後に擬似的な操作ミスとしてTruncateしてデータを空にしてみる。

mysql> select * from TABLE001 order by id desc limit 0,10;
+----+----------------------+-----------------------------------------------+
| id | title                | comment                                       |
+----+----------------------+-----------------------------------------------+
| 32 | Recreate Replication | 20130125 mysql-bin.000004 and relay-bin.00000 |
| 31 | Recreate Replication | 20130125 mysql-bin.000004 and relay-bin.00000 |
| 30 | Recreate Replication | mysql-bin.000004 and relay-bin.000008         |
| 29 | Recreate Replication | mysql-bin.000004 and relay-bin.000008         |
| 28 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
| 27 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
| 26 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
| 25 | LOG20120113          | mysql-bin.000034 Take Full Backup             |
| 24 | LOG20120111--01      | after mysql-bin.000034                        |
| 23 | LOG20120111--01      | after mysql-bin.000034                        |
+----+----------------------+-----------------------------------------------+
10 rows in set (0.00 sec)

mysql>

mysql> insert into TABLE001(title,comment) values("Recreate Replication","after dump 20120126");
Query OK, 1 row affected (0.45 sec)

mysql> insert into TABLE001(title,comment) values("Recreate Replication","after dump 20120126");
Query OK, 1 row affected (0.62 sec)

mysql> insert into TABLE001(title,comment) values("Recreate Replication","after dump 20120126");
Query OK, 1 row affected (0.13 sec)

mysql> select * from TABLE001 order by id desc limit 0,10;
+----+----------------------+-----------------------------------------------+
| id | title                | comment                                       |
+----+----------------------+-----------------------------------------------+
| 35 | Recreate Replication | after dump 20120126                           |
| 34 | Recreate Replication | after dump 20120126                           |
| 33 | Recreate Replication | after dump 20120126                           |
| 32 | Recreate Replication | 20130125 mysql-bin.000004 and relay-bin.00000 |
| 31 | Recreate Replication | 20130125 mysql-bin.000004 and relay-bin.00000 |
| 30 | Recreate Replication | mysql-bin.000004 and relay-bin.000008         |
| 29 | Recreate Replication | mysql-bin.000004 and relay-bin.000008         |
| 28 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
| 27 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
| 26 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
+----+----------------------+-----------------------------------------------+
10 rows in set (0.00 sec)

mysql>


mysql> truncate table TABLE001;
Query OK, 0 rows affected (0.40 sec)

mysql> select * from TABLE001 order by id desc limit 0,10;
Empty set (0.00 sec)

mysql>

confirmation1


上記でバックアップしたダンプファイルの中身を確認してLOGのポジションを確認。

[root@HOME001 backup]# cat MYSQL_DUMP_2013-01-26_test.sql | egrep -i master
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=107;
[root@HOME001 backup]#


擬似オペミス直前まで戻す為にどのバイナリーログまで戻したら良いか確認。

最後のバックアップから全てのデータを戻したい場合は、
バックアップのログポジションを確認した後に確認したポジション
以降の全てのログを戻せば良い。

[root@HOME001 data]# mysqlbinlog --no-defaults mysql-bin.000007 | egrep -i -B5 truncate
#130126 11:26:50 server id 1  end_log_pos 929   Xid = 366
COMMIT/*!*/;
# at 929
#130126 11:41:11 server id 1  end_log_pos 1015  Query   thread_id=5     exec_time=0     error_code=0
SET TIMESTAMP=1359168071/*!*/;
truncate table TABLE001
[root@HOME001 data]#

ロールフォワードする為には以下のログの中身を適用する必要がある。
今回の検証で確認したケースでのStartとEndのポジション

mysql-bin.000007
 –start-position=107
 –stop-position=929

バイナリーログから戻すべきデータを再作成する為のスクリプトを作成する。
OracleでいうArchiveログを適用するRecoveryモード時に適用するログをマニュアル作成する感じ?
Positionは上記で確認したPositionを設定。

[root@HOME001 data]# mysqlbinlog --no-defaults --start-position=107 --stop-position=929 mysql-bin.000007 > /home/mysql/backup/recovery.sql
[root@HOME001 data]#

障害発生前まで戻す為の材料が揃ったのでリカバリー開始

[root@HOME001 backup]# ls -l
合計 524
drwxr-xr-x. 6 root root   4096  1月 24 14:45 2013 2013-01-24_14-44-57
drwxr-xr-x. 6 root root   4096  1月 24 15:23 2013 2013-01-24_15-23-31
-rw-r--r--. 1 root root 516386  1月 26 11:00 2013 MYSQL_DUMP_2013-01-26_ALL.sql
-rw-r--r--. 1 root root   4000  1月 26 11:03 2013 MYSQL_DUMP_2013-01-26_test.sql
-rw-r--r--. 1 root root   2713  1月 26 12:17 2013 recovery.sql
[root@HOME001 backup]#

[root@HOME001 backup]# mysql -u root -p test < MYSQL_DUMP_2013-01-26_test.sql
Enter password:
&#91;root@HOME001 backup&#93;# mysql -u root -p test < recovery.sql
Enter password:
&#91;root@HOME001 backup&#93;#
&#91;/SHELL&#93;

<strong>リカバリー完了したのでデータを確認して完了。</strong>
[SHELL]
mysql> use test
Database changed
mysql> select * from TABLE001 order by id desc limit 0,10;
+----+----------------------+-----------------------------------------------+
| id | title                | comment                                       |
+----+----------------------+-----------------------------------------------+
| 35 | Recreate Replication | after dump 20120126                           |
| 34 | Recreate Replication | after dump 20120126                           |
| 33 | Recreate Replication | after dump 20120126                           |
| 32 | Recreate Replication | 20130125 mysql-bin.000004 and relay-bin.00000 |
| 31 | Recreate Replication | 20130125 mysql-bin.000004 and relay-bin.00000 |
| 30 | Recreate Replication | mysql-bin.000004 and relay-bin.000008         |
| 29 | Recreate Replication | mysql-bin.000004 and relay-bin.000008         |
| 28 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
| 27 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
| 26 | LOG20120113          | mysql-bin.000034 After  Full Backup           |
+----+----------------------+-----------------------------------------------+
10 rows in set (0.00 sec)

mysql>

after

スレーブでmysqldumpを取得時にバイナリーログPOSITIONを記録する場合の留意:

--master-data

オプションは、バックアップを取得したサーバーでのポジションになるので
スレーブでバックアップ取得していてマスターDBが破損した場合でも、
スレーブのバイナリーログから対象のデータをリカバリーする必要があります。
もしマスター側のバイナリーログから必要なDDL、DMLを追加で取得する場合は、
調査と対応に時間がかなりかかる事が想定されます。
MYSQL5.5以降であれば、スレーブで取得する場合は

--dump-slave

を使用する事で、
MasterデータベースのバイナリーログのPOSITIONを記録してくれるので、
マスターのログを利用してのリカバリーが可能です。
但し、マスターが全損する場合もあるので用途によって運用でカバーする必要があります。

検証結果

mysqldump

参考サイト
How to obtain a correct dump using mysqldump and single-transaction when DDL is used at the same time?
mysqldump –single-transaction に –flush-logs をつけてはいけない
mysqldump の option 復習
7.12. mysqldump — データベースバックアッププログラム
mysqlbinlog — バイナリログファイルを処理するためのユーティリティ

Comments are closed.

Post Navigation