MySQL數據備份與恢復

    一、簡介

    數據在當今的互聯網行業中非常重要,掌握了數據能夠從中發現價值,所以數據對於公司來書再重要不過了,當我們面臨數據的丟失時,比如數據意外刪除、自然災害等,然而數據的備份和恢復就顯得尤爲重要。   

   

    二、MySQL/MariaDB數據備份與恢復

    常見的備份類型:

    根據備份時數據庫是否在線:

    冷備:cold backup,服務器離線,線上業務終止,無法執行讀寫操作,但是此方法備份數據最爲靠譜,丟數據少      熱備:hot backup,服務器在線,線上業務正常進行,讀寫操作都可進行,此方法備份要求複雜 

    溫備:warn backup,服務器在線,但是對數據庫施加全局鎖,只讀操作正常進行,不可寫 

    根據備份時的接口:

    物理備份:physical backup,直接從數據庫的數據目錄進行cp複製歸檔的方式

    邏輯備份:logical backup,把數據從庫中提取出來保存爲文本文件,主要用到的工具是mysqldump 

    注意在數據量很大時使用邏輯備份很實用,當數據量小於10G時可以考慮使用mysqldump實現邏輯備份

    根據備份的數據集:

    完全備份:full backup,指的是備份整個庫 

    部分備份:partial backup,指的是備份數據庫中的部分數據  

    根據備份時是否備份整個 數據還是僅僅備份變化的數據

    完全備份: full backup,備份整個數據庫

    增量備份:incremental backup,僅僅備份一次完全備份之後所改變的數據做備份的爲增量備份

    差異備份:differential backup,比如說週一做一次備份,到週二了就把週一和週二這兩天的做一次備份,到週三就把週一週二週三的做一次備份,這就叫差異備份。比較容易恢復。

    MYISAM與InnoDB區別:

    MYISAM存儲引擎不支持熱備,而InnoDB支持 InnoDB記錄數據時都會給數據一個序列號,所以在備份時基於MVCC(多版本併發控制)的機制自動加快照,每啓動一個事務都會創建當前集的一個快照,而後基於MVCC的機制把每一個序列號都給它記錄一份下來,備份時只備份序列號或序列號之前的數據,往後發生的將不做備份,如果事務的隔離級別不是特別高的話,它並不會影響事務的讀寫操作,而這樣備份出來的數據一定是時間點一致的數據,所以要完成熱備份,通常是基於事務的存儲引擎才能夠完成的。           

     Innobase:提供了商業備份工具爲Innobackup,可以實現InnoDB的熱備支持增量備份;但是對於MyISAM不支持增量備份,只能實現完全備份,屬於物理備份,速度比較快。
   Xtrabackup:由Percona組織提供的開源備份工具,物理備份,速度快;

    mysqldump:常用的備份工具,也是個邏輯備份工具,用於小數據備份,一般都是在10G以下的小數據進行備份;可以使用文本進行二次處理;相當於MySQL的客戶端工具 
  

    

    三、數據備份與恢復實戰

    常見備份工具:

    mysqldump:邏輯備份工具,備份和恢復過程都比較慢 

    mysqldumper:多線程,的mysqldump,很難實現差異或增量備份 

    lvm-snapshot: 

    接近於熱備的工具,因爲要事先請求全局鎖,而後創建快照,並在創建快照完成後釋放全局鎖。使用cp,tar等工具進行物理備份;備份和恢復速度快,很難實現增量備份,並且請求全局需要一段時間,  

    邏輯備份工具,快於mysqldump  

    Innobase:商業備份工具,innobackup 

    xtrabackup:由percona提供的開源備份工具 

    innodb熱備,增量備份 

    myisam溫備,不支持增量  

    物理備份,速度快 

    mysqlhotcopy:幾乎冷備 

    mysqldump:僅適用於數據集較小的數據庫,數據量達到10G以上時建議不使用,備份太慢 

mysqldump:
mysqldump [options] [db_name [tbl_name ...]]    
mysqldump -uroot -hlocalhost -p testdb>/tmp/testdb.sql #備份單個表
mysql -uroot -hlocalhost -p testdb</tmp/testdb.sql #恢復時要事先創建數據庫
mysqldump -uroot -hlocalhost -p --databases db1 db2 db2 >/tmp/dbs.sql #使用此備份方法恢復時無需連入mysql創建數據庫
mysqldump -uroot -hlocalhost -p --all-databases >/tmp/all.sql #備份所有數據庫,適用於冷備
備份單庫或多庫:--databases    備份所有數據庫:--all-databases
注意:線上備份時,在實施溫備時需施加鎖對單表或多表施加鎖,讓用戶只能讀而不能寫
mysqldump -uroot -hlocalhost --databases testdb --lock-all-tables --flush-logs>/tmp/testdb.sql
mysqldump -uroot -hlocalhost --databases testdb --single-transaction --flush-logs >/tmp/testdb1.sql #僅對Innodb存儲引擎實現熱備,不支持myisam引擎
mysqldump -uroot -hlocalhost --databases testdb --lock-all-tables --flush-logs --master-data=2 >/tmp/testdb2.sql
mysqldump -uroot -hlocalhost --databases testdb --single-transaction --flush-logs --master-data=2 >/tmp/testdb3.sql
--lock-all-tables #請求鎖定所有表之後備份    --single-transaction #能夠對innodb存儲引擎實現熱備
--flush-logs #備份時滾動日誌    --master-data=[0|1|2]設置爲1:保存爲一個change master語句 設置爲2:註釋掉的change master語句,設置爲0:不記錄
數據恢復:建議關閉二進制日誌,關閉其他用戶連接:set session sql_log_bin=0

