binlog2sql数据恢复常见错误处理
1. binlog2sql数据恢复
- 1. binlog2sql数据恢复
- 1.1. 安装binlog2sql报错总结
- 1.1.1. 常见报错:pymysql.err.OperationalError: (1045, u'Unknown error 1045')
- 1.1.2. 常见报错:ValueError: parameter error: start_file /opt/mysql-bin.000007 not in mysql server
- 1.1.3. 常见报错:AttributeError: exit
- 1.1.4. 常见报错:binlog2sql.py: error: argument -p/--password: expected one argument
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 报错解决方法
- pymysql.err.InternalError: (1236, u"Cannot replicate GTID-transaction when @@GLOBAL.GTID_MODE = OFF, at file ./testdb1-bin.000001, position 234.; the first event 'testdb1-bin.000001' at 4, the last event read from './testdb1-
- 1.2. binlog-rollback.pl工具介绍
- 问题二:python 连接 mysql 数据库出现 keyerror: 255
- 问题三:ModuleNotFoundError: No module named 'pymysql.util'
- 问题四:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 39: invalid start byte
- null
- 闪回sql中文乱码问题:
- 1.1. 安装binlog2sql报错总结
不管你什么架构,一切都是为数据服务的,数据是一个企业最核心的价值。不过出现问题的话,数据一旦被删除,每过一秒,都将对企业造成巨大的损失。最近,还真的发生了一起删库跑路事件。



1.1. 安装binlog2sql报错总结
1.1.1. 常见报错:pymysql.err.OperationalError: (1045, u'Unknown error 1045')

解决:不能用root用户,改成普通用户就可以了
1.1.2. 常见报错:ValueError: parameter error: start_file /opt/mysql-bin.000007 not in mysql server

解决:复制mysql-binlog.index和对应的binlog到测试环境数据库,注意测试环境数据库binlog要指定到生产环境复制过来的binlog位置
比如测试库里面的binglog文件为
[root@centos7 binary]# ll
mybinlog.000029
mybinlog.000030
mybinlog.000031
[root@centos7 binary]# cat mybinlog.index
/data/mysql/logs3307/binary/mybinlog.000029
/data/mysql/logs3307/binary/mybinlog.000030
/data/mysql/logs3307/binary/mybinlog.000031
将生产环境的binglog传到当前目录下,并将名称改为当前binglog中的一个,不要改最新的binglog,
比如
mv mybinlog.000029 mybinlog.000029_bak
mv 生产的binglig mybinlog.000029
并且要创建服务器上一样的表结构和数据库
create database crushzhengqi;
create table sys_staff;
然后执行分析
/opt/dbtools/python /opt/dbtools/binlog2sql/binlog2sql.py -h127.0.0.1 -P3307 -uroot -p'root' -dcrushzhengqi -t sys_staff --start-file='mybinlog.000029' > old2.sql
1.1.3. 常见报错:AttributeError: exit

解决:binlog2sql文件有问题
1.1.4. 常见报错:binlog2sql.py: error: argument -p/--password: expected one argument

解决:在-p参数后加上密码
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 报错解决方法
.py文件中添加如下内容
import sys
defaultencoding = 'utf-8'
if sys.getdefaultencoding() != defaultencoding:
reload(sys)
sys.setdefaultencoding(defaultencoding)
pymysql.err.InternalError: (1236, u"Cannot replicate GTID-transaction when @@GLOBAL.GTID_MODE = OFF, at file ./testdb1-bin.000001, position 234.; the first event 'testdb1-bin.000001' at 4, the last event read from './testdb1-
解决办法:
set @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
解析完之后,记得把GTID_MOD 关掉
set @@GLOBAL.GTID_MODE = OFF;
1.2. binlog-rollback.pl工具介绍
基于row模式的binlog,生成DML(insert/update/delete)的rollback语句
操作流程
#通过mysqlbinlog -v 解析binlog生成可读的sql文件
#提取需要处理的有效sql
#"### "开头的行.如果输入的start-position位于某个event group中间,则会导致"无法识别event"错误
#将INSERT/UPDATE/DELETE 的sql反转,并且1个完整sql只能占1行
#INSERT: INSERT INTO => DELETE FROM, SET => WHERE
#UPDATE: WHERE => SET, SET => WHERE
#DELETE: DELETE FROM => INSERT INTO, WHERE => SET
#用列名替换位置@{1,2,3}
#通过desc table获得列顺序及对应的列名
#特殊列类型value做特别处理
#逆序
注意事项:
#表结构与现在的表结构必须相同[谨记]
#由于row模式是幂等的,并且恢复是一次性,所以只提取sql,不提取BEGIN/COMMIT
#只能对INSERT/UPDATE/DELETE进行处理
#线上误操作后,一定要立刻对操作的表进行加锁,避免其他数据继续写入
1.2.1. binlog格式介绍
MYSQL binlog复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED。
① STATEMENT模式(SBR)
每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
② ROW模式(RBR)
不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table的时候会让日志暴涨。
③ MIXED模式(MBR)
以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。
1.2.2. binlog格式
一个完整的binlog文件是由一个format description event开头,一个rotate event结尾,中间由多个其他event组合而成。

每个event都是由event header 和event data组成。下面简单介绍下几种常见的binlog event。
① formart description event

表达的含义是:
170905 01:59:33 server id 10 end_log_pos 123 CRC32 0xed1ec563
Start: binlog v 4, server v 5.7.18-log created 170905 01:59:33
② table map event
问题二:python 连接 mysql 数据库出现 keyerror: 255
Traceback (most recent call last):
File "E:\IdeaProjects\binlog2sql\binlog2sql\binlog2sql.py", line 145, in <module>
binlog2sql = Binlog2sql(connection_settings=conn_setting, start_file=args.start_file, start_pos=args.start_pos,
File "E:\IdeaProjects\binlog2sql\binlog2sql\binlog2sql.py", line 46, in __init__
self.connection = pymysql.connect(**self.conn_setting)
File "E:\Program Files\PYTHON3.9.5\lib\site-packages\pymysql\__init__.py", line 90, in Connect
return Connection(*args, **kwargs)
File "E:\Program Files\PYTHON3.9.5\lib\site-packages\pymysql\connections.py", line 706, in __init__
self.connect()
File "E:\Program Files\PYTHON3.9.5\lib\site-packages\pymysql\connections.py", line 931, in connect
self._get_server_information()
File "E:\Program Files\PYTHON3.9.5\lib\site-packages\pymysql\connections.py", line 1269, in _get_server_information
self.server_charset = charset_by_id(lang).name
File "E:\Program Files\PYTHON3.9.5\lib\site-packages\pymysql\charset.py", line 38, in by_id
return self._by_id[id]
KeyError: 255
该问题主要原因是MySQL8.0更新了很多字符集,但是这些字符集长度超过255了,所以旧版的PyMySQL不支持长度超过255的字符。解决方法是更新该工具包:
pip install --upgrade PyMySQL
问题三:ModuleNotFoundError: No module named 'pymysql.util'
这是因为没有'pymysql ,这里我们防止本地有包冲突,所以先卸载再安装:
PS E:\Program Files (x86)\mysql-8.0.23-winx64\data> pip uninstall pymsql
WARNING: Skipping pymsql as it is not installed.
PS E:\Program Files (x86)\mysql-8.0.23-winx64\data> pip install pymysql==0.9.3
Collecting pymysql==0.9.3
Downloading PyMySQL-0.9.3-py2.py3-none-any.whl (47 kB)
---------------------------------------- 47.7/47.7 KB 480.7 kB/s eta 0:00:00
Installing collected packages: pymysql
Attempting uninstall: pymysql
Found existing installation: PyMySQL 1.0.2
Uninstalling PyMySQL-1.0.2:
Successfully uninstalled PyMySQL-1.0.2
Successfully installed pymysql-0.9.3
问题四:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 39: invalid start byte
E:\Program Files\PYTHON3.9.5\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 1")
result = self._query(query)
Traceback (most recent call last):
File "E:\IdeaProjects\binlog2sql\binlog2sql\binlog2sql.py", line 150, in <module>
binlog2sql.process_binlog()
File "E:\IdeaProjects\binlog2sql\binlog2sql\binlog2sql.py", line 121, in process_binlog
self.print_rollback_sql(filename=tmp_file)
File "E:\IdeaProjects\binlog2sql\binlog2sql\binlog2sql.py", line 129, in print_rollback_sql
for line in reversed_lines(f_tmp):
File "E:\IdeaProjects\binlog2sql\binlog2sql\binlog2sql_util.py", line 249, in reversed_lines
block = block.decode("utf-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 39: invalid start byte
根据报错信息可以知道,这个跟binlog2sql工具里的binlog2sql.py代码有关,网上有好几种解决方案,这里贴一种我使用没问题的方案:即修改binlog2sql源码中的binlog2sql_util.py指定字符编码的代码(注意有好几行都涉及到编码,但是我们不用全修改,仔细对照下图,千万别改错了),修改的内容如下图:
vim binlog2sql_util.py

闪回sql中文乱码问题:
用binlog2sql时,解析出原sql时,sql中的中文正常显示,编码格式也正常
但是解析成回滚sql的时候,中文显示为乱码
经过测试该问题出现在mysql8.0的版本中,
建议回滚sql使用my2sql工具解析,性能更好

浙公网安备 33010602011771号