MySQL Binlog 解析工具 Maxwell 详解 (7)

从 MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式。通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。

在原来基于二进制日志的复制中,从库需要告知主库要从哪个偏移量进行增量同步,如果指定错误会造成数据的遗漏,从而造成数据的不一致。借助GTID,在发生主备切换的情况下,MySQL的其它从库可以自动在新主库上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。

注意事项 timestamp column

maxwell对时间类型(datetime, timestamp, date)都是当做字符串处理的,这也是为了保证数据一致(比如0000-00-00 00:00:00这样的时间在timestamp里是非法的,但mysql却认,解析成java或者python类型就是null/None)。

如果MySQL表上的字段是 timestamp 类型,是有时区的概念,binlog解析出来的是标准UTC时间,但用户看到的是本地时间。比如 f_create_time timestamp 创建时间是北京时间 2018-01-05 21:01:01,那么mysql实际存储的是 2018-01-05 13:01:01,binlog里面也是这个时间字符串。如果不做消费者不做时区转换,会少8个小时。

与其每个客户端都要考虑这个问题,我觉得更合理的做法是提供时区参数,然后maxwell自动处理时区问题,否则要么客户端先需要知道哪些列是timestamp类型,或者连接上原库缓存上这些类型。

binary column

maxwell可以处理binary类型的列,如blob、varbinary,它的做法就是对二进制列使用 base64_encode,当做字符串输出到json。消费者拿到这个列数据后,不能直接拼装,需要 base64_decode。

表结构不同步

如果是拿比较老的binlog,放到新的mysql server上去用maxwell拉去,有可能表结构已经发生了变化,比如binlog里面字段比 schema_host 里面的字段多一个。目前这种情况没有发现异常,比如阿里RDS默认会为 无主键无唯一索引的表,增加一个__##alibaba_rds_rowid##__,在 show create table 和 schema 里面都看不到这个隐藏主键,但binlog里面会有,同步到从库。

另外我们有通过git去管理结构版本,如果真有这种场景,也可以应对。

大事务binlog

当一个事物产生的binlog量非常大的时候,比如迁移日表数据,maxwell为了控制内存使用,会自动将处理不过来的binlog放到文件系统

Using kafka version: 0.11.0.1 21:16:07,109 WARN MaxwellMetrics - Metrics will not be exposed: metricsReportingType not configured. 21:16:07,380 INFO SchemaStoreSchema - Creating maxwell database 21:16:07,540 INFO Maxwell - Maxwell v?? is booting (RabbitmqProducer), starting at Position[BinlogPosition[mysql-bin.006235:24980714], lastHeartbeat=0] 21:16:07,649 INFO AbstractSchemaStore - Maxwell is capturing initial schema 21:16:08,267 INFO BinlogConnectorReplicator - Setting initial binlog pos to: mysql-bin.006235:24980714 21:16:08,324 INFO BinaryLogClient - Connected to rm-xxxxxxxxxxx.mysql.rds.aliyuncs.com:3306 at mysql-bin.006235/24980714 (sid:637 9, cid:9182598) 21:16:08,325 INFO BinlogConnectorLifecycleListener - Binlog connected. 03:15:36,104 INFO ListWithDiskBuffer - Overflowed in-memory buffer, spilling over into /tmp/maxwell7935334910787514257events 03:17:14,880 INFO ListWithDiskBuffer - Overflowed in-memory buffer, spilling over into /tmp/maxwell3143086481692829045events

但是遇到另外一个问题,overflow随后就出现异常 EventDataDeserializationException: Failed to deserialize data of EventHeaderV4,当我另起一个maxwell指点之前的binlog postion开始解析,却有没有抛异常。事后的数据也表明并没有数据丢失。

问题产生的原因还不明,Caused by: java.net.SocketException: Connection reset,感觉像读取 binlog 流的时候还没读取到完整的event,异常关闭了连接。这个问题比较顽固,github上面类似问题都没有达到明确的解决。(这也从侧面告诉我们,大表数据迁移,也要批量进行,不要一个insert into .. select 搞定)

03:18:20,586 INFO ListWithDiskBuffer - Overflowed in-memory buffer, spilling over into /tmp/maxwell5229190074667071141events 03:19:31,289 WARN BinlogConnectorLifecycleListener - Communication failure. com.github.shyiko.mysql.binlog.event.deserialization.EventDataDeserializationException: Failed to deserialize data of EventHeaderV4{time stamp=1514920657000, eventType=WRITE_ROWS, serverId=2115082720, headerLength=19, dataLength=8155, nextPosition=520539918, flags=0} at com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer.deserializeEventData(EventDeserializer.java:216) ~[mys ql-binlog-connector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer.nextEvent(EventDeserializer.java:184) ~[mysql-binlog-c onnector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.BinaryLogClient.listenForEventPackets(BinaryLogClient.java:890) [mysql-binlog-connector-java-0 .13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.BinaryLogClient.connect(BinaryLogClient.java:559) [mysql-binlog-connector-java-0.13.0.jar:0.13 .0] at com.github.shyiko.mysql.binlog.BinaryLogClient$7.run(BinaryLogClient.java:793) [mysql-binlog-connector-java-0.13.0.jar:0.13.0 ] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121] Caused by: java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:210) ~[?:1.8.0_121] at java.net.SocketInputStream.read(SocketInputStream.java:141) ~[?:1.8.0_121] at com.github.shyiko.mysql.binlog.io.BufferedSocketInputStream.read(BufferedSocketInputStream.java:51) ~[mysql-binlog-connector- java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.io.ByteArrayInputStream.readWithinBlockBoundaries(ByteArrayInputStream.java:202) ~[mysql-binlo g-connector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.io.ByteArrayInputStream.read(ByteArrayInputStream.java:184) ~[mysql-binlog-connector-java-0.13 .0.jar:0.13.0] at com.github.shyiko.mysql.binlog.io.ByteArrayInputStream.readInteger(ByteArrayInputStream.java:46) ~[mysql-binlog-connector-jav a-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.event.deserialization.AbstractRowsEventDataDeserializer.deserializeLong(AbstractRowsEventDataD eserializer.java:212) ~[mysql-binlog-connector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.event.deserialization.AbstractRowsEventDataDeserializer.deserializeCell(AbstractRowsEventDataD eserializer.java:150) ~[mysql-binlog-connector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.event.deserialization.AbstractRowsEventDataDeserializer.deserializeRow(AbstractRowsEventDataDeserializer.java:132) ~[mysql-binlog-connector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.event.deserialization.WriteRowsEventDataDeserializer.deserializeRows(WriteRowsEventDataDeserializer.java:64) ~[mysql-binlog-connector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.event.deserialization.WriteRowsEventDataDeserializer.deserialize(WriteRowsEventDataDeserializer.java:56) ~[mysql-binlog-connector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.event.deserialization.WriteRowsEventDataDeserializer.deserialize(WriteRowsEventDataDeserializer.java:32) ~[mysql-binlog-connector-java-0.13.0.jar:0.13.0] at com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer.deserializeEventData(EventDeserializer.java:210) ~[mysql-binlog-connector-java-0.13.0.jar:0.13.0] ... 5 more 03:19:31,514 INFO BinlogConnectorLifecycleListener - Binlog disconnected. 03:19:31,590 WARN BinlogConnectorReplicator - replicator stopped at position: mysql-bin.006236:520531744 -- restarting 03:19:31,595 INFO BinaryLogClient - Connected to rm-xxxxxx.mysql.rds.aliyuncs.com:3306 at mysql-bin.006236/520531744 (sid:6379, cid:9220521) tableMapCache

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjggp.html