2019-04-29 MySQL企業(yè)級備份應(yīng)用知識與實(shí)踐

1. 數(shù)據(jù)庫管理員的兩大工作核心

1.1 能夠讓數(shù)據(jù)安全得到保護(hù)

所謂得數(shù)據(jù)安全,最容易備份誤以為是只有數(shù)據(jù)丟失,其實(shí)還包含數(shù)據(jù)被脫庫、泄密等方面。

1.2 能7 x 24小時(shí)提供服務(wù)

數(shù)據(jù)庫劇本7 x 24小時(shí)提供服務(wù)的能力,是數(shù)據(jù)庫管理員得重要職責(zé)。

2. 全量備份與增量備份

2.1 全量備份的概念

全量數(shù)據(jù)就是數(shù)據(jù)庫中所有的數(shù)據(jù)(或某一個(gè)庫的全部數(shù)據(jù));全量備份就是把數(shù)據(jù)庫中所有的數(shù)據(jù)進(jìn)行備份。
下面以InnoDB引擎數(shù)據(jù)庫為例進(jìn)行講解。
備份數(shù)據(jù)庫中所有庫的所有數(shù)據(jù)的命令:

mysqldump -B --master-data=2 --single-transaction -A | gzip > /opt/all.sql.gz

備份oldboy一個(gè)庫中所有數(shù)據(jù)的命令:

mysqldump -B --master-data=2 --single-transaction oldboy | gzip > /opt/oldboy.sql.gz

2.2 增量備份的概念

增量數(shù)據(jù)就是指上一次全量備份數(shù)據(jù)之后到下一次全量備份之前數(shù)據(jù)庫所更新的數(shù)據(jù)。在使用mysqldump命令做全備時(shí),增量數(shù)據(jù)就是MySQL的binlog日志,因此,對binlog日志的備份在此處就可以稱為增量備份。

2.3 全量與增量如何結(jié)合備份

按天全備與增量備份數(shù)據(jù)示例

按天全備的特點(diǎn)如下:
優(yōu)點(diǎn):恢復(fù)數(shù)據(jù)時(shí)需要的數(shù)據(jù)文件數(shù)量少,恢復(fù)時(shí)間短,維護(hù)成本低。
缺點(diǎn):每天一個(gè)全備,占用空間多,占用系統(tǒng)資源多,經(jīng)常備份會影響用戶體驗(yàn)。中小企業(yè)用得最多的策略就是按天全備,然后根據(jù)空間情況保留全備份數(shù),例如僅保留7天內(nèi)的備份數(shù)據(jù),如果企業(yè)數(shù)據(jù)很重要,則可以使用磁帶機(jī)等設(shè)備留存1年以上的備份數(shù)據(jù)。
binlog增量得清理可以通過在my.cnf中配置“過期清理天數(shù)”的相關(guān)參數(shù)(expire_logs_days = 7)來實(shí)現(xiàn),例如保留7天內(nèi)的binlog日志,理論上如果每天進(jìn)行全備,那么binlog只要保留1天就夠了。

按周全備與增量備份數(shù)據(jù)示例

按周全備的特點(diǎn)如下:
優(yōu)點(diǎn):每周僅有一個(gè)完整備份,因此占用磁盤總空間小,占用系統(tǒng)資源少,備份次數(shù)少,用戶體驗(yàn)好一些。
缺點(diǎn):恢復(fù)時(shí)數(shù)據(jù)文件多,導(dǎo)致恢復(fù)麻煩,維護(hù)成本高,恢復(fù)時(shí)間長。
大型企業(yè)由于數(shù)據(jù)量特別大,每天全備時(shí)間太長,因此有可能會采用周備的策略,這樣不僅有利于節(jié)省數(shù)據(jù)存儲空間而且不會影響用戶訪問數(shù)據(jù)庫的體驗(yàn)。

3. MySQL常用的備份方式

MySQL備份的常用方式有邏輯備份和物理備份。

3.1 邏輯備份方式

