Debezium

Debezium 用于捕获数据库中的更改,以便应用程序可以查看这些更改并对其做出响应。 Debezium 会记录每个数据库表中所有行级别的更改,并将其作为更改事件流记录下来 主流CDC工具: canal : 监控binlog,支持mysql,社区已不活跃,非首选 debezium : 支持mysql, postgresql, mongodb等十余种数据库,mysql也支持binlog,成熟稳定 flink cdc: 主要应用于大数据,基于debezium,延迟较低 这里选择debezium的理由: 不选canal的原因 只支持mysql,并且社区已不活跃,除了老项目使用新的已经不是首选,在阿里也都边缘化了 不选flink cdc的原因,公司大数据没有flink的项目,增加运维成本,并且需要使用java开发,并不是所有开发都会使用java 选择debezium的原因,debezium成熟稳定,支持多种数据库,经典的使用方式是使用的是kafka connect部署, 我们有自己的kafka,不会增加运维成本, kafka connect是kafka自带的分布式工具,不用搭建额外的平台管理任务,使用消息队列和固定语言解耦,降低开发成本 当我们想监控数据库数据变动时我可以使用一些CDC工具,这里介绍一款配合Kafka使用的Connect插件Debezium,他支持Mysql, PostgreSQL, MongoDB等 能做什么: 1. 解耦数据修改端和使用端,减少应该通知但是没有通知的数据变更的错误,或者手动修改数据库时没有或忘记通知其他端 2. 异构数据库同步数据,比如搜索相关业务,需要数据实时同步,但是要保证数据一致 3. 缓存数据的生成和过期 4. 一些计算任务(数据统计,聚合) 这里我们以MySQL为例 环境 1. Kafka 3.7 2. MySQL 8.0 3. Debezium Mysql connect Plugin 2.6.2 Final Mysql 需要开启row格式binlog [mysqld] bind-address = 0.0.0.0 binlog_format = ROW server_id = 1 log_bin = /var/log/mysql/mysql-bin.log 需要以下权限 GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'user' IDENTIFIED BY 'password'; 权限 作用 SELECT 查询数据,仅在执行快照时使用 RELOAD 允许连接器使用 FLUSH 语句来清除或重新加载内部缓存、刷新表或获取锁。仅在执行快照时使用 SHOW DATABASES 使连接器能够通过发出 SHOW DATABASE 语句来查看数据库名称。仅在执行快照时使用 REPLICATION SLAVE 使连接器能够连接并读取 MySQL 服务器二进制日志 REPLICATION CLIENT 允许连接器使用以下语句:SHOW MASTER STATUS,SHOW SLAVE STATUS,SHOW BINARY LOGS LOCK TABLES 执行快照时需要锁表 Debezium 把插件解压到一个目录下,我这里解压到Kafka目录下,创建一个connects目录,解压到这里,解压后我的目录像这样 --kafka |--connects |--debezium-connector-mysql 在kafka的config文件夹下配置connect-distributed.properties这个文件 修改plugin.path填写connects文件夹路径 ...

<span title='2024-06-28 11:15:28 +0800 +0800'>六月 28, 2024</span>

添加字段引发的不兼容

大家都是知道如果我们在接口返回值添加字段或者proto中添加字段一般是不会发生不兼容的情况,那么在数据库中给表添加字段会导致不兼容问题吗? 通常情况是不会,添加字段不会影响到已有的数据,但是下面这种情况会引发不兼容 假设A表有字段id, bid, c, B表有id, d,业务中有这么一条语句 select a.id, b.d from a join b on a.bid = b.id where c = 1; 那么现在我们给B表加字段c,那么现在这个语句就会错,因为a表有个c,b表有个c,现在where条件中的c已经有歧义了,所以这条语句就会报错,所以给表加字段会引发不兼容 所以加字段的时候也要小心,sql如果是多表一定给字段加上别名,避免这种歧义就比如上面的语句就改为 select a.id, b.d from a join b on a.bid = b.id where a.c = 1; 这只能说约束我们自己,历史的老系统中有什么样的写法都未可知

<span title='2024-01-12 12:37:19 +0800 +0800'>一月 12, 2024</span>

mysql中time_zone的作用,以及为什么要配置本地时区和db时区

mysql中time_zone的作用,以及为什么要配置本地时区和db时区 1. mysql中time_zone的作用 mysql中time_zone的作用,就是用来设置时区的(废话),time_zone影响TIMESTAMP类型和NOW等函数的值,但并不影响DATETIME类型和DATE类型。 因为TIMESTAMP存储的时时间戳,当用户发送过来一个时间如“2023-12-11 10:41:18”,那么mysql会将其时间戳,这个时间就是按time_zone设置的时区来解析的,然后转换成时间戳保存, 在给用户查询时在通过时区转换会时间串。 DATETIME类型不是时间戳,存入时是“2023-12-11 10:41:18”,查询时也是“2023-12-11 10:41:18”,不会做转换,也和时区无关 2. 为什么要配置本地时区和db时区 本地时区是给mysql驱动使用,并不会影响mysql的时区,只会影响mysql驱动的解析, db时区是mysql的时区,会影响mysql的时区,会影响mysql的查询结果。 本地时区作用 在读取到mysql发来的时间,go会按照本地时区来解析,转换为time.Time类型mysql按照数据库time_zone返回时间串后,go并不知道用哪个时区来解析这个时间串,所以需要设置本地时区。 本在写入time.Time类型时,go会把time.Time转换为本地时区发送给mysql 比如设置本地时区为“Asia/Shanghai” root:root@tcp(127.0.0.1:3306)/db?charset=utf8&loc=Asia%2FShanghai&parseTime=true通过loc参数来这设置 同时设置本地和数据库时区 root:root@tcp(127.0.0.1:3306)/db?charset=utf8&loc=Asia%2FShanghai&parseTime=true&time_zone=%27%2B8%3A00%27 dsn上的参数有的是给数据库驱动使用,有的是给mysql使用,具体可参阅mysql驱动的DSN

<span title='2023-12-11 10:41:18 +0800 +0800'>十二月 11, 2023</span>