目前對MySQL比較流行的備份方式有兩種,一種上是使用自帶的mysqldump,另外一種是xtrabackup,對於數據時大的環境,廣泛使用了xtrabackup+binlog進行全量或者增量備份,那麼如何快速的從xtrabackup備份中恢復單張表呢?從mysql 5.6版本開始,支持可移動表空間(Transportable Tablespace),利用這個功能也能夠實現單表的恢復,下面進行從備份中恢復單張innodb表進行演練。html
1. 針對InnoDB表恢復python
2. 開啓了參數innodb_file_per_tablemysql
3. 安裝工具:mysql-utilities,其中mysqlfrm能夠讀取表結構。sql
進行mysql-utilities安裝:數據庫
yum install mysql-utilities -y
建立一個測試,往裏面插入數據後進行備份:安全
<test>(root@localhost) [xuanzhi]> show create table tb1\G *************************** 1. row *************************** Table: tb1 Create Table: CREATE TABLE `tb1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec) <test>(root@localhost) [xuanzhi]> insert into tb1 (name) values ('aa'),('bb'),('cc'),('dd'); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 <test>(root@localhost) [xuanzhi]> select * from tb1; +----+------+ | id | name | +----+------+ | 1 | aa | | 2 | bb | | 3 | cc | | 4 | dd | +----+------+ 4 rows in set (0.00 sec) <test>(root@localhost) [xuanzhi]>
進行xtrabackup備份操做:app
[root@localhost data]# innobackupex --defaults-file='/data/service/mysql-5.6.25/my.cnf' --user='root' --password='123456' --sock='/data/mysql-5.6/mysql.sock' /data
apply-log:ide
[root@localhost data]# innobackupex --defaults-file='/usr/local/mysql-5.6.25/my.cnf' --user='root' --password='123456' --sock='/data/mysql-5.6/mysql.sock' --apply-log /data/2017-03-24_09-40-54/
進行完整備份後,咱們繼續往測試表tb1裏插入數據,儘可能模擬線上環境:工具
<test>(root@localhost) [xuanzhi]> insert into tb1 (name) values ('aa2'),('bb2'),('cc2'),('dd2'); Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 <test>(root@localhost) [xuanzhi]> select * from tb1; +----+------+ | id | name | +----+------+ | 1 | aa | | 2 | bb | | 3 | cc | | 4 | dd | | 5 | aa2 | | 6 | bb2 | | 7 | cc2 | | 8 | dd2 | +----+------+ 8 rows in set (0.00 sec) <test>(root@localhost) [xuanzhi]>
xtrabackup備份裏只有四條數據,備份後的數據,咱們一會使用binlog來進行恢復。post
進行誤操操做,把表drop了:
<test>(root@localhost) [xuanzhi]> drop table tb1; Query OK, 0 rows affected (0.21 sec) <test>(root@localhost) [xuanzhi]> show tables; Empty set (0.02 sec) <test>(root@localhost) [xuanzhi]>
使用mysqlfrm從備份中讀取表結構:
[root@localhost data]# mysqlfrm --diagnostic /data/2017-03-24_09-40-54/xuanzhi/tb1.frm # WARNING: Cannot generate character set or collation names without the --server option. # CAUTION: The diagnostic mode is a best-effort parse of the .frm file. As such, it may not identify all of the components of the table correctly. This is especially true for damaged files. It will also not read the default values for the columns and the resulting statement may not be syntactically correct. # Reading .frm file for /data/2017-03-24_09-40-54/xuanzhi/tb1.frm: # The .frm file is a TABLE. # CREATE TABLE Statement: CREATE TABLE `xuanzhi`.`tb1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(30) DEFAULT NULL, PRIMARY KEY `PRIMARY` (`id`) ) ENGINE=InnoDB; #...done. [root@localhost data]#
登陸數據庫進行建表:
<test>(root@localhost) [xuanzhi]> CREATE TABLE `xuanzhi`.`tb1` ( -> `id` int(11) NOT NULL AUTO_INCREMENT, -> `name` char(30) DEFAULT NULL, -> PRIMARY KEY `PRIMARY` (`id`) -> ) ENGINE=InnoDB; Query OK, 0 rows affected (0.05 sec) <test>(root@localhost) [xuanzhi]>
加一個寫鎖,確保安全:
<test>(root@localhost) [xuanzhi]> lock tables tb1 write; Query OK, 0 rows affected (0.00 sec) <test>(root@localhost) [xuanzhi]>
丟棄表空間:
<test>(root@localhost) [xuanzhi]> alter table tb1 discard tablespace; Query OK, 0 rows affected (0.01 sec)
從備份中拷貝ibd文件,而且修改權限:
[root@localhost data]# cp /data/2017-03-24_09-40-54/xuanzhi/tb1.ibd /data/mysql-5.6/xuanzhi/ [root@localhost data]# chown -R mysql:mysql /data/mysql-5.6/xuanzhi/tb1.ibd
載入表空間:
<test>(root@localhost) [xuanzhi]> alter table tb1 import tablespace; Query OK, 0 rows affected, 1 warning (0.04 sec) <test>(root@localhost) [xuanzhi]> show warnings; +---------+------+---------------------------------------------------------------------------------------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------------------------------------------------------------------------------------+ | Warning | 1810 | InnoDB: IO Read error: (2, No such file or directory) Error opening './xuanzhi/tb1.cfg', will attempt to import without schema verification | +---------+------+---------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) <test>(root@localhost) [xuanzhi]>
有報一個warning,但不影響恢復,詳情能夠看:https://yq.aliyun.com/articles/59271,咱們查一下數據:
<test>(root@localhost) [xuanzhi]> select * from tb1; +----+------+ | id | name | +----+------+ | 1 | aa | | 2 | bb | | 3 | cc | | 4 | dd | +----+------+ 4 rows in set (0.02 sec) <test>(root@localhost) [xuanzhi]>
能夠看到備份的數據已經恢復了,可是備份後插入的數據明顯沒有出現,這個時候咱們只能經過binlog進行恢復了,因此binlog的備份也是很是重要的。
咱們查看一下備份時的pos點和binlog的文件名:
[root@localhost data]# cd /data/2017-03-24_09-40-54/ [root@localhost 2017-03-24_09-40-54]# cat xtrabackup_binlog_info mysql-bin.000002 1014
咱們知道了備份後的起始POS點,還須要找出到誤操前的一個POS點進行恢復,找到drop table 前的POS點:
[root@localhost 2017-03-24_09-40-54]# mysqlbinlog -v --base64-output=DECODE-ROWS /data/mysql-5.6/mysql-bin.000002 | grep -C 10 -i "DROP" ### SET ### @1=8 ### @2='dd2' # at 1292 #170324 9:43:00 server id 1313306 end_log_pos 1323 CRC32 0x9f776b03 Xid = 198 COMMIT/*!*/; # at 1323 #170324 9:46:55 server id 1313306 end_log_pos 1445 CRC32 0x3fa6b448 Query thread_id=27 exec_time=0 error_code=0 use `xuanzhi`/*!*/; SET TIMESTAMP=1490320015/*!*/; DROP TABLE `tb1` /* generated by server */ /*!*/; # at 1445 #170324 9:51:52 server id 1313306 end_log_pos 1674 CRC32 0xdd5e1448 Query thread_id=27 exec_time=0 error_code=0 SET TIMESTAMP=1490320312/*!*/; CREATE TABLE `xuanzhi`.`tb1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(30) DEFAULT NULL, PRIMARY KEY `PRIMARY` (`id`) ) ENGINE=InnoDB /*!*/;
能夠看到DROP TABLE 前的POS點是1323,那咱們能夠經過binlog2sql進行標準SQL的生成,binlog2sql的使用的和安裝請看以前我寫的博客:http://www.cnblogs.com/xuanzhi201111/p/6602489.html,再次爲開源數據閃回工具的大神們點贊。
[root@localhost binlog2sql]# python binlog2sql.py -uroot -p123456 -dxuanzhi -ttb1 --start-position=1014 --stop-position=1323 --start-file='mysql-bin.000002' > recovery_tb1.sql
[root@localhost binlog2sql]# cat recovery_tb1.sql FLUSH ENGINE LOGS; INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (5, 'aa2'); #start 1094 end 1292 time 2017-03-24 09:43:00 INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (6, 'bb2'); #start 1094 end 1292 time 2017-03-24 09:43:00 INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (7, 'cc2'); #start 1094 end 1292 time 2017-03-24 09:43:00 INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (8, 'dd2'); #start 1094 end 1292 time 2017-03-24 09:43:00 [root@pm2 binlog2sql]#
把這sql文件進入導入便可進行備份後的數據恢復,導入數據前先進行解鎖:
<test>(root@localhost) [xuanzhi]> unlock tables; Query OK, 0 rows affected (0.01 sec)
[root@localhost binlog2sql]# mysql -uroot -p123456 <./recovery_tb1.sql
Warning: Using a password on the command line interface can be insecure.
[root@localhost binlog2sql]#
查看數據:
test>(root@localhost) [xuanzhi]> select * from tb1; +----+------+ | id | name | +----+------+ | 1 | aa | | 2 | bb | | 3 | cc | | 4 | dd | | 5 | aa2 | | 6 | bb2 | | 7 | cc2 | | 8 | dd2 | +----+------+ 8 rows in set (0.02 sec) <test>(root@localhost) [xuanzhi]>
能夠看到數據成功的恢復了,你們能夠多加測試。
參考文章:
https://yq.aliyun.com/articles/59271
http://www.cnblogs.com/gomysql/p/6600616.html
做者:陸炫志 出處:xuanzhi的博客 http://www.cnblogs.com/xuanzhi201111 您的支持是對博主最大的鼓勵,感謝您的認真閱讀。本文版權歸做者全部,歡迎轉載,但請保留該聲明。 |