1. 邏輯備份

MySQL的邏輯備份其實(shí)就是使用MySQL自帶的mysqldump命令或其他相關(guān)工具,把MySQL數(shù)據(jù)以SQL語句的形式導(dǎo)出或備份成文件。在恢復(fù)的時(shí)候則通過執(zhí)行mysql恢復(fù)命令(或source等)將存儲的SQL語句文件數(shù)據(jù)還原到MySQL數(shù)據(jù)庫中。

2. 邏輯備份的特點(diǎn)

邏輯備份的優(yōu)點(diǎn)為操作簡單、方便、可靠,并且備份的數(shù)據(jù)可以跨平臺、跨版本、甚至跨軟件、跨操作系統(tǒng),還可以實(shí)現(xiàn)分庫分表備份;邏輯備份也有一定的缺點(diǎn),例如,備份速度比物理備份慢、恢復(fù)的效率也不是特別高等。

3. 邏輯備份的常用工具

mysqldump是MySQL官方自帶得最常用的邏輯備份工具,還能實(shí)現(xiàn)分表分庫備份,也是本章重點(diǎn)講解的備份工具。除此之外,還有一個(gè)mydumper工具,它是一個(gè)在GPL許可下發(fā)布的高性能MySQL備份和恢復(fù)工具集。

4. 邏輯備份的企業(yè)應(yīng)用場景

適用于數(shù)據(jù)量不是特別大的場景,例如打包前不大于30GB的數(shù)據(jù)庫數(shù)據(jù)(30GB為參考值)。30GB的值主要是考慮備份效率的問題,以及管理員使用復(fù)雜度的平衡。
不過,在跨版本、跨軟件升級或遷移數(shù)據(jù)的時(shí)候,此時(shí)物理備份一般就不能使用了。

3.2 物理備份方式

1. 物理備份

(1)冷備方法
MySQL的物理備份方法之一是使用cp、rsync、tar、scp等復(fù)制工具把MySQL數(shù)據(jù)文件復(fù)制成多份,由于在備份期間數(shù)據(jù)仍然有寫入操作,所以,直接復(fù)制的備份方式會引起數(shù)據(jù)丟失。
一般在進(jìn)行大規(guī)模數(shù)據(jù)庫遷移時(shí),先停庫,然后物理遷移。
(2)除了在Linux命令行通過命令直接復(fù)制MySQL數(shù)據(jù)文件之外,還有一些其他的第三方的開源或商業(yè)物理熱備份工具,如Xtrabackup。這個(gè)工具可以實(shí)現(xiàn)物理全備及增量備份。

2. 物理備份的特點(diǎn)

優(yōu)點(diǎn):速度快,效率高
缺點(diǎn):不容易跨平臺、跨版本、跨軟件、跨操作系統(tǒng),可以實(shí)現(xiàn)分庫分表備份,但恢復(fù)時(shí)會麻煩很多,軟件的使用也比較復(fù)雜一些

3. 物理備份的常用工具或方法

Linux下冷備份工具為cp、tar,備份時(shí)需要鎖表或者停庫以確保數(shù)據(jù)的一致性;開源的熱備份(基于InnoDB)工具則是Xtrabackup。

4. 物理備份的企業(yè)應(yīng)用場景
  • 數(shù)據(jù)庫總數(shù)據(jù)量超過30GB的,可使用Xtrabackup熱備工具進(jìn)行備份,以提升效率
  • 可以選擇在數(shù)據(jù)庫的從庫上進(jìn)行備份,備份時(shí)停止SQL線程應(yīng)用數(shù)據(jù)到數(shù)據(jù)庫,然后通過cp或tar打包備份,這也是一種不錯(cuò)的冷備方案,不會影響數(shù)據(jù)庫的服務(wù)

3.3 物理備份與邏輯備份的區(qū)別

物理備份與邏輯備份的區(qū)別

4 邏輯備份的企業(yè)級應(yīng)用實(shí)戰(zhàn)

