實際線上的場景比較復雜,當時涉及了truncate, delete 兩個操作,經確認丟數據差不多7萬多行,等停下來時,差不多又有共計1萬多行數據寫入。 這里為了簡單說明,只拿弄一個簡單的業務場景舉例。
測試環境: Percona-Server-5.6.16
日志格式: mixed 沒起用gtid
表結構如下:
| CREATE TABLE `tb_wubx` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CREATE TABLE `tb_wubx` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 |
基于某個時間點有一個備份或是有全量的binlog是能恢復數據的一個唯一保證。 例如我們的備份就是一個表結構創建語句,binlog pos相關信息: mysql-bin.000004 , 4,然后進行了如下:
–t1時間 程序寫入:
| insert into tb_wubx(name) values(‘張三'),(‘李四');insert into tb_wubx(name) values(‘隔壁老王'); |
–t2時間 某個人員失誤
| truncate table tb_wubx; |
–t3時間 程序寫入
| insert into tb_wubx(name) values(‘老趙');update tb_wubx set name='老趙趙' where id=1; |
現在表里的數據情況:
| mysql>select * from tb_wubx;+----+-----------+| id | name |+----+-----------+| 1 | 老趙趙 |+----+-----------+1 row in set (0.00 sec) mysql>select * from tb_wubx;+----+-----------+| id | name |+----+-----------+| 1 | 老趙趙 |+----+-----------+1 row in set (0.00 sec) |
可以見truncate table操作后,表的自增id又變更為從1開始,原來寫入的數據應該是:
| +—-+———–+| id | name |+—-+———–+| 1 | 張三 |+—-+———–+| 2 | 李四 |+—-+———–+| 3 | 隔壁老王 |+—-+———–+ |
如果沒生truncate table操作,實際的數據應該為:
| +—-+———–+| id | name |+—-+———–+| 1 | 張三 |+—-+———–+| 2 | 李四 |+—-+———–+| 3 | 隔壁老王 |+—-+———–+| 4 | 老趙趙 |+—-+———–+ |
而且線上的恢復那個表時和序序開發人員了解才知道,原來那個id和緩存及其它地方有依賴,因為id亂了,也會造成程序錯亂。這個時間修復id在程序層錯亂的事,留給開發人員了關建是給他們講明白恢復的結果是什么樣,我們的關建任務是把數據恢復出來。好,接下來的工作是開始從binlog中恢復數據。
利用: show binary logs; 查看當的log文件分布, 然后利用show binlog events in ‘binary log文件'; 查看log文件的內容,目的是找到truncate發生的日志位置。
新聞熱點
疑難解答