實(shí)際線上的場(chǎng)景比較復(fù)雜,當(dāng)時(shí)涉及了truncate, delete 兩個(gè)操作,經(jīng)確認(rèn)丟數(shù)據(jù)差不多7萬多行,等停下來時(shí),差不多又有共計(jì)1萬多行數(shù)據(jù)寫入。 這里為了簡(jiǎn)單說明,只拿弄一個(gè)簡(jiǎn)單的業(yè)務(wù)場(chǎng)景舉例。
測(cè)試環(huán)境: Percona-Server-5.6.16
日志格式: mixed 沒起用gtid
表結(jié)構(gòu)如下:
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
基于某個(gè)時(shí)間點(diǎn)有一個(gè)備份或是有全量的binlog是能恢復(fù)數(shù)據(jù)的一個(gè)唯一保證。 例如我們的備份就是一個(gè)表結(jié)構(gòu)創(chuàng)建語句,binlog pos相關(guān)信息: mysql-bin.000004 , 4,然后進(jìn)行了如下:
–t1時(shí)間 程序?qū)懭耄?br />
insert into tb_wubx(name) values(‘張三'),(‘李四'); insert into tb_wubx(name) values(‘隔壁老王');
–t2時(shí)間 某個(gè)人員失誤
truncate table tb_wubx;
–t3時(shí)間 程序?qū)懭?br />
insert into tb_wubx(name) values(‘老趙'); update tb_wubx set name='老趙趙' where id=1;
現(xiàn)在表里的數(shù)據(jù)情況:
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開始,原來寫入的數(shù)據(jù)應(yīng)該是:
+—-+———–+ | id | name | +—-+———–+ | 1 | 張三 | +—-+———–+ | 2 | 李四 | +—-+———–+ | 3 | 隔壁老王 | +—-+———–+
如果沒生truncate table操作,實(shí)際的數(shù)據(jù)應(yīng)該為:
+—-+———–+ | id | name | +—-+———–+ | 1 | 張三 | +—-+———–+ | 2 | 李四 | +—-+———–+ | 3 | 隔壁老王 | +—-+———–+ | 4 | 老趙趙 | +—-+———–+
而且線上的恢復(fù)那個(gè)表時(shí)和序序開發(fā)人員了解才知道,原來那個(gè)id和緩存及其它地方有依賴,因?yàn)閕d亂了,也會(huì)造成程序錯(cuò)亂。這個(gè)時(shí)間修復(fù)id在程序?qū)渝e(cuò)亂的事,留給開發(fā)人員了關(guān)建是給他們講明白恢復(fù)的結(jié)果是什么樣,我們的關(guān)建任務(wù)是把數(shù)據(jù)恢復(fù)出來。好,接下來的工作是開始從binlog中恢復(fù)數(shù)據(jù)。
利用: show binary logs; 查看當(dāng)?shù)膌og文件分布, 然后利用show binlog events in ‘binary log文件'; 查看log文件的內(nèi)容,目的是找到truncate發(fā)生的日志位置。
另外因?yàn)榛趥浞荩ㄓ蒷og的啟始位置)或是從量log, 如果基于備份有l(wèi)og的起始位置,我們需要處理的log文件是啟始位置到發(fā)生truncate的日值(后面的數(shù)據(jù)處理不了,會(huì)發(fā)生主建沖突的錯(cuò)誤造成truncate后的數(shù)據(jù)不能恢復(fù)),
如果是全量日志,需要從創(chuàng)建完mysql后庫(kù)后的日志去處理到當(dāng)前的發(fā)生truncate的位置(后面數(shù)據(jù)會(huì)因?yàn)橹鹘_突寫不進(jìn)去)
恢復(fù)準(zhǔn)備工作,創(chuàng)建一個(gè)庫(kù)用于恢復(fù)數(shù)據(jù),這里創(chuàng)建了一個(gè)re_wubx, 及原結(jié)構(gòu)的表: tb_wubx (相當(dāng)于恢復(fù)了備份,過程省略)
mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 143 | | mysql-bin.000002 | 261 | | mysql-bin.000003 | 562 | | mysql-bin.000004 | 1144 | +------------------+-----------+ 4 rows in set (0.00 sec) mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 143 | | mysql-bin.000002 | 261 | | mysql-bin.000003 | 562 | | mysql-bin.000004 | 1144 | +------------------+-----------+ 4 rows in set (0.00 sec)
我這里有一個(gè)備份文件就是那個(gè)創(chuàng)建表的sql語句,位置是mysql-bin.000004 , 4
在這個(gè)案例里我只用cover住mysql-bin.000004這個(gè)文件。
mysql>show binlog events in 'mysql-bin.000004'; +------------------+------+-------------+-----------+-------------+----------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+------+-------------+-----------+-------------+----------------------------------------------------+ | mysql-bin.000004 | 4 | Format_desc | 753306 | 120 | Server ver: 5.6.16-64.2-rel64.2-log, Binlog ver: 4 | | mysql-bin.000004 | 120 | Query | 753306 | 209 | use `wubx`; truncate table tb_wubx | | mysql-bin.000004 | 209 | Query | 753306 | 281 | BEGIN | | mysql-bin.000004 | 281 | Table_map | 753306 | 334 | table_id: 91 (wubx.tb_wubx) | | mysql-bin.000004 | 334 | Write_rows | 753306 | 393 | table_id: 91 flags: STMT_END_F | | mysql-bin.000004 | 393 | Xid | 753306 | 424 | COMMIT /* xid=1073 */ | | mysql-bin.000004 | 424 | Query | 753306 | 496 | BEGIN | | mysql-bin.000004 | 496 | Table_map | 753306 | 549 | table_id: 91 (wubx.tb_wubx) | | mysql-bin.000004 | 549 | Write_rows | 753306 | 602 | table_id: 91 flags: STMT_END_F | | mysql-bin.000004 | 602 | Xid | 753306 | 633 | COMMIT /* xid=1074 */ | | mysql-bin.000004 | 633 | Query | 753306 | 722 | use `wubx`; truncate table tb_wubx | | mysql-bin.000004 | 722 | Query | 753306 | 794 | BEGIN | | mysql-bin.000004 | 794 | Table_map | 753306 | 847 | table_id: 92 (wubx.tb_wubx) | | mysql-bin.000004 | 847 | Write_rows | 753306 | 894 | table_id: 92 flags: STMT_END_F | | mysql-bin.000004 | 894 | Xid | 753306 | 925 | COMMIT /* xid=1081 */ | | mysql-bin.000004 | 925 | Query | 753306 | 997 | BEGIN | | mysql-bin.000004 | 997 | Table_map | 753306 | 1050 | table_id: 92 (wubx.tb_wubx) | | mysql-bin.000004 | 1050 | Update_rows | 753306 | 1113 | table_id: 92 flags: STMT_END_F | | mysql-bin.000004 | 1113 | Xid | 753306 | 1144 | COMMIT /* xid=1084 */ | +------------------+------+-------------+-----------+-------------+----------------------------------------------------+ 19 rows in set (0.00 sec) mysql>show binlog events in 'mysql-bin.000004'; +------------------+------+-------------+-----------+-------------+----------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+------+-------------+-----------+-------------+----------------------------------------------------+ | mysql-bin.000004 | 4 | Format_desc | 753306 | 120 | Server ver: 5.6.16-64.2-rel64.2-log, Binlog ver: 4 | | mysql-bin.000004 | 120 | Query | 753306 | 209 | use `wubx`; truncate table tb_wubx | | mysql-bin.000004 | 209 | Query | 753306 | 281 | BEGIN | | mysql-bin.000004 | 281 | Table_map | 753306 | 334 | table_id: 91 (wubx.tb_wubx) | | mysql-bin.000004 | 334 | Write_rows | 753306 | 393 | table_id: 91 flags: STMT_END_F | | mysql-bin.000004 | 393 | Xid | 753306 | 424 | COMMIT /* xid=1073 */ | | mysql-bin.000004 | 424 | Query | 753306 | 496 | BEGIN | | mysql-bin.000004 | 496 | Table_map | 753306 | 549 | table_id: 91 (wubx.tb_wubx) | | mysql-bin.000004 | 549 | Write_rows | 753306 | 602 | table_id: 91 flags: STMT_END_F | | mysql-bin.000004 | 602 | Xid | 753306 | 633 | COMMIT /* xid=1074 */ | | mysql-bin.000004 | 633 | Query | 753306 | 722 | use `wubx`; truncate table tb_wubx | | mysql-bin.000004 | 722 | Query | 753306 | 794 | BEGIN | | mysql-bin.000004 | 794 | Table_map | 753306 | 847 | table_id: 92 (wubx.tb_wubx) | | mysql-bin.000004 | 847 | Write_rows | 753306 | 894 | table_id: 92 flags: STMT_END_F | | mysql-bin.000004 | 894 | Xid | 753306 | 925 | COMMIT /* xid=1081 */ | | mysql-bin.000004 | 925 | Query | 753306 | 997 | BEGIN | | mysql-bin.000004 | 997 | Table_map | 753306 | 1050 | table_id: 92 (wubx.tb_wubx) | | mysql-bin.000004 | 1050 | Update_rows | 753306 | 1113 | table_id: 92 flags: STMT_END_F | | mysql-bin.000004 | 1113 | Xid | 753306 | 1144 | COMMIT /* xid=1084 */ | +------------------+------+-------------+-----------+-------------+----------------------------------------------------+ 19 rows in set (0.00 sec)
看到這個(gè)表剛開始就發(fā)生一次truncate, 那其實(shí)也可以說明我就恢復(fù)剛開始那個(gè)truncate到后來那個(gè)誤操作的truncate table的語句之間的數(shù)據(jù)就是丟失的數(shù)據(jù)。
這個(gè)恢復(fù)可以從mysql-bin.000004 pos: 4到mysql-bin.000004 pos: 633 即:
mysqlbinlog --rewrite-db='wubx->re_wubx' --start-position=4 --stop-position=633 mysql-bin.000004 |mysql -S /tmp/mysql.sock re_wubx mysqlbinlog --rewrite-db='wubx->re_wubx' --start-position=4 --stop-position=633 mysql-bin.000004 |mysql -S /tmp/mysql.sock re_wubx
恢復(fù)結(jié)果如下:
mysql -S /tmp/mysql.sock re_wubx; mysql>select count(*) from tb_wubx; +----------+ | count(*) | +----------+ | 3 | +----------+ 1 row in set (0.02 sec) mysql>select * from tb_wubx; +----+--------------+ | id | name | +----+--------------+ | 1 | 張三 | | 2 | 李四 | | 3 | 隔壁老王 | +----+--------------+ 3 rows in set (0.00 sec) mysql>insert into tb_wubx(name) select name from wubx.tb_wubx; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> rename table wubx.tb_wubx to wubx.bak_tb_wubx; Query OK, 0 rows affected (0.04 sec) mysql> rename table re_wubx.tb_wubx to wubx.tb_wubx; Query OK, 0 rows affected (0.03 sec) mysql> select * from wubx.tb_wubx; +----+--------------+ | id | name | +----+--------------+ | 1 | 張三 | | 2 | 李四 | | 3 | 隔壁老王 | | 4 | 老趙趙 | +----+--------------+ 4 rows in set (0.00 sec) mysql -S /tmp/mysql.sock re_wubx; mysql>select count(*) from tb_wubx; +----------+ | count(*) | +----------+ | 3 | +----------+ 1 row in set (0.02 sec) mysql>select * from tb_wubx; +----+--------------+ | id | name | +----+--------------+ | 1 | 張三 | | 2 | 李四 | | 3 | 隔壁老王 | +----+--------------+ 3 rows in set (0.00 sec) mysql>insert into tb_wubx(name) select name from wubx.tb_wubx; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> rename table wubx.tb_wubx to wubx.bak_tb_wubx; Query OK, 0 rows affected (0.04 sec) mysql> rename table re_wubx.tb_wubx to wubx.tb_wubx; Query OK, 0 rows affected (0.03 sec) mysql> select * from wubx.tb_wubx; +----+--------------+ | id | name | +----+--------------+ | 1 | 張三 | | 2 | 李四 | | 3 | 隔壁老王 | | 4 | 老趙趙 | +----+--------------+ 4 rows in set (0.00 sec)
恢復(fù)完成。
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com