4.1 中小企業(yè)的MySQL備份實(shí)戰(zhàn)

1. 中小企業(yè)全備備份策略與實(shí)踐

中小企業(yè)一般會采用邏輯備份,常用的工具就是mysqldump命令,備份的策略一般是每日進(jìn)行全量備份,備份會選擇在數(shù)據(jù)庫業(yè)務(wù)流量低谷時(shí)執(zhí)行,備份時(shí)可以鎖表或者采用事務(wù)方式備份,以下為簡單的實(shí)戰(zhàn)備份腳本案例:

[root@oldboy scripts]# cat bak.sh 
#!/bin/bash
export PATH=/application/mysql/bin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
bak_path=/server/backup
file_name=bak_$(date +%F)
[ ! -d $bak_path ] && mkdir -p $bak_path    ---若備份路徑不存在則創(chuàng)建
mysqldump -B -A --master-data=2 | gzip > $bak_path/${file_name}.sql.gz
---如果僅為innodb引擎,則可以再加上--single-transaction參數(shù)
#rsync all data to backup server    ---備份完成后立即推送至備份服務(wù)器,需要提前部署rsync服務(wù)
rsync -az $bak_path/ rsync_backup@172.16.1.31::mysql/ --password-file=/etc/rsync.password

#del expiries file    ---刪除本地的7天備份,如果空間緊張那么保留三天也可以
find $bak_path/ -type -f -name "*.sql.gz" -mtime +7 | xargs rm -f

稍微復(fù)雜點(diǎn)的備份腳本:

[root@oldboy scripts]# cat bak.sh 
#!/bin/bash
export PATH=/application/mysql/bin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
bak_path=/server/backup
[ ! -d $bak_path ] && mkdir -p $bak_path
#if week is 6 then bak other file name.
if [ $(date +%w) -eq 6 ]    ---如果時(shí)間為周六,則
    then
        file_name=bak_$(date +%w_%F)    ---將備份文件名改為周和日期,目的是在備份服務(wù)器上保留每周六的數(shù)據(jù)
    else
        file_name=bak_$(date +%F)    ---否則,備份文件名為日期
fi
mysqldump -B -A --master-date=2 | gzip > $bak_path/${file_name}.sql.gz
md5sum $bak_path/${file_name}.sql.gz > $bak_path/${file_name}.flag
---做md5指紋的目的是用于未來檢查備份及傳輸結(jié)果是否正常
#rsync all data to backup server
rsync -az $bak_path/ rsync_backup@172.16.1.31::mysql/ --password-file=/etc/rsync.password

#del expiries file
find $bak_path/ -type -f -name "*.sql.gz" -mtime +7 | xargs rm -f
#send mail to self or adminstrator    ---還可以將備份結(jié)果發(fā)送郵件給管理員,不過最佳策略是在備份服務(wù)器上檢查備份結(jié)果統(tǒng)一發(fā)管理員

上述兩個(gè)腳本是相對比較簡單的企業(yè)級實(shí)戰(zhàn)數(shù)據(jù)庫備份腳本,在實(shí)際工作中,可能在判斷及邏輯上會更復(fù)雜一些。
最后配置定時(shí)任務(wù),使其每日0點(diǎn)執(zhí)行上述腳本:

[root@oldboy scripts]# crontab -e    ---在最后添加以下兩行
#bak mysql for oldboy at 20190427
00 00 * * * /bin/sh /server/scripts/bak.sh &> /dev/null

最終的數(shù)據(jù)庫本地(備份服務(wù)器相同)備份結(jié)果示例如下:

[root@oldboy scripts]# ll /server/backup/
total 12
-rw-r--r--. 1 root root 73 Apr 26 00:00 bak_2019-04-26.flag    ---普通備份對應(yīng)的指紋文件
-rw-r--r--. 1 root root 20 Apr 26 00:00 bak_2019-04-26.sql.gz    ---普通的備份文件
-rw-r--r--. 1 root root 73 Apr 27 00:00 bak_6_2019-04-27.flag    ---周六備份對應(yīng)的指紋文件
-rw-r--r--. 1 root root 20 Apr 27 00:00 bak_6_2019-04-27.sql.gz    ---周六的備份文件
[root@oldboy scripts]# cat /server/backup/bak_6_2019-04-27.flag 
024226a8b13b16415b6affc62aa55024  /server/backup/bak_6_2019-04-27.sql.gz

