七、MySQL備份恢復

圖片來自網絡

文/Bruce.Liu1

文章大綱

  1. 備份概念
    1.1. 備份目的
    1.2. 備份方式
    1.3. 備份類型
    1.4. 備份對象
    1.5. 備份策略
  2. mysqldump
    2.1. mysqldump原理
    2.2. 相關參數
    2.3. 最佳實踐
  3. Xtrabackup
    3.1. Xtrabackup原理
    3.2. 文件介紹
    3.3. 相關參數
    3.4. 最佳實踐
  4. mydumper
    4.1. mydumper原理
    4.2. 相關參數
    4.3. 最佳實踐

1.備份概念

為什么要備份?我們試著想一想, 在生產環境中什么最重要?如果我們服務器的硬件壞了可以維修或者換新, 軟件問題可以修復或重新安裝, 但是如果數據沒了呢?這可能是最恐怖的事情了吧,我感覺在生產環境中應該沒有什么比數據跟更為重要. 那么我們該如何保證數據不丟失、或者丟失后可以快速恢復呢?只要看完這篇, 大家應該就能對數據備份和恢復能有一定的了解。

當年的911事件致使多少個金融公司遭受巨額損失,據初步估計,損失在100億美元以上。辦公室設在世貿大樓上的公司就更加倒霉,他們的業務幾近癱瘓,大量數據丟失,其中著名的公司有美洲銀行、朝日銀行、德國銀行、國際信托銀行、肯珀保險公司、馬什保險公司、帝國人壽保險公司、蓋伊·卡彭特保險公司、坎特·菲茲杰拉德投資公司、摩根斯坦利金融公司、美國商品期貨交易所。其中,摩根斯坦利損失最慘,因為它在世貿中心總共租用了29.8萬平米的辦公用地,公司很多職員連辦公地點都沒有。

更多的故障案例:
1. GitLab.com丟失6個小時數據,操作員將被迫看“10小時的彩虹貓”,以示懲罰!
2. 攜程內部數據嚴重丟失問題
3. 谷歌數據中心遭雷劈 部分數據永久丟失
4. 9.11事件造成的建筑數據等財產直接損失達340億美元

1.1.備份目的

在生產環境中我們數據庫可能會遭遇各種各樣的不測從而導致數據丟失,數據備份就是針對以下幾種情況:

  • 硬件故障
  • 軟件故障
  • 自然災害
  • 黑客攻擊
  • 誤操作 (占比最大)

總結:針對以上各種災難性的場景發生,一個良好的備份,能恢復至故障前一秒正常的運行狀態。

1.2.備份方式

備份方式

  • 冷備(cold backup):需要關mysql服務,讀寫請求均不允許狀態下進行;
    1.即:停止數據庫、將整個數據文件、日志文件、配置文件等拷貝至一個鏡像。

  • 熱備(hot backup):備份的同時,業務不受影響。
    1.邏輯備份
    a) mysqldump:官方自帶的邏輯備份工具
    b) mydumper:開源的多線程邏輯備份工具
    2.物理備份
    a) Enterprise Backup:官方企業級備份工具(收費產品)
    b) Xtrabackup tools:業界中最著名的開源備份工具,由Percona公司研發。

引擎支持是否備份方式

引擎 熱備 冷備
MyISAM ×
InnoDB
TokuDB

備份工具是否支持引擎

  1. 邏輯的備份工具一般來說都支持各種引擎(邏輯的導出和底層的Engine沒啥關系!!)
  2. 物理備份工具就有很大的局限性,著名的Xtrabackup也只是支持MyISAM、innodb引擎

1.3.備份類型

  • 完全備份:
    full backup,備份全部數據集。

  • 增量備份:
    incremental backup,上次完全備份或增量備份以來改變了的數據,不能單獨使用,要借助完全備份,備份的頻率取決于數據的更新頻率。

  • 差異備份:
    differential backup,上次完全備份以來改變了的數據。

1.4. 備份對象

一般情況下, 我們需要備份的數據分為以下幾種

  • 全量數據
  • 二進制日志, InnoDB事務日志
  • 代碼(存儲過程、存儲函數、觸發器、事件調度器)
  • 服務器配置文件

1.5.備份策略

在訂制一個備份策略之前,首先我們先要向架構或業務部門了解清楚,我們的業務模型/場景類型/安全優先級/以及對數據恢復的時間要求等因素, 在我遇到的很多中小型公司/甚至連一些互聯網金融機構等對于數據安全級別很高的場景中,對數據庫備份策略也是一無所知,他們常見的做法幾乎都是由信息部門數據庫負責人或信息部技術意淫出來的。沒有人會徹徹底底的觀察場景/業務/以及安全級別等因素。

