首先咱們要檢查下咱們是否開啓了Binlog
輸入命令:mysql
show variables like '%bin%';
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
則兼容statement
和rows
,會自動根據場景來選擇使用前二者的哪種通常咱們推薦使用mixed
,由於statement
存在隔離限制,若是在"rc/ru" 即 讀未提交/讀提交的隔離級別下,會產生不可重複讀,配置主從後使用statement
格式(由於只是記錄sql)進行復制會致使主從數據不一致,而 rows 因爲記錄的行數據操做的上下文,相比statement
佔用空間更大spa
接着咱們先查看一下當前的isolation
3d
輸入命令:
show variables like '%isolation%';
ps:5.7+變量名變爲`tracsaction_isolation`,我這邊是5.6版本的因此仍是`tx_isolation`
經過圖能夠看到,我這邊隔離級別爲rc,也就是讀提交日誌
對照上面講的,rc 不支持 statement
格式,因此咱們要切換格式爲rows
或者mixed
code
能夠直接經過global 變量更改,或者直接修改my.cnf,我這裏直接修改my.cnform
保存,重啓服務,而後從新查看變量binlog_format
,ok,已變動爲mixed
server
創建一個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-datetime
和 stop-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 ~~~
第一次在思否發文章,感受格式啥不太標準。。見諒。。