將來在備份服務(wù)器上可以檢查備份是否成功,以及數(shù)據(jù)在備份過程中是否被改變等:

[root@oldboy backup]# md5sum -c bak_6_2019-04-27.flag     ---檢測備份文件是否正常以及在傳輸過程中是否有損壞或被篡改
/server/backup/bak_6_2019-04-27.sql.gz: OK    ---OK表示一切正常

一般會在備份服務(wù)器上保留最近7天的所有備份,同時(shí)保留每周六的全部備份:

[root@oldboy backup]# find /server/backup/ -type f -name "bak_*" -mtime +7 ! -name "bak_6*"
/server/backup/bak_2019-04-26.flag
/server/backup/bak_2019-04-26.sql.gz
2. 全備的數(shù)據(jù)什么時(shí)候可以派上用場
  • 遷移或者升級數(shù)據(jù)庫時(shí)
  • 增加從庫的時(shí)候
  • 人為執(zhí)行DDL、DML語句破壞數(shù)據(jù)庫數(shù)據(jù)時(shí)(此時(shí)若使用主從庫就無法防止數(shù)據(jù)丟失,因?yàn)樗袔於紩?zhí)行破壞的語句)
  • 跨機(jī)房災(zāi)備時(shí),此時(shí)需要將全備份復(fù)制到異地

若是因?yàn)橛布騽h除物理文件導(dǎo)致數(shù)據(jù)庫故障,就不需要用備份數(shù)據(jù)恢復(fù)了,可以直接把主庫關(guān)閉,在從庫上配置好VIP等配置后,啟動從庫提供服務(wù)即可。

3. 中小企業(yè)增量備份策略與實(shí)踐

比較好的binlog增量備份或MySQL備份方法就是為MySQL數(shù)據(jù)庫配置異機(jī)主從復(fù)制功能(實(shí)時(shí)復(fù)制功能),即binlog會被實(shí)時(shí)地發(fā)送到從服務(wù)器上,這樣效果是最好的。當(dāng)然,也要相應(yīng)地在主從復(fù)制的從庫上實(shí)現(xiàn)全備。

4. 備份binlog增量文件何時(shí)可以派上用場

當(dāng)需要完整恢復(fù)數(shù)據(jù)庫數(shù)據(jù)的時(shí)候,就會需要binlog增量恢復(fù)。

5. 企業(yè)里MySQL備份策略選擇

大多數(shù)中小企業(yè)得數(shù)據(jù)庫環(huán)境都為一主多從,因此,可采取在一個(gè)從庫服務(wù)器上專門做全量以及增量備份。

4.2 中小企業(yè)MySQL增量恢復(fù)案例實(shí)戰(zhàn)

假設(shè)當(dāng)前數(shù)據(jù)庫內(nèi)的數(shù)據(jù)如下:

[root@oldboy ~]# mysql -e "select * from oldboy.test;"
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
|  5 | kaka    |
+----+---------+

模擬0點(diǎn)開始對數(shù)據(jù)庫oldboy數(shù)據(jù)庫進(jìn)行全備:

[root@oldboy ~]# mkdir -p /data/backup
[root@oldboy ~]# mysqldump -B --master-data=2 --single-transaction oldboy | gzip > /data/backup/oldboy_$(date +%F).sql.gz
[root@oldboy ~]# ll /data/backup/
total 4
-rw-r--r--. 1 root root 870 Apr 27 07:01 oldboy_2019-04-27.sql.gz

模擬0點(diǎn)全備后用戶繼續(xù)寫入數(shù)據(jù):

