這周又是上線周。辦公桌的頭髮愈來愈多了,保溫杯都是枸杞,電腦壁紙也換成了應急逃生通道(不要問我爲何是應急通道,由於打算隨時跑路)。前端
由於是新系統要與舊系統之間進行數據同步,清洗,分發。因此,這周任務是不斷地核實數據,調試程序,與數據庫打交道的佔比很高。mysql
一旦要到數據庫這個話題,永遠也避不開數據安全的問題。因此今天我就來說講怎麼使用 MySQL
的備份與恢復。sql
首先,在講 MySQL
備份以前,我想明確我們接下來須要探究的問題shell
時間是往前流動的,人生是不可逆轉的,可是數據庫能。我想說幾個場景你是否還很熟悉?數據庫
Bug
或客戶騷操做的問題,致使業務數據缺失,流程沒法繼續走下去,沒有回頭了只硬着頭皮線上改數據,結果表一多起來,改了那條都不知道了SQL
,哎呀,IS NOT NULL
忘了改回了 IS NULL
,含淚全庫刪除,從新導庫清洗;rm -rf /*
,結果我趕忙給他發了一張高清的緊急逃生通道...因此說,爲何咱們要備份?由於咱們要++作到無所畏懼,有路可退++。在風險面前,咱們盡能力去規避風險。這些風險,小到不當心在別的服務器執行了 Alter Table
,大到服務器硬件出現故障,全機崩潰,軟件硬件故障/天然災害/人爲操做等等。安全
因此咱們須要備份是爲了應對來自各方面的威脅bash
提及備份,可能你的頭腦裏浮現了 熱備份
/冷備份
/增量備份
/差別備份
/邏輯備份
...放棄的聲音席捲而來!
其實先不要懼怕這些術語,它們都是有專門的由來的。
首先是熱備份,溫備份和冷備份。熱
備份指的是不須要中止任何服務便可備份,就好像你備份不用關掉數據庫來備份,隨時隨地可進行;冷
備份指的是中止數據庫進行數據備份。服務器
而後全量備份和部分備份。ui
增量備份
和差別備份
,下面使用表格說明:名稱 | 說明 |
---|---|
增量備份 | 對自上次全備份後全部改變的部分而作的備份 |
差別備份 | 自從任意類型的上次備份後全部修改作的備份 |
舉例說明,假設在週日作了一個全量備份。在週一,對自週日以來全部的改變作一個差別備份。在週二,你有兩個選擇:備份週日以來全部的改變(差別備份
),或只備份自從週一備份後全部的改變(增量備份
)加密
可能說到這個問題上,大多數人第一反應就是備份表結構+表數據。恭喜你,你猜對了一半,可是這個方案是備份中最低的要求,由於在數據庫中還存在不少被忽略的數據在默默支撐着數據庫的正常運行。下面介紹一下數據庫哪些值得關注的數據:
類型 | 內容 |
---|---|
非顯著信息 | 二進制日誌和 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
裏,對查詢等操做並不會記錄。
根據==場景模擬==開始以前,咱們須要確認 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
。 ,能夠利用觸發器記錄修改時間到一個小的「最後修改時間」表中,幫助追蹤最新的修改操做。須要確保只對變動不頻繁的表進行跟蹤,這樣才能下降開銷。經過定製腳本能夠輕鬆得到哪些表變動了。