MySQL備份策略

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 資源。(若是索引較多,邏輯備份會比物理備份小。)
  • 恢復時間更長,使用邏輯備份的數據恢復,須要佔用更多資源去進行鎖分配、索引構建、衝突檢查、日誌刷新。

邏輯備份經常使用方法:數據庫

  • mysqldumpMySQL自帶的備份工具,通用性強,很是常見。使用的使用一般要加上一些參數,後面繼續介紹。
  • 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 表示在備份過程當中記錄主庫的 binlogpos 點,並在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. 總結

  1. 邏輯備份和物理備份能夠一塊兒使用,不一樣的備份週期使用不一樣的工具,全備週期不該該太長,至少一週一次全備
  2. 若是數據量較大,可使用增量備份的方式減小數據量,要注意的是,增量備份風險更大
  3. binlog功能要開啓,設爲 row 模式,設置 log_slave_updates = 1,且最好定時備份 binlog
  4. 有條件的話能夠增長一個 Delay 庫,在作緊急恢復的時候有奇效
  5. 數據校驗要定時去作,不然當須要備份恢復的時候而備份文件又失效,後悔都來不及
相關文章
相關標籤/搜索