1. 程式人生 > 資料庫 >mysql 001 | 3種mysql備份恢復方案優劣對比!

mysql 001 | 3種mysql備份恢復方案優劣對比!

mysql 001 | 3種mysql備份恢復方案優劣對比!

點選上方“java進階架構師”,選擇右上角“置頂公眾號”
20大進階架構專題每日送達
mysql 001 | 3種mysql備份恢復方案優劣對比!

前言

這周又是上線周。辦公桌的頭髮越來越多了,保溫杯都是枸杞,電腦桌布也換成了應急逃生通道(不要問我為什麼是應急通道,因為打算隨時跑路)。

因為是新系統要與舊系統之間進行資料同步,清洗,分發。所以,這周任務是不斷地核實資料,除錯程式,與資料庫打交道的佔比很高。

一旦要到資料庫這個話題,永遠也避不開資料安全的問題。所以今天我就來講講怎麼使用 MySQL 的備份與恢復。

丟擲本文問題

首先,在講 MySQL 備份之前,我想明確咱們接下來需要探究的問題

備份這麼麻煩,但是為什麼值得我們去做?

多得一批的備份術語
我們究竟需要備份什麼?
備份需要考慮什麼因素?
備份的方案有哪些?
實踐

知識背景

為什麼我們需要備份?

時間是往前流動的,人生是不可逆轉的,但是資料庫能。我想說幾個場景你是否還很熟悉?

