基于 mysql 的存储插件,与 mysql 的 binlog 开发了一个 mysql cdc table 。可以在 mysql select binlog 中表的变化数据
0 delete data
1 insert data
2 update before data
3 update after date
全局事务 id
row event 发生的时间
效果大概是这样
![]() | 1 akin520 2024-06-17 16:52:48 +08:00 虽然不知道是什么东西,感觉就是高大上的东西 |
![]() | 3 ChainLock 2024-06-17 17:21:57 +08:00 没明白,是做什么的 |
4 bluebo OP @ChainLock 比如增量同步到 oracle, 因为原表数据删除后,历史数据是不会存在表里面的, 但是 binlog 里面有记录, 我这个可以直接查 binlog 记录到 cdc 表中,这样历史记录也能查出来。 这样可以根据历史记录可以封装成 sql 到 oracle 执行, 实现增量同步 row = select * from cdc_table where gitd> xxx and __tm > xxx ; switch __op { case 0: delete from dest_table where colx = row[x][x]; case 1: insert into dest_table values row[x][x]; case 2 update set colx = row[x+1][x] where colx = row[x][x]; } |
![]() | 5 wenxueywx 2024-06-17 17:42:09 +08:00 有用 可以用来查询数据的历史版本、变更记录;是查问题的好帮手。 有几个疑问? 1 、 只能读取本地 mysql 的 binlog ?还是可以远程读 2 、 是否支持只过滤某些表(黑白名单)? |
6 youngPacce 2024-06-17 17:44:31 +08:00 |
7 bluebo OP @wenxueywx 目前只能读本地 binlog 对于表的过滤, 我这边是一张 cdc 表对应一个 mysql 的表, 并不是所有表都会采集到一张 cdc 表,在创建 cdc 表时, 表名 为 xxx_cdc ,xxx 为具体要捕获的 mysql 表 |
10 bluebo OP @youngPacce 是的,这种都大同小异, 只不过我是直接把捕获的数据重新写回 myql 了, 当作了 mysql 的记录集 |
![]() | 11 wenxueywx 2024-06-17 17:56:51 +08:00 想问问是怎么想到这么做的,初衷是为了解决什么问题? |
![]() | 12 cheng6563 2024-06-17 17:57:45 +08:00 看起来挺有用的,但如果不是独立部署而是 mysql 插件的话,感觉用起来会很难... |
![]() | 15 RedisMasterNode 2024-06-17 18:07:24 +08:00 觉得不太可能推广出去,因为 cdc 的工具有很多,并且都有各自的特色 + 不小的社区: - https://github.com/alibaba/canal - https://github.com/debezium/debezium - https://github.com/apache/flink-cdc - https://github.com/zendesk/maxwell 所以楼主开发的工具和它们比起来有什么区别呢? PS:不是说钻研不好,只是钻研之后造轮子一个重要的原因应该是:现有工具不好用、不适合。不过从帖子描述看似乎不是很明显。 |
16 bluebo OP @RedisMasterNode 倒是没想着往 cdc 走,要做 cdc 差的太多太多了。只是去年的练手项目, 直接用的 mysql 源码 自己加的估计就 2000 来行。只是想着有没有往小工具之类的发展形式 |
![]() | 17 changdy 2024-06-17 21:10:50 +08:00 15l 列举的比较相信.. 变更工具太多了. |
![]() | 18 wenxueywx 2024-06-18 09:44:14 +08:00 可以改一下 |
![]() | 19 wenxueywx 2024-06-18 09:57:33 +08:00 有个想法可以参考:可以做成一个可以查询一定范围内任意时间点的历史数据的插件引擎(假设叫 binlogdb ) 1 、当使用 binlogdb 引擎创建表时会自动创建一个__optime 隐藏字段; 2 、远程读多个 mysql server 的 binlog ,如果本地有同名的表,就将数据带上变更的时间写入该表 3 、引入会话变量 optime ,使用 sql 查询表时默认加上 optime 字段,如果 optime 为空,则读取最新数据,不为空则读取__optime<=optime 的最新一条数据。 4 、 设置一个淘汰机制 |
20 bluebo OP @wenxueywx 会话变量 optime? 是不是就是刚连接上来的时间戳? __optime 就是数据变更时间戳把, 我那里是有一个__tm 的, 这个字段就是数据操作记录的变更时间戳, 我感觉我这玩意的优势就是内置到数据库了, 可以直接用 sql 去过滤不需要的记录, 而且根据 gtid 去拿的数据的 会很快。 |
21 zhenjiachen 2024-06-18 13:08:46 +08:00 我们直接用 flink cdc ,mysql ,postgresql ,sqlserver 都支持。 |
![]() | 22 wenxueywx 2024-06-18 14:08:58 +08:00 @bluebo 是的,__optime 就是数据变更时间__tm ; 优势就是实现了 mysql 引擎的接口可以内置到 mysql 中使用,可以对接 mysql 生态。 然后用户使用 gtid 去拿数据有点不符合操作习惯,你还得先知道 gtid ;使用时间就比较正常了。正常操作你只需设置一下时间,再用原来的 sql 直接执行就行,也基本没有增加使用负担。 |
23 lvlongxiang199 2024-06-18 14:42:08 +08:00 MySQL 中的表发生 DDL 你是咋处理的 ? MySQL8 之前的 binlog 里头没列名, binlog 中元素对应的表结构可能跟当前 MySQL 那边的表结构不一样 |
24 bluebo OP @lvlongxiang199 DDL ,我没捕获, 但是 DDL 应该是对系统表做了增删改的操作,需要捕获系统表,而且不同版本的 mysql 不知道系统表有没有变化。 |
25 bluebo OP @wenxueywx gtid 确实不直观,但是比__tm 更精准些。想想能不能直接在 mysql 上操作其他数据库(CRUD)。 应该也能实现,体量太大了 |
26 bluebo OP @zhenjiachen 暂时只是做了捕获和展示的动作, 数据落地应该不会接着做了 |