下面我們舉常見的幾種業務場景進行分析:

  • SNS社交網絡服務類場景(Social Network Site)(國內常見的SNS如:微博/人人網/豆瓣/論壇)
    a) 高并發
    b) 高可靠性99.999%
    c) 低數據一致性
    d) 數據恢復時間要求高

  • 傳統行業類業務場景(電力/物流/零售/服務/餐飲)
    a) 普遍低并發
    b) 高可靠性99.999%
    c) 高數據一致性
    d) 數據恢復時間一般

  • 傳統金融類場景(銀行/證券/股票)
    a) 普遍低并發
    b) 高可靠性99.999%
    c) 高數據一致性
    d) 數據恢復時間一般

  • 互聯網金融/支付類場景(微信/支付寶/P2P/電子商務)
    a) 并發一般
    b) 高可靠性99.999%
    c) 高數據一致性
    d) 數據恢復時間高

以上任何一類業務場景中,對于可靠性都期望是99.999%,如果不知道什么是5個9,請自己默默的打開鏈接掃掃盲。但他們對于數據一致性要求卻有著重大的不同。那有的同學會說了,可靠性和數據一致性可不可以兼顧呢?我相信大家都知道魚和熊掌不可兼得的道理吧!

2.mysqldump

MySQL Client管理工具也叫:獨立的管理實用程序,程序本身不依賴于其他程序模塊。能夠獨立運行。這是MySQL的特性。

2.1.mysqldump原理

1.連接MySQL數據庫,設置基本session級環境變量
2.開啟快照級事務(加鎖)并獲取當前的GTID
3.釋放鎖資源
4.create savepoint
5.獲取表結構信息/設置字符集/備份數據
6.roll back savepoint
7.重復步驟5~6直至備份完成

savepoint原理

圖片來自原創

2.2.相關參數

