使用binlog恢复数据
這里看下使用binlog恢復數(shù)據(jù)的思路和過程
一般重要的業(yè)務庫都會定時做全備,并且打開binlog功能,mysql5.6以后就默認打開binlog了。
想要手動開啟binlog,可以在配置文件中加上下面的字段:
[mysqld]
log-bin = /usr/local/var/mysql/logs/mysql-bin.log ##日志位置
expire-logs-days = 14 ##過期時間
max-binlog-size = 500M ##日志最大限制,超過會自動切割
server-id = 1
如果線上出現(xiàn)誤刪除數(shù)據(jù)的情況,我們可以采用下面的思路進行數(shù)據(jù)恢復:
1:創(chuàng)建臨時庫,并用最近的一個全備去恢復
2:查看binlog,找到這個全備時間點到誤刪除數(shù)據(jù)的點之間的操作
3:如果范圍在一個binlog里,直接用指令恢復。如果范圍跨越多個binlog,從最久遠的那個開始恢復,直到恢復到刪除數(shù)據(jù)的那個position,就能把數(shù)據(jù)控制到刪除數(shù)據(jù)之前節(jié)點的狀態(tài)!
mysql> show binary logs; ##查看具體binlog文件,也可以用‘show master logs;’來實現(xiàn)
+------------------+-----------+
| Log_name| File_size |
+------------------+-----------+
| mysql-bin.000001 |2160 |
| mysql-bin.000002 |43064 |
| mysql-bin.000003 |3909 |
| mysql-bin.000004 |143 |
| mysql-bin.000005 |143 |
| mysql-bin.000006 |2244 |
+------------------+-----------+
mysql> show binlog events; ##查新第一個binlog里的內容,很多,不截取了!
mysql> show binlog events in 'mysql-bin.000006'; ##查詢指定binlog文件‘mysql-bin.000006’的內容,注意單引號!
mysql> show master status; ##查看當前正在寫的binlog以及位置position
以上是查找binlog相關的指令。
倘若我們已經(jīng)找到了對應binlog中的事務節(jié)點。如下:
mysql> show binlog events in 'mysql-bin.000007';
+------------------+-----+-------------+-----------+-------------+------------------------------------------------------+
| Log_name| Pos | Event_type| Server_id | End_log_pos | Info|
+------------------+-----+-------------+-----------+-------------+------------------------------------------------------+
| mysql-bin.000007 |4 | Format_desc |2 |120 | Server ver: 5.6.41-log, Binlog ver: 4|
| mysql-bin.000007 | 120 | Query|2 |195 | BEGIN|
| mysql-bin.000007 | 195 | Query|2 |294 | use `RW`; insert into T values(2,3,4,5)|
| mysql-bin.000007 | 294 | Xid|2 |325 | COMMIT /* xid=25479 */|
| mysql-bin.000007 | 325 | Query|2 |400 | BEGIN|
| mysql-bin.000007 | 400 | Query|2 |512 | use `RW`; insert into account00 values (23,45,67,89) |
| mysql-bin.000007 | 512 | Xid|2 |543 | COMMIT /* xid=25530 */|
| mysql-bin.000007 | 543 | Query|2 |618 | BEGIN|
| mysql-bin.000007 | 618 | Query|2 |722 | use `RW`; insert into T values (23,45,6,789)|
| mysql-bin.000007 | 722 | Xid|2 |753 | COMMIT /* xid=25532 */|
| mysql-bin.000007 | 753 | Query|2 |828 | BEGIN|
| mysql-bin.000007 | 828 | Query|2 |911 | use `RW`; delete from T|
| mysql-bin.000007 | 911 | Xid|2 |942 | COMMIT /* xid=25536 */|
| mysql-bin.000007 | 942 | Rotate|2 |989 | mysql-bin.000008;pos=4|
+------------------+-----+-------------+-----------+-------------+------------------------------------------------------+
這里看到,我們在828position開始的事務中刪除了T表,那么恢復的節(jié)點就是從上次全備到753的position位置。
指令如下:
[root@VM-75-68 lib]# /usr/local/mysql/bin/mysqlbinlog --no-defaults --start-position=325 --stop-position=753 --database=RW /var/lib/mysql/mysql-bin.000007 | mysql -uroot -p51..dmz
這里的‘--no-defaults’參數(shù)是用來規(guī)避如下報錯的:
/usr/local/mysql/bin/mysqlbinlog: unknown variable 'default-character-set=utf8'
mysqlbinlog二進制在mysql的編譯目錄的bin下,這里要使用絕對路徑。
注意這里的--stop-position的位置不能是722,753才是這個事務提交的節(jié)點!
一般線上的二進制日志都比較大,這里具體二進制的內容可以使用如下命令讀取到本地文件中:
[root@VM-75-68 lib]# mysql -uroot -p51..dmz -e "show binlog events in 'mysql-bin.000007';" > 007
這樣就方便查找對應的時間或操作節(jié)點了!
由于線上的binlog很大,很多時候我們需要知道誤操作的大致時間點,這樣才能更快的幫助我們定位刪除操作所在的position,也就能盡快的定位需要回復的position!
但是通過:
‘show binlog events in 'mysql-bin.000007';’的輸出看不到關于時間的信息,因此往往還需要我們把二進制日志通過下面的方式讀取下來:
[root@VM-75-68 mysql]# /usr/local/mysql/bin/mysqlbinlog --no-defaults /var/lib/mysql/mysql-bin.000007 -r test.sql
‘-r’表示輸出的文件名,此時我們看下test.sql的內容:
[root@VM-75-68 mysql]# cat test.sql
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#1909121:07:05 server id 2end_log_pos 120 CRC32 0xe569da34Start: binlog v 4, server v 5.6.41-log created 1909121:07:05
BINLOG '
uSl5XQ8CAAAAdAAAAHgAAAAAAAQANS42LjQxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAATTa
aeU=
'/*!*/;
# at 120
#1909121:18:17 server id 2end_log_pos 195 CRC32 0xcd2d1809Querythread_id=16exec_time=0error_code=0
SET TIMESTAMP=1568222297/*!*/;
SET @@session.pseudo_thread_id=16/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 195
#1909121:18:17 server id 2end_log_pos 294 CRC32 0x60c0bec1Querythread_id=16exec_time=0error_code=0
use `RW`/*!*/;
SET TIMESTAMP=1568222297/*!*/;
insert into T values(2,3,4,5)
/*!*/;
# at 294
#1909121:18:17 server id 2end_log_pos 325 CRC32 0x0f140a49Xid = 25479
COMMIT/*!*/;
# at 325
#1909121:20:59 server id 2end_log_pos 400 CRC32 0x93250026Querythread_id=16exec_time=0error_code=0
SET TIMESTAMP=1568222459/*!*/;
BEGIN
/*!*/;
# at 400
#1909121:20:59 server id 2end_log_pos 512 CRC32 0x17df84f4Querythread_id=16exec_time=0error_code=0
SET TIMESTAMP=1568222459/*!*/;
insert into account00 values (23,45,67,89)
/*!*/;
# at 512
#1909121:20:59 server id 2end_log_pos 543 CRC32 0xa6ed016eXid = 25530
COMMIT/*!*/;
# at 543
#1909121:21:28 server id 2end_log_pos 618 CRC32 0x618edf7eQuerythread_id=16exec_time=0error_code=0
SET TIMESTAMP=1568222488/*!*/;
BEGIN
/*!*/;
# at 618
#1909121:21:28 server id 2end_log_pos 722 CRC32 0xc2bc15a5Querythread_id=16exec_time=0error_code=0
SET TIMESTAMP=1568222488/*!*/;
insert into T values (23,45,6,789)
/*!*/;
# at 722
#1909121:21:28 server id 2end_log_pos 753 CRC32 0x70421b22Xid = 25532
COMMIT/*!*/;
# at 753
#1909121:21:53 server id 2end_log_pos 828 CRC32 0x9667e2a6Querythread_id=16exec_time=0error_code=0
SET TIMESTAMP=1568222513/*!*/;
BEGIN
/*!*/;
# at 828
#1909121:21:53 server id 2end_log_pos 911 CRC32 0x92b49dfeQuerythread_id=16exec_time=0error_code=0
SET TIMESTAMP=1568222513/*!*/;
delete from T
/*!*/;
# at 911
#1909121:21:53 server id 2end_log_pos 942 CRC32 0x3753a272Xid = 25536
COMMIT/*!*/;
# at 942
#1909121:22:02 server id 2end_log_pos 989 CRC32 0x4d526bbeRotate to mysql-bin.000008pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
這里看起來似乎很雜亂無章,但是仔細看你會發(fā)現(xiàn)都是有規(guī)律的,我們單獨拿一個事務出來分析:
BEGIN ##表示開始事務
/*!*/;
# at 400 ##開始的position
#1909121:20:59 server id 2end_log_pos 512 CRC32 0x17df84f4Querythread_id=16exec_time=0error_code=0
SET TIMESTAMP=1568222459/*!*/;
insert into account00 values (23,45,67,89) ##執(zhí)行的操作
/*!*/;
# at 512 ##操作結束的position
#1909121:20:59 server id 2end_log_pos 543 CRC32 0xa6ed016eXid = 25530
COMMIT/*!*/;
# at 543 ##提交的position
因此,我們指定的stop-position一定要是commit之后的position,也就是這里的543!也就對應mysql界面的:
mysql-bin.000007512Xid2543COMMIT /* xid=25530 */
這行的543位置的操作!
注意,在執(zhí)行了誤刪除之后,在盡快的時間內執(zhí)行‘flush logs;’這條指令會刷新binlog,也就是重新生成一個binlog文件,這樣保證需要恢復的數(shù)據(jù)都存儲在一個固定的binlog中,新的binlog會寫入新的binlog中。
并且binlog的顯示時間也很有意思,你在執(zhí)行flush logs;的時候,生產(chǎn)新log的同時,截止到當前時間的上一個binlog的修改時間也會同步過來,因此,更方便我們查找某個時間段對應的binlog!
以上就是使用binlog恢復數(shù)據(jù)的一些操作,共勉!
總結
以上是生活随笔為你收集整理的使用binlog恢复数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java代码中StringUtils.i
- 下一篇: estemplate 导入MySQL_[