[root@oldboy ~]# mysql -e "use oldboy;insert into test values(6,'bingbing');"
[root@oldboy ~]# mysql -e "use oldboy;insert into test values(7,'xiaoting');"
[root@oldboy ~]# mysql -e "select * from oldboy.test;"
+----+----------+
| id | name     |
+----+----------+
|  1 | oldboy   |
|  2 | oldgirl  |
|  3 | inca     |
|  4 | zuma     |
|  5 | kaka     |
|  6 | bingbing |    ---全備后寫入的數(shù)據(jù)
|  7 | xiaoting |
+----+----------+

模擬上午10點(diǎn)管理人員刪除oldboy數(shù)據(jù)庫:

[root@oldboy ~]# date -s "2019-04-27 10:00"
Sat Apr 27 10:00:00 CST 2019
[root@oldboy ~]# mysql -e "drop database oldboy;show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| oldboy_utf8        |
| performance_schema |
+--------------------+

假設(shè)數(shù)據(jù)庫出問題10分鐘后,發(fā)現(xiàn)故障,聯(lián)系運(yùn)維人員DBA處理問題。DBA會查看網(wǎng)站報(bào)錯(cuò)(或查看后臺日志),可以看到連不上oldboy數(shù)據(jù)庫的提示,登錄數(shù)據(jù)庫排查,發(fā)現(xiàn)數(shù)據(jù)庫已經(jīng)不存在了。登錄系統(tǒng)分析系統(tǒng)審計(jì)日志,以及分析數(shù)據(jù)庫binlog可以發(fā)現(xiàn)庫丟失的原因。
找到原因后,準(zhǔn)備開始恢復(fù)。恢復(fù)前先要移走所有binlog增量文件,防止被二次破壞,并確認(rèn)是否有全備:

[root@oldboy ~]# cp -a /application/mysql/data/oldboy-bin.* /data/backup/
[root@oldboy ~]# ll /data/backup/
total 28
-rw-r--r--. 1 root  root   870 Apr 27 07:01 oldboy_2019-04-27.sql.gz    ---全備
-rw-rw----. 1 mysql mysql  168 Feb  7 21:46 oldboy-bin.000001
-rw-rw----. 1 mysql mysql  168 Feb  7 21:47 oldboy-bin.000002
-rw-rw----. 1 mysql mysql 8899 Apr 27 10:00 oldboy-bin.000003
-rw-rw----. 1 mysql mysql   60 Feb  7 21:47 oldboy-bin.index

數(shù)據(jù)庫恢復(fù):
1)停止數(shù)據(jù)庫對外訪問。因?yàn)槭峭ㄟ^drop命令刪除數(shù)據(jù)庫的,后面不會有寫入操作,因此,這里可以不用額外停止寫入,但如果是因?yàn)閡pdate導(dǎo)致得數(shù)據(jù)破壞,最好是停庫處理或?qū)ν馔V箤懭?。這里采用iptables防火墻屏蔽所有應(yīng)用程序的寫入:

[root@oldboy ~]# iptables -I INPUT -p tcp --dport 3306 ! -s 192.168.9.115 -j DROP    ---非192.168.9.115禁止訪問數(shù)據(jù)庫3306端口
---系統(tǒng)是CentOS7的話默認(rèn)防火墻是firewalld,需自行改成firewalld的規(guī)則

2)解壓全備的數(shù)據(jù):

[root@oldboy ~]# cd /data/backup/
[root@oldboy backup]# gzip -cd oldboy_2019-04-27.sql.gz > oldboy.sql
[root@oldboy backup]# ls -lrt oldboy.sql 
-rw-r--r--. 1 root root 2205 Apr 27 10:14 oldboy.sql

3)解析binlog文件增量數(shù)據(jù):
由于在全備時(shí)增加了--master-data=2參數(shù),所以可以知道全備后的binlog文件名以及binlog文件對應(yīng)的恢復(fù)位置點(diǎn)。

