我手里维护了一个项目,其功能是用Java模拟一个MariaDB的slave库连接到主库,对从主库传输过来的binlog事件进行监听与分析

碰到一个问题是:

如果主库做了一个很大的修改操作(比方说直接delete了一个百万条数据的表),那么会产生一个很大的binlog事件,这个binlog事件会在我们的binlog监听器中被处理,然后组装成一个很大的对象(含有这100万条数据)

问题就出在这里,这个对象太大了(占用上g的heap毫不费力),然后我们在对这个对象的分析过程中,会产生更多的对象,而这些对象都是强引用,占用的是实打实的内存。于是就OOM了

我接受这个项目的时候,前人提出的方案很简单:禁止用户执行过大的操作。

很暴力的方案,而且确实也可以解决问题。

但是我觉得应该有更好的解决方法

第一反应是修改binlog监听器模块的代码

由于binlog事件是通过网络传输,我们也许可以在接收binlog事件的时候,对监听到的超大binlog事件进行拆分,将其逐步拆分为多个等效的小binlog事件

但是这一块的代码风格很差,很难修改

于是在Google上搜了一下相关的关键词,发现有一个叫做binlog-row-event-max-size的神奇启动参数,其英文注释如下

The maximum size in bytes of a row-based binary log event. Should be a multiple of 256. Minimum 256, maximum 18446744073709547520.

似乎正好是我需要的?

但是很不幸,这个参数只在MariaDB 10.0.17之后有效

而公司的生产环境用的是MariaDB 10.0.10

对比一下两者的效果吧

MariaDB 10.0.10,delete一个百万元素的表

| Log_name            | Pos             | Event_type | Server_id | End_log_pos | Info  

| mysql-bin.000319 | 446952048 | Gtid | 90174306 | 446952086 | BEGIN GTID 17186-90174306-429975571 |
| mysql-bin.000319 | 446952086 | Table_map | 90174306 | 446952126 | table_id: 14520 (cc.t1) |
| mysql-bin.000319 | 446952126 | Delete_rows_v1 | 90174306 | 455952146 | table_id: 14520 flags: STMT_END_F |
| mysql-bin.000319 | 455952146 | Xid | 90174306 | 455952173 | COMMIT /* xid=489278797 */

可以看到这个delete事件对应于一个很大的binlog事件

MariaDB 10.1.22,binlog-row-event-max-size设置为262144,同样delete一个百万元素的表