線上專案因為 Bug 或客戶騷操作的問題,導致業務資料缺失,流程無法繼續走下去,沒有回頭了只硬著頭皮線上改資料,結果表一多起來,改了那條都不知道了
上線前從舊系統遷移資料,為上線做準備,結果一執行清洗 SQL,哎呀,IS NOT NULL 忘了改回了 IS NULL,含淚全庫刪除,重新導庫清洗;
新同事在伺服器執行了技術大佬傳授真經命令列 rm -rf /*,結果我趕緊給他發了一張高清的緊急逃生通道...

所以說,為什麼我們要備份?因為我們要做到無所畏懼,有路可退。在風險面前,我們盡能力去規避風險。這些風險,小到不小心在別的伺服器執行了 Alter Table,大到伺服器硬體出現故障,全機崩潰,軟體硬體故障/自然災害/人為操作等等。

所以我們需要備份是為了應對來自各方面的威脅

多得一批的備份術語

說起備份,可能你的頭腦裡浮現了 熱備份/冷備份/增量備份/差異備份/邏輯備份...放棄的聲音席捲而來!
其實先不要害怕這些術語,它們都是有專門的由來的。
首先是熱備份,溫備份和冷備份。熱備份指的是不需要停止任何服務即可備份,就好像你備份不用關掉資料庫來備份,隨時隨地可進行;冷備份指的是停止資料庫進行資料備份。

然後全量備份和部分備份。

全量備份(類似名字還有全域性備份,完全備份)指的是將整個資料庫備份下來。顯然當專案資料達到一定規模,那麼整庫備份變得不現實,因為備份時間變得更長,同時需要更多地磁碟資源,機器資源...
部分備份指的是將部分資料集備份下來,例如備份某庫某表某個時間段的資料,或者是僅僅備份某庫某表的所有資料。部分備份一般不包含完整的資料集,而我們明顯可以僅僅備份所更改的資料,這樣可以減少伺服器的開銷/備份時間/備份空間。根據部分備份的概念,我們可以拆分成兩種備份方式:增量備份和差異備份,下面使用表格說明:

名稱  說明
增量備份    對自上次全備份後所有改變的部分而做的備份
差異備份    自從任意型別的上次備份後所有修改做的備份

舉例說明,假設在週日做了一個全量備份。在週一,對自週日以來所有的改變做一個差異備份。在週二,你有兩個選擇:備份週日以來所有的改變(差異備份),或只備份自從週一備份後所有的改變(增量備份)

我們究竟需要備份資訊?

可能說到這個問題上,大多數人第一反應就是備份表結構+表資料。恭喜你,你猜對了一半,但是這個方案是備份中最低的要求,因為在資料庫中還存在很多被忽略的資料在默默支撐著資料庫的正常執行。下面介紹一下資料庫哪些值得關注的資料:

型別  內容
非顯著資訊   二進位制日誌和 InnoDB 事務日誌
程式碼  觸發器和儲存過程
複製配置    二進位制日誌/中繼日誌/日誌索引檔案/.info 檔案
伺服器配置   伺服器的配置檔案
選定的作業系統檔案   對生產伺服器至關重要的外部配置。在 unix 伺服器上,可能包括了 cron 任務/使用者和組的配置/管理指令碼/sudo 規則等

根據業務權衡,備份的資料越多,型別越齊全,就越有利於你恢復到想要的效果

備份我們需要考慮什麼因素

其實備份考慮的因素不多,關鍵的有以下幾個

鎖時間
備份時間
備份負載
恢復時間
關於鎖時間,我們需要考慮是否一定要鎖表?鎖表時間可接受的範圍是多少?如果是熱備份,在什麼時候進行鎖表才不會影響業務?

備份的方案有哪些?

方案名稱    適用場景
mysqldump + binlog  全量備份 + 增量備份混合方案
xtrabackup  InnoDB 支援熱備,支援全量備份/增量備份,MyISAM 支援溫備,只支援全量備份
lvm + binlog    熱備,物理備份

實踐

前期準備

建立一個數據庫
執行以下 SQL,準備好我們的基礎資料

-- ----------------------------
-- 建立一個表
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- 插入基礎資料
-- ----------------------------
INSERT INTO `user` VALUES ('1', '123');
INSERT INTO `user` VALUES ('2', '456');

❤️ 使用 mysqldump+binlog 備份

mysqldump 其實是一個 mysql 的一個命令列。binlog 是一個二進位制格式的檔案,用於記錄使用者對資料庫更新的 SQL 語句資訊,例如更改資料庫表和更改內容的 SQL 語句都會記錄到 binlog 裡,對查詢等操作並不會記錄。

場景模擬

在基礎資料下,先做一個全量備份
模擬新增資料操作,增加新資料
然後使用 binlog 做一個增量備份
模擬資料庫誤操作,將資料表刪除
關閉二進位制日誌,然後恢復全量備份,備份完後開啟二進位制日誌
通過增量備份恢復資料
檢查恢復情況
根據場景模擬開始之前,我們需要確認 mysqldump 是否開啟。在 SQL 命令列模式下檢查是否開啟:

// Off 關閉;On 開啟
show variables like 'log_bin';

如果沒開啟,我們開啟並編輯 /etc/my.cnf

log-bin=/root/mysql/bin-log/bin-log-file
expire-logs-days = 14
max-binlog-size = 500M
server-id = 1

儲存後重啟,再次檢查是否開啟

第一步

檢查目前的 binlog 備份狀態,便於


mysql -e 'SHOW MASTER STATUS'

結果

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000000 |      45 |              |                  |
+------------------+----------+--------------+------------------+

Position 代表著已經被備份資料的位置,我們需要記住便於接下來從這個位置恢復。
使用 mysqldump 進行全量備份


mysqldump --all-databases --lock-all-tables  > user_backerup.sql

第二步

模擬前端新增操作,代表著目前的資料已經發生了變化


INSERT INTO `user` VALUES ('3', '456');

第三步

我們再次檢視目前的增量備份檔案是多少


show master status

假設結果是


+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000000 |      80  |              |                  |
+------------------+----------+--------------+------------------+

使用 binlog 進行增量備份,在 sql 命令執行 flush logs 後,會在你之前設的 logbin 資料夾下多一份檔案 mysql-bin.000001,那麼這份就是增量備份。

第四步

我們可以資料庫誤操作,例如說不小心刪了表,或者刪除了一些表資料。我這裡通過刪表作為誤操作


drop table user;

再檢查是否真的刪除了


show tables;

第五步

因為現在我們已經誤操作了,我們需要進行全量備份,然後再增量備份。
關閉二進位制日誌


SET sql_log_bin=OFF;

然後執行全量備份檔案


mysql -uroot -p user < user_backerup.sql

執行完後再次開啟二進位制日誌


SET sql_log_bin=ON;

第六步

這時候,我們應該想到了,還差增量備份的資料。就能返回到了誤操作的前面。
所以我們使用 mysqlbinlog 命令執行增量備份檔案


mysqlbinlog --start-position=45 --stop-position=80 mysql-bin.000001 | mysql user

第七步

接下來就是檢查的情況了


show tables;

❤️ 使用 xtrabackup 備份

xtrabackup 是一款開源的免費資料庫熱備份軟體,實現非阻塞備份 InnoDB 引擎資料庫,但是對於 MyISAM 還是需要加表鎖備份。

下面是 xtrabackup 的優點

備份速度快,還原速度快,物理備份可靠
無須鎖表,實現熱備份;支援壓縮備份
低負載備份,降低伺服器負載
備份檔案可跨平臺
還原速度快
支援加密備份

環境安裝

預設你已經根據自身情況安裝了相對的版本的 xtrabackup

我們依舊通過上面的場景模擬,用 xtrabackup 進行全量備份指令碼、增量備份恢復

模擬全量備份指令碼

執行以下 SQL,準備好我們的基礎資料
使用 xtrabackup 進行全量備份
模擬人為資料庫誤操作
通過 xtrabackup 進行恢復
使用命令列進行全量備份


xtrabackup --backup --target-dir=/root/xtrabackup/bakcups --user=root --password=root

引數解釋:
--backup:將備份檔案讓道 target-dir,也就是說明它和 target-dir 是搭配使用的
--target-dir:備份檔案放置檔案,當前我使用的資料夾是 /root/xtrabackup/bakcups

如果看到有類似輸出,即說明已經成功備份了


190904 14:30:48 [00] Writing xtrabackup_info
190904 14:30:48 [00]        ...done
xtrabackup: Transaction log of lsn (4417990) to (4417999) was copied.
190904 14:30:49 completed OK!

然後我們執行 SQL,模擬誤操作,增刪改都可以。我這裡就直接刪除一個表吧~


drop tables tablesname;

接著通過命令進行全量恢復


xtrabackup --prepare --target-dir=/root/xtrabackup/bakcups

這時候可以開啟資料進行檢驗。

模擬增量備份恢復

增量備份目前僅可用於 InnoDB 或 XtraDB,對於 MyISAM,增量和全量備份同樣還是會掃描全表的

通常在做增量備份,先做一個全量備份的(如果需要賬號密碼登入自行加上)。


xtrabackup --backup --target-dir=/root/xtrabackup/base

在 /data/backups/base 下會生成很多檔案。我對於增量備份,我們著重看一個叫 xtrabackup_checkpoints。以下是它的結構:


backup_type = full-backuped     // 備份型別
from_lsn = 0                    // 初始位置
to_lsn = 15188961605            // 備份位置
last_lsn = 15188961605          // 最後備份位置

也就是說,增量備份會基於全量備份的資訊進行備份的。


xtrabackup --backup --target-dir=/root/xtrabackup/inc1 \ --incremental-basedir=/root/xtrabackup/base

剛剛生成的 /root/xtrabackup/inc1 裡邊包含大多資訊,而且這裡邊也有一個 xtrabackup_checkpoints 檔案。我給出一個大概結構的檔案


backup_type = incremental
from_lsn = 4124244              
to_lsn = 6938371
last_lsn = 7110572
compact = 0
recover_binlog_info = 1

現在我們通過 xtrabackup --prepare 進行資料恢復。


innobackupex --defaults-file=/etc/my.cnf --user=root --password='password' /backup/20180423/

接下來就是檢查的情況了

關於備份與恢復的一些知識點

有些部分備份不會真正減少伺服器的開銷。
不要備份沒有改變的表。MyISAM 會記錄每個表最後修改時間,通過檢視磁碟檔案或執行 show tables status 來看時間;如果是 InnoDB。,可以利用觸發器記錄修改時間到一個小的“最後修改時間”表中,幫助追蹤最新的修改操作。需要確保只對變更不頻繁的表進行跟蹤,這樣才能降低開銷。通過定製指令碼可以輕鬆獲得哪些表變更了。
增量備份的缺點是,增加了恢復的複雜度,額外的風險,更長的恢復時間。如果可以做全備,儘量做全備。
建議備份至少一週一次。
但是一般情況下,這個備份是不能用於恢復的,因為備份的資料中可能會包含尚未提交的事務或已經提交但尚未同步至資料檔案中的事務。因此,此時資料檔案處於不一致的狀態,我們現在就是要通過回滾未提交的事務及同步已經提交的事務至資料檔案也使得資料檔案處於一致性狀態。
備份檔案的命名需要規範起來。例如全量備份的話可以使用特定標識作為字首;增量備份可以以時間段作為命名
———— e n d ————
微服務、高併發、JVM調優、面試專欄等20大進階架構師專題請關注公眾號【Java進階架構師】後在選單欄檢視。
mysql 001 | 3種mysql備份恢復方案優劣對比!
看到這裡,說明你喜歡本文
你的轉發,是對我最大的鼓勵!在看亦是支援!