[root@oldboy backup]# sed -n '22p' oldboy.sql     ---這邊的案例是在第22行,所以只看第22行
-- CHANGE MASTER TO MASTER_LOG_FILE='oldboy-bin.000003', MASTER_LOG_POS=8343;

從上面的代碼可以看到,要從oldboy-bin.000003文件的8343位置點(diǎn)開始恢復(fù)增量數(shù)據(jù):

[root@oldboy backup]# mysqlbinlog -d oldboy oldboy-bin.000003 --start-position 8343 -r bin.sql

工作中除了oldboy-bin.000003文件之外,還可能生成oldboy-bin.000004、oldboy-bin.000005……多個(gè)binlog文件,現(xiàn)在可以繼續(xù)恢復(fù)后面的所有binlog文件:

[root@oldboy backup]# mysqlbinlog -d oldboy oldboy-bin.000004 oldboy-bin.000005 -r bin1.sql
---由于此次模擬環(huán)境只有一個(gè)binlog文件oldboy-bin.000003,因此此命令就不要執(zhí)行了

4)需要注意得是,這里需要剔除誤刪數(shù)據(jù)庫的drop語句,否則,直接恢復(fù)就又進(jìn)入了刪庫故障的坑了:

[root@oldboy backup]# grep -w drop bin.sql     ---把誤刪語句找出來
drop database oldboy
[root@oldboy backup]# sed -i '/drop database oldboy/d' bin.sql    ---刪除drop數(shù)據(jù)庫oldboy的語句

現(xiàn)在準(zhǔn)備工作全部完成,開始正式恢復(fù)。
先恢復(fù)出故障以前得全備數(shù)據(jù):

[root@oldboy backup]# mysql < /data/backup/oldboy.sql     ---先恢復(fù)全備,即出故障以前的備份
[root@oldboy backup]# mysql -e "select * from oldboy.test;"
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
|  5 | kaka    |
+----+---------+

可以看到,出故障以前的數(shù)據(jù)已恢復(fù),但0點(diǎn)全備到出故障時(shí)間的增量還沒有。
再恢復(fù)增量數(shù)據(jù),即從binlog中解析出清理了drop語句的bin.sql文件:

[root@oldboy backup]# mysql oldboy < /data/backup/bin.sql     ---恢復(fù)增量文件,由于增量備份沒有use db,所以需要指定數(shù)據(jù)庫名
[root@oldboy backup]# mysql -e "select * from oldboy.test;"
+----+----------+
| id | name     |
+----+----------+
|  1 | oldboy   |
|  2 | oldgirl  |
|  3 | inca     |
|  4 | zuma     |
|  5 | kaka     |
|  6 | bingbing |    ---增量的數(shù)據(jù)回來了
|  7 | xiaoting |     ---增量的數(shù)據(jù)回來了
+----+----------+

5. 分庫分表的生產(chǎn)備份策略

5.1 為什么要分庫分表備份

還原時(shí),很多時(shí)候只需要還原一個(gè)庫或者多個(gè)庫的一個(gè)表,這個(gè)時(shí)候,整個(gè)備份文件就會很難拆分,給恢復(fù)也會帶來麻煩。對于這種情況,最好是分庫分表備份。

5.2 如何進(jìn)行分庫備份

最佳的方法就是從數(shù)據(jù)庫中取出所有庫名,然后對每個(gè)數(shù)據(jù)庫執(zhí)行一次備份。
分庫備份的腳本如下:

[root@oldboy scripts]# cat fenku.sh 
#!/bin/bash
export PATH=/application/mysql/bin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
bak_path=/server/bakup/$(date +%F)
[ ! -d $bak_path ] && mkdir -p $bak_path
for dbname in `mysql -e "show databases" | sed '1,2d' | grep -v _schema`    ---取庫名輪詢備份
do
mysqldump -B --master-data=2 $dbname | gzip > $bak_path/${dbname}_$(date +%F).sql.gz
done
執(zhí)行分庫腳本并查看備份結(jié)果:
[root@oldboy scripts]# sh fenku.sh
[root@oldboy scripts]# ll /server/bakup/2019-04-27/
total 188
-rw-r--r--. 1 root root 181184 Apr 27 11:22 mysql_2019-04-27.sql.gz
-rw-r--r--. 1 root root    890 Apr 27 11:22 oldboy_2019-04-27.sql.gz
-rw-r--r--. 1 root root    604 Apr 27 11:22 oldboy_utf8_2019-04-27.sql.gz