mysql> SHOW BINLOG EVENTS IN 'mysqld-bin.000001';
+-------------------+---------+-------------------+-----------+-------------+-----------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+-------------------+---------+-------------------+-----------+-------------+-----------------------------------------------------+
| mysqld-bin.000001 | 4 | Format_desc | 1 | 249 | Server ver: 10.1.22-MariaDB-1~jessie, Binlog ver: 4 |
| mysqld-bin.000001 | 249 | Gtid_list | 1 | 274 | [] |
| mysqld-bin.000001 | 274 | Binlog_checkpoint | 1 | 314 | mysqld-bin.000001 |
| mysqld-bin.000001 | 314 | Gtid | 1 | 352 | BEGIN GTID 0-1-1 |
| mysqld-bin.000001 | 352 | Table_map | 1 | 394 | table_id: 19 (test.t1) |
| mysqld-bin.000001 | 394 | Delete_rows_v1 | 1 | 262557 | table_id: 19 |
| mysqld-bin.000001 | 262557 | Delete_rows_v1 | 1 | 524720 | table_id: 19 |
| mysqld-bin.000001 | 524720 | Delete_rows_v1 | 1 | 786883 | table_id: 19 |
| mysqld-bin.000001 | 786883 | Delete_rows_v1 | 1 | 1049046 | table_id: 19 |
| mysqld-bin.000001 | 1049046 | Delete_rows_v1 | 1 | 1311209 | table_id: 19 |
| mysqld-bin.000001 | 1311209 | Delete_rows_v1 | 1 | 1573372 | table_id: 19 |
| mysqld-bin.000001 | 1573372 | Delete_rows_v1 | 1 | 1835535 | table_id: 19 |
| mysqld-bin.000001 | 1835535 | Delete_rows_v1 | 1 | 2097698 | table_id: 19 |
| mysqld-bin.000001 | 2097698 | Delete_rows_v1 | 1 | 2359861 | table_id: 19 |
| mysqld-bin.000001 | 2359861 | Delete_rows_v1 | 1 | 2622024 | table_id: 19 |
| mysqld-bin.000001 | 2622024 | Delete_rows_v1 | 1 | 2884187 | table_id: 19 |
| mysqld-bin.000001 | 2884187 | Delete_rows_v1 | 1 | 3146350 | table_id: 19 |
| mysqld-bin.000001 | 3146350 | Delete_rows_v1 | 1 | 3408513 | table_id: 19 |
| mysqld-bin.000001 | 3408513 | Delete_rows_v1 | 1 | 3670676 | table_id: 19 |
| mysqld-bin.000001 | 3670676 | Delete_rows_v1 | 1 | 3932839 | table_id: 19 |
| mysqld-bin.000001 | 3932839 | Delete_rows_v1 | 1 | 4195002 | table_id: 19 |
| mysqld-bin.000001 | 4195002 | Delete_rows_v1 | 1 | 4457165 | table_id: 19 |
| mysqld-bin.000001 | 4457165 | Delete_rows_v1 | 1 | 4719328 | table_id: 19 |
| mysqld-bin.000001 | 4719328 | Delete_rows_v1 | 1 | 4981491 | table_id: 19 |
| mysqld-bin.000001 | 4981491 | Delete_rows_v1 | 1 | 5243654 | table_id: 19 |
| mysqld-bin.000001 | 5243654 | Delete_rows_v1 | 1 | 5505817 | table_id: 19 |
| mysqld-bin.000001 | 5505817 | Delete_rows_v1 | 1 | 5767980 | table_id: 19 |
| mysqld-bin.000001 | 5767980 | Delete_rows_v1 | 1 | 6030143 | table_id: 19 |
| mysqld-bin.000001 | 6030143 | Delete_rows_v1 | 1 | 6292306 | table_id: 19 |
| mysqld-bin.000001 | 6292306 | Delete_rows_v1 | 1 | 6554469 | table_id: 19 |
| mysqld-bin.000001 | 6554469 | Delete_rows_v1 | 1 | 6816632 | table_id: 19 |
| mysqld-bin.000001 | 6816632 | Delete_rows_v1 | 1 | 7078795 | table_id: 19 |
| mysqld-bin.000001 | 7078795 | Delete_rows_v1 | 1 | 7340958 | table_id: 19 |
| mysqld-bin.000001 | 7340958 | Delete_rows_v1 | 1 | 7603121 | table_id: 19 |
| mysqld-bin.000001 | 7603121 | Delete_rows_v1 | 1 | 7865284 | table_id: 19 |
| mysqld-bin.000001 | 7865284 | Delete_rows_v1 | 1 | 8127447 | table_id: 19 |
| mysqld-bin.000001 | 8127447 | Delete_rows_v1 | 1 | 8389610 | table_id: 19 |
| mysqld-bin.000001 | 8389610 | Delete_rows_v1 | 1 | 8651773 | table_id: 19 |
| mysqld-bin.000001 | 8651773 | Delete_rows_v1 | 1 | 8913936 | table_id: 19 |
| mysqld-bin.000001 | 8913936 | Delete_rows_v1 | 1 | 9001409 | table_id: 19 flags: STMT_END_F |
| mysqld-bin.000001 | 9001409 | Xid | 1 | 9001436 | COMMIT /* xid=3000082 */ |
+-------------------+---------+-------------------+-----------+-------------+-----------------------------------------------------+

可以看到这个delete事件已经被拆分成了30多个稍小的binlog事件

看来只能尽量推动数据库的升级工作了。

