【Mysql】从binlog中找出单个表的binlog信息
发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,无聊研究binlog写了个提取单个表的binlog 的信息,便于误删恢复数据,这样做的目的是为了减少恢复时其他表可能引起的出错,以及缩短恢复时间首先研究binlog日志的格式如下:/*!50530 S
千家信息网最后更新 2025年01月31日【Mysql】从binlog中找出单个表的binlog信息无聊研究binlog写了个提取单个表的binlog 的信息,便于误删恢复数据,这样做的目的是为了减少恢复时其他表可能引起的出错,以及缩短恢复时间
首先研究binlog日志的格式
测试:
mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)
[root@localhost chenliang]# mysql -uroot -p`cat /etc/sqlpass ` TENNIS
[root@localhost chenliang]# sh v1.sh --binlog=mysqlbin.000019 --database=TENNIS --table=TEAMS ---提前单表的binlog 信息
[root@localhost chenliang]# mysql -uroot -p`cat /etc/sqlpass ` TENNIS
检查
mysql> select * from TEAMS;
+--------+----------+----------+
| TEAMNO | PLAYERNO | DIVISION |
+--------+----------+----------+
| 1 | 6 | first |
| 2 | 27 | second |
| 3 | 89 | asd |
| 4 | 89 | BBBB |
| 5 | 89 | DDDD |
| 6 | 67 | GGGG |
| 7 | 77 | KKKK |
| 8 | 77 | uuuuuu |
| 9 | 77 | iiiiii |
| 10 | 77 | oooo |
+--------+----------+----------+
成功
TIP:脚本有点小bug,就是有时vcommit0 第一个begin commit可能记录的是别的表的信息而导致恢复时报错,那么就手工替换这部分的为第一个我们目标表的binlog信息再执行
首先研究binlog日志的格式
- 如下:
- /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#160229 15:19:52 server id 162 end_log_pos 123 CRC32 0xbbe9b551 Start: binlog v 4, server v 5.7.9-log created 160229 15:19:52 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
GPHTVg+iAAAAdwAAAHsAAAABAAQANS43LjktbG9nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAY8dNWEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AVG16bs=
'/*!*/;
# at 123
#160229 15:19:52 server id 162 end_log_pos 154 CRC32 0xd473f6f4 Previous-GTIDs
# [empty]
# at 154
#160229 15:18:07 server id 162 end_log_pos 219 CRC32 0xe86bb499 Anonymous_GTID last_committed=0 sequence_number=1
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#160229 15:18:07 server id 162 end_log_pos 291 CRC32 0xe1803afe Query thread_id=102887 exec_time=341 error_code=0
SET TIMESTAMP=1456730287/*!*/;
SET @@session.pseudo_thread_id=102887/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=524288/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 291
#160229 15:18:07 server id 162 end_log_pos 343 CRC32 0xcfc435f2 Table_map: `test`.`ty` mapped to number 127
# at 343
#160229 15:18:07 server id 162 end_log_pos 463 CRC32 0xb4ef18fe Write_rows: table id 127 flags: STMT_END_F
BINLOG '
r/DTVhOiAAAANAAAAFcBAAAAAH8AAAAAAAEABHRlc3QAAnR5AAQDDw8DBBQAFAAP8jXEzw==
r/DTVh7iAAAAeAAAAM8BAAAAAH8AAAAAAAEAAgAE//AFAAAABEVFRUUCQzFfAAAA8AEAAAAEQUFB
QQJDMUMAAADwAwAAAARDQ0NDAkMxQwAAAPAEAAAABEREREQCQzFBAAAA8AIAAAAEQkJCQgJDMTcA
AAD+GO+0
'/*!*/;
# at 463
#160229 15:18:07 server id 162 end_log_pos 494 CRC32 0xed1fb95b Xid = 53
COMMIT/*!*/; -------到第一个commit为第一部分 为binlog必须的,缺失会报错
# at 494
#160229 15:18:07 server id 162 end_log_pos 559 CRC32 0xef3ac14c Anonymous_GTID last_committed=1 sequence_number=2
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 559
#160229 15:18:07 server id 162 end_log_pos 631 CRC32 0xe834f1d8 Query thread_id=102887 exec_time=350 error_code=0
SET TIMESTAMP=1456730287/*!*/;
BEGIN
/*!*/;
# at 631
#160229 15:18:07 server id 162 end_log_pos 683 CRC32 0xc64ac724 Table_map: `test`.`ty` mapped to number 127
# at 683
#160229 15:18:07 server id 162 end_log_pos 803 CRC32 0x4a5f1c75 Write_rows: table id 127 flags: STMT_END_F
BINLOG '
r/DTVhOiAAAANAAAAKsCAAAAAH8AAAAAAAEABHRlc3QAAnR5AAQDDw8DBBQAFAAPJMdKxg==
r/DTVh7iAAAAeAAAACMDAAAAAH8AAAAAAAEAAgAE//AFAAAABEVFRUUCQzFfAAAA8AEAAAAEQUFB
QQJDMUMAAADwAwAAAARDQ0NDAkMxQwAAAPAEAAAABEREREQCQzFBAAAA8AIAAAAEQkJCQgJDMTcA
AAB1HF9K
'/*!*/;
# at 803
#160229 15:18:07 server id 162 end_log_pos 834 CRC32 0x96148022 Xid = 77
COMMIT/*!*/; ------到下一个commit为第二部分,一个事物语句,可以缺失
# at 834
#160229 15:18:07 server id 162 end_log_pos 899 CRC32 0xa1e52982 Anonymous_GTID last_committed=2 sequence_number=3
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 899
#160229 15:18:07 server id 162 end_log_pos 971 CRC32 0x89fc0e48 Query thread_id=102887 exec_time=359 error_code=0
SET TIMESTAMP=1456730287/*!*/;
BEGIN
/*!*/;
# at 971
#160229 15:18:07 server id 162 end_log_pos 1023 CRC32 0xc1309696 Table_map: `test`.`ty` mapped to number 127
# at 1023
#160229 15:18:07 server id 162 end_log_pos 1143 CRC32 0x0993d08b Write_rows: table id 127 flags: STMT_END_F
BINLOG '
r/DTVhOiAAAANAAAAP8DAAAAAH8AAAAAAAEABHRlc3QAAnR5AAQDDw8DBBQAFAAPlpYwwQ==
r/DTVh7iAAAAeAAAAHcEAAAAAH8AAAAAAAEAAgAE//AFAAAABEVFRUUCQzFfAAAA8AEAAAAEQUFB
QQJDMUMAAADwAwAAAARDQ0NDAkMxQwAAAPAEAAAABEREREQCQzFBAAAA8AIAAAAEQkJCQgJDMTcA
AACL0JMJ
'/*!*/;
# at 1143
#160229 15:18:07 server id 162 end_log_pos 1174 CRC32 0x7c2054fd Xid = 101
。。。。。省略
COMMIT/*!*/; -------最后一个commit到最后必须存在
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
- 代码如下:
- [root@localhost chenliang]# more v1.sh
#!/bin/bash
# author:Jonnychen
# date:2016-3-1
# set -x
# get the key value of input
get_key_value()
{
echo "$1" | sed 's/^--[A-Za-z_-]*=//'
}
use_help()
{
cat << EOF
Info :
Author:Michael.xu
Usage :
Usage : $0 [configure-options]
-? , --help
--binlog=<> , set binlogfile
--database=<> , set database
--table=<>,set table
EOF
}
parse_options()
{
while [ $# -gt 0 ]
do
case "$1" in
--binlog=*)
vbinlog=`get_key_value "$1"`;;
--database=*)
vdatabase=`get_key_value "$1"`;;
--table=*)
vtable=`get_key_value "$1"`;;
-? | --help)
use_help
exit 0;;
*)
echo "unknown configure option '$1'"
exit 1;;
esac
shift
done
}
parse_options "$@"
echo "$vbinlog,$vdatabase,$vtable"
if [ ! -n "$vbinlog" ];then
use_help
exit
fi
if [ ! -n "$vdatabase" ];then
use_help
exit
fi
if [ ! -n "$vtable" ];then
use_help
exit
fi
#####binlog日志格式化为txt文件
mysqlbinlog_dir=`which mysqlbinlog`
${mysqlbinlog_dir} ${vbinlog}>${vbinlog}.txt
filename=${vbinlog}.txt
#####txt日志文件按照commit字段进行切割
csplit $filename /COMMIT\/*\// -n 1 -s {*} -f vcommit
cou_comm=`ls -l | grep vcommit|awk -F " " '{print $9}'|wc -l`
let "maxseq=${cou_comm}-1"
#echo $maxseq
let "sec_max=$maxseq-1"
#echo ${sec_max}
cat vcommit0>>${vbinlog}.sql #####提取第一部分
for((i=1;i<=${sec_max};i++))
do
hastab=$(grep "\`${vdatabase}\`.\`${vtable}\`" vcommit$i|wc -l ) ---循环从每个分割部分去找出单个表的信息
echo "vcommit$i:$hastab"
if [ $hastab -ge 1 ]
then
cat vcommit$i>>${vbinlog}.sql
fi
done
cat vcommit$maxseq>>${vbinlog}.sql ###提取最后一部分
rm -rf $filename vcommit*
测试:
- 1:mysql> select * from TEAMS; 原始数据
- +--------+----------+----------+
| TEAMNO | PLAYERNO | DIVISION |
+--------+----------+----------+
| 1 | 6 | first |
| 2 | 27 | second |
| 3 | 89 | asd |
| 4 | 89 | BBBB |
| 5 | 89 | DDDD |
| 6 | 67 | GGGG |
| 7 | 77 | KKKK | - 模拟此时做了个备份
- mysqldump -uroot -p`cat /etc/sqlpass ` -F TENNIS>TENNIS.sql --此时binlog到了19
- 模拟做些操作
- mysql> insert into TEAMS values(8,77,'uuuuuu');
Query OK, 1 row affected (0.00 sec)
mysql> insert into TEAMS values(9,77,'iiiiii');
Query OK, 1 row affected (0.00 sec) - mysql> insert into TEAMS values(10,77,'oooo');
Query OK, 1 row affected (0.01 sec)
mysql> update TEAMS set DIVISION='pppp' where TEAMNO in(9,10); ---误操作
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)
[root@localhost chenliang]# mysql -uroot -p`cat /etc/sqlpass ` TENNIS
[root@localhost chenliang]# sh v1.sh --binlog=mysqlbin.000019 --database=TENNIS --table=TEAMS ---提前单表的binlog 信息
点击(此处)折叠或打开
- 查看提取出来的信息,删除update那部分即可
- COMMIT/*!*/;
# at 704
#160301 13:55:35 server id 162 end_log_pos 769 CRC32 0x0593de75 Anonymous_GTID last_committed=2 sequence_number=3
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 769
#160301 13:55:35 server id 162 end_log_pos 843 CRC32 0x2978f290 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1456811735/*!*/;
BEGIN
/*!*/;
# at 843
#160301 13:55:35 server id 162 end_log_pos 897 CRC32 0xe52bc252 Table_map: `TENNIS`.`TEAMS` mapped to number 134
# at 897
#160301 13:55:35 server id 162 end_log_pos 946 CRC32 0x7331e254 Update_rows: table id 134 flags: STMT_END_F
BINLOG '
1y7VVhOiAAAANgAAAIEDAAAAAIYAAAAAAAEABlRFTk5JUwAFVEVBTVMAAwMD/gL+EgBSwivl
1y7VVh7iAAAAMQAAALIDAAAAAIYAAAAAAAEAAgAD//gKAAAATQAAAARvb29vVOIxcw==
'/*!*/;
# at 946
#160301 13:55:35 server id 162 end_log_pos 977 CRC32 0x7da650c4 Xid = 271
COMMIT/*!*/; ----从sql中将update的binlog信息删除即可
[root@localhost chenliang]# mysql -uroot -p`cat /etc/sqlpass ` TENNIS
检查
mysql> select * from TEAMS;
+--------+----------+----------+
| TEAMNO | PLAYERNO | DIVISION |
+--------+----------+----------+
| 1 | 6 | first |
| 2 | 27 | second |
| 3 | 89 | asd |
| 4 | 89 | BBBB |
| 5 | 89 | DDDD |
| 6 | 67 | GGGG |
| 7 | 77 | KKKK |
| 8 | 77 | uuuuuu |
| 9 | 77 | iiiiii |
| 10 | 77 | oooo |
+--------+----------+----------+
成功
TIP:脚本有点小bug,就是有时vcommit0 第一个begin commit可能记录的是别的表的信息而导致恢复时报错,那么就手工替换这部分的为第一个我们目标表的binlog信息再执行
信息
文件
日志
单个
格式
第一部
备份
就是
数据
缺失
部分
研究
原始
成功
无聊
中将
事物
代码
命令
字段
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
流媒体服务器软件多少钱
网络安全主动攻击视频
网络安全顺口溜30字
网络安全为主题手抄报图片
旗祥网络技术有限公司
网络技术与行政管理
生物数据库分为哪几级
信息网络安全中数据安全是
软件开发 kpi考核
mysql数据库工资
上海吾牛互联网科技丁卫莉
如何打开电脑的服务器管理在哪
每次亮屏都是无法连接服务器
美记软件开发者
石门软件开发专业学校
北京质量软件开发设施参考价格
学校网络安全和宣传工作总结
暑期网络技术培训
服务器怎么获得人物信息
移动宽带游戏服务器
江苏软件开发技术服务公司
长沙物流软件开发教程
sql数据库刷新失败
未来之役服务器怎么改回原来的
网络公司网络服务器型号
达梦数据库登入后不显示模式
网络安全的应用有哪些
分享家网络技术有限公司
济南商中网络技术
武侠q传v19星耀版服务器