5.3 如何進(jìn)行分表備份

分表備份比分庫更細(xì),實(shí)際上就是先取一個(gè)庫名,然后循環(huán)讀取該庫里的表進(jìn)行備份,備份完之后,再取下一個(gè)庫名,繼續(xù)循環(huán)庫里的所有表進(jìn)行備份,直到所有庫里的所有表都備份完畢。
實(shí)際腳本如下:

[root@oldboy scripts]# cat fenbiao.sh 
#!/bin/bash
export PATH=/application/mysql/bin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
bak_path=/server/bakup/$(date +%F)
[ ! -d bak_path ] && mkdir -p $bak_path
for dbname in `mysql -e "show databases" | sed '1,2d' | grep -v _schema`
do
    for tablename in `mysql -e "show tables from $dbname;" | sed '1d'`
    do
        mysqldump -B --master-data=2 $dbname $tablename | gzip > $bak_path/${dbname}_${tablename}_$(date +%F).sql.gz
    done
done
執(zhí)行分表腳本并查看備份結(jié)果:
[root@oldboy scripts]# sh fenbiao.sh
[root@oldboy scripts]# ll -tr /server/bakup/2019-04-27/
total 5232
-rw-r--r--. 1 root root 181184 Apr 27 11:22 mysql_2019-04-27.sql.gz
-rw-r--r--. 1 root root    890 Apr 27 11:22 oldboy_2019-04-27.sql.gz
-rw-r--r--. 1 root root    604 Apr 27 11:22 oldboy_utf8_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_columns_priv_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_db_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_event_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_func_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_general_log_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_help_category_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_help_keyword_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_help_relation_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_help_topic_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_innodb_index_stats_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_innodb_table_stats_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_ndb_binlog_index_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_plugin_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_proc_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_procs_priv_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_proxies_priv_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_servers_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_slave_master_info_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_slave_relay_log_info_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_slave_worker_info_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_slow_log_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_tables_priv_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_time_zone_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_time_zone_leap_second_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_time_zone_name_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_time_zone_transition_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_time_zone_transition_type_2019-04-27.sql.gz
-rw-r--r--. 1 root root 181020 Apr 27 11:40 mysql_user_2019-04-27.sql.gz
-rw-r--r--. 1 root root    795 Apr 27 11:40 oldboy_test_2019-04-27.sql.gz

事實(shí)上,分庫分表的數(shù)據(jù)盡量不要用于完整恢復(fù),因?yàn)閎inlog有可能會有寫入操作,用于單庫單表的恢復(fù),如果非要用來做完整恢復(fù),最好通過寫腳本來實(shí)現(xiàn)。

6. MySQL生產(chǎn)常用備份架構(gòu)方案

在中小公司一般比較常用的做法是,每日0點(diǎn)執(zhí)行全備任務(wù),先把數(shù)據(jù)按照日期備份到數(shù)據(jù)庫本地,然后推送到數(shù)據(jù)庫備份服務(wù)器,由于本地空間有限,因此本地僅保留3~7日的全備。
如果有備用的服務(wù)器資源可用,那么最好通過主從同步的方式進(jìn)行備份,這樣即使物理機(jī)損壞了也可以很快地切換到新服務(wù)器(還可以HA自動切換),但是主從復(fù)制得缺點(diǎn)是不能解決錯(cuò)誤執(zhí)行SQL語句的問題。
因此,一般會在一臺不對外提供業(yè)務(wù)的從庫上使用上述的mysqldump或Xtrabackup來進(jìn)行定時(shí)備份。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容