1 關於備份
1.1 爲何要備份
- 災難恢復,數據庫在運行過程當中,終會遇到各類各樣的問題: 硬件故障、Bug 致使數據損壞、因爲服務器宕機或者其餘緣由形成的數據庫不可用。除此之外還有人爲操做:
DELETE
語句忘加條件、ALTER TABLE
執行錯表、DROP TABLE
執行錯表、黑客攻擊,即便這些問題你都還沒遇到,可是根據墨菲定律,總會有趕上的時候。 - 回滾,因爲某種Bug或系統被黑形成大量的損失,這個時候就須要回滾到某個狀態。常見的有區塊鏈交易所被黑而後回滾,遊戲漏洞被利用而後總體回滾。
- 審計,有時候有這樣的需求:須要知道某一個時間點的數據是怎麼樣的,多是年底審計,也多是由於官司。
- 測試,一個基本的測試需求是,定時拉取線上數據到測試環境,若是有備份,就能夠很是方便地拉取數據。
1.2 有哪些備份方式
1.2.1 邏輯備份
邏輯備份是最多見的方式,在數據量比較少的時候很經常使用。html
邏輯備份的優點:mysql
- 備份恢復比較簡單,例如
mysqldump
就是 MySQL 自帶的備份工做,無需額外安裝。恢復的時候能夠直接使用mysql
命令進行恢復。 - 能夠遠程備份和恢復,也就是說,能夠在其餘機器執行備份命令。
- 備份出來的數據很是直觀,備份出來後,可使用
sed
grep
等工具進行數據提取或者修改。 - 與存儲引擎無關,由於備份文件是直接從 MySQL 裏面提取出來的數據,因此在直觀上,備份數據數據不對引擎作區分,能夠很方便地從
MyISAM
引擎改到InnoDB
引擎。 - 避免受到文件損壞的影響,若是直接複製原始文件,可能會受到某個文件損壞的影響而獲得一個損壞的備份。使用邏輯備份,只要 MySQL 還能執行 SELECT 語句,就能夠獲得一份能夠信賴的邏輯備份,在文件損壞的時候頗有用。
邏輯備份缺點:sql
- 由於必須使用 MySQL 服務進行數據操做,因此備份的時候會佔用更多 CPU,且備份時間可能會更長。
- 邏輯備份在某些場景下比數據庫文件更大,文本存儲的數據不老是比存儲引擎更高效。固然,使用壓縮的話會獲得一個更小的備份,可是要佔用 CPU 資源。(若是索引較多,邏輯備份會比物理備份小。)
- 恢復時間更長,使用邏輯備份的數據恢復,須要佔用更多資源去進行鎖分配、索引構建、衝突檢查、日誌刷新。
邏輯備份經常使用方法:數據庫
mysqldump
是MySQL
自帶的備份工具,通用性強,很是常見。使用的使用一般要加上一些參數,後面繼續介紹。select into outfile
,以符號分割數據建立邏輯備份,對於要導入到CSV
等表格會比較實用。mydumper
,容許使用多線程進行備份,備份文件會進行表結構和數據分離,在恢復某些表或數據的時候會很是有效。
1.2.2 物理備份
物理備份在數據量較大的時候很是常見。緩存
物理備份的優點:安全
- 備份速度快,由於物理備份是基於複製進行備份,意味者複製有多快,備份就能有多快。
- 恢復速度快,只須要把文件複製到數據庫目錄就能夠完成恢復,不須要檢查鎖、構建索引。
- 恢復簡單,對於 MySIAM 引擎的表,不須要停庫,只須要簡單地複製進數據目錄就能夠。對於 InnoDB,若是是每一個表一個表空間,也能夠不停庫操做,使用卸載加載表空間的方式即可導入(不太安全)。
物理備份缺點:服務器
- 沒有官方物理熱備份工具的支持。沒有官方工具的支持,意味着出問題的機率較大,使用的時候就要謹慎了
- InnoDB 的原始文件一般比邏輯備份要大。InnoDB 表空間每每包含不少未被使用的空間,InnoDB 表在刪除數據後不會釋放空間,因此即便數據量不大,文件有可能很大。除此之外,文件中除了數據還包含了索引、日誌等信息。
- 物理備份不總能夠跨平臺跨版本。MySQL 文件和操做系統、MySQL 版本息息相關,若是環境與原來不一致,頗有可能會出現問題。
物理備份經常使用方法:多線程
xtrabackup
是最經常使用的物理備份工具,由percona
開源,可以實現對 InnoDB 存儲引擎和 XtraDB 存儲引擎非阻塞地備份(對於 MyISAM 仍是要加鎖),獲得一份一致性備份。直接複製文件/文件系統快照
,這種方式對於MySIAM
引擎是很是高效的,只須要執行FLUSH TABLE WITH READ LOCK
就能夠複製獲得一份備份文件。可是對於InnoDB
引擎就比較困難,由於InnoDB
引擎使用了大量的異步技術,即便執行了FLUSH TABLE WITH READ LOCK
,它仍是會繼續合併日誌、緩存數據。因此要用這種方法備份InnoDB
,須要確保checkpoint
已經最新。
1.2 爲何要備份 binlog
若是有 DBA 告訴你,這個數據庫可以恢復到兩個個月內任何狀態,這說明了,這個數據庫的 binlog 日誌至少保留了兩個月。備份 binlog 的好處:app
- 能夠實現基於任意時間點的恢復
- 能夠用於誤操做數據閃回
- 能夠用於審計
當你要進行數據恢復的時候,就會很是慶幸有作 binlog
備份。固然,使用 binlog
恢復數據的前提是 binlog
格式要設爲 row
,不要擔憂空間問題,當前最不缺的資源就是硬盤空間。對於 binlog
,咱們推薦的配置是異步
# 記錄每一行數據的變化 binlog_format = row # 備庫在重作數據的時候,記錄一條 binlog log_slave_updates = 1
1.3 複製和備份
主從複製等於多了一個數據副本,可是複製並不等於備份,也不能代替備份。假設在主庫執行了 drop table
操做,會馬上同步到備庫,並執行相同的操做,沒有辦法在出現意外的時候使用備庫進行數據恢復。
延遲複製也不能代替備份,可是能加快恢復的速度,是一種很是有用的策略。
在實際使用中,爲了避免影響主庫的使用,咱們每每會在備庫進行備份,同時記錄同步點,以方便進行新備庫搭建。在備庫備份須要注意的是,主從複製並不能保證主備間數據是一致的。實際上,基於複製的 MySQL
集羣並不能保證集羣內部一致性,當前也沒有很是好的辦法,經常使用的是使用 pt-table-checksum
進行一致性檢查。
2. 全量備份
全量備份介紹最經常使用的邏輯備份工具 mysqldump
和物理備份工具 xtrabackup
。若是對 mysqldump
不太滿意 可使用 mydumper
來替代 mysqldump
。
2.1 mysqldump
mysqldump
是用得最多的工具,可是要用好的話,須要增長一些額外的參數。mysqldump
有不少可用參數,這裏不展開,建議直接訪問官網 mysqldump。使用 mysqldump
某些參數須要 select,reload,lock tables
權限。
2.1.1 常見例子
2.1.1.1 InnoDB 全庫備份
mysqldump --opt --single-transaction --master-data=2 --default-character-set=utf8 -h<host> -u<user> -p<password> -A > backup.sql
--opt
若是有這個參數表示同時激活了mysqldump命令的quick,add-drop-table,add-locks,extended-insert,lock-tables參數,它能夠給出很快的轉儲操做併產生一個能夠很快裝入MySQL服務器的轉儲文件。當備份大表時,這個參數能夠防止佔用過多內存--single-transaction
設置事務的隔離級別爲可重複讀,而後備份的時候開啓事務,這樣能保證在一個事務中全部相同的查詢讀取到一樣的數據。注意,這個參數只對支持事務的引擎有效,若是有MyISAM
的數據表,並不能保證數據一致性-A
導出所有數據庫–-default-character-set=charset
指定導出數據時採用何種字符集--master-data=2
表示在備份過程當中記錄主庫的binlog
和pos
點,並在dump文件中註釋掉這一行,在使用備份文件作新備庫時會用到
2.1.1.2 MyISAM 全庫備份
mysqldump --opt --lock-all-tables --master-data=2 --default-character-set=utf8 -h<host> -u<user> -p<password> -A > backup.sql
--lock-all-tables
鎖表備份。因爲MyISAM
不能提供一致性讀,若是要獲得一份一致性備份,只能進行全表鎖定。
2.1.1.3 備份帶上壓縮
mysqldump -h<host> -u<user> -p<password> -A | gzip >> backup.sql.gz
2.1.1.4 備份多個庫
mysqldump -h<host> -u<user> -p<password> --databases <dbname1> <dbname2> > backup.sql
2.1.2 恢復
恢復方式比較簡單,直接執行 sql 語句就能夠了
mysql -h<host> -u<user> -p<password> < backup.sql
2.1.3 mysqldump執行流程
打開 general_log
能夠查看 mysqldump
的執行流程,這裏以 --single-transaction --opt -A
參數爲例
FLUSH /*!40101 LOCAL */ TABLES FLUSH TABLES WITH READ LOCK SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ START TRANSACTION SHOW VARIABLES LIKE 'gtid\_mode' SHOW MASTER STATUS UNLOCK TABLES ... SHOW CREATE DATABASE IF NOT EXISTS `employees` SAVEPOINT sp ... SELECT /*!40001 SQL_NO_CACHE */ * FROM `departments` ....
2.2 xtrabackup
2.2.1 安裝方式
更多安裝方式參考官網 xtrabackup
這裏咱們使用 rpm
安裝的方式
yum install http://www.percona.com/downloads/percona-release/redhat/0.1-6/percona-release-0.1-6.noarch.rpm yum update percona-release # qpress 用做壓縮解壓 yum install percona-xtrabackup-24 qpress
2.2.2 使用方法
2.2.2.1 增長備份帳號並受權
CREATE USER 'backup'@'localhost' IDENTIFIED BY 'backup'; GRANT PROCESS,RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup'@'localhost'; FLUSH PRIVILEGES;
2.2.2.2 全備
innobackupex --defaults-file=/etc/my.cnf --user=<user> --password=<pwd> <要備份到哪一個目錄> --no-timestamp --compress --compress-threads=4 --parallel=4
--no-timestamp
不使用當前時間創建文件夾。默認狀況下會在備份目錄以當前時間建立文件夾--compress
壓縮--compress-threads=N
壓縮線程--parallel=N
備份線程
2.2.2.3 恢復
# 步驟一:解壓 innobackupex --decompress <備份文件所在目錄> --parallel=4 # 步驟二:應用日誌 innobackupex --apply-log <備份文件所在目錄> --parallel=4 # 步驟三:複製備份文件到數據目錄 innobackupex --datadir=<MySQL數據目錄> --copy-back <備份文件所在目錄> --parallel=4
3. 增量備份
當數據了變得龐大時,一個常見策略就是作按期的增量備份。例如:週一作了一次全量備份,而後週二到日作增量備份。
增量備份只包含變化的數據集,通常狀況不會比原始數據量大,因此能夠減小服務器的開銷、備份時間、備份空間。
固然,使用增量備份也會有風險,增量備份每一次迭代都是基於上一次的備份實現,意味着只要其中一份備份出現問題,那麼就有可能致使全部備份不可用。
下面介紹一些增量備份方法:
3.1 使用 xtrabackup 作增量備份
xtrabackup 容許進行增量備份,命令以下:
innobackupex --defaults-file=/etc/my.cnf --user=<user> --password=<pwd> --no-timestamp --compress --incremental --incremental-basedir=<全量備份的目錄> <要增量備份到什麼目錄>
恢復:
# 步驟一:對全備解壓 innobackupex --decompress <全量備份文件所在目錄> # 步驟二:對全備應用日誌 innobackupex --apply-log --redo-only <全量備份文件所在目錄> # 步驟三:對增量備份進行解壓 innobackupex --decompress <增量文件所在目錄> # 步驟四:合併增量數據 innobackupex --apply-log --redo-only --incremental <全量備份文件所在目錄> --incremental-dir=<增量文件所在目錄> # 步驟五:對合並後的數據應用日誌 innobackupex --apply-log <全量備份文件所在目錄> # 步驟六:複製備份文件到數據目錄 innobackupex --datadir=<MySQL數據目錄> --copy-back <全量備份文件所在目錄>
3.2 使用 binlog 作增量備份
使用 binlog
作增量備份比較簡單,備份的時候執行 FLUSH LOGS
輪轉日誌,而後把舊的 binlog
複製到備份目錄就能夠了。
恢復的時候使用 mysqlbinlog --start-position=<備份集的pos點> binlog日誌 | mysql -u<user> -p
就能夠了
4. 延遲同步
延遲同步是常見的使用主從複製使用模式,在遇到誤操做的時候,不管是用於恢復數據,仍是使用跳過的方式跳過錯誤都是很是有用。
例如在主庫作了 drop
的誤操做,在主庫找到命令所在 binlog 日誌和 pos 位置,Delay庫中止同步,而後使用 start slave until master_log_file='<對應file>',master_log_pos=<誤操做命令前一個SQL的pos>;
等待同步到這個位置,執行跳過一條 SQL 的命令再開啓同步。
常見的延遲同步複製模式有:
一主帶三從
有時候爲了減小主庫壓力,會把延遲庫放在備節點以後
延遲同步開啓方式以下:
stop slave; CHANGE MASTER TO MASTER_DELAY = N秒; start slave;
5. 數據校驗
除了備份,很是重要的一件事情就是驗證備份數據的可用性。想象一下,當你須要進行數據恢復的時候,突然發現過去的備份數據都是無效的,那得有多難受。不少朋友在寫好備份腳本加到定時任務後,只要檢查到定時任務有執行,備份目錄有文件就再也不關注了,每每到了須要使用備份文件的時候才發現備份數據有問題。
目前對於備份文件的數據校驗沒有很是方便的辦法,用的比較多的仍是定時把備份文件拉出來作備份恢復演練,例如一個月作一次備份恢復演練就能夠有效提升備份文件可用性,內心也踏實。
數據校驗部分,若是是邏輯備份,每每會抽查某個表的數據,檢查是否符合預期。若是是物理備份,首先要使用 mysqlcheck
等命令檢查是否有表損壞,沒有損壞再抽查表數據。
6. 總結
- 邏輯備份和物理備份能夠一塊兒使用,不一樣的備份週期使用不一樣的工具,全備週期不該該太長,至少一週一次全備
- 若是數據量較大,可使用增量備份的方式減小數據量,要注意的是,增量備份風險更大
- binlog功能要開啓,設爲
row
模式,設置log_slave_updates = 1
,且最好定時備份 binlog - 有條件的話能夠增長一個 Delay 庫,在作緊急恢復的時候有奇效
- 數據校驗要定時去作,不然當須要備份恢復的時候而備份文件又失效,後悔都來不及