使用mysqldump實現備份及其使用二進制日誌做恢復:                 

使用mysqldump實現備份,用二進制日誌恢復數據,這裏我們以當前系統上的數據庫hellodb爲例:

   第一步:先把hellodb這個數據庫做一次完全備份,當數據庫的數據很大,比如說大於10G的話不建議使用mysqldump這個工具做備份,而使用物理備份更爲合理:

mysqldump -uroot -hlocalhost -p --databases hellodb --lock-all-tables --flush-logs --master-data=2 >/tmp/hellodb.sql

   第二步:在數據庫hellodb中修改或創建一些表或數據,使得之前備份的數據跟現有的數據庫中的數據存在差別,以完後後面的通過二進制日誌進行數據恢復:

MariaDB [(none)]> use hellodb;
Database changed
MariaDB [hellodb]> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| t1                |
| teachers          |
| toc               |
+-------------------+
8 rows in set (0.00 sec)
MariaDB [hellodb]> drop table t1;
Query OK, 0 rows affected (0.01 sec)
MariaDB [hellodb]> create table tb1(id int,name varchar(20));
Query OK, 0 rows affected (0.02 sec)
MariaDB [hellodb]> insert into tb1 values(1,'alren'),(2,'tbname');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0
MariaDB [hellodb]> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| tb1               |
| teachers          |
| toc               |
+-------------------+
8 rows in set (0.00 sec)
MariaDB [hellodb]> \q
Bye

   第三步:使用另外一臺服務器做恢復測試,將hellodb.sql,及發生改變的二進制日誌導入出來拷貝至另一臺主機

[root@centos6 binlog]# mysqlbinlog --start-position=245 master-bin.000005
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#161117  6:43:00 server id 1  end_log_pos 245 Start: binlog v 4, server v5.5.32-MariaDB-log created 161117  6:43:00
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
9OAsWA8BAAAA8QAAAPUAAAABAAQANS41LjMyLU1hcmlhREItbG9nAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAA2QAEGggAAAAICAgCAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAALfrHBw==
'/*!*/;
# at 245
#161117  7:01:18 server id 1  end_log_pos 352 Querythread_id=23exec_time=0error_code=0
use `hellodb`/*!*/;
SET TIMESTAMP=1479337278/*!*/;
SET @@session.pseudo_thread_id=23/*!*/;
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=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
DROP TABLE `t1` /* generated by server */
/*!*/;
# at 352
#161117  7:01:51 server id 1  end_log_pos 459 Querythread_id=23exec_time=0error_code=0
SET TIMESTAMP=1479337311/*!*/;
create table tb1(id int,name varchar(20))
/*!*/;
# at 459
#161117  7:02:43 server id 1  end_log_pos 530 Querythread_id=23exec_time=0error_code=0
SET TIMESTAMP=1479337363/*!*/;
BEGIN
/*!*/;
# at 530
#161117  7:02:43 server id 1  end_log_pos 642 Querythread_id=23exec_time=0error_code=0
SET TIMESTAMP=1479337363/*!*/;
insert into tb1 values(1,'alren'),(2,'tbname')
/*!*/;
# at 642
#161117  7:02:43 server id 1  end_log_pos 669 Xid = 1515
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos6 binlog]# mysqlbinlog --start-position=245 master-bin.000005 >inre.sql

第四步:恢復數據,進入到mysql的命令行模式下或在命令行,把二進制日誌關掉,恢復數據時不需要把恢復信息記錄到二進制日誌中去;

MariaDB [(none)]>set sql_log_bin=0
MariaDB [hellodb]>source /root/hellodb1.sql
MariaDB [hellodb]> source /root/inre.sql
MariaDB [hellodb]>set sql_log_bin=1
MariaDB [hellodb]> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| tb1               |
| teachers          |
| toc               |
+-------------------+
8 rows in set (0.00 sec)

    

如上訴結果說明數據已經恢復到原來最初始的狀態,基於mysqldump+二進制日誌的備份和恢復完成。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章