MySQL備份與恢復常用方法總結
(mysqldump/xtrabackup/lvm快照備份/邏輯備份與恢復/二進制日誌及時點恢復)
一、瞭解備份相關知識
1)按服務器備份時狀態可分爲:
熱備份:讀、寫不受影響;
溫備份:僅可以執行讀操作;
冷備份:離線備份;讀、寫操作均中止;
2)按服務器備份數據集可分爲:
物理備份:複製數據文件;
邏輯備份:將數據導出至文本文件中;
3)按服務器備份數據量可分爲:
完全備份:備份全部數據;
增量備份:僅備份上次完全備份或增量備份以後變化的數據;
差異備份:僅備份上次完全備份以來變化的數據;
4)我們需要備份些什麼數據文件?
數據、配置文件、二進制文件、事務日誌
二、學習相關備份工具
1)mysqldump:邏輯備份工具
2)lvm-snapshot:溫備(首先需要先全局鎖表,而後創建LVM快照,然後釋放鎖。)
3)xtrabackup:完全備份、增量備份以及高級部分備份
4)邏輯備份
三、mysqldump備份與恢復實驗
1)準備條件:查看當前數據庫狀態
mysql> show databases; //查看己有的數據庫; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.00 sec) mysql> show tables; //查看當前數據庫mydb中有哪些表; +----------------+ | Tables_in_mydb | +----------------+ | tb1 | +----------------+ 1 row in set (0.00 sec) mysql> select * from tb1; //查看tb1數據; +----+-----------+--------+------+ | id | name | gender | age | +----+-----------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 27 | | 3 | windy.ma | m | 30 | | 4 | lilian.wu | f | 27 | +----+-----------+--------+------+ 4 rows in set (0.00 sec) mysql> show binary logs; //如果此時你的系統中有多個二進制日誌文件,可以用下面一條命令將其手動刪除; +-------------------+-----------+ | Log_name | File_size | +-------------------+-----------+ | master-bin.000005 | 120 | +-------------------+-----------+ 1 row in set (0.00 sec) mysql> purge binary logs to 'master-bin.000005'; //刪除之前的所有二進制日誌; mysql> show master status; //查看當前正在使用的二進制日誌; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000006 | 120 | | | | +-------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
2)全量數據備份與增量備份
# mysqldump --lock-all-tables --master-data=2 --all-databases --flush-logs >mydb_all_backup_`date +%F`.sql mysqldump常用選項: --master-data={0|1|2} 0:不記錄二進制日誌文件及路徑位置 1:以change master to 的方式記錄位置,可用於恢復後直接啓動從服務器 2:以change master to 的方式記錄位置,但默認爲被註釋 --lock-all-tables: 鎖定所有表 --flush-logs: 執行日誌flush 如果指定庫中的表類型爲Innodb則可以使用--single-transaction啓動熱備; --all-databases :備份所有庫 --databases DB_NAME1,DB_NAME2,....: 備份多個庫 --events :事務 --routines :存儲過程,存儲函數 --triggers :觸發器 mysql> insert into tb1 (name,gender,age) values('tom.chen','m',47); Query OK, 1 row affected (0.08 sec) mysql> insert into tb1 (name,gender,age) values('tina.li','f',35); Query OK, 1 row affected (0.03 sec) # cp /mydata/data/master-bin.000006 /root/mydb_backup/ 1.模擬數據全部刪除: # service mysqld stop Shutting down MySQL.. [ OK ] # rm -fr /mydata/data/* 2.重新初始化 # cd /usr/local/mysql # scripts/mysql_install_db --user=mysql --datadir=/mydata/data/ 3.my.cnf配置文件 datadir = /mydata/data port = 3306 server_id = 1 socket = /tmp/mysql.sock innodb_file_per_table = 1 query_cache_type = 1 log-bin = mysql-bin 4.啓動mysql服務 # service mysqld start Starting MySQL.. [ OK ] 5.恢復操作 1)全量恢復操作 # mysql </root/mydb_backup/mydb_all_backup_2014-07-12.sql # mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.6.10-log MySQL Community Server (GPL) Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.00 sec) mysql> use mydb; mysql> show tables; +----------------+ | Tables_in_mydb | +----------------+ | tb1 | +----------------+ 1 row in set (0.00 sec) mysql> select * from tb1; +----+-----------+--------+------+ | id | name | gender | age | +----+-----------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 27 | | 3 | windy.ma | m | 30 | | 4 | lilian.wu | f | 27 | +----+-----------+--------+------+ 4 rows in set (0.00 sec) 2)增量恢復操作 # mysqlbinlog master-bin.000006 |mysql mysql> select * from mydb.tb1; +----+-----------+--------+------+ | id | name | gender | age | +----+-----------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 27 | | 3 | windy.ma | m | 30 | | 4 | lilian.wu | f | 27 | | 5 | tom.chen | m | 47 | | 6 | tina.li | f | 35 | +----+-----------+--------+------+ 6 rows in set (0.01 sec) 當然這裏操作完成我們需要將二進制日誌滾動一下,以備以後方便日誌恢復; mysql> flush logs; Query OK, 0 rows affected (0.06 sec) mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 559316 | | mysql-bin.000002 | 120 | +------------------+-----------+ 2 rows in set (0.00 sec) mysql> purge binary logs to 'mysql-bin.000002'; Query OK, 0 rows affected (0.06 sec)
當然對於事務型數據庫及表,我們還需要備份事務日誌等。
四、lvm-snapshot備份與恢復
由於系統沒有可用的lvm分區,所以這裏需要加裝塊磁盤以及創建lvm,就當是回顧一下lvm的使用吧... ...
# service mysqld stop # fdisk /dev/sdb Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-2610, default 1): Using default value 1 Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +5G Command (m for help): t Selected partition 1 Hex code (type L to list codes): 8e Changed system type of partition 1 to 8e (Linux LVM) Command (m for help): w Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (655-2610, default 655): Using default value 655 Last cylinder, +cylinders or +size{K,M,G} (655-2610, default 2610): +1G Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): 8e Changed system type of partition 2 to 8e (Linux LVM) Command (m for help): w # partprobe /dev/sdb # pvcreate /dev/sdb1 Physical volume "/dev/sdb1" successfully created # pvcreate /dev/sdb2 Physical volume "/dev/sdb2" successfully created # vgcreate mydata /dev/sdb1 Volume group "mydata" successfully created # vgextend mydata /dev/sdb2 Volume group "mydata" successfully extended # lvcreate -L 5G -n mydata mydata Logical volume "mydata" created # lvs LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert mydata mydata -wi-a---- 5.00g lv_root vg_server -wi-ao--- 15.60g lv_swap vg_server -wi-ao--- 3.91g # mkfs.ext4 /dev/mapper/mydata-mydata # mount /dev/mapper/mydata-mydata /mydata/data/ # vim /etc/fstab //新加入下面一行; /dev/mapper/mydata-mydata /mydata/data ext4 defaults 0 0 初始化數據庫 # cd /usr/local/mysql # scripts/mysql_install_db --user=mysql --datadir=/mydata/data/ # vim my.cnf datadir = /mydata/data port = 3306 server_id = 1 socket = /tmp/mysql.sock innodb_file_per_table = 1 query_cache_type = 1 log-bin = mysql-bin # service mysqld start 爲了節省保貴的時間,還是使用上面mysqldump完全備份下來的數據: mysql> source /root/mydb_backup/mydb_all_backup_2014-07-12.sql mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.00 sec) mysql> select * from mydb.tb1; +----+-----------+--------+------+ | id | name | gender | age | +----+-----------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 27 | | 3 | windy.ma | m | 30 | | 4 | lilian.wu | f | 27 | | 5 | tom.chen | m | 47 | | 6 | tina.li | f | 35 | +----+-----------+--------+------+ 6 rows in set (0.00 sec) mysql> flush tables with read lock; //此時,其它會話都將無法修改數據; Query OK, 0 rows affected (0.01 sec) mysql> flush logs; Query OK, 0 rows affected (0.01 sec) # mysql -uroot -p -e 'SHOW MASTER STATUS\G' >/root/mydb_backup/master.info //通過另外終端備份當前二進制日誌狀態; # lvcreate -L 50M -s -n mysql_snapshot /dev/mapper/mydata-mydata Rounding up size to full physical extent 52.00 MiB Logical volume "mysql_snapshot" created mysql> unlock tables; Query OK, 0 rows affected (0.00 sec) # lvs LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert mydata mydata owi-aos-- 5.00g mysql_snapshot mydata swi-a-s-- 52.00m mydata 0.02 lv_root vg_server -wi-ao--- 15.60g lv_swap vg_server -wi-ao--- 3.91g # mkdir snapshot # mount /dev/mapper/mydata-mysql_snapshot /root/snapshot/ # cd snapshot/ # ls auto.cnf ib_logfile0 mydb mysql-bin.000001 mysql-bin.000003 mysql-bin.index server102.neo.com.pid ibdata1 ib_logfile1 mysql mysql-bin.000002 mysql-bin.000004 performance_schema test # mkdir /root/mydb_backup/data # cp -fr * /root/mydb_backup/data/ # umount /dev/mapper/mydata-mysql_snapshot # lvremove /dev/mapper/mydata-mysql_snapshot Do you really want to remove active logical volume mysql_snapshot? [y/n]: y Logical volume "mysql_snapshot" successfully removed 模擬數據全部刪除 # service mysqld stop Shutting down MySQL.. [ OK ] # rm -fr /mydata/data/* # cp -fr /root/mydb_backup/data/* /mydata/data/ # chown -R mysql.mysql /mydata/data # service mysqld start Starting MySQL [ OK ] mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.05 sec) mysql> select * from mydb.tb1; +----+-----------+--------+------+ | id | name | gender | age | +----+-----------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 27 | | 3 | windy.ma | m | 30 | | 4 | lilian.wu | f | 27 | | 5 | tom.chen | m | 47 | | 6 | tina.li | f | 35 | +----+-----------+--------+------+ 6 rows in set (0.06 sec)
注:由於此前沒有對數據庫進行任何修改數據操作,也沒對其進行增量備份,如果你的真實環境做過增量備份,按照上面mysqldump上面恢復二進制方法進行就行了。
五、XtraBackup備份與恢復
1、XtraBackup介紹
(摘自官網http://www.percona.com/software/percona-xtrabackup)
Percona XtraBackup is an open source, free MySQL hot backup software that performs non-blocking backups for InnoDB and XtraDB databases. With Percona XtraBackup, you can achieve the following benefits:
Backups that complete quickly and reliably
Uninterrupted transaction processing during backups
Savings on disk space and network bandwidth
Automatic backup verification
Higher uptime due to faster restore time
首先安裝完xtrabackup後,我們還需要了解下面兩個工具:
1)xtrabackup 只能備份InnoDB和XtraDB兩種數據表,支持在線熱備份,可以在不加鎖的情況下備份Innodb數據表,不過此工具不能操作Myisam引擎表
2)innobackupex 是一個腳本封裝,封裝了xtrabackup,能同時處理Innodb和Myisam,但在處理Myisam時需要加一個讀鎖。
按如上的介紹,由於操作Myisam時需要加讀鎖,這會堵塞線上服務的寫操作,而Innodb沒有這樣的限制,所以數據庫中Innodb表類型所佔的比例越大,則越有利。實際應用中一般是直接使用innobackupex方法。
2、安裝percona xtrabackup軟件包
# yum localinstall percona-xtrabackup-2.1.9-744.rhel6.x86_64.rpm -y
3、完全備份
1)準備:
1> mysql的配置文件存放路徑改爲/etc/my.cnf //* 由於innobackupex只識別/etc/my.cnf配置文件 *//
2> socket = /var/lib/mysql/mysql.sock //* 也是因爲innobackupex只識別此路徑下的sock文件 *//
3> ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock //* 這裏我也不知如何解釋,當配置文件中指定爲/var/lib/mysql/mysql.sock時,mysql會去找/tmp/mysql.sock,不知是哪裏出了問題,所以暫時就這麼解決吧; *//
4> 創建個數據庫與表;
mysql> select * from mydb.tb1; +----+-----------+--------+------+ | id | name | gender | age | +----+-----------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 28 | | 3 | windy.ma | m | 30 | | 4 | lilia.wu | f | 27 | +----+-----------+--------+------+ 4 rows in set (0.00 sec)
5> 創建備份目錄;
# mkdir /root/backup/{full_backup,increment} -p
2)備份
# innobackupex --user=root /root/backup/full_backup/ //* /root/backup/full_backup: 指定完全備份路徑;*// //* --user=root: 爲安全起見,你也可以創建一個其它權限用戶進行備份;*// ... ... //省略; innobackupex: Backup created in directory '/root/backup/full_backup/2014-07-12_12-00-25' innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 120 140712 12:00:28 innobackupex: Connection to database server closed 140712 12:00:28 innobackupex: completed OK!
在備份的同時,innobackupex還會在備份目錄中創建如下文件:
(1)xtrabackup_checkpoints 備份類型(如完全或增量)、備份狀態(如是否已經爲prepared狀態)和LSN(日誌序列號)範圍信息;每個InnoDB頁(通常爲16k大小)都會包含一個日誌序列號,即LSN。LSN是整個數據庫系統的系統版本號,每個頁面相關的LSN能夠表明此頁面最近是如何發生改變的。
(2)xtrabackup_binlog_info mysql服務器當前正在使用的二進制日誌文件及至備份這一刻爲止二進制日誌事件的位置。
(3)xtrabackup_binlog_pos_innodb 二進制日誌文件及用於InnoDB或XtraDB表的二進制日誌文件的當前position。
(4)xtrabackup_binary 備份中用到的xtrabackup的可執行文件;
(5)backup-my.cnf 備份命令用到的配置選項信息;
3)完全備份恢復
1> 恢復準備
在備份完成後,數據尚且不能用於恢復操作,因爲備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據文件仍處理不一致狀態。“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。而下面命令行中的"--apply-log"就是用於實現該功能的;
# innobackupex --apply-log /root/backup/full_backup/2014-07-12_12-00-25/ ... ... //省略; xtrabackup: starting shutdown with innodb_fast_shutdown = 1 InnoDB: FTS optimize thread exiting. InnoDB: Starting shutdown... InnoDB: Shutdown completed; log sequence number 1638422 140712 12:25:32 innobackupex: completed OK!
2> 恢復
# rm -fr /mydata/data/* # innobackupex --copy-back /root/backup/full_backup/2014-07-12_12-00-25/ ... ... //省略; innobackupex: Finished copying back files. 140712 12:30:11 innobackupex: completed OK! # chown -R mysql.mysql /mydata/data/* mysql> select * from mydb.tb1; //直接使用,不需要重啓mysql服務器; +----+-----------+--------+------+ | id | name | gender | age | +----+-----------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 28 | | 3 | windy.ma | m | 30 | | 4 | lilia.wu | f | 27 | +----+-----------+--------+------+ 4 rows in set (0.00 sec)
4、增量備份
這裏我們做兩次增量備份,以便更接近生產環境;
1)第一次增量備份:
mysql> insert into tb1 (name,gender,age) values('cherry.dai','f',27),('tom.chen','m',35); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 # innobackupex --incremental /root/backup/increment/ --incremental-basedir=/root/backup/full_backup/2014-07-12_13-56-38/ //* --incremental: 增量備份存放路徑,innobackupex會自動在此目錄下創建一個新的目錄; *// //* --incremental-basedir: 對於第一次增量備份,指定完全備份路徑即可;對於第一次以後的增量備份需要指定前一次增量備份的存放路徑; *// ... ... //省略; innobackupex: Backup created in directory '/root/backup/increment/2014-07-12_14-02-51' innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 417 140712 14:02:55 innobackupex: Connection to database server closed 140712 14:02:55 innobackupex: completed OK!
2)第二次增量備份:
mysql> create table tb2 (id int auto_increment not null primary key, name char(30) not null); Query OK, 0 rows affected (0.10 sec) mysql> insert into tb2 (name) values ('user1'),('user2'),('user3'),('user4'); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 # innobackupex --incremental /root/backup/increment/ --incremental-basedir=/root/backup/increment/2014-07-12_14-02-51/ //* --incremental-basedir: 這裏的路徑爲第一次增量備份的路徑; *// ... ... //省略; innobackupex: Backup created in directory '/root/backup/increment/2014-07-12_14-04-28' innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 861 140712 14:04:31 innobackupex: Connection to database server closed 140712 14:04:31 innobackupex: completed OK!
3)增量備份恢復:
1)模擬數據損壞:
# service mysqld stop Shutting down MySQL.... [ OK ] # rm -fr /mydata/data/*
需要注意的是,增量備份僅能應用於InnoDB或XtraDB表,對於MyISAM表而言,執行增量備份時其實進行的是完全備份。
“準備"增量備份與整理完全備份有着一些不同,尤其要注意的是:
(1)需要在每個備份(包括完全和各個增量備份)上,將已經提交的事務進行“重放”。“重放”之後,所有的備份數據將合併到完全備份上。
(2)基於所有的備份將未提交的事務進行“回滾”。
2)還原準備: # innobackupex --apply-log --redo-only /root/backup/full_backup/2014-07-12_13-56-38/ //* --apply-log: 前面己提到;*// //* --redo-only: 對於多次增量備份僅提交;*// //* /root/backup/full_backup/2014-07-12_13-56-38/: 完全備份目錄;*// ... ... //* 省略;*// xtrabackup: starting shutdown with innodb_fast_shutdown = 1 InnoDB: Starting shutdown... InnoDB: Shutdown completed; log sequence number 1638934 140712 14:16:46 innobackupex: completed OK! 3)第一次備份與完全備份合併: # innobackupex --apply-log --redo-only /root/backup/full_backup/2014-07-12_13-56-38/ --incremental-dir=/root/backup/increment/2014-07-12_14-02-51/ //* /root/backup/full_backup/2014-07-12_13-56-38/: 準備好後的完全備份目錄;*// //* /root/backup/increment/2014-07-12_14-02-51/: 第一次增量備份目錄;*// ... ... //* 省略;*// innobackupex: Copying '/root/backup/increment/2014-07-12_14-02-51/mydb/tb1.frm' to '/root/backup/full_backup/2014-07-12_13-56-38/mydb/tb1.frm' innobackupex: Copying '/root/backup/increment/2014-07-12_14-02-51/mydb/db.opt' to '/root/backup/full_backup/2014-07-12_13-56-38/mydb/db.opt' 140712 14:18:44 innobackupex: completed OK! 4)第二次備份與完全備份合併: # innobackupex --apply-log --redo-only /root/backup/full_backup/2014-07-12_13-56-38/ --incremental-dir=/root/backup/increment/2014-07-12_14-04-28/ //* /root/backup/full_backup/2014-07-12_13-56-38/: 準備好後的完全備份目錄;*// //* /root/backup/increment/2014-07-12_14-04-28/ 第二次增量備份目錄;*// ... ... //* 省略; *// innobackupex: Copying '/root/backup/increment/2014-07-12_14-04-28/mydb/tb2.frm' to '/root/backup/full_backup/2014-07-12_13-56-38/mydb/tb2.frm' innobackupex: Copying '/root/backup/increment/2014-07-12_14-04-28/mydb/tb1.frm' to '/root/backup/full_backup/2014-07-12_13-56-38/mydb/tb1.frm' innobackupex: Copying '/root/backup/increment/2014-07-12_14-04-28/mydb/db.opt' to '/root/backup/full_backup/2014-07-12_13-56-38/mydb/db.opt' 140712 14:19:38 innobackupex: completed OK! 5)將多次合併後的數據恢復: # innobackupex --copy-back /root/backup/full_backup/2014-07-12_13-56-38/ ... ... //* 省略;*// innobackupex: Starting to copy InnoDB log files innobackupex: in '/root/backup/full_backup/2014-07-12_13-56-38' innobackupex: back to original InnoDB log directory '/mydata/data' innobackupex: Copying '/root/backup/full_backup/2014-07-12_13-56-38/ib_logfile1' to '/mydata/data/ib_logfile1' innobackupex: Copying '/root/backup/full_backup/2014-07-12_13-56-38/ib_logfile0' to '/mydata/data/ib_logfile0' innobackupex: Finished copying back files. 140712 14:24:04 innobackupex: completed OK! 6)啓動mysql服務,檢查數據: # chown -R mysql.mysql /mydata/data/* # service mysqld start Starting MySQL. [ OK ] mysql> use mydb; mysql> show tables; +----------------+ | Tables_in_mydb | +----------------+ | tb1 | | tb2 | +----------------+ 2 rows in set (0.00 sec)
5、xtrabackup高級用法:部分表備份與恢復;
XtraBackup也可以實現部分備份,即只備份某個或某些指定的數據庫或某數據庫中的某個或某些表。但要使用此功能,必須啓用innodb_file_per_table選項,即每張表保存爲一個獨立的文件。同時,其也不支持--stream選項,即不支持將數據通過管道傳輸給其它程序進行處理。
還原部分備份跟還原全部數據的備份也有所不同,即你不能通過簡單地將prepared的部分備份使用--copy-back選項直接複製回數據目錄,而是要通過導入表的方向來實現還原。當然,有些情況下,部分備份也可以直接通過--copy-back進行還原,但這種方式還原而來的數據多數會產生數據不一致的問題,因此,無論如何不推薦使用這種方式。
創建部分備份的方式有三種:正則表達式(--include), 枚舉表文件(--tables-file)和列出要備份的數據庫(--databases)。
使用--include
使用--include時,要求爲其指定要備份的表的完整名稱,即形如databasename.tablename,如:
# innobackupex --include='^mydb[.]tb1' /path/to/backup
使用--tables-file
此選項的參數需要是一個文件名,此文件中每行包含一個要備份的表的完整名稱;如:
# echo -e 'mydb.tb1\mydb.tb2' > /tmp/tables.txt
# innobackupex --tables-file=/tmp/tables.txt /path/to/backup
使用--databases
此選項接受的參數爲數據名,如果要指定多個數據庫,彼此間需要以空格隔開;同時,在指定某數據庫時,也可以只指定其中的某張表。此外,此選項也可以接受一個文件爲參數,文件中每一行爲一個要備份的對象。如:
# innobackupex --databases="mydb testdb" /path/to/backup
1)重置mysql服務器:(爲了不影響實驗,我們將之前所有操作全部刪除重置)
mysql> create database mydb; Query OK, 1 row affected (0.00 sec) # mysql mydb <mydb_full_2014-07-12.sql mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.00 sec) mysql> show tables from mydb; +----------------+ | Tables_in_mydb | +----------------+ | tb1 | | tb2 | +----------------+ 2 rows in set (0.00 sec)
2)考慮到安全性,我們還是將整個數據做一次完全備份,然後進行指定表備份;
# innobackupex --user=root backup/ //* 完全備份;*// innobackupex: Backup created in directory '/root/backup/2014-07-13_11-54-05' innobackupex: MySQL binlog position: filename 'mysql-bin.000003', position 2071 140713 11:54:08 innobackupex: Connection to database server closed 140713 11:54:08 innobackupex: completed OK! # innobackupex --include='mydb.tb1' backup/2014-07-13_11-54-05 //* 對指定的表進行指定路徑備份;*// ... ... //* 省略;*// innobackupex: Backup created in directory '/root/backup/2014-07-13_11-54-05/2014-07-13_11-54-53' innobackupex: MySQL binlog position: filename 'mysql-bin.000003', position 2071 140713 11:54:56 innobackupex: Connection to database server closed 140713 11:54:56 innobackupex: completed OK! # innobackupex --apply-log --export /root/backup/2014-07-13_11-54-05/2014-07-13_11-54-53/ //* 整理部分備份數據;*// xtrabackup: starting shutdown with innodb_fast_shutdown = 0 InnoDB: FTS optimize thread exiting. InnoDB: Starting shutdown... InnoDB: Shutdown completed; log sequence number 1666070 140713 11:57:27 innobackupex: completed OK!
3)還原數據或遷移部分數據
注意,對於還原部分表或數據,需要創建與原表一樣的數據結構;
mysql> create database testdb; //* 由於資源有限,這裏就另創建一個數據庫來演示;*// Query OK, 1 row affected (0.00 sec) mysql> use mydb; Database changed mysql> show create table tb1; | Table | Create Table | tb1 | CREATE TABLE `tb1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(30) NOT NULL, `gender` enum('f','m') DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 | 1 row in set (0.00 sec) mysql> use testdb; mysql> CREATE TABLE `tb1` ( -> `id` int(11) NOT NULL AUTO_INCREMENT, -> `name` char(30) NOT NULL, -> `gender` enum('f','m') DEFAULT NULL, -> `age` int(11) DEFAULT NULL, -> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.06 sec) mysql> alter table tb1 discard tablespace; //* 由於我們要還原備份的表,所以需要將新創建的表空間文件移除; *// Query OK, 0 rows affected (0.00 sec) # pwd /root/backup/2014-07-13_11-54-05/2014-07-13_11-54-53/mydb # ls tb1.cfg tb1.exp tb1.frm tb1.ibd # cp tb1.exp tb1.ibd /mydata/data/testdb/ //* 複製備份時路徑下的.exp .ibd文件;*// # ll total 128 -rw-rw---- 1 mysql mysql 65 Jul 13 11:59 db.opt -rw-r--r-- 1 root root 16384 Jul 13 12:05 tb1.exp -rw-rw---- 1 mysql mysql 8654 Jul 13 12:02 tb1.frm -rw-r----- 1 root root 98304 Jul 13 12:05 tb1.ibd # chown -R mysql.mysql . //* 修改權限,下面會報錯;*// mysql> alter table tb1 import tablespace; //* 導入表空間;*// Query OK, 0 rows affected, 1 warning (0.30 sec) mysql> select * from tb1; +----+------------+--------+------+ | id | name | gender | age | +----+------------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 28 | | 3 | windy.ma | m | 30 | | 4 | lilia | f | 27 | | 5 | cherry.dai | f | 27 | | 6 | tom.chen | m | 35 | +----+------------+--------+------+ 6 rows in set (0.00 sec)
說明:爲何部分數據要如此麻煩?我們知道對於InnoDB來說,直接複製.ibd文件是起不了作用的,就如同之前直接刪除庫目錄下的文件,之後在創建同名的表時,就會報錯。悲劇的是現在都沒找到很好的解決辦法,如果你那樣做了,找到解決方法後記得分享一下。。。
六、邏輯備份與恢復
我們知道了邏輯備份是將數據導出到文件中,然後利用導出的文件恢復數據,下面我們一起來了解一下;
mysql> select * from tb1; +----+------------+--------+------+ | id | name | gender | age | +----+------------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 28 | | 3 | windy.ma | m | 30 | | 4 | lilia | f | 27 | | 5 | cherry.dai | f | 27 | | 6 | tom.chen | m | 35 | +----+------------+--------+------+ 6 rows in set (0.00 sec) mysql> select * from tb1 into outfile '/tmp/tb1_backup.txt'; //*導出來mysql用戶有權限的目錄;*// Query OK, 6 rows affected (0.01 sec) # cat /tmp/tb1_backup.txt 1 jun.wang m 25 2 jerry.liu m 28 3 windy.ma m 30 4 lilia f 27 5 cherry.dai f 27 6 tom.chen m 35 mysql> create table tb5 like tb1; //* 由於導出的文件爲文本文件,如果我們還需要導入這個表,則需要將其表結構創建出來;*// Query OK, 0 rows affected (0.03 sec) mysql> load data infile '/tmp/tb1_backup.txt' into table tb5; //* 文件導入到表中;*// Query OK, 6 rows affected (0.00 sec) Records: 6 Deleted: 0 Skipped: 0 Warnings: 0 mysql> select * from tb5; +----+------------+--------+------+ | id | name | gender | age | +----+------------+--------+------+ | 1 | jun.wang | m | 25 | | 2 | jerry.liu | m | 28 | | 3 | windy.ma | m | 30 | | 4 | lilia | f | 27 | | 5 | cherry.dai | f | 27 | | 6 | tom.chen | m | 35 | +----+------------+--------+------+ 6 rows in set (0.00 sec)
六、總結
無論使用哪種備份與恢復,在生產環境中都無法做到及時點恢復,此時我們需要利用二進制日誌進行恢復;所以請務必確保二進制日誌文件的安全。
下面來複習一下二進制日誌恢復;
mysql> flush logs; Query OK, 0 rows affected (0.01 sec) mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 69375 | | mysql-bin.000002 | 1164429 | | mysql-bin.000003 | 2024 | | mysql-bin.000004 | 120 | +------------------+-----------+ 4 rows in set (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000004 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> insert into tb2 (name) values('user5'),('user6'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000004 | 384 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) # cp /mydata/data/mysql-bin.000004 /root/ # service mysqld stop Shutting down MySQL.... [ OK ] # rm -fr /mydata/data/*
如果此時數據損壞
我們首先使用前面的方法將數據還原,然後利用二進日誌進行數據恢復;
# mysqlbinlog --start-position=120 --stop-position=384 /root/mysql-bin.000004 |mysql //* --start-position: 從數據操作起始點;*// //* --stop-position: 到數據操作後結束點;*// //* 注意在xtrabackup軟件中使用innobackupex備份時,可以查看備份目錄中xtrabackup_binlog_info文件中有記錄備份時二進制日誌所記錄和position位置,跟據這個位置我們可恢復到沒做增量備份的數據;*// mysql> select * from mydb.tb2; +----+-------+ | id | name | +----+-------+ | 1 | user1 | | 2 | user2 | | 3 | user3 | | 4 | user4 | | 5 | user5 | | 6 | user6 | +----+-------+ 6 rows in set (0.00 sec)