下面我們就看一下常見的備份工具,以及目前最流行的 Percona XtraBackup 的備份流程。
十年的郊區(qū)網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。營銷型網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整郊區(qū)建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“郊區(qū)網(wǎng)站設(shè)計”,“郊區(qū)網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。
MySQL 常見的備份工具主要分為三種:
這里先說一下 binlog 備份,它只是把 binlog 又復(fù)制了一份,并且需要在邏輯備份或者物理備份的基礎(chǔ)上才能進(jìn)行數(shù)據(jù)恢復(fù),無法單獨進(jìn)行數(shù)據(jù)恢復(fù)。
mysqldump 備份出的文件就是 sql 文件,其核心就是對每個表執(zhí)行 select ,然后轉(zhuǎn)化成相應(yīng)的 insert 語句。mysqldump 的備份流程大致如下:
從上面可以看出在 mysqldump 備份期間,備份到某個數(shù)據(jù)庫時,該數(shù)據(jù)庫下的表都會處于只讀狀態(tài),無法對表進(jìn)行任何變更,直到該庫下的表備份完畢,這對于線上環(huán)境一般是無法接受的。若是指定了--master-data或者 --dump-slave 則會在備份開始時加全局讀鎖(FLUSH TABLES WITH READ LOCK),直到備份結(jié)束。當(dāng)然我們可以選一個從庫進(jìn)行備份,這樣就不會影響線上業(yè)務(wù)。另外使用 mysqldump 備份還有一個最大的好處,因為備份出來的是 sql 語句,所以它支持跨平臺和跨版本的數(shù)據(jù)遷移或者恢復(fù),這是物理備份無法做到的。
但是也正是因為 mysqldump 備份出來的是 sql 語句,在使用時要更加注意,否則可能會釀成大禍。例如,使用 mysqldump 常見的問題有:
所以使用 mysqldump 時一定要了解各個選項的作用,以及確認(rèn)備份出來的 sql 文件里會有什么操作,會對現(xiàn)有數(shù)據(jù)造成什么影響。
Mydumper 原理與 Mysqldump 原理類似,最大的區(qū)別是引入了多線程備份,每個備份線程備份一部分表,當(dāng)然并發(fā)粒度可以到行級,達(dá)到多線程備份的目的。這里不再單獨介紹。
Percona XtraBackup 是 Percona 公司開發(fā)的一個用于 MySQL 數(shù)據(jù)庫物理熱備的備份工具,是基于 InnoDB 的崩潰恢復(fù)功能來實現(xiàn)的。它的基本工作原理如下:
Percona XtraBackup 在進(jìn)行恢復(fù)時會應(yīng)用拷貝的 redo log ,應(yīng)用已提交的事務(wù),回滾未提交的事物,將數(shù)據(jù)庫恢復(fù)到一致性狀態(tài)。因為 Percona XtraBackup 備份出來的是物理文件,所以在使用備份出的文件進(jìn)行恢復(fù)或者遷移時,不會像 mysqldump 那樣會存在很多問題。
使用 XtraBackup 備份時根據(jù)備份參數(shù)設(shè)置不同,對數(shù)據(jù)庫的變更會造成不同程度的影響,具體影響會在下文分析。
通過對比發(fā)現(xiàn),XtraBackup 具有對數(shù)據(jù)庫影響小,且能快速恢復(fù)的優(yōu)點,在日常備份中是首選;mysqldump 使用相對更加靈活,但是使用是要注意對數(shù)據(jù)庫原有數(shù)據(jù)的影響。
備份策略主要有:全量備份和增量備份,再加上 binlog 備份。
目前去哪兒網(wǎng)數(shù)據(jù)庫備份主要采用 XtraBackup 全量備份 +binlog 備份。數(shù)據(jù)庫的重要級別不同,全量備份的頻率不同。備份程序主要架構(gòu)如下:
說明:
Percona XtraBackup 是目前備份 MySQL 使用最廣泛的工具。在備份過程中,數(shù)據(jù)庫可以進(jìn)行正常的讀寫或者其他變更操作,但是偶爾也會遇見備份引起的元數(shù)據(jù)鎖,或提交事務(wù)時發(fā)現(xiàn)被 binlog lock 阻塞等情況。下面我們就看一下 Percona XtraBackup 的備份流程和加鎖時機。
說明:以下對 Percona XtraBackup 的分析都是基于 2.4.23 的版本,其他版本會略有差別,但是關(guān)鍵步驟基本相同。
XtraBackup 在備份開始時,會創(chuàng)建一個后臺線程,專門用于拷貝數(shù)據(jù)庫的 redo log 。首先 XtraBackup 會掃描每組 redo log 的頭部,找出當(dāng)前的 checkpoint lsn ,然后從該 lsn 后順序拷貝所有的 redo log ,包括后續(xù)新產(chǎn)生的 redo log 。該線程會一直持續(xù)到將非事務(wù)表完全拷貝完成,才會安全退出。備份日志輸出中會記錄拷貝開始時的 checkpoint lsn 。日志輸出如下:
在拷貝ibd文件之前,會先掃描數(shù)據(jù)庫的數(shù)據(jù)文件目錄,獲取ibdata1,undo tablespaces及所有的ibd文件列表,并會記錄相應(yīng)的 space id,因為在恢復(fù)時需要這些 space id來找到對應(yīng) doublewrite buffer里頁面的內(nèi)容,以及對應(yīng)的redo log條目。然后開始循環(huán)拷貝ibdata1,undo tablespaces及所有的ibd文件。
這里可通過設(shè)置--parallel進(jìn)行多線程備份,提高物理文件的拷貝效率。不設(shè)置則默認(rèn)為1。
在所有ibd文件拷貝完成后,XtraBackup開始備份非ibd文件。這一部分的邏輯比較復(fù)雜,因為備份非ibd文件前需要加鎖,具體是否會加鎖主要受到--no-lock 參數(shù)設(shè)置的影響。
若是設(shè)置了--no-lock為TRUE,則不會使用"FLUSH TABLES WITH READ LOCK"去加全局讀鎖,但是若備份過程中對non-InnoDB表執(zhí)行了DDL或者DML操作, 這會導(dǎo)致備份的不一致,恢復(fù)出來的數(shù)據(jù)就會有問題。所以是不建議將--no-lock為TRUE,默認(rèn)值是FALSE,也就是在不指定該選項的情況下會在備份非ibd文件前加全局讀鎖。
下面我們結(jié)合源碼來看看判斷是否加全局鎖這部分的具體流程邏輯:
流程圖如下:
總結(jié)來看:
1)若--no-lock為FALSE(默認(rèn)值),則先施加全局讀鎖,然后再進(jìn)行拷貝文件,另外若 --safe-slave-backup 設(shè)置為TRUE ,則會在加全局鎖之前關(guān)閉SQL_THREAD線程;
2)若--no-lock為TRUE,則不會施加鎖,直接進(jìn)行拷貝文件。
加鎖的邏輯主要由lock_tables_maybe實現(xiàn),先看一下lock_tables_maybe源代碼,如下:
lock_tables_maybe 函數(shù)簡化處理流程如下:
1)若備份實例上已經(jīng)加鎖( LOCK TABLES FOR BACKUP / FLUSH TABLES WITH READ LOCK)或者設(shè)置lock-ddl-per-table 則直接返回;
2)若支持備份鎖,則執(zhí)行LOCK TABLES FOR BACKUP;
3)若不支持備份鎖,則執(zhí)行 FLUSH TABLES WITH READ LOCK。根據(jù)相應(yīng)選項設(shè)置,在執(zhí)行該操作前會判斷是否有執(zhí)行中的DDL/DML,以及等待超時時間,是否kill 對應(yīng)的未結(jié)束的事務(wù)等。
從上文中我們還看到一個參數(shù)--safe-slave-backup ,該參數(shù)的主要作用是:
若是在從庫執(zhí)行的備份操作時設(shè)置了該參數(shù),可以防止因從庫同步主庫操作,而導(dǎo)致XtraBackup長時間請求不到鎖而造成備份失敗。
若是設(shè)置了 --safe-slave-backup 為TRUE,那么會執(zhí)行"STOP SLAVE SQL_THREAD",并等待Slave_open_temp_tables 為零才開始拷貝非 ibd 文件,Slave_open_temp_tables 為零說明SQL thread執(zhí)行的事務(wù)都已經(jīng)完成,這樣就能保證備份的一致性。并且此時也不會有在執(zhí)行的事務(wù)阻塞 XtraBackup 施加全局鎖。
備份完非 ibd 文件后,將會備份 slave 和 binlog 信息。
mysql-bin.000004 2004 6b7bda9f-15f0-11ec-ba14-fa163ea367a4:1-83,9841546e-15f0-11ec-9557-fa163e736db4:1
需要注意,在支持備份鎖的實例上備份,指定了 --slave-info 或--binlog-info 均會先施加 binlog 備份鎖( LOCK BINLOG FOR BACKUP),這會阻塞任何會更改 binlog 位點的操作。
備份完數(shù)據(jù)庫的所有文件和binlog等相關(guān)信息,備份工作就基本完成了,之后主要執(zhí)行的操作如下:
1)執(zhí)行"FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS",將所有的redo log刷盤;
2)停止redo log復(fù)制線程;
3)釋放全局讀鎖(備份鎖),binlog鎖;
4)開啟SQL_THREAD;
5)拷貝ib_buffer_pool和ib_lru_dump文件;
6)生成配置文件backup-my.cnf;
7)打印備份信息到xtrabackup_info文件,這些信息主要包含備份時使用的參數(shù)信息,備份起止時間,binlog位點信息,以及將會回到的lsn點。
下面是xtrabackup_info記錄的部分內(nèi)容:
加鎖對應(yīng)的函數(shù)是 mdl_lock_tables ,釋放鎖對應(yīng)的函數(shù)是 mdl_unlock_all,主要是執(zhí)行COMMIT,結(jié)束 mdl_lock_tables 中開啟的顯式事務(wù),來釋放MDL鎖。mdl_lock_tables 流程如下:
上面參數(shù)--lock-ddl和--lock-ddl-per-table是在 Percona XtraBackup 2.4.8 之后添加的,因為 MySQL 5.7 新增了一個叫做 Sorted Index Builds 的功能,這會導(dǎo)致某些 DDL 操作不記錄重做日志而導(dǎo)致備份失敗。使用--lock-ddl或--lock-ddl-per-table 就會在備份開始時施加鎖,阻止 DDL 操作。
另外,若備份時指定了--lock-ddl或--lock-ddl-per-table,則在備份非 ibd 文件時就不是再有加鎖操作。
注意:LOCK TABLES FOR BACKUP和LOCK BINLOG FOR BACKUP 語句只有在支持備份鎖的實例上才會執(zhí)行,Percona Server for MySQL已經(jīng)在 5.6.16-64.0 版本開始支持這種更加輕量的備份鎖。
Q1: 使用 XtraBackup 備份的文件進(jìn)行恢復(fù)時,恢復(fù)到哪個時間點? A1:恢復(fù)到執(zhí)行 LOCK BINLOG FOR BACKUP 或 FLUSH TABLES WITH READ LOCK 的時間點,因為這時任何改變 binlog 位點的操作都會被阻塞,redo log和binlog 是一致的。
Q2: 在開啟 binlog 的情況下,MySQL 的奔潰恢復(fù)是同時依賴 binlog 和 redo log 這兩種日志的,為什么XtraBackup 不用備份binlog?
A2:因為在備份中有執(zhí)行LOCK BINLOG FOR BACKUP/FLUSH TABLES WITH READ LOCK,阻止了任何改變binlog位點的操作,這樣只需要根據(jù)redo log將有commit log 的事務(wù)提交,沒有commit log的事務(wù)進(jìn)行回滾即可。
Q3: 使用Percona XtraBackup備份完成后redo的位點是和binlog是一樣還是比binlog多一些?
A3:通過分析備份流程可以發(fā)現(xiàn)備份 binlog 位點信息(加binlog鎖)是發(fā)生在停止 redo 拷貝線程前,而釋放鎖是在停止 redo 拷貝線之后,所以 redo log 會多一些。鎖住了 binlog 保證了在該 binlog 位點前已經(jīng)提交的事務(wù)的 redo log 都有 commit log 的信息,未提交的事物也就沒有對應(yīng)的 commit log 的信息,即便在鎖住 binlog 后有 Innodb 表新的 DML 產(chǎn)生的 redo log ,但是事務(wù)無法提交,也就沒有 commit log 的信息的,最后在回放的過程中對沒有 commit log 的事務(wù)進(jìn)行回滾就可以了。
Q4:Percona XtraBackup什么時候會加鎖,以及影響加鎖時間長度的因素有哪些?
A4:上面進(jìn)行了分析,加鎖操作只在備份非 ibd 文件時執(zhí)行,加鎖時長主要和非事務(wù)表的數(shù)量和大小有關(guān),非事務(wù)表的數(shù)量越多,體積越大,拷貝文件所用的時間越長,那么加鎖時間也就越長。也會和 redo log 生成的速度有關(guān),只是 redo log 刷盤受到多個因素的影響,未及時刷盤的 redo log 一般很小。
Q5:Percona XtraBackup 和mysqldump選擇哪個更好?
A5:通過上面的的解析,若是整個實例備份,首先選擇 Percona XtraBackup ,因為對數(shù)據(jù)庫的影響最小。若只是備份某個庫表,這個就要視數(shù)據(jù)量而定,若數(shù)據(jù)量不大可以使用 mysqldump 。注意,對數(shù)據(jù)庫做備份時最好選擇業(yè)務(wù)連接最少的從庫,因為備份也會消耗一定的資源,避免影響業(yè)務(wù)。
方案一:mysqldump全備份+日志增量備份
1, mysqldump備份方案:
周一凌晨3點 全備
周二到周日凌晨3點增量備份
2, 備份步驟
(1) 創(chuàng)建備份目錄,備份腳本存放目錄
Shell mkdir /usr/mysqlbackup;
Shell chmod 755 /usr/mysqlbackup;
Shell mkdir /usr/mysqlbackup/daily;
Shell chmod 755 /usr/mysqlbackup/daily;
Shell mkdir /usr/script;
Shell chmod 777 /usr/script/*.sh
(2) 啟用二進(jìn)制日志
如果日志沒有啟開,必須啟用binlog,要重啟mysqld,首先,關(guān)閉mysqld,打開/etc/my.cnf,加入以下幾行:
[mysqld]
log-bin
然后重新啟動mysqld,會產(chǎn)生hostname-bin.000001以及hostname-bin.index,前面的日志文件是記錄所有對數(shù)據(jù)的更新操作,后面的文件是存儲所有二進(jìn)制文件的索引,不能輕易被刪除。
(3) 全備份,增量備份。
詳細(xì)見mysqlFullBackup.sh、mysqlDailyBackup.sh腳本(請注意腳本里面的備份目錄、mysql軟件安裝目錄、壓縮文件名以及用戶名密碼,如有不符,請修改)。
下面是部分shell上單個手動執(zhí)行的測試命令。
Shell /usr/local/mysql/bin/mysqldump -uroot -pnYuIman25040slave201012301124 --no-create-info=FALSE --order-by-primary=FALSE --force=FALSE --no-data=FALSE --tz-utc=TRUE --flush-privileg
es=FALSE --compress=FALSE --replace=FALSE --insert-ignore=FALSE --extended-insert=TRUE --quote-names=TRUE --hex-blob=TRUE --complete-insert=FALSE --add-locks=TRUE --port=3306 --d
isable-keys=TRUE --delayed-insert=FALSE --create-options=TRUE --delete-master-logs=FALSE --comments=TRUE --default-character-set=utf8 --max_allowed_packet=1G --flush-logs=FALSE -
-dump-date=TRUE --lock-tables=TRUE --allow-keywords=FALSE --events=FALSE --single-transaction=TRUE --routines --all-databases /backup/mysql/full/mysql_20110104_195546.sql
(4) 設(shè)置crontab任務(wù),每天執(zhí)行備份腳本
shell crontab –e
#每個星期日凌晨3:00執(zhí)行完全備份腳本
#周一到周六凌晨3:00做增量備份
0 3 * * 1-6 /root/MySQLBackup/mysqlDailyBackup.sh /dev/null 21
(5) 清除舊的備份文件。
每天去看查看下備份磁盤空間,刪除舊的備份壓縮文件。
1、首先打開mysql數(shù)據(jù)庫軟件進(jìn)入軟件主界面。
2、然后再左側(cè)樹里打開自己的的數(shù)據(jù)庫。
3、然后需要點擊需要備份的數(shù)據(jù)庫名。
4、如圖所示為打開數(shù)據(jù)庫后界面。
5、然后需要點擊轉(zhuǎn)儲sql文件選項。
6、然后需要打開選擇存儲文件路徑并選擇保存。
7、點擊保存即可在路徑備份好格式為sql的數(shù)據(jù)庫文件。