Mysql 備份恢復與xtrabackup備份
原文:Mysql 備份恢復與xtrabackup備份 - 慘綠少年 - 部落格園 (cnblogs.com)
1.1 備份的原因
備份是資料安全的最後一道防線,對於任何資料丟失的場景,備份雖然不一定能恢復百分之百的資料(取決於備份週期),但至少能將損失降到最低。衡量備份恢復有兩個重要的指標:恢復點目標(RPO)和恢復時間目標(RTO),前者重點關注能恢復到什麼程度,而後者則重點關注恢復需要多長時間。
1.1.1 備份的目錄
做災難恢復:對損壞的資料進行恢復和還原
需求改變:因需求改變而需要把資料還原到改變以前
測試:測試新功能是否可用
1.1.2 備份中需要考慮的問題
可以容忍丟失多長時間的資料;
恢復資料要在多長時間內完;
恢復的時候是否需要持續提供服務;
恢復的物件,是整個庫,多個表,還是單個庫,單個表。
1.1.3 備份的型別
熱備份:
這些動態備份在讀取或修改資料的過程中進行,很少中斷或者不中斷傳輸或處理資料的功能。使用熱備份時,系統仍可供讀取和修改資料的操作訪問。
冷備份:
這些備份在使用者不能訪問資料時進行,因此無法讀取或修改資料。這些離線備份會阻止執行任何使用資料的活動。這些型別的備份不會干擾正常執行的系統的效能。但是,對於某些應用程式,會無法接受必須在一段較長的時間裡鎖定或完全阻止使用者訪問資料。
溫備份:
這些備份在讀取資料時進行,但在多數情況下,在進行備份時不能修改資料本身。這種中途備份型別的優點是不必完全鎖定終端使用者。但是,其不足之處在於無法在進行備份時修改資料集,這可能使這種型別的備份不適用於某些應用程式。在備份過程中無法修改資料可能產生效能問題。
1.2 備份的方式
1.2.1 冷備份
最簡單的備份方式就是,關閉MySQL伺服器,然後將data目錄下面的所有檔案進行拷貝儲存,需要恢復時,則將目錄拷貝到需要恢復的機器即可。這種方式確實方便,但是在生產環境中基本沒什麼作用。因為所有的機器都是要提供服務的,即使是Slave有時候也需要提供只讀服務,所以關閉MySQL停服備份是不現實的。與冷備份相對應的一個概念是熱備份,所謂熱備份是在不影響MySQL對外服務的情況下,進行備份。
冷備份及停止業務進行備份。
1.2.2 快照備份
首先要介紹的熱備份是快照備份,快照備份是指通過檔案系統支援的快照功能對資料庫進行備份。備份的原理是將所有的資料庫檔案放在同一分割槽中,然後對該分割槽執行快照工作,對於Linux而言,需要通過LVM(Logical Volumn Manager)來實現。LVM使用寫時複製(copy-on-write)技術來建立快照,例如,對整個卷的某個瞬間的邏輯副本,類似於資料庫中的innodb儲存引擎的MVCC,只不過LVM的快照在檔案系統層面,而MVCC在資料庫層面,而且僅支援innodb儲存引擎。
LVM有一個快照預留區域,如果原始卷資料有變化時,LVM保證在任何變更寫入之前,會複製受影響塊到快照預留區域。簡單來說,快照區域內保留了快照點開始時的一致的所有old資料。對於更新很少的資料庫,快照也會非常小。
對於MySQL而言,為了使用快照備份,需要將資料檔案,日誌檔案都放在一個邏輯卷中,然後對該卷快照備份即可。由於快照備份,只能本地,因此,如果本地的磁碟損壞,則快照也就損壞了。快照備份更偏向於對誤操作防範,可以將資料庫迅速恢復到快照產生的時間點,然後結合二進位制日誌可以恢復到指定的時間點。基本原理如下圖:
1.2.3 邏輯備份(文字表示:SQL 語句)
冷備份和快照備份由於其弊端在生產環境中很少使用,使用更多是MySQL自帶的邏輯備份和物理備份工具,這節主要講邏輯備份,MySQL官方提供了Mysqldump邏輯備份工具,雖然已經足夠好,但存在單執行緒備份慢的問題。在社群提供了更優秀的邏輯備份工具mydumper,它的優勢主要體現在多執行緒備份,備份速度更快。
1.2.4 其他常用的備份方式
物理備份(資料檔案的二進位制副本)
全量備份概念
全量資料就是資料庫中所有的資料(或某一個庫的全部資料);
全量備份就是把資料庫中所有的資料進行備份。
mysqldump會取得一個時刻的一致性資料.
增量備份(重新整理二進位制日誌)
增量資料就是指上一次全量備份資料之後到下一次全備之前資料庫所更新的資料
對於mysqldump,binlog就是增量資料.
1.2.5 備份工具的介紹
1、mysqldump: mysql原生自帶很好用的邏輯備份工具
2、mysqlbinlog: 實現binlog備份的原生態命令
3、xtrabackup: precona公司開發的效能很高的物理備份工具
1.3 mysqldump備份介紹
備份的基本流程如下:
1.呼叫FTWRL(flush tables with read lock),全域性禁止讀寫 2.開啟快照讀,獲取此時的快照(僅對innodb表起作用) 3.備份非innodb表資料(*.frm,*.myi,*.myd等) 4.非innodb表備份完畢後,釋放FTWRL鎖 5.逐一備份innodb表資料 6.備份完成。
整個過程,可以參考我同事的一張圖,但他的這張圖只考慮innodb表的備份情況,實際上在unlock tables執行完畢之前,非innodb表已經備份完畢,後面的t1,t2和t3實質都是innodb表,而且5.6的mysqldump利用儲存點機制,每備份完一個表就將一個表上的MDL鎖釋放,避免對一張表鎖更長的時間。
1.3.1 mysqldump備份流程
1.3.2 常用的備份引數
引數 |
引數說明 |
-A |
備份全庫 |
-B |
備某一個數據庫下的所有表 |
-R, --routines |
備份儲存過程和函式資料 |
--triggers |
備份觸發器資料 |
--master-data={1|2} |
告訴你備份後時刻的binlog位置 如果等於1,則將其列印為CHANGE MASTER命令; 如果等於2,那麼該命令將以註釋符號為字首。 |
--single-transaction |
對innodb引擎進行熱備 |
-F, --flush-logs |
重新整理binlog日誌 |
-x, --lock-all-tables |
鎖定所有資料庫的所有表。這是通過在整個轉儲期間採用全域性讀鎖來實現的。 |
-l, --lock-tables |
鎖定所有表以供讀取 |
-d |
僅表結構 |
-t |
僅資料 |
--compact |
減少無用資料輸出(除錯) |
一個完整的備份語句: innodb引擎的備份命令如下: mysqldump -A -R --triggers --master-data=2 --single-transaction |gzip >/opt/all_$(date +%F).sql.gz 適合多引擎混合(例如:myisam與innodb混合)的備份命令如下:
mysqldump -A -R --triggers --master-data=2 |gzip >/opt/all_$(date +%F).sql.gz |
1.3.3 -A 引數
備份全庫,備份語句
mysqldump -uroot -p123 -A > /backup/full.sql
1.3.4 -B 引數
備某一個數據庫下的所有表
增加建庫(create)及“use庫”的語句,可以直接接多個庫名,同時備份多個庫* -B 庫1 庫2
mysqldump -uroot -p123 -B world > /backup/worldb.sql
備份語句:
create database if not 存在 use db1 drop table create table insert into
不加-B備份資料庫時,只是備份資料庫下的所有表,不會建立資料庫
只能備份單獨的資料庫(一般用於備份單表時使用)
mysqldump -uroot -p123 world > /backup/world.sql
備份單表
mysqldump -uroot -p123 world city > /backup/world_city.sql
對於單表備份的粒度,再恢復資料庫資料時速度最快。
備份多個表
mysqldump 庫1 表1 表2 表3 >庫1.sql mysqldump 庫2 表1 表2 表3 >庫2.sql
分庫備份:for迴圈
mysqldump -uroot -p'mysql123' -B mysql ... mysqldump -uroot -p'mysql123' -B mysql_utf8 ... mysqldump -uroot -p'mysql123' -B mysql ... ......
分庫備份
for name in `mysql -e "show databases;"|sed 1d` do mysqldump -uroot -p'mysql123' -B $name done
1.3.5 --master-data={1|2}引數
告訴你備份後時刻的binlog位置
2為註釋 1為非註釋,要執行的(主從複製)
[root@db02 logs]# sed -n '22p' /opt/t.sql CHANGE MASTER TO MASTER_LOG_FILE='clsn-bin.000005', MASTER_LOG_POS=344; [root@db02 logs]# mysqldump -B --master-data=2 clsn >/opt/t.sql
1.3.6 --single-transaction 引數
對innodb引擎進行熱備
只支援innodb引擎
使用該引數會單獨開啟一個事務進行備份,利用事務的快照技術實現。
基於事務引擎:不用鎖表就可以獲得一致性的備份.
體現了ACID四大特性中的隔離性,生產中99% 使用innodb事務引擎.
雖然支援熱備,並不意味著你可以再任意時間點進行備份,特別是業務繁忙期,不要做備份策略,一般夜裡進行備份。
innodb引擎的備份命令如下:
mysqldump -A -B -R --triggers --master-data=2 --single-transaction |gzip >/opt/all.sql.gz
1.3.7 --flush-logs引數/-F
重新整理binlog日誌
每天晚上0點備份資料庫
mysqldump -A -B -F >/opt/$(date +%F).sql
[root@db02 ~]# ll /application/mysql/logs/ -rw-rw---- 1 mysql mysql 168 Jun 21 12:06 clsn-bin.000001 -rw-rw---- 1 mysql mysql 168 Jun 21 12:06 clsn-bin.000002 -rw-rw---- 1 mysql mysql 210 Jun 21 12:07 clsn-bin.index
提示:每個庫都會重新整理一次.
1.3.8 壓縮備份
壓縮備份命令:
mysqldump -B --master-data=2 clsn|gzip >/opt/t.sql.gz
解壓:
zcat t.sql.gz >t1.sql gzip -d t.sql.gz #刪壓縮包 gunzip alL_2017-12-22.sql.gz
一個完整的備份語句
innodb引擎的備份命令如下:
mysqldump -A -R --triggers --master-data=2 --single-transaction |gzip >/opt/all.sql.gz
適合多引擎混合(例如:myisam與innodb混合)的備份命令如下:
mysqldump -A -R --triggers --master-data=2 |gzip >/opt/alL_$(date +%F).sql.gz
1.3.9 使用Mysqldump備份進行恢復實踐
備份innodb引擎資料庫clsn並壓縮:
mysqldump -B -R --triggers --master-data=2 clsn|gzip >/opt/all_$(date +%F).sql.gz
人為刪除clsn資料庫:
[root@db02 opt]# mysql -e “drop database clsn;” [root@db02 opt]# mysql -e “show databases;”
恢復資料庫:
使用gzip解壓 gzip -d xxx.gz shell> mysql </opt/all_2017-1222.sql 或 mysql> set sql_log_bin=0; Query OK, 0 rows affected (0.00 sec) mysql> source /backup/alL_2017-12-22.sql
驗證資料:
[root@db02 opt]# mysql -e “use clsn;select * from test;”
1.4 【模擬】增量恢復企業案例
1.4.1 前提條件:
1.具備全量備份(mysqldump)。
2.除全量備份以外,還有全量備份之後產生的的所有binlog增量日誌。
1.4.2 環境準備
(1)準備環境:
drop database clsn; CREATE DATABASE clsn; USE `clsn`; CREATE TABLE `test` ( `id` int(4) NOT NULL AUTO_INCREMENT, `name` char(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; INSERT INTO `test` VALUES (1,'clsn'),(2,'znix'),(3,'inca'),(4,'zuma'),(5,'kaka');
檢視建立好的資料
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | clsn | | 2 | znix | | 3 | inca | | 4 | zuma | | 5 | kaka | +----+------+ 5 rows in set (0.00 sec)
(2)模擬環境:
mkdir /data/backup -p date -s "2017/12/22"
全備份:
mysqldump -B --master-data=2 --single-transaction clsn|gzip>/data/backup/clsn_$(date +%F).sql.gz
模擬增量:
mysql -e "use clsn;insert into test values(6,'haha');" mysql -e "use clsn;insert into test values(7,'hehe');" mysql -e "select * from clsn.test;"
(3)模擬誤刪資料:
date -s "2017/12/22 11:40" mysql -e "drop database clsn;show databases;"
出現問題10分鐘後,發現問題,刪除了資料庫了.
1.4.3 恢復資料準備
(1)採用iptables防火牆遮蔽所有應用程式的寫入。
[root@clsn ~]# iptables -I INPUT -p tcp --dport 3306 ! -s 172.16.1.51 -j DROP #<==非172.16.1.51禁止訪問資料庫3306埠。
或採用mysql 配置引數,但是需要重啟資料庫
--skip-networking
複製二進位制日誌檔案
cp -a /application/mysql/logs/clsn-bin.* /data/backup/
擷取日誌
zcat clsn_2017-12-22.sql.gz >clsn_2017-12-22.sql sed -n '22p' clsn_2017-12-22.sql mysqlbinlog -d clsn --start-position=339 clsn-bin.000008 -r bin.sql
需要恢復的日誌:
1.clsn_2017-12-22.sql 2.bin.sql grep -i drop bin.sql sed -i '/^drop.*/d' bin.sql
1.4.4 進行資料恢復
恢復資料
[root@db02 backup]# mysql <clsn_2017-12-22.sql [root@db02 backup]# mysql -e "show databases;" +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | clsn | | znix | | performance_schema | +--------------------+
檢視資料庫
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | clsn | | 2 | znix | | 3 | inca | | 4 | zuma | | 5 | kaka | +----+------+ 5 rows in set (0.00 sec)
恢復增量資料:
[root@db02 backup]# mysql clsn <bin.sql mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | clsn | | 2 | znix | | 3 | inca | | 4 | zuma | | 5 | kaka | | 6 | haha | | 7 | hehe | +----+------+ 7 rows in set (0.00 sec)
恢復完畢。
調整iptables允許使用者訪問.
1.4.5 多個binlog問題
mysqlbinlog -d clsn --start-position=339 clsn-bin.000009 clsn-bin.0000010 -r bin1.sql mysql clsn <bin1.sql
1.5 mysql資料庫實際生產慘案
1.5.1 發生背景
1、mysql伺服器會在每天夜裡0點全量備份
2、某個開發人員某個陽光明媚的上午,喝著茶,優雅的誤刪除了clsn_oss(核心)資料庫。
3、導致公司業務異常停止,無法正常提供服務。
1.5.2 怎麼解決的
1、當前系統進行評估。
什麼損壞了,有沒有備份,
恢復資料時間(誤操作的資料有關,備份、恢復策略),
恢復業務時間
2、恢復方案
(1)恢復0點的全備,到測試庫
(2)恢復0點開始到故障時間點的binlog,到測試庫
(3)將誤操作的資料匯出,恢復到生產庫。
(4)檢驗資料是不是完整的(開發測試環境測試恢復成功資料庫)
(5)檢驗完成之後,重新開啟生產業務
1.5.3 專案總結
1、經過我的恢復處理,30分鐘整體業務重新提供服務(速度慢。。。)
2、在以後的工作中制定嚴格的開發規範,開發,開發。
3、將來制定更好的架構方案。
1.6 備份工具的選擇
資料量範圍:30G --> TB級別
1.6.1 資料量大,變換量小
(1)全備分花費的成本較高,mysqldump+binlog實現全備 + 增量備份,缺點是恢復成本比備份時間成本還高
(2)xtrabackup:可以較長時間做一次全備,其餘時間都是增量,全量備份空間成本很高如果資料量在30G-->TB級別的話,更推薦使用xtrabackup工具。
1.6.2 資料量小,變化量大
只需要考慮時間成本。
只用全備備份即可,兩種工具選擇都可以。恢復成本上xtrabackup小一些
1.6.3 資料量、變化量都大
時間成本和空間成本都要考慮了。
資料量達到PB或更高時(facebook),mysqldump可能成為首選,佔用空間小,但技術成本高。需要對mysqldump進行二次開發(大資料量公司首選)。
1.7 xtrabackup備份軟體
percona公司官網 https://www.percona.com/
1.7.1 Xtrabackup介紹
Xtrabackup是由percona開源的免費資料庫熱備份軟體,它能對InnoDB資料庫和XtraDB儲存引擎的資料庫非阻塞地備份(對於MyISAM的備份同樣需要加表鎖);mysqldump備份方式是採用的邏輯備份,其最大的缺陷是備份和恢復速度較慢,如果資料庫大於50G,mysqldump備份就不太適合。
Xtrabackup安裝完成後有4個可執行檔案,其中2個比較重要的備份工具是innobackupex、xtrabackup
1)xtrabackup 是專門用來備份InnoDB表的,和mysql server沒有互動; 2)innobackupex 是一個封裝xtrabackup的Perl指令碼,支援同時備份innodb和myisam,但在對myisam備份時需要加一個全域性的讀鎖。 3)xbcrypt 加密解密備份工具 4)xbstream 流傳打包傳輸工具,類似tar 5)物理備份工具,在同級資料量基礎上,都要比邏輯備份效能好的多,特別是在資料量較大的時候,體現的更加明顯。
1.7.1 Xtrabackup優點
1)備份速度快,物理備份可靠
2)備份過程不會打斷正在執行的事務(無需鎖表)
3)能夠基於壓縮等功能節約磁碟空間和流量
4)自動備份校驗
5)還原速度快
6)可以流傳將備份傳輸到另外一臺機器上
7)在不增加伺服器負載的情況備份資料
8)物理備份工具,在同級資料量基礎上,都要比邏輯備份效能要好的多。幾十G到不超過TB級別的條件下。但在同資料量級別,物理備份恢復資料上有一定優勢。
1.7.2 備份原理
拷貝資料檔案、拷貝資料頁
對於innodb表可以實現熱備。
(1)在資料庫還有修改操作的時刻,直接將資料檔案備走,此時,備份走的資料對於當前mysql來講是不一致的。 (2)將備份過程中的redo和undo一併備走。 (3)為了恢復的時候,只要保證備份出來的資料頁lsn能和redo lsn匹配,將來恢復的就是一致的資料。redo應用和undo應用。
對於myisam表實現自動鎖表拷貝檔案。
備份開始時首先會開啟一個後臺檢測程序,實時檢測mysql redo的變化,一旦發現有新的日誌寫入,立刻將日誌記入後臺日誌檔案xtrabackup_log中,之後複製innodb的資料檔案一系統表空間檔案ibdatax,複製結束後,將執行flush tables with readlock,然後複製.frm MYI MYD等檔案,最後執行unlock tables,最終停止xtrabackup_log
1.7.3 xtrabackup的安裝
安裝依賴關係
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL
下載軟體包,並安裝軟體
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm yum -y install percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
1.8 xtrabackup實踐操作
1.8.1 全量備份與恢復
這一階段會啟動xtrabackup內嵌的innodb例項,回放xtrabackup日誌xtrabackup_log,將提交的事務資訊變更應用到innodb資料/表空間,同時回滾未提交的事務(這一過程類似innodb的例項恢復)。恢復過程如下圖:
備份
建立備份目錄
mkdir /backup -p
進行第一次全量備份
innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --socket=/application/mysql/tmp/mysql.sock --no-timestamp /backup/xfull
恢復前準備
恢復資料前的準備(合併xtabackup_log_file和備份的物理檔案)
innobackupex --apply-log --use-memory=32M /backup/xfull/
檢視合併後的 checkpoints 其中的型別變為 full-prepared 即為可恢復。
[root@db02 full]# cat xtrabackup_checkpoints backup_type = full-prepared from_lsn = 0 to_lsn = 4114824 last_lsn = 4114824 compact = 0 recover_binlog_info = 0
破壞資料庫資料檔案
[root@db02 full]# cd /application/mysql/data/ [root@db02 data]# ls auto.cnf db02.pid ibdata2 mysql mysql-bin.index world clsn haha ib_logfile0 mysql-bin.000001 oldboy db02.err ibdata1 ib_logfile1 mysql-bin.000002 performance_schema [root@db02 data]# \rm -rf ./* [root@db02 data]# ls [root@db02 data]# killall mysql
恢復方法
方法一:直接將備份檔案複製回來
cp -a /backup/full/ /application/mysql/data chown -R mysql.mysql /application/mysql/data
方法二:使用innobackupex命令進行恢復(推薦)
[root@db02 mysql]# innobackupex --copy-back /backup/xfull [root@db02 mysql]# chown -R mysql.mysql /application/mysql/
說明:無論使用那種恢復方法都要恢復後需改屬組屬主,保持與程式一致。
[root@db02 data]# cd /application/mysql/data/ [root@db02 data]# ls clsn ibdata2 ibtmp1 performance_schema xtrabackup_info haha ib_logfile0 mysql world ibdata1 ib_logfile1 oldboy xtrabackup_binlog_pos_innodb
啟動是資料庫
[root@db02 data]# /etc/init.d/mysqld start
1.8.2 增量備份與恢復
innobackupex增量備份過程中的"增量"處理,其實主要是相對innodb而言,對myisam和其他儲存引擎而言,它仍然是全拷貝(全備份)
"增量"備份的過程主要是通過拷貝innodb中有變更的"頁"(這些變更的資料頁指的是"頁"的LSN大於xtrabackup_checkpoints中給定的LSN)。增量備份是基於全備的,第一次增備的資料必須要基於上一次的全備,之後的每次增備都是基於上一次的增備,最終達到一致性的增備。增量備份的過程如下,和全備的過程很類似,區別僅在第2步。
增量備份從哪增量?
基於上一次的備份進行增量。
redo預設情況下是一組兩個檔案,並且有固定大小。其使用的檔案是一種輪詢使用方式,他不是永久的,檔案隨時可能被覆蓋。
注意:千萬不要在業務繁忙時做備份。
備份什麼內容
1、可以使用binlog作為增量
2、自帶的增量備份,基於上次備份後的變化的資料頁,還要備份在備份過程中的undo、redo變化
怎麼備份
1、先進行第一次全備
innobackupex --user=root --password=123 --no-timestamp /bakcup/xfull
對原庫做了修改,修改了小紅那行然後commit。
2、再進行增量備份
innobackupex --user=root --password=123 --incremental --no-timestamp --incremental-basedir=/backup/xfull/ /backup/xinc1
怎麼恢復
1、先應用全備日誌(--apply-log,暫時不需要做回滾操作--redo-only)
innobackupex --apply-log --redo-only /backup/xfull/
2、合併增量到全備中(一致性的合併)
innobackupex --apply-log --incremental-dir=/backup/xinc1 /backup/xfull/ innobackupex --apply-log /backup/xfull
3、合併完成進行恢復
方法一:直接將備份檔案複製回來
cp -a /backup/full/ /application/mysql/data chown -R mysql.mysql /application/mysql/data
方法二:使用innobackupex命令進行恢復(推薦)
[root@db02 mysql]# innobackupex --copy-back /backup/xfull [root@db02 mysql]# chown -R mysql.mysql /application/mysql/
說明:無論使用那種恢復方法都要恢復後需改屬組屬主,保持與程式一致。
1.8.3 資料庫備份策略
每週的週日進行一次全備;週一到週六每天做上一天增量,每週輪詢一次。
xfull --apply-log --redo-only 保證last-lsn=週一增量開始lsn xinc1 合併週一的增量到全備,並apply-log --redo-only 保證last-lsn=週二增量開始lsn xinc2 合併週二的增量到全備,並apply-log --redo-only 保證last-lsn=週三增量開始lsn xinc3 合併週三的增量到全備,並apply-log --redo-only 保證last-lsn=週四增量開始lsn xinc4 合併週四的增量到全備,並apply-log --redo-only 保證last-lsn=週五增量開始lsn xinc5 合併週五的增量到全備,並apply-log --redo-only 保證last-lsn=週六增量開始lsn xinc6 合併週六的增量到全備,--apply-log 準備恢復即可
1.8.4 真實生產實戰案例分析
背景:某物流公司網站核心系統,資料量是220G,每日更新量100M-200M
備份方案: xtrabackup全備+增量
備份策略(crontab):
1、週六 晚上0點全備
0 0 * * 6 zjs_full.sh ---這行可以沒有
2、週一至週五、週日 是增量,基於上一天增量
0 1 * * 0-5 zjs_inc.sh---這行可以沒有
故障場景:
週三的時候,下午兩點,開發人員誤刪除了一張表zjs_base,大約10G。
專案職責:
1) 指定恢復方案、利用現有備份;
2) 恢復誤刪除資料;
3) 制定運維、開發流程規範。
恢復流程:
a) 準備上週六全備。 b) 合併週日、週一 、週二增量。 c) 在測試庫恢復以上資料,資料的目前狀態應該週三凌晨1:00 d) 需要恢復的資料狀態是,下午2點鐘左右 e) 從1點開始的binlog恢復到刪除之前轉檯 f) 匯出刪除的表zjs_base,恢復到生產庫,驗證資料可用性、完整性。 g) 啟動應用連線資料庫。
總結:經過30分鐘將誤刪表恢復了。服務總共停止40分鐘。
1.8.5 故障恢復小結
恢復思路:
1、首先確保斷開所有應用,保證資料的安全。
2、檢查用於恢復的備份存在嗎。
3、設計快速、安全恢復簡單方案,制定突發問題解決辦法。
具體恢復流程:
1、準備上週六全備,並--apply-log --redo-only 2、合併增量,週日、週一 、週二 --apply-log --redo-only 週三 --apply-log 3、在測試庫恢復以上資料,資料的目前狀態應該週三凌晨1:00 4、需要恢復的資料狀態是,下午2點鐘左右,刪除zjs_base之前的資料狀態 從1點開始的binlog恢復到刪除之前的那個events的position。 5、匯出刪除的表zjs_base,恢復到生產庫,驗證資料可用性、完整性。 6、啟動應用連線資料庫。
確定恢復所需時間
恢復視窗要多長?----> 預計3小時 和你恢復+驗證+意外情況有關。 業務停多長時間?----> 6小時?或者更多?更少?
1.8.6 【模擬】生產事故恢復
資料建立階段
1、建立備份需要的目錄
mkdir full inc1 inc2
2、週日全備
innobackupex --user=root --password=123 --no-timestamp /backup/xbackup/full/
3、模擬資料變化
use oldboy create table test(id int,name char(20),age int); insert into test values(8,'outman',99); insert into test values(9,'outgirl',100); commit;
4、週一增量備份
innobackupex --user=root --password=123 --incremental --no-timestamp --incremental-basedir=/backup/xbackup/full/ /backup/xbackup/inc1
5、模擬資料變化
use oldboy insert into test values(8,'outman1',119); insert into test values(9,'outgirl1',120); commit;
6、週二的增量備份
innobackupex --user=root --password=123 --incremental --no-timestamp --incremental-basedir=/backup/xbackup/inc1 /backup/xbackup/inc2
7. 再插入新的行操作
use oldboy insert into test values(10,'outman2',19); insert into test values(11,'outgirl2',10); commit;
模擬誤操作事故
模擬場景,週二下午2點誤刪除test表
use oldboy; drop table test;
準備恢復資料
1.準備xtrabackup備份,合併備份
innobackupex --apply-log --redo-only /backup/xbackup/full innobackupex --apply-log --redo-only --incremental-dir=/backup/xbackup/inc1 /backup/xbackup/full innobackupex --apply-log --incremental-dir=/backup/xbackup/inc2 /backup/xbackup/full innobackupex --apply-log /backup/xbackup/full
2.確認binlog起點,準備擷取binlog。
cd /backup/xbackup/inc2/ cat xtrabackup_binlog_info mysql-bin.000001 1121
3.擷取到drop操作之前的binlog
mysqlbinlog --start-position=1121 /tmp/mysql-bin.000003 找到drop之前的event和postion號做日誌擷取,假如 1437 mysqlbinlog --start-position=1121 --stop-position=1437 /tmp/mysql-bin.000003 >/tmp/incbinlog.sql
4.關閉資料庫、備份二進位制日誌
/etc/init.d/mysqld stop cd /application/mysql/data/ cp mysql-bin.000001 /tmp
5.刪除MySQL所有資料
cd /application/mysql/data/ rm -rf *
恢復資料
1.將全量備份的資料恢復到資料目錄下
innobackupex --copy-back /backup/xbackup/full/ chown -R mysql.mysql /application/mysql/data/ /etc/init.d/mysqld start
2.恢復binlog記錄
set sql_log_bin=0 source /tmp/incbinlog.sql
1.8.7 xtarbackup匯出
(1)“匯出”表 匯出表是在備份的prepare階段進行的,因此,一旦完全備份完成,就可以在prepare過程中通過--export選項將某表匯出了:
innobackupex --apply-log --export /path/to/backup
此命令會為每個innodb表的表空間建立一個以.exp結尾的檔案,這些以.exp結尾的檔案則可以用於匯入至其它伺服器。
(2)“匯入”表 要在mysql伺服器上匯入來自於其它伺服器的某innodb表,需要先在當前伺服器上建立一個跟原表表結構一致的表,而後才能實現將表匯入:
mysql> CREATE TABLE mytable (...) ENGINE=InnoDB;
然後將此表的表空間刪除:
mysql> ALTER TABLE mydatabase.mytable DISCARD TABLESPACE;
接下來,將來自於“匯出”表的伺服器的mytable表的mytable.ibd和mytable.exp檔案複製到當前伺服器的資料目錄,然後使用如下命令將其“匯入”:(記得改許可權)
mysql> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;
示例:
innobackupex --user=root --password=123 --no-timestamp /backup/xbackup/full/
進入到全備的資料庫目錄下
[root@db02 haha]# ls db.opt PENALTIES.frm PENALTIES.ibd PLAYERS.frm PLAYERS.ibd [root@db02 haha]# pwd /backup/xbackup/full/haha
匯出表
[root@db02 haha]# innobackupex --apply-log --export /backup/xbackup/full/ [root@db02 haha]# ls db.opt PENALTIES.exp PENALTIES.ibd PLAYERS.exp PLAYERS.ibd PENALTIES.cfg PENALTIES.frm PLAYERS.cfg PLAYERS.frm
創建出同結構表
CREATE TABLE `PLAYERS` ( `PLAYERNO` int(11) NOT NULL, `NAME` char(15) NOT NULL, `INITIALS` char(3) NOT NULL, `BIRTH_DATE` date DEFAULT NULL, `SEX` char(1) NOT NULL, `JOINED` smallint(6) NOT NULL, `STREET` varchar(30) NOT NULL, `HOUSENO` char(4) DEFAULT NULL, `POSTCODE` char(6) DEFAULT NULL, `TOWN` varchar(30) NOT NULL, `PHONENO` char(13) DEFAULT NULL, `LEAGUENO` char(4) DEFAULT NULL, PRIMARY KEY (`PLAYERNO`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
複製恢復資料到庫下
[root@db02 haha]# cp PLAYERS.ibd PLAYERS.exp /application/mysql/data/backup/ cp: overwrite `/application/mysql/data/backup/PLAYERS.ibd'? y
恢復資料
mysql> ALTER TABLE backup.PLAYERS DISCARD TABLESPACE; Query OK, 0 rows affected (0.00 sec)
1.8.8 innobackupex引數說明
引數 |
引數說明 |
--compress |
該選項表示壓縮innodb資料檔案的備份。 |
--compress-threads |
該選項表示並行壓縮worker執行緒的數量。 |
--compress-chunk-size |
該選項表示每個壓縮執行緒worker buffer的大小,單位是位元組,預設是64K。 |
--encrypt |
該選項表示通過ENCRYPTION_ALGORITHM的演算法加密innodb資料檔案的備份,目前支援的演算法有ASE128,AES192,AES256。 |
--encrypt-threads |
該選項表示並行加密的worker執行緒數量。 |
--encrypt-chunk-size |
該選項表示每個加密執行緒worker buffer的大小,單位是位元組,預設是64K。 |
--encrypt-key |
該選項使用合適長度加密key,因為會記錄到命令列,所以不推薦使用。 |
--encryption-key-file |
該選項表示檔案必須是一個簡單二進位制或者文字檔案,加密key可通過以下命令列命令生成:openssl rand -base64 24。 |
--include |
該選項表示使用正則表示式匹配表的名字[db.tb],要求為其指定匹配要備份的表的完整名稱,即databasename.tablename。 |
--user |
該選項表示備份賬號。 |
--password |
該選項表示備份的密碼。 |
--port |
該選項表示備份資料庫的埠。 |
--host |
該選項表示備份資料庫的地址。 |
--databases |
該選項接受的引數為資料名,如果要指定多個數據庫,彼此間需要以空格隔開;如:"xtra_test dba_test",同時,在指定某資料庫時,也可以只指定其中的某張表。如:"mydatabase.mytable"。該選項對innodb引擎表無效,還是會備份所有innodb表。此外,此選項也可以接受一個檔案為引數,檔案中每一行為一個要備份的物件。 |
--tables-file |
該選項表示指定含有表列表的檔案,格式為database.table,該選項直接傳給--tables-file。 |
--socket |
該選項表示mysql.sock所在位置,以便備份程序登入mysql。 |
--no-timestamp |
該選項可以表示不要建立一個時間戳目錄來儲存備份,指定到自己想要的備份資料夾。 |
--ibbackup |
該選項指定了使用哪個xtrabackup二進位制程式。IBBACKUP-BINARY是執行percona xtrabackup的命令。這個選項適用於xtrbackup二進位制不在你是搜尋和工作目錄,如果指定了該選項,innoabackupex自動決定用的二進位制程式。 |
--slave-info |
該選項表示對slave進行備份的時候使用,打印出master的名字和binlog pos,同樣將這些資訊以change master的命令寫入xtrabackup_slave_info檔案。可以通過基於這份備份啟動一個從庫。 |
--safe-slave-backup |
該選項表示為保證一致性複製狀態,這個選項停止SQL執行緒並且等到show status中的slave_open_temp_tables為0的時候開始備份,如果沒有開啟臨時表,bakcup會立刻開始,否則SQL執行緒啟動或者關閉知道沒有開啟的臨時表。如果slave_open_temp_tables在--safe-slave-backup-timeount (預設300秒)秒之後不為0,從庫sql執行緒會在備份完成的時候重啟。 |
--kill-long-queries-timeout |
該選項表示從開始執行FLUSH TABLES WITH READ LOCK到kill掉阻塞它的這些查詢之間等待的秒數。預設值為0,不會kill任何查詢,使用這個選項xtrabackup需要有Process和super許可權。 |
--kill-long-query-type |
該選項表示kill的型別,預設是all,可選select。 |
--ftwrl-wait-threshold |
該選項表示檢測到長查詢,單位是秒,表示長查詢的閾值。 |
--ftwrl-wait-query-type |
該選項表示獲得全域性鎖之前允許那種查詢完成,預設是ALL,可選update。 |
--galera-info |
該選項表示生成了包含建立備份時候本地節點狀態的檔案xtrabackup_galera_info檔案,該選項只適用於備份PXC。 |
--stream |
該選項表示流式備份的格式,backup完成之後以指定格式到STDOUT,目前只支援tar和xbstream。 |
--defaults-file |
該選項指定了從哪個檔案讀取MySQL配置,必須放在命令列第一個選項的位置。 |
--defaults-extra-file |
該選項指定了在標準defaults-file之前從哪個額外的檔案讀取MySQL配置,必須在命令列的第一個選項的位置。一般用於存備份使用者的使用者名稱和密碼的配置檔案。 |
----defaults-group |
該選項表示從配置檔案讀取的組,innobakcupex多個例項部署時使用。 |
--no-lock |
該選項表示關閉FTWRL的表鎖,只有在所有表都是Innodb表並且不關心backup的binlog pos點,如果有任何DDL語句正在執行或者非InnoDB正在更新時(包括mysql庫下的表),都不應該使用這個選項,後果是導致備份資料不一致,如果考慮備份因為獲得鎖失敗,可以考慮--safe-slave-backup立刻停止複製執行緒。 |
--tmpdir |
該選項表示指定--stream的時候,指定臨時檔案存在哪裡,在streaming和拷貝到遠端server之前,事務日誌首先存在臨時檔案裡。在使用引數stream=tar備份的時候,你的xtrabackup_logfile可能會臨時放在/tmp目錄下,如果你備份的時候併發寫入較大的話 xtrabackup_logfile可能會很大(5G+),很可能會撐滿你的/tmp目錄,可以通過引數--tmpdir指定目錄來解決這個問題。 |
--history |
該選項表示percona server 的備份歷史記錄在percona_schema.xtrabackup_history表。 |
--incremental |
該選項表示建立一個增量備份,需要指定--incremental-basedir。 |
--incremental-basedir |
該選項表示接受了一個字串引數指定含有full backup的目錄為增量備份的base目錄,與--incremental同時使用。 |
--incremental-dir |
該選項表示增量備份的目錄。 |
--incremental-force-scan |
該選項表示建立一份增量備份時,強制掃描所有增量備份中的資料頁。 |
--incremental-lsn |
該選項表示指定增量備份的LSN,與--incremental選項一起使用。 |
--incremental-history-name |
該選項表示儲存在PERCONA_SCHEMA.xtrabackup_history基於增量備份的歷史記錄的名字。Percona Xtrabackup搜尋歷史表查詢最近(innodb_to_lsn)成功備份並且將to_lsn值作為增量備份啟動出事lsn.與innobackupex--incremental-history-uuid互斥。如果沒有檢測到有效的lsn,xtrabackup會返回error。 |
--incremental-history-uuid |
該選項表示儲存在percona_schema.xtrabackup_history基於增量備份的特定歷史記錄的UUID。 |
--close-files |
該選項表示關閉不再訪問的檔案控制代碼,當xtrabackup開啟表空間通常並不關閉檔案控制代碼目的是正確的處理DDL操作。如果表空間數量巨大,這是一種可以關閉不再訪問的檔案控制代碼的方法。使用該選項有風險,會有產生不一致備份的可能。 |
--compact |
該選項表示建立一份沒有輔助索引的緊湊的備份。 |
--throttle |
該選項表示每秒IO操作的次數,只作用於bakcup階段有效。apply-log和--copy-back不生效不要一起用。 |
1.9 參考文獻
https://www.cnblogs.com/cchust/p/5452557.html http://www.cnblogs.com/gomysql/p/3650645.html xtrabackup 詳解 https://www.percona.com/software/mysql-database/percona-xtrabackup https://learn.percona.com/hubfs/Manuals/Percona_Xtra_Backup/Percona_XtraBackup_2.4/Percona-XtraBackup-2.4.9.pdf