dothetrick / binlogportal

mysql binlog同步工具
130 stars 58 forks source link

项目启动后会报 java.net.SocketException: Connection reset #10

Open lipeishen opened 2 years ago

lipeishen commented 2 years ago

Failed to deserialize data of EventHeaderV4{timestamp=1650557453000, eventType=TABLE_MAP, serverId=2, headerLength=19, dataLength=62, nextPosition=86626369, flags=0}.mysql-bin.000001/86626288 com.github.shyiko.mysql.binlog.event.deserialization.EventDataDeserializationException: Failed to deserialize data of EventHeaderV4{timestamp=1650557453000, eventType=TABLE_MAP, serverId=2, headerLength=19, dataLength=62, nextPosition=86626369, flags=0} at com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer.deserializeEventData(EventDeserializer.java:300) at com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer.deserializeTableMapEventData(EventDeserializer.java:272) at com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer.nextEvent(EventDeserializer.java:219) at com.github.shyiko.mysql.binlog.BinaryLogClient.listenForEventPackets(BinaryLogClient.java:984) at com.github.shyiko.mysql.binlog.BinaryLogClient.connectWithTimeout(BinaryLogClient.java:517) at com.github.shyiko.mysql.binlog.BinaryLogClient.connect(BinaryLogClient.java:490) at com.insistingon.binlogportal.distributed.RedisDistributedHandler$1.lambda$run$0(RedisDistributedHandler.java:61) at java.util.HashMap.forEach(HashMap.java:1289) at com.insistingon.binlogportal.distributed.RedisDistributedHandler$1.run(RedisDistributedHandler.java:56) at java.util.TimerThread.mainLoop(Timer.java:555) at java.util.TimerThread.run(Timer.java:505) Caused by: java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:210) at java.net.SocketInputStream.read(SocketInputStream.java:141) at com.github.shyiko.mysql.binlog.io.BufferedSocketInputStream.read(BufferedSocketInputStream.java:51) at com.github.shyiko.mysql.binlog.io.ByteArrayInputStream.readWithinBlockBoundaries(ByteArrayInputStream.java:202) at com.github.shyiko.mysql.binlog.io.ByteArrayInputStream.read(ByteArrayInputStream.java:184) at com.github.shyiko.mysql.binlog.io.ByteArrayInputStream.readZeroTerminatedString(ByteArrayInputStream.java:81) at com.github.shyiko.mysql.binlog.event.deserialization.TableMapEventDataDeserializer.deserialize(TableMapEventDataDeserializer.java:36) at com.github.shyiko.mysql.binlog.event.deserialization.TableMapEventDataDeserializer.deserialize(TableMapEventDataDeserializer.java:27) at com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer.deserializeEventData(EventDeserializer.java:294) ... 10 common frames omitted

dothetrick commented 2 years ago

这个问题先确认下: 1.mysql的版本是多少? 2.binlog 记录的格式是不是 row 类型的

lipeishen commented 2 years ago

image image

lipeishen commented 2 years ago

最近报错挺多的,一般都是运行一天之后,binlog 应该是切换到下一个文件时候无法正常切换。 image

dothetrick commented 2 years ago

这类问题一般是mysql服务端对binlog操作有问题导致的,可以从下面几点排查下:

  1. master端mysql服务是不是用了类似于 “reset master” 这类的命令清理binlog,这个命令不会发出rotate事件,无法正常替换binlog文件

  2. 确认下上一个binlog文件,是否在产生新的binlog文件时,正常的记录了rotate。比如现在最新的文件是mysql-bin.000004,那么上一个binlog文件是mysql-bin.000003,这个binlog文件结尾是会有一个rotate事件的。接到这个事件程序中才会替换新binlog文件。

截屏2022-04-30 下午3 58 14

  1. 还有一种情况,你连接的数据库是直接连的master的ip么,还是一个代理的域名或者ip,这种需要确认是否是代理后面触发了mysql的主从切换,这种也会有问题,主从的机器上,binlog文件名和position可能是不同的。
lipeishen commented 2 years ago
  1. binlog 清理设置的自动清理 expire_logs_days =30,没有手动 reset master 过。

  2. 看着 binlog 末尾有 rotate 事件 image

  3. 现在的数据库是直接连接开发机的 master 上的 IP,未来线上环境可能会有代理地址

很是奇怪,搜遍了很多资料,也没找到问题在什么地方。

dothetrick commented 2 years ago

有rotate事件,可以看下是不是有更新redis的错误,位点是保存在redis里面的, redis的key是:mysql域名 + ":" + 端口。

还可以看下mysql实例是不是重启过。

直接使用 flush logs 生成新的binlog文件,程序会报错么?

PeifengZhang commented 2 years ago

Connection reset的问题应该是使用mysql-binlog-connector-java读取binlog的时候,服务端因为某些原因关闭了连接,客户端还在读取数据导致的,网上说可以考虑用重试去解决,但是也没有mysql-binlog-connector-java的源码,不知道怎么处理。 另外还有几个问题想请教下作者:

  1. mysql实例上所有库的binlog都会放到一起,如何仅做库级别维度的同步呢?
  2. 目前的分布式方式是通过分布式锁来实现的,读取log还是单线程,测试发现1S内写入1500条数据,读取binlog耗时3S-5S,是什么原因呢,有没有办法提升性能
PeifengZhang commented 2 years ago

运行一段时间之后报错:,Client requested master to start replication from position > file size.mysql-bin.106094/2917571713

dothetrick commented 2 years ago

Connection reset的问题应该是使用mysql-binlog-connector-java读取binlog的时候,服务端因为某些原因关闭了连接,客户端还在读取数据导致的,网上说可以考虑用重试去解决,但是也没有mysql-binlog-connector-java的源码,不知道怎么处理。 另外还有几个问题想请教下作者:

  1. mysql实例上所有库的binlog都会放到一起,如何仅做库级别维度的同步呢?
  2. 目前的分布式方式是通过分布式锁来实现的,读取log还是单线程,测试发现1S内写入1500条数据,读取binlog耗时3S-5S,是什么原因呢,有没有办法提升性能

1.按库只能根据返回值在处理逻辑里过滤,因为mysql的binlog写入是按实例的,同步的实际就是binlog文件的内容。或者可以在msyql server端指定哪些库要写binlog来实现。

2.模拟主从的时候,目前受mysql规范限制,只能是一个线程读取log,影响速度的主要是msyql server性能,网络环境。读取到内容后处理逻辑可以按库或表做多线程处理。

dothetrick commented 2 years ago

运行一段时间之后报错:,Client requested master to start replication from position > file size.mysql-bin.106094/2917571713

这个问题通常是因为,mysql server端的binlog文件重置了。模拟的线程使用redis之前保存的位点信息去增量读取binlog就会报错。 使用 binlog文件 + position 的方式同步就会有这个问题。

下个版本会支持用GTID的方式同步,可以避免这个问题。