关于超大binlog事件的问题的更多相关文章

  1. 【文档】三、Mysql Binlog事件类文件和类型

    在内部,服务器使用C++类文件来表示binlog事件.标准在log_event.h文件中,这些类的方法代码在log_event.cc中. log_event是基础类.其他的详细的事件子类都是来源于他. ...

  2. 【文档】五、Mysql Binlog事件结构

    这个部分描述了事件被写入binlog或者delay log中的属性.所有的事件有相同的整体结构,也就是包含事件头和事件数据: +===================+ | event header ...

  3. 【文档】四、Mysql Binlog事件含义详解

    下面对binlog中事件做个简单说明: UNKNOWN_EVENT 这个事件类型应该永远不会出现.它从不会写入binlog中.如果binlog中的事件没法被识别成其他已知事件,他被当做UNKNOWN_ ...

  4. 不同复制模式下,如何忽略某些binlog事件

    在MySQL复制中,如果slave节点上遇到错误,比如数据不存在或者主键冲突等错误时,想要忽略这些错误,可以采用以下几种方法: 1.未启用GTID模式时 只需通过设定 SQL_SLAVE_SKIP_C ...

  5. [转]mysql binlog in realtime

    原文:http://guweigang.com/blog/2013/11/18/mysql-binlog-in-realtime/ 众所周知,MySQL是最受欢迎的互联网数据库(没有之一)—————— ...

  6. MYSQL-- binlog事件详解

    mysqlbinlog -vvv log.000001 # at # :: server id end_log_pos CRC32 sequence_number= SET @@SESSION.GTI ...

  7. load data 方式导入的数据不可以用binlog日志进行恢复,因为binlog里面不产生insert sql语句。

    QQ群里面有人问起这个问题:    用load data 导入数据的时候,在binlog文件中记录的不是insert 语句,这样的话,如果用load data 导入数据,当需要恢复数据库的时候  bi ...

  8. 腾讯工程师带你深入解析 MySQL binlog

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 本文由 腾讯云数据库内核团队 发布在云+社区 1.概述 binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的red ...

  9. 教你MySQL Binlog实用攻略

    本文由云+社区发表 1.概述 binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的redo/undo log是完全不同的日志:其主要是用来记录对mysql数据更新或潜在发 ...

随机推荐

  1. Fire Game FZU - 2150 (bfs)

    Problem 2150 Fire Game Accept: 3772    Submit: 12868Time Limit: 1000 mSec    Memory Limit : 32768 KB ...

  2. BZOJ - 2744 朋友圈 (二分图上的最大团)

    [题目大意] 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着.一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目.两 ...

  3. [Poj3281]Dining(最大流)

    Description 有n头牛,f种食物,d种饮料,每头牛有nf种喜欢的食物,nd种喜欢的饮料,每种食物如果给一头牛吃了,那么另一个牛就不能吃这种食物了,饮料也同理,问最多有多少头牛可以吃到它喜欢的 ...

  4. [Bzoj2588]Count on a tree(主席树+LCA)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  5. U1

    如果 activity_main.xml没有xml代码可以对图像右键 go to mxl同时可以在design  和  text  切换 在安装了Android Studio3.3版本之后,第一个He ...

  6. mysql-copy to tmp table

    今天数据后台数据反映有些迟缓后查看链接 processlist 发下好多 锁 和磁盘写入,   参考文章 : http://bbs.chinaunix.net/forum.php?mod=viewth ...

  7. Java技术——Java多线程学习

    )适合多个相同程序代码的线程区处理同一资源的情况.比如下面这个买票的例子. //使用Thread实现 public static class MyThread extends Thread{ priv ...

  8. JavaScript 计时事件-setInterval()-clearInterval() -setTimeout()-clearTimeout()

    (PS:JavaScript 一个设定的时间间隔之后来执行代码,我们称之为计时事件.) JavaScript 计时事件 通过使用 JavaScript,我们有能力做到在一个设定的时间间隔之后来执行代码 ...

  9. 手把手教你启用RemoteFX以及Hyper-V GPU卸载

    [TechTarget中国原创] 微软的RemoteFX特性可以帮助改善虚拟机图形密集型应用工作负载的性能. 服务器虚拟化已经成熟到大多数工作负载都能够在虚拟机内运行的程度.毫无疑问,与其他工作负载相 ...

  10. 虚拟机VMware安Mac OS时没有Apple mac选项

    相信大家很多人在虚拟机安装mac os时候发现在选择客户机操作系统时候,没有Apple mac os选项,这样就会导致无法进行下一步,下面我来给大家详细介绍怎么添加这一项. 1.首先安装unlocke ...