--all-databases , -A 導出全部數據庫。
--all-tablespaces , -Y 導出全部表空間。
--no-tablespaces , -y 不導出任何表空間信息。
--add-drop-database 每個數據庫創建之前添加drop數據庫語句。
--add-drop-table 每個數據表創建之前添加drop數據表語句。(默認為打開狀態)
--add-locks 在每個表導出之前增加LOCK TABLES并且之后UNLOCK  TABLE。(默認為打開狀態)
--allow-keywords 允許創建是關鍵詞的列名字。這由表名前綴于每個列名做到。
--apply-slave-statements 在'CHANGE MASTER'前添加'STOP SLAVE',并且在導出的最后添加'START SLAVE'。
--character-sets-dir 字符集文件的目錄
--comments 附加注釋信息。默認為打開,可以用--skip-comments取消
--compatible 導出的數據將和其它數據庫或舊版本的MySQL 相兼容。值可以為mysql323、mysql40、PG、oracle、mssql等,用逗號將它們隔開。它并不保證能完全兼容,而是盡量兼容。
--compact 導出更少的輸出信息(用于調試)。去掉注釋和頭尾等結構。可以使用選項:--skip-add-drop-table  --skip-add-locks --skip-comments --skip-disable-keys
--complete-insert, -c 使用完整的insert語句(包含列名稱)。這么做能提高插入效率,但是可能會受到max_allowed_packet參數的影響而導致插入失敗。
--compress, -C 在客戶端和服務器之間啟用壓縮傳遞所有信息
--create-options, -a 在CREATE TABLE語句中包括所有MySQL特性選項。(默認為打開狀態)
--databases, -B 導出幾個數據庫。參數后面所有名字參量都被看作數據庫名。
--debug 輸出debug信息,用于調試。默認值為:d:t:o,/tmp/mysqldump.trace
--debug-check 檢查內存和打開文件使用說明并退出。
--debug-info 輸出調試信息并退出
--default-character-set 設置默認字符集,默認值為utf8
--delayed-insert 采用延時插入方式(INSERT DELAYED)導出數據
--delete-master-logs master 備份后刪除日志. 這個參數將自動激活--master-data。
--disable-keys 對于每個表,用/*!40000 ALTER TABLE tbl_name DISABLE KEYS */;和/*!40000 ALTER TABLE tbl_name ENABLE KEYS */;語句引用INSERT語句。該選項只適合MyISAM表,默認為打開狀態。
--dump-slave 該選項將導致主的binlog位置和文件名追加到導出數據的文件中。設置為1時,將會以CHANGE MASTER命令輸出到數據文件;設置為2時,在命令前增加說明信息。該選項將會打開--lock-all-tables,除非--single-transaction被指定。該選項會自動關閉--lock-tables選項。默認值為0。
--events, -E 導出事件。
--extended-insert,  -e 使用具有多個VALUES列的INSERT語法。這樣使導出文件更小,并加速導入時的速度。默認為打開狀態,使用--skip-extended-insert取消選項。
--fields-terminated-by 導出文件中忽略給定字段。與--tab選項一起使用,不能用于--databases和--all-databases選項
--fields-enclosed-by 輸出文件中的各個字段用給定字符包裹。與--tab選項一起使用,不能用于--databases和--all-databases選項
--fields-optionally-enclosed-by 輸出文件中的各個字段用給定字符選擇性包裹。與--tab選項一起使用,不能用于--databases和--all-databases選項
--fields-escaped-by 輸出文件中的各個字段忽略給定字符。與--tab選項一起使用,不能用于--databases和--all-databases選項
--flush-logs 開始導出之前刷新日志。
--flush-privileges 在導出mysql數據庫之后,發出一條FLUSH  PRIVILEGES 語句。為了正確恢復,該選項應該用于導出mysql數據庫和依賴mysql數據庫數據的任何時候。
--force ,-f 在導出過程中忽略出現的SQL錯誤。
--help 顯示幫助信息并退出。
--hex-blob 使用十六進制格式導出二進制字符串字段。如果有二進制數據就必須使用該選項。影響到的字段類型有BINARY、VARBINARY、BLOB。
--host, -h 需要導出的主機信息
--ignore-table 不導出指定表。指定忽略多個表時,需要重復多次,每次一個表。每個表必須同時指定數據庫和表名。例如:--ignore-table=database.table1 --ignore-table=database.table2 ……
--include-master-host-port 在--dump-slave產生的'CHANGE  MASTER TO..'語句中增加'MASTER_HOST=<host>,MASTER_PORT=<port>'  
--insert-ignore 在插入行時使用INSERT IGNORE語句.
--lines-terminated-by 輸出文件的每行用給定字符串劃分。與--tab選項一起使用,不能用于--databases和--all-databases選項。
--lock-all-tables,  -x 提交請求鎖定所有數據庫中的所有表,以保證數據的一致性。這是一個全局讀鎖,并且自動關閉--single-transaction 和--lock-tables 選項。
--lock-tables,  -l 開始導出前,鎖定所有表。用READ  LOCAL鎖定表以允許MyISAM表并行插入。
--log-error 附加警告和錯誤信息到給定文件
--master-data 該選項將binlog的位置和文件名追加到輸出文件中。如果為1,將會輸出CHANGE MASTER 命令;如果為2,輸出的CHANGE  MASTER命令前添加注釋信息。該選項將打開--lock-all-tables 選項,除非--single-transaction也被指定(在這種情況下,全局讀鎖在開始導出時獲得很短的時間;其他內容參考下面的--single-transaction選項)。該選項自動關閉--lock-tables選項。
--max_allowed_packet 服務器發送和接受的最大包長度。
--net_buffer_length TCP/IP和socket連接的緩存大小。
--no-autocommit 使用autocommit/commit 語句包裹表。
--no-create-db,  -n 只導出數據,而不添加CREATE DATABASE 語句。
--no-create-info,  -t 只導出數據,而不添加CREATE TABLE 語句。
--no-data, -d 不導出任何數據,只導出數據庫表結構。
--no-set-names,  -N 等同于--skip-set-charset
--opt 等同于--add-drop-table,  --add-locks, --create-options, --quick, --extended-insert, --lock-tables,  --set-charset, --disable-keys 該選項默認開啟,  可以用--skip-opt禁用.
--order-by-primary 如果存在主鍵,或者第一個唯一鍵,對每個表的記錄進行排序。
--password, -p 連接數據庫密碼
--pipe(windows系統可用) 使用命名管道連接mysql
--port, -P 連接數據庫端口號
--protocol 使用的連接協議,包括:tcp, socket, pipe, memory.
--quick, -q 不緩沖查詢,直接導出到標準輸出。默認為打開狀態,使用--skip-quick取消該選項。
--quote-names,-Q 使用(`)引起表和列名。默認為打開狀態,使用--skip-quote-names取消該選項。
--replace 使用REPLACE INTO 取代INSERT INTO.
--result-file,  -r 直接輸出到指定文件中。該選項應該用在使用回車換行對(\\r\\n)換行的系統上(例如:DOS,Windows)。該選項確保只有一行被使用。
--routines, -R 導出存儲過程以及自定義函數。
--set-charset 添加'SET NAMES  default_character_set'到輸出文件。默認為打開狀態,使用--skip-set-charset關閉選項。
--single-transaction 該選項在導出數據之前提交一個BEGIN SQL語句,BEGIN 不會阻塞任何應用程序且能保證導出時數據庫的一致性狀態。它只適用于多版本存儲引擎,僅InnoDB。本選項和--lock-tables 選項是互斥的,因為LOCK  TABLES 會使任何掛起的事務隱含提交。要想導出大表的話,應結合使用--quick 選項。
--dump-date 將導出時間添加到輸出文件中。默認為打開狀態,使用--skip-dump-date關閉選項。
--skip-opt 禁用–opt選項.
--socket,-S 指定連接mysql的socket文件位置,默認路徑/tmp/mysql.sock
--tab,-T 為每個表在給定路徑創建tab分割的文本文件。注意:僅僅用于mysqldump和mysqld服務器運行在相同機器上。
--tables ,定需要導出的表名,需要配合--databases (-B)參數一起使用
--triggers 導出觸發器。該選項默認啟用,用--skip-triggers禁用它。
--tz-utc 在導出頂部設置時區TIME_ZONE='+00:00' ,以保證在不同時區導出的TIMESTAMP 數據或者數據被移動其他時區時的正確性。
--user, -u 指定連接的用戶名。
--verbose, --v 輸出多種平臺信息。
--version, -V 輸出mysqldump版本信息并退出
--where, -w 只轉儲給定的WHERE條件選擇的記錄。請注意如果條件包含命令解釋符專用空格或字符,一定要將條件引用起來。
--xml, -X 導出XML格式.
--plugin_dir 客戶端插件的目錄,用于兼容不同的插件版本。
--default_auth 客戶端插件默認使用權限。

more info... ...

2.3.最佳實踐

導出表結構

mysqldump --no-data --trigger=false mysql > mysql_01.sql

導出存儲過程

mysqldump -f -Rtdn --trigger=false mysql > mysql_02.sql

導出觸發器

mysqldump -f -tdn --trigger mysql > mysql_03.sql

導出事件

mysqldump -f -Etdn --trigger=false mysql > mysql_04.sql

導出數據

mysqldump -f --single-transaction --trigger=false -t mysql > mysql_05.sql

基于條件導出

mysqldump -t --single-transaction --where='cname="'jreey'"'  tydb tab01 > /tmp/tab01.sql

導出某張表

mysqldump -S /data1/db3316/my3316.sock -pxxxxx --default-character-set=utf8 --single-transaction --set-gtid-purged=off --databases intelligent_os --tables beacon_base_pos > /tmp/beacon_base_pos.sql

實例一:數據庫邏輯導出于恢復

備份一個數據庫

mysqldump -S /data1/db3307/my3307.sock --default-character-set=utf8 --master-data=2 --no-create-db --single-transaction --set-gtid-purged=off -q --extended-insert --databases zabbix > /data1/mysqlbackup/m3307-20170306-dump.sql

恢復

mysql -S /data1/db3307/my3307.sock -e "create database zabbix"
mysql -S /data1/db3307/my3307.sock < /data1/mysqlbackup/m3307-20170306-dump.sql

補充:導出導入平面文件”

select * INTO OUTFILE '/tmp/errorlog.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' from error_log;
load data infile '/tmp/errorlog.txt' into table test.error_log FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';

3.Xtrabackup

xtrabackup是Percona公司CTO Vadim參與開發的一款基于InnoDB的在線熱備工具,具有開源,免費,支持在線熱備,備份恢復速度快,占用磁盤空間小等特點,并且支持不同情況下的多種備份形式。(該產品的出現解決了業界內MySQL社區版本中物理備份的空白)xtrabackup的官方下載地址為http://www.percona.com/software/percona-xtrabackup

Xtrabackup是由percona提供的mysql數據庫備份工具,據官方介紹,這也是世界上惟一一款開源的能夠對innodb和xtradb數據庫進行熱備的工具。特點:

  • 備份過程快速、可靠;
  • 備份過程不會打斷正在執行的事務;
  • 能夠基于壓縮等功能節約磁盤空間和流量;
  • 自動實現備份檢驗;
  • 還原速度快;

xtrabackup包含兩個主要的工具,即xtrabackup和innobackupex:

  • xtrabackup只能備份innodb和xtradb兩種引擎的表,而不能備份myisam引擎的表;
  • innobackupex是一個封裝了xtrabackup的Perl腳本,支持同時備份innodb和myisam,但在對myisam備份時需要加一個全局的讀鎖。還有就是myisam不支持增量備份。

3.1.Xtrabackup原理

3.1.1.全備份|恢復原理
  • 備份原理
圖片來自網絡

1.備份開始前開啟一個后臺檢測進程,實時檢測mysql redo的變化寫入到xtrabackup_logfile文件
2.拷貝innodb engine涉及的ibd ibdata1數據文件(拷貝的單位是page,而不是文件)
3.數據庫級只讀鎖(FLUSH TABLES WITH READ LOCK)
4.拷貝除innodb enging之外的數據文件(多數指MyIASM的表)
5.獲取當前數據庫binary log position
6.釋放數據庫級只讀鎖(釋放全局級鎖)
7.等待redo變化寫入xtrabackup_logfile并關閉Xtrbackup進程

建議: xtrabackup工具最好只備份innodb engine的表,因為這樣,就會節省掉步驟四的物理copy時間,從而大大減少,數據庫鎖的時間.

  • 恢復原理
圖片來自網絡

1.Xtrabackup內嵌的innodb實例,回放xtrabackup_log日志至備份集
2.將提交的事務信息變更應用到innodb數據/表空間,同時回滾未提交的事務(這一過程類似innodb的實例恢復)。
3.根據配置文件(my.cnf)恢復數據文件、日志文件到指定路徑

3.1.2.增量備份|恢復原理
  • 備份原理

"增量"備份的過程主要是通過拷貝innodb中有變更的"頁"(這些變更的數據頁指的是"頁"的LSN大于xtrabackup_checkpoints中給定的LSN)。增量備份是基于全備的,第一次增備的數據必須要基于上一次的全備,之后的每次增備都是基于上一次的增備,最終達到一致性的增備。

圖片來自網絡

1.備份開始前開啟一個后臺檢測進程,實時檢測mysql redo的變化寫入到xtrabackup_logfile文件
2.拷貝上次全備份以后LSN變化的數據
3.數據庫級只讀鎖(FLUSH TABLES WITH READ LOCK)
4.拷貝除innodb enging之外的數據文件(多數指MyIASM的表)
5.獲取當前數據庫binary log position
6.釋放數據庫級只讀鎖(釋放全局級鎖)
7.等待redo變化寫入xtrabackup_logfile并關閉Xtrbackup進程

注意:innobackupex增量備份過程中的"增量"處理,其實主要是相對innodb而言,對myisam和其他存儲引擎而言,它仍然是全拷貝(全備份)

  • 恢復原理
圖片來自網絡
圖片來自網絡

1.全備份以只"重做"的方式回放xtrabackup_log日志至備份集(為后面增量數據的合并做基礎)
2.依次合并增量備份至完整備份集(此時的merge可以commit、rollback)
3.Xtrabackup內嵌的innodb實例,回放xtrabackup_log日志至備份集
4.將提交的事務信息變更應用到innodb數據/表空間,同時回滾未提交的事務(這一過程類似innodb的實例恢復)。
5.根據配置文件(my.cnf)恢復數據文件、日志文件到指定路徑

和全備恢復類似,也需要兩步,一是數據文件的恢復,如圖1,這里的數據來源由3部分組成:全備份,增量備份和xtrabackup log。圖2是對未提交事務的回滾

  • 如何選擇備份集
圖片來自原創

3.2.文件介紹

  • backup-my.cnf
    備份集的配置選項文件

  • xtrabackup_binlog_info
    當前正在使用的二進制日志文件及至備份的位置。

  • xtrabackup_binlog_pos_innodb
    包含二進制日志文件及用于InnoDB或XtraDB表的二進制日志文件的當前position

  • xtrabackup_checkpoints
    備份類型(如完全或增量)、備份狀態(如是否已經為prepared狀態)和LSN(日志序列號)范圍信息;

  • xtrabackup_info
    備份集概要

  • xtrabackup_logfile
    備份過程中記錄redo變化的日志文件

3.3.相關參數

--defaults-file=# 該選項傳遞給xtrabackup子進程,從指定文件讀取缺省選項
--apply-log 從備份恢復
--redo-only 選項用于準備全庫備份和合并處最有一個備份外的所有增量備份。該選項強制跳過rollback階段,只進行redo。這是有必要使用的,如果備份后,要使用增量改變的。
--copy-back 從備份目錄拷貝數據和索引文件到datadir目錄
--move-back 移動之前的所有備份從一個備份目錄到他們的原始位置
--incremental 建立一個增量備份,傳遞給xtrabackup的子進程。該參數可以和參數--incremental-lsn or --incremental-basedir配合使用。
--incremental-basedir=DIRECTORY 指定一個包換全庫備份的目錄作為增量備份的基礎數據庫。
--incremental-dir=DIRECTORY 指定增量備份與全庫備份合并去建立一個新的全備份的目錄。
--remote-host=HOSTNAME 備份到遠程主機上,使用ssh
--stream=[tar|cpio(notimplemented)] 指定備份標準輸出格式
--tmpdir=DIRECTORY 默認與tmpdir相同。使用—remote-host或—stream參數后,傳輸日志文件將存放在臨時目錄下
--use-memory=MB 傳遞給xtrabackup子進程。恢復使用內存大小
--parallel=NUMBER-OF-THREADS 選項傳遞給xtrabackup子進程,指定數據傳輸線程總數。默認為1
--compress[=LEVEL] 選項傳遞給xtrabackup子進程。壓縮級別在0-9.1快速壓縮,9最佳壓縮,0不壓縮。默認為1.
--compress-threads[=NUMBER] 壓縮時的并行線程總數,一般來說要和--parallel保持一致
--throttle=iOS 選項傳遞給xtrabackup子進程,限制IO線程數量
--sleep=MS 選項傳遞給xtrabackup子進程。每拷貝1MB數據暫停多少MS時間
--include=REGEXP 選項傳遞給xtrabackup子進程。使用正則進行匹配
--databases=LIST 指定備份數據庫
--tables-file=FILE 指定需要備份的表
--uncompress 選項傳遞給xtrabackup子進程。對壓縮過的InnoDB數據文件不進行壓縮
--export 僅使用于prepare選項。選項傳遞給xtrabackup子進程。
--slave-info 備份復制從服務端,主從信息記錄在ibbackup_slave_info文件中
--no-timestamp 不在備份根目錄下創建以當前時間戳為名稱的新的備份目錄
--ibbackup=IBBACKUP-BINARYibbackup 二進制路徑
--no-lock 禁止表級鎖。全部是InnoDB引擎表和不關系二進制日志位置下使用
--scpopt=SCP-OPTIONS 指定scp參數

3.4.最佳實踐

xtrabackup官方網站:https://www.percona.com/
xtrabackup下載站點:https://www.percona.com/downloads/XtraBackup/LATEST/

3.4.1.完全備份恢復
  • 備份數據庫
innobackupex --defaults-file=/etc/mysql/my10059.cnf -S /var/wd/db10059/my10059.sock -p 123 --use-memory=256M --no-timestamp /data1/mysqlbackup/xtra_full_135156_10059
  • 恢復數據庫
innobackupex --defaults-file=/data1/mysqlbackup/xtra_full_135156_10059/backup-my.cnf --apply-log /data1/mysqlbackup/xtra_full_135156_10059
innobackupex --defaults-file=/etc/mysql/my10059.cnf --move-back /data1/mysqlbackup/xtra_full_135156_10059
chown -R mysql:mysql /var/wd/db10059/
3.4.2.增量備份恢復
  • 備份數據庫
  1. 全備份
innobackupex --defaults-file=/etc/my.cnf -u root -S /data1/db3306/my3306.sock -p123 --no-timestamp /data1/xtra_full_168160_3306
  1. 增量備份
innobackupex --defaults-file=/etc/my.cnf -S /data1/db3306/my3306.sock -p 123 --no-timestamp --incremental /data1/xtra_incr_168160_3306 --incremental-basedir=/data1/xtra_full_168160_3306
  • 恢復數據庫
  1. 全備份只"重做"回放xtrabackup log
innobackupex --apply-log --redo-only /data1/xtra_full_168160_3306
  1. merge增量備份集(如果有多個,順序merge)
innobackupex --apply-log --redo-only xtra_full_168160_3306 --incremental-dir=xtra_incr_168160_3306
  1. 完整的回放xtrabackup log
innobackupex --defaults-file=/data1/xtra_full_168160_3306/backup-my.cnf  --apply-log /data1/xtra_incr_168160_3306
innobackupex --defaults-file=/etc/my.cnf --move-back xtra_full_168160_3306
  1. 通過binlog恢復誤刪除數據
mysqlbinlog --start-position=423234035  16703402-bin.000561 | mysql -S /data1/db3402/my3402.sock -pxxx
mysqlbinlog 16703402-bin.000562 16703402-bin.000563 16703402-bin.000564 16703402-bin.000565 16703402-bin.000566 | mysql -S /data1/db3402/my3402.sock -pxxx
mysqlbinlog 16703402-bin.000567 16703402-bin.000568 16703402-bin.000569 16703402-bin.000570 16703402-bin.000571 16703402-bin.000572 | mysql -S /data1/db3402/my3402.sock -pxxx
mysqlbinlog 16703402-bin.000573 16703402-bin.000574 16703402-bin.000575 16703402-bin.000576 16703402-bin.000577 | mysql -S /data1/db3402/my3402.sock -pxxx
mysqlbinlog --stop-position=657188280 16703402-bin.000578 | mysql -S /data1/db3402/my3402.sock -pxxxx
3.4.3.備份新特性
  • "流"方式壓縮備份
    Xtrabackup對備份的數據文件支持“流”功能,即可以將備份的數據通過STDOUT傳輸給tar程序進行歸檔,而不是默認的直接保存至某備份目錄中。要使用此功能,僅需要使用--stream選項即可。
innobackupex --defaults-file=/etc/mysql/my10059.cnf -p 123 --use-memory=256M --no-timestamp --stream=tar /data1/mysqlbackup/xtra_full_gzip135156_10059 | gzip  > /data1/mysqlbackup/xtra_full_gzip135156_10059.tar.gz
  • "innodb page"方式壓縮備份
innobackupex --defaults-file=/etc/mysql/my10059.cnf -S /var/wd/db10059/my10059.sock -p 123 --compress --use-memory=256M --no-timestamp /data1/mysqlbackup/xtra_full_135156_10059
  • 部分備份
innobackupex --defaults-file=/etc/mysql/my10059.cnf -S /var/wd/db10059/my10059.sock -p 123 --databases='sys performance_schema mysql custom_db' --use-memory=256M --no-timestamp /data1/mysqlbackup/xtra_full_135156_10059
  • 并行備份
innobackupex --defaults-file=/etc/mysql/my10059.cnf -S /var/wd/db10059/my10059.sock -p 123 --parallel=6 --use-memory=256M --no-timestamp /data1/mysqlbackup/xtra_full_135156_10059

4.mydumper

mydumper(&myloader)是用于對MySQL數據庫進行多線程備份和恢復的開源 (GNU GPLv3)工具。開發人員主要來自MySQL、Facebook和SkySQL公司,目前由Percona公司開發和維護,是 Percona Remote DBA 項目的重要組成部分,包含在Percona XtraDB Cluster中。mydumper的第一版0.1發布于2010.3.26,最新版本0.9.1發布于2015.11.06。

Mydumper主要特性:

  • 開源 (GNU GPLv3)
  • 輕量級C語言寫的
  • 快速的文件壓縮
  • 支持導出binlog
  • 執行速度比mysqldump快10倍
  • 多線程恢復(適用于0.2.1以上版本)
  • 事務性和非事務性表一致的快照(適用于0.2.2以上版本)
  • 以守護進程的工作方式,定時快照和連續二進制日志(適用于0.5.0以上版本)

4.1.mydumper原理

mydumper作為一個實用工具,能夠良好支持多線程工作,可以并行的多線程的從表中讀入數據并同時寫到不同的文件里,這使得它在處理速度方面快于傳統的mysqldump N倍

圖片來自網絡

原理分析
mydumper的工作過程:

  • 主線程對備份實例加讀鎖,阻塞寫操作以建立一致性數據備份快照(FLUSH TABLES WITH READ LOCK)
  • 讀取當前時間點的二進制日志文件名和日志寫入的位置并記錄在metadata文件中,以供即使點恢復使用
  • 創建工作線程,初始化備份任務隊列,并向隊列中推送數據庫元數據(schema)、非InnoDB表和InnoDB表的備份任務;
  • 工作線程負責將備份任務隊列中的任務按順序取出并完成備份(dump線程數可以指定,默認是4)
  • 分別建立與備份實例連接,將session的事務級別設置為repeatable-read,用于實現可重復讀;
  • 在主線程仍持有全局讀鎖時開啟事務進行快照讀,這樣保證了讀到的一致性數據與主線程相同,實現了備份數據的一致性;
  • 按序從備份任務隊列中取出備份任務,工作線程先進行MyISAM等非InnoDB表備份
  • 非事物引擎備份完后,主線程釋放全局只讀鎖(UNLOCK TABLES)
  • 完成InnoDB表備份,事務結束,關閉鏈接

表數據拆分方式如下所述:

  • mydumper優先選擇主鍵索引的第一列作為chunk劃分字段
  • 若不存在主鍵索引,則選擇第一個唯一索引作為劃分依據
  • 若還不存在,則選擇區分度(Cardinality)最高的任意索引。
  • 如果還是無法滿足,則只能進行表級的并行備份

范圍拆分方式:

  • 在確定了chunk劃分字段后,先獲取該字段的最大和最小值
  • 再通過執行“explain select field from db.table”來估計該表的記錄數
  • 最后根據所設的每個任務(文件)記錄數來將該表劃分為多個chunk。

備份所生成的文件
目錄中包含一個metadata文件:

  • 記錄了備份數據庫在備份時間點的二進制日志文件名,日志的寫入位置
  • 如果是在從庫進行備份,還會記錄備份時同步至主庫的二進制日志文件及寫入位置

每個表有兩個備份文件:

  • database.table-schema.sql 表結構文件
  • database.table.sql 表數據文件
  • 如果對表文件分片,將生成多個備份數據文件,可以指定行數或指定大小分片

注意:mydumper導出時不寫binlog,復制環境中需要注意。

4.2.相關參數

  • mydumper參數介紹:
-B, --database 需要備份的庫
-T, --tables-list 需要備份的表,用,分隔
-o, --outputdir 輸出目錄 
-s, --statement-size Attempted size of INSERT statement in bytes, default 1000000
-r, --rows 試圖分裂成很多行塊表
-c, --compress 壓縮輸出文件
-e, --build-empty-files 即使表沒有數據,還是產生一個空文件
-x, --regex 支持正則表達式
-i, --ignore-engines 忽略的存儲引擎,用,分隔
-m, --no-schemas 不導出表結構
-k, --no-locks 不執行臨時共享讀鎖 警告:這將導致不一致的備份
-l, --long-query-guard 長查詢,默認60s
--kill-long-queries kill掉長時間執行的查詢(instead of aborting)
-D, --daemon 啟用守護進程模式
-I, --snapshot-interval dump快照間隔時間,默認60s,需要在daemon模式下
-L, --logfile 日志文件
-h, --host
-u, --user
-p, --password
-P, --port
-S, --socket
-t, --threads 使用的線程數,默認4
-C, --compress-protocol 在mysql連接上使用壓縮
-V, --version
-v, --verbose 更多輸出, 0 = silent, 1 = errors, 2 = warnings, 3 = info, default 2
  • myloader參數介紹:
-d, --directory 導入備份目錄
-q, --queries-per-transaction 每次執行的查詢數量, 默認1000
-o, --overwrite-tables 如果表存在刪除表
-B, --database 需要還原的庫
-e, --enable-binlog 啟用二進制恢復數據
-h, --host
-u, --user
-p, --password
-P, --port
-S, --socket
-t, --threads 使用的線程數量,默認4
-C, --compress-protocol 連接上使用壓縮
-V, --version
-v, --verbose 更多輸出, 0 = silent, 1 = errors, 2 = warnings, 3 = info, default 2

4.3.最佳實踐

yum install gcc gcc-c++ make cmake glib2-devel zlib-devel pcre-devel openssl-devel mysql-devel
cd mydumper-0.9.1
cmake .
make
cp -p mydumper /usr/local/bin
cp -p myloader /usr/local/bin
ldd mydumper
  • 備份數據庫
mydumper -S /data1/db3307/my3307.sock -u root --tz-utc --threads 32 -o /data1/mysqlbackup/full_3307_mydumper
  • 恢復數據庫
myloader -S /data1/db3307/my3307.sock -u root --threads 32 -o -d /data1/mysqlbackup/full_3307_mydumper
  • 常見錯誤
** (mydumper:142452): WARNING **: Broken table detected, please review: wanda.view_s06_ffan_mem_reg_cnt_minute
** (mydumper:142452): WARNING **: Broken table detected, please review: wanda.view_s06_ffan_wifi_mobile_to_plaza_uniq_real_time
** (mydumper:142452): CRITICAL **: Could not read data from imc.MSG_BLACK_BATCH: Table definition has changed, please retry transaction
** (mydumper:142452): CRITICAL **: Error dumping table (scm_db.gerritapp_plan_jenkins) data: Table 'scm_db.gerritapp_plan_jenkins' doesn't exist
** (mydumper:142452): CRITICAL **: Error dumping schemas (wanda.view_s06_ffan_mem_reg_cnt_hour): SELECT command denied to user ''@'%' for column 'plaza_id' in table 's06_ffan_mem_reg_real_time'
** (mydumper:142452): CRITICAL **: Error dumping schemas (wanda.view_s06_ffan_mem_reg_info_uniq_real_time): SELECT command denied to user ''@'%' for column 'mobile' in table 's06_ffan_mem_reg_info_real_time'
** (myloader:1408769): CRITICAL **: Error restoring invoice.INVOICE_STOREINFO from file invoice.INVOICE_STOREINFO-schema.sql: Invalid default value for 'PAUSE_TIME'
** (myloader:1408769): CRITICAL **: Error restoring invoice.INVOICE_TASK from file invoice.INVOICE_TASK-schema.sql: Invalid default value for 'INVOICE_START_TIME'
** (myloader:1408769): CRITICAL **: Error restoring pubsub.logs from file pubsub.logs-schema.sql: Invalid default value for 'operatorTime'

出現問題的View

CREATE ALGORITHM=UNDEFINED DEFINER=`mycat`@`10.%` SQL SECURITY DEFINER VIEW `view_s06_ffan_mem_reg_cnt_hour` AS select `mycat`.`s06_ffan_mem_reg_real_time`.`plaza_id` AS `plaza_id`,date_format(`mycat`.`s06_ffan_mem_reg_real_time`.`create_time`,'%Y-%m-%d %H') AS `reg_time`,count(1) AS `total`,count((case when (`mycat`.`s06_ffan_mem_reg_real_time`.`channel` = 'app') then 1 end)) AS `app`,count((case when (`mycat`.`s06_ffan_mem_reg_real_time`.`channel` = 'web') then 1 end)) AS `web`,count((case when (`mycat`.`s06_ffan_mem_reg_real_time`.`channel` = 'html5') then 1 end)) AS `html5`,count((case when (`mycat`.`s06_ffan_mem_reg_real_time`.`channel` = 'wifi') then 1 end)) AS `wifi`,count((case when (`mycat`.`s06_ffan_mem_reg_real_time`.`channel` = 'card') then 1 end)) AS `card`,count((case when (`mycat`.`s06_ffan_mem_reg_real_time`.`channel` = 'sms') then 1 end)) AS `sms`,count((case when (`mycat`.`s06_ffan_mem_reg_real_time`.`channel` = 'thrid') then 1 end)) AS `thrid`,count((case when (`mycat`.`s06_ffan_mem_reg_real_time`.`channel` = 'offline') then 1 end)) AS `offline` from `s06_ffan_mem_reg_real_time` where (`mycat`.`s06_ffan_mem_reg_real_time`.`create_time` >= '2015-12-08') group by `mycat`.`s06_ffan_mem_reg_real_time`.`plaza_id`,`reg_time`;
  • 案例分享
    1.8T數據庫服務器,32核,希捷pci-E SSD卡
    導出時間25分鐘(意不意外、驚不驚喜、刺不刺激)
    導入時間5小時15分鐘

掃描下方二維碼關注本人微信號!歡迎大家交流學習!

Bruce.Liu










最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,517評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,087評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,521評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,493評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,207評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,603評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,624評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,813評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,364評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,110評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,305評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,874評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,532評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,953評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,209評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,033評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,268評論 2 375

推薦閱讀更多精彩內容