嘗試用binlog恢復mysql數據

Binlog介紹:

  • Binlog又稱歸檔日誌是專門用來記錄邏輯的 (監控並記錄你在幹啥,好比有沒有偷偷刪表刪庫??)
  • Binlog位於server層,所以全部的存儲引擎均可以使用
  • Binlog沒有固定大小,會追加寫入且不會覆蓋舊的Binlog

Binlog開啓和配置:

首先咱們要檢查下咱們是否開啓了Binlog
輸入命令:mysql

show variables like '%bin%';

noteshare?id=127b916424ed782ae675bdb5b17bbf72&sub=086129FD40E043A38FD03CC77DA70D12

1,變量log_bin 爲 on表示已開啓 (如何開啓? 直接my.cnf添加log_bin="log_bin_basername"便可)sql


2,變量log_bin_basename 爲 binlog日誌的文件名,還會自動接後綴.00000xx,每次重啓mysql服務或者使用flush logs命令都會生成一個新的binlog文件數據庫


3,變量bin_format則表示日誌記錄的格式,共有三種格式,分別是statement,rows,mixed,測試

  • statement 記錄的是sql語句
  • rows 記錄的是對數據操做的上下文
  • mixed 則兼容statementrows,會自動根據場景來選擇使用前二者的哪種

通常咱們推薦使用mixed,由於statement存在隔離限制,若是在"rc/ru" 即 讀未提交/讀提交的隔離級別下,會產生不可重複讀,配置主從後使用statement格式(由於只是記錄sql)進行復制會致使主從數據不一致,而 rows 因爲記錄的行數據操做的上下文,相比statement佔用空間更大spa


接着咱們先查看一下當前的isolation3d

輸入命令:
show variables like '%isolation%';

圖片描述

ps:5.7+變量名變爲`tracsaction_isolation`,我這邊是5.6版本的因此仍是`tx_isolation`

經過圖能夠看到,我這邊隔離級別爲rc,也就是讀提交日誌

對照上面講的,rc 不支持 statement 格式,因此咱們要切換格式爲rows或者mixedcode

能夠直接經過global 變量更改,或者直接修改my.cnf,我這裏直接修改my.cnform

圖片描述

保存,重啓服務,而後從新查看變量binlog_format,ok,已變動爲mixedserver

圖片描述


創建測試數據並備份

創建一個test庫,而後在test庫中創建一個簡單的t1表用以測試

CREATE TABLE `t1` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `num` int(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

而後往t1表插入三條數據

insert into t1  (num) values(1),(2),(3);

圖片描述

這樣咱們測試表和備份數據就完成了,而後用mysqldump進行備份

mysqldump -u -h -p database > /dirs/xxx.sql

圖片描述

接着再插入3條新數據用以測試數據恢復,因爲備份中不存在這三條,因此這三條是須要恢復的數據

insert into t1  (num) values(4),(5),(6);

圖片描述

而後咱們僞裝誤刪表。。。。

drop table t1

準備階段到此結束~~~

開始恢復數據:

ok,如今開始進入場景,因爲我誤刪了t1表,因此我須要恢復數據(t1應當數據有6條),但備份的數據中只有3條,因此後面插入的那3條記錄遺失了,但因爲咱們配置了binlog,因此後面那3條的數據日誌是有被記錄的,所以咱們只須要用Binlog來恢復那三條數據便可,下面開始數據恢復。

1,先使用備份恢復

咱們先把數據恢復到備份狀態

mysql -uroot -p -h127.0.0.1 test < /data/mysql/test_backup.sql

圖片描述

恢復成功,檢查表中數據

圖片描述

ok,已經恢復到備份狀態啦

2,使用Binlog恢復

先查詢下當前使用的binlog是哪一個文件

show master status;

圖片描述

能夠看到使用的是binlog.000001文件,position累計計數到1615

接着咱們先熟悉下mysqlbinlog的篩選規則

mysqlbinlog --help

圖片描述

如圖,咱們能夠看到mysqlbinlog 命令有4個篩選條件:

start-datetime/stop-datetime 分別表示想要篩選的記錄區間的`起始時間`和`截止時間`
start-position/stop-position 則表示想要篩選的記錄區間的`起始位置`和`截止位置`

咱們須要用這幾個篩選條件來定位所須要恢復的日誌區間

而後咱們來瞅一下這個binlog.000001文件

/*-d參數表示篩選的數據庫名稱*/
mysqlbinlog -d test /data/mysql/binlog.000001

圖片描述

因爲咱們使用的隔離限制爲rc,mixed會自動選擇rows格式記錄對行的數據操做,因此看不到對應的sql,只能看到對應的上下文

But whatever 直接向下拉,而後咱們找到一個重點!

圖片描述

position 699 有一個drop table t1 的操做, 然後面的position 814 和 poistion 939則是恢復備份時的刪表建表操做。

所以咱們肯定了stop-position 就是699

而後咱們在找下備份時間,由於咱們很差肯定start-position,而不指定開始位置所有恢復又有點太說不過去了。。所以直接查看下備份時間。

圖片描述

ok,這樣咱們的start-datetime也肯定了, 有了 start-datetimestop-position,咱們就能肯定所要恢復的日誌區間了

接下來就要用mysqlbinlog 命令開始恢復了

/*這裏的 -D 參數表示防止出現新的日誌記錄,我不想把恢復時添加的數據記錄也加到binlog裏面*/
mysqlbinlog -d test -D --start-datetime="2019-05-25 09:39:00" --start-position=699 /data/mysql/binlog.000001 | mysql -uroot -p -h127.0.0.1 test

圖片描述

能夠看到加了 -D 參數 `position`數目沒有發生改變,即沒有生成新的日誌記錄

圖片描述

查詢t1表, 發現已經恢復成功了,id 567都恢復進來了

恢復結束


上面的操做是直接經過mysqlbinlog 導入到庫中的,固然你也能夠選擇用mysqlbinlog生成sql文件,而後再導入sql文件進行恢復,咱們再試一下。

圖片描述

先恢復到備份狀態(由於-D 參數沒有生成新的記錄,因此直接start-position = 699便可)

圖片描述

而後用mysqlbinlog 生成sql

/*沒有加-D 參數就是爲了測試會不會出現新的日誌記錄*/
mysqlbinlog -d test --start-datetime="2019-05-25 09:39:00" --stop-position=699 /data/mysql/binlog.000001 > binlog_201905025.sql

圖片描述

生成成功,接着導入sql

mysql -uroot -p -h127.0.0.1 test < /data/mysql/binlog_20190525.sql

圖片描述

ok,發現恢復也成功了

圖片描述

而後查看position個數

show master status;

圖片描述

果真position變多啦~

通常建議恢復時添加-D 參數,由於恢復時記錄也會被記錄到binlog中,至關於重複了。

that's all ~~~

第一次在思否發文章,感受格式啥不太標準。。見諒。。

相關文章
相關標籤/搜索