msyql的備份是爲了防止mysql服務器故障導致數據丟失,或者人爲誤操作導致的數據丟失,總之就是爲了保證的安全性和可恢復性。
mysql的備份類型有很多種,我們針對不同的場合當然會有不同的選擇了。
根據備份時,數據庫服務器是否在線:
冷備:cold backup:在關閉sql服務之後進行的備份是最簡單最安全的,而且損壞或者不一致的風險最小,但是關閉sql識別會讓公司的業務停止一段時間,而且對於高負載和高數據量下的關閉和重啓mysql也可能是要花很長一段時間的。
溫備:warm backup:給sql加上讀鎖,意味着,加鎖之後的事務請求只能讀不能寫,而且在用FLUSH TABLES WITH READ LOK加鎖式,或者全局的讀鎖之後,纔可以進行備份,當然這會花去很長一段時間。
熱備:hot backup:顧名思義就是在sql服務運行的情況下,進行備份,當然線上肯定還有很多的用戶請求以及各種操作都在進行,這樣的備份數據完全有可能產生損壞。
根據備份的數據集:
完全備份:full backup:也就是說,備份這個數據庫。
部分備份: partial backup:部分備份,在備份的時候有可能我們只是對部分數據庫或者部分數據庫裏面的表進行備份而已。
根據備份時的接口(直接備份數據文件還是通過mysql服務器導出數據):
物理備份:直接複製(歸檔)數據文件的備份方式;physical backup
物理備份,就是簡單的文件複製了,至需要將需要的文件複製到其他地方即可完成備份。而且物理備份的恢復可能就更簡單,對應InnoDB則需要停止數據庫服務。
邏輯備份:把數據從庫中提出出來保存爲文本文件;logical backup
邏輯備份,它只是將我們事務執行的所有操作,用SQL;語句或者文本文件保存起來,恢復的時候就需要將這些SQL語句再一次在服務器上運行一遍。
根據備份時是備份整個數據還是僅備份變化的數據:
完全備份:full backup:對於完全備份就是把整個數據庫做一個備份
增量備份:incremental backup:在完全備份或者上次增量備份的基礎上做備份
差異備份:differential backup:從上次完全備份的基礎上到當然的備份
備份策略:
選擇備份方式選擇備份時間考慮到恢復成本恢復時長
備份成本:
鎖時間備份時長備份負載
備份工具:
mysqldump:邏輯備份工具
InnoDB熱備、MyISAM溫備、Aria溫備
備份和恢復過程較慢
mysqldumper: 多線程的mysqldump
很難實現差異或增量備份;
lvm-snapshot:
接近於熱備的工具:因爲要先請求全局鎖,而後創建快照,並在創建快照完成後釋放全局鎖;
使用cp、tar等工具進行物理備份;
備份和恢復速度較快;
很難實現增量備份,並且請求全局需要等待一段時間,在繁忙的服務器上尤其如此;
本文中會講訴三種備份方式:
1、Mysqldump
2、LVM-snapshot
3、Xtarbackup
恢復:
我們用完全備份+(增量備份/差異備份)+二進制日誌文件(FLUSH LOGS),可以實現數據的完整恢復。
一、Mysqldump
注意:
1、備份的時候要加鎖;--lock-all-tables:加鎖是溫備。
2、滾動日誌;--flush-logs
3、--single-transaction: 加此選項指定是熱備能夠對InnoDB存儲引擎實現熱備
熱備不需要加鎖;
4、指定導出的庫 --databases tb_name 備份指定庫
--all-databases 備份所有庫
5、記錄二進制日誌文件及位置: --master-data=[0|1|2]
[root@station112 ~]# mysqldump --databases tb_name --flush-logs --master-data=[0 |1|2] > /tmp/tb_name.sql
恢復:
完全備份+二進日誌文件
Set session sql_log_bin=0; 先關掉日誌文件
下面進行實驗:本次是用熱備。
1、先查看下我們所有的庫。
mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | hellodb | | mydb | | mysql | | performance_schema | | test | +--------------------+ 6 rows in set (0.00 sec)
2、我們備份所以的數據庫到/tmp/all.sql
[root@station112 tmp]# mysqldump --all-databases --flush-logs --single-transaction --master-data=2 > /tmp/all.sql
3、我們爲了恢復完全備份之後產生的二進制日誌文件,我們來插入點數據,之後再進行刪除
mysql> CREATE DATABASE xie; Query OK, 1 row affected (0.00 sec) mysql> USE xie; Database changed mysql> CREATE TABLE t1(Name char(20),ID tinyint); Query OK, 0 rows affected (0.12 sec) mysql> INSERT INTO xie.t1 VALUE('tb1','123'); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM t1; +------+------+ | Name | ID | +------+------+ | tb1 | 123 | +------+------+ 1 row in set (0.00 sec)
我們進行了完全備份之後,進行了上面才操作,之後我們其他人一不小心刪除掉了我們剛纔建立的那個數據庫
mysql> DROP DATABASE xie; Query OK, 1 row affected (0.06 sec)
我們的二進制日誌文件就派上用場了
我們先來查看下系統生成的二進制日誌文件
[root@station112 tmp]# mysqlbinlog /mydata/binlogs/master-bin.000007 查看生成的二進制文件,將剛纔所做操作的position之前的內容備份到一個文件中,一會用來恢復 SET @@session.collation_database=DEFAULT/*!*/; CREATE DATABASE xie /*!*/; # at 188 #140412 8:51:04 server id 1 end_log_pos 291 Query thread_id=14 exec_time=0 error_code=0 end_log_pos 291這個是建立數據庫時的位置記錄點 use `xie`/*!*/; SET TIMESTAMP=1397263864/*!*/; CREATE TABLE t1(Name char(20),ID tinyint) /*!*/; # at 291 #140412 8:52:00 server id 1 end_log_pos 358 Query thread_id=14 exec_time=0 error_code=0 SET TIMESTAMP=1397263920/*!*/; BEGIN /*!*/; # at 358 #140412 8:52:00 server id 1 end_log_pos 457 Query thread_id=14 exec_time=0 error_code=0 SET TIMESTAMP=1397263920/*!*/; INSERT INTO xie.t1 VALUE('tb1','123') /*!*/; # at 457 #140412 8:52:00 server id 1 end_log_pos 484 Xid = 1363 COMMIT/*!*/; # at 484 #140412 9:05:36 server id 1 end_log_pos 563 Query thread_id=14 exec_time=0 error_code=0 end_log_pos 563 這個是刪除數據庫的那一條。我們要取這個中間的內容。 SET TIMESTAMP=1397264736/*!*/; DROP DATABASE xie /*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
DELIMITER /*!*/; # at 4 #140412 8:47:35 server id 1 end_log_pos 107 Start: binlog v 4, server v 5.5.33-log created 140412 8:47:35 #總這個地方開始 BINLOG ' J41IUw8BAAAAZwAAAGsAAAAAAAQANS41LjMzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA== '/*!*/; # at 107 #140412 8:50:17 server id 1 end_log_pos 188 Query thread_id=14 exec_time=0 error_code=0 SET TIMESTAMP=1397263817/*!*/; SET @@session.pseudo_thread_id=14/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; CREATE DATABASE xie /*!*/; # at 188 #140412 8:51:04 server id 1 end_log_pos 291 Query thread_id=14 exec_time=0 error_code=0 use `xie`/*!*/; SET TIMESTAMP=1397263864/*!*/; CREATE TABLE t1(Name char(20),ID tinyint) /*!*/; # at 291 #140412 8:52:00 server id 1 end_log_pos 358 Query thread_id=14 exec_time=0 error_code=0 SET TIMESTAMP=1397263920/*!*/; BEGIN /*!*/; # at 358 #140412 8:52:00 server id 1 end_log_pos 457 Query thread_id=14 exec_time=0 error_code=0 SET TIMESTAMP=1397263920/*!*/; INSERT INTO xie.t1 VALUE('tb1','123') /*!*/; # at 457 #140412 8:52:00 server id 1 end_log_pos 484 Xid = 1363 COMMIT/*!*/; #到這個地方結束,導出二進制日誌 # at 484 #140412 9:05:36 server id 1 end_log_pos 563 Query thread_id=14 exec_time=0 error_code=0 SET TIMESTAMP=1397264736/*!*/; DROP DATABASE xie /*!*/; # at 563 #140412 9:42:11 server id 1 end_log_pos 607 Rotate to master-bin.000008 pos: 4 DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
查詢完之後我們就要導出這個二進制日誌文件了,一會用來恢復數據庫
[root@station112 tmp]# mysqlbinlog --start-position=107 --stop-position=484 /mydata/binlogs/master-bin.000007 > /tmp/binlog.sql
接下來我們來恢復試試;
此刻不要讓其他人連入數據庫做任何的讀寫操作;
先來查看下那個刪除掉的數據庫是不是不存在
我們之前創建的那個 xie 庫 不在了!!!!
mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | hellodb | | mydb | | mysql | | performance_schema | | test | +--------------------+ 6 rows in set (0.00 sec)
1、我們停掉二進制日誌文件記錄。
mysql> FLUSH LOGS; Query OK, 0 rows affected (0.11 sec) mysql> SHOW MASTER STATUS; +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-bin.000008 | 107 | | | +-------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> SET session sql_log_bin=0; Query OK, 0 rows affected (0.00 sec)
2、再導入數據,然後查看;
mysql> set session sql_log_bin=0; Query OK, 0 rows affected (0.00 sec) mysql> SOURCE /tmp/binlog.sql Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec)
查看
mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | hellodb | | mydb | | mysql | | performance_schema | | test | | xie | +--------------------+ 7 rows in set (0.00 sec)
哈哈,已導入了,是不是二進制日誌文件有點強大?????
二、LVM-snapshot
用快照來進行備份恢復,這個就很簡單了。
具體步驟:
創建