[MySQL] 刪庫跑路,還不如學習一下怎麼備份恢復

關於備份與恢復的討論問題應該包括

  1. 爲何要備份
  2. 定義恢復需求
  3. 設計備份方案
  4. 管理和備份二進制日誌
  5. 備份數據
  6. 從數據中恢復
  7. 備份和恢復的工
  8. 備份腳本化

前言

這周又是上線周。辦公桌的頭髮愈來愈多了,保溫杯都是枸杞,電腦壁紙也換成了應急逃生通道(不要問我爲何是應急通道,由於打算隨時跑路)。前端

由於是新系統要與舊系統之間進行數據同步,清洗,分發。因此,這周任務是不斷地核實數據,調試程序,與數據庫打交道的佔比很高。mysql

一旦要到數據庫這個話題,永遠也避不開數據安全的問題。因此今天我就來說講怎麼使用 MySQL 的備份與恢復。sql

拋出本文問題

首先,在講 MySQL 備份以前,我想明確我們接下來須要探究的問題shell

  1. 備份這麼麻煩,可是爲何值得咱們去作?
  2. 多得一批的備份術語
  3. 咱們究竟須要備份什麼?
  4. 備份須要考慮什麼因素?
  5. 備份的方案有哪些?
  6. 實踐

知識背景

爲何咱們須要備份?

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

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

因此說,爲何咱們要備份?由於咱們要++作到無所畏懼,有路可退++。在風險面前,咱們盡能力去規避風險。這些風險,小到不當心在別的服務器執行了 Alter Table,大到服務器硬件出現故障,全機崩潰,軟件硬件故障/天然災害/人爲操做等等。安全

因此咱們須要備份是爲了應對來自各方面的威脅bash

多得一批的備份術語

提及備份,可能你的頭腦裏浮現了 熱備份/冷備份/增量備份/差別備份/邏輯備份...放棄的聲音席捲而來!
其實先不要懼怕這些術語,它們都是有專門的由來的。
首先是熱備份溫備份冷備份備份指的是不須要中止任何服務便可備份,就好像你備份不用關掉數據庫來備份,隨時隨地可進行;備份指的是中止數據庫進行數據備份。服務器

而後全量備份部分備份ui

  1. 全量備份(相似名字還有全局備份,徹底備份)指的是將整個數據庫備份下來。顯然當項目數據達到必定規模,那麼整庫備份變得不現實,由於備份時間變得更長,同時須要更多地磁盤資源,機器資源...
  2. 部分備份指的是將部分數據集備份下來,例如備份某庫某表某個時間段的數據,或者是僅僅備份某庫某表的全部數據。部分備份通常不包含完整的數據集,而咱們明顯能夠僅僅備份所更改的數據,這樣能夠減小服務器的開銷/備份時間/備份空間。 根據部分備份的概念,咱們能夠拆分紅兩種備份方式:增量備份差別備份,下面使用表格說明:
名稱 說明
增量備份 對自上次全備份後全部改變的部分而作的備份
差別備份 自從任意類型的上次備份後全部修改作的備份

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

咱們究竟須要備份信息?

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

類型 內容
非顯著信息 二進制日誌和 InnoDB 事務日誌
代碼 觸發器和存儲過程
複製配置 二進制日誌/中繼日誌/日誌索引文件/.info 文件
服務器配置 服務器的配置文件
選定的操做系統文件 對生產服務器相當重要的外部配置。在 unix 服務器上,可能包括了 cron 任務/用戶和組的配置/管理腳本/sudo 規則等

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

備份咱們須要考慮什麼因素

其實備份考慮的因素很少,關鍵的有如下幾個

  1. 鎖時間
  2. 備份時間
  3. 備份負載
  4. 恢復時間

關於鎖時間,咱們須要考慮是否必定要鎖表?鎖表時間可接受的範圍是多少?若是是熱備份,在何時進行鎖表纔不會影響業務?

備份的方案有哪些?

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

實踐

前期準備

  1. 建立一個數據庫
  2. 執行如下 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 裏,對查詢等操做並不會記錄。

場景模擬

  1. 在基礎數據下,先作一個全量備份
  2. 模擬新增數據操做,增長新數據
  3. 而後使用 binlog 作一個增量備份
  4. 模擬數據庫誤操做,將數據表刪除
  5. 關閉二進制日誌,而後恢復全量備份,備份完後開啓二進制日誌
  6. 經過增量備份恢復數據
  7. 檢查恢復狀況

根據==場景模擬==開始以前,咱們須要確認 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 的優勢

  1. 備份速度快,還原速度快,物理備份可靠
  2. 無須鎖表,實現熱備份;支持壓縮備份
  3. 低負載備份,下降服務器負載
  4. 備份文件可跨平臺
  5. 還原速度快
  6. 支持加密備份

環境安裝

默認你已經根據自身狀況安裝了相對的版本的 xtrabackup

咱們依舊經過上面的場景模擬,用 xtrabackup 進行全量備份腳本增量備份恢復

模擬全量備份腳本

  1. 執行如下 SQL,準備好咱們的基礎數據
  2. 使用 xtrabackup 進行全量備份
  3. 模擬人爲數據庫誤操做
  4. 經過 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/
複製代碼

接下來就是檢查的狀況了

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

  1. 有些部分備份不會真正減小服務器的開銷。
  2. 不要備份沒有改變的表。MyISAM 會記錄每一個表最後修改時間,經過查看磁盤文件或運行 show tables status 來看時間;若是是 InnoDB。 ,能夠利用觸發器記錄修改時間到一個小的「最後修改時間」表中,幫助追蹤最新的修改操做。須要確保只對變動不頻繁的表進行跟蹤,這樣才能下降開銷。經過定製腳本能夠輕鬆得到哪些表變動了。
  3. 增量備份的缺點是,增長了恢復的複雜度,額外的風險,更長的恢復時間。若是能夠作全備,儘可能作全備。
  4. 建議備份至少一週一次。
  5. 可是通常狀況下,這個備份是不能用於恢復的,由於備份的數據中可能會包含還沒有提交的事務或已經提交但還沒有同步至數據文件中的事務。所以,此時數據文件處於不一致的狀態,咱們如今就是要經過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。
  6. 備份文件的命名須要規範起來。例如全量備份的話可使用特定標識做爲前綴;增量備份能夠以時間段做爲命名
相關文章
相關標籤/搜索