修改Canal的消费位点

修改Canal的消费位点

日常的使用中,当使用 ZooKeeper 作为高可用方案时,因某些原因需要重新采集数据,只要目标库中的 binlog 文件依旧存在,那么就能够将 Canal 的解析位置重新定位,从指定的位置开始解析。
canal instance的配置文件修改无效果,因为zookeeper已经记录binlog日志位置,修改为新的也不会生效,需要在zookeeper配置中修改或者删除重新生成

canal 默认在 ZooKeeper 中存储的节点为:

/otter/canal
一、停止canal服务

在有数据被消费时,客户端的每次 Ack 都会使得服务端用本地缓存的位点信息去覆盖 ZooKeeper 上的位点,所以在修改 ZooKeeper 的位点之前,应先避免其不再被覆盖,即停止 Canal 服务。(停止对应的instance,无需停止整个canal服务)

亦可停止该 instance 对应的消费端程序,则不会再触发服务端使用缓存中的位点信息去覆盖 ZooKeeper 中的信息。
二、获取位点信息

停止服务后,可通过 zkCli.sh、ZooInspector、zkui 等工具连接到相应的 ZooKeeper 服务器上,并获取到当前的位点信息。
默认情况下,位点信息存储在下述节点中:

/otter/canal/destinations/${destination}/1001/cursor

注意:请将 ${destination} 替换成预期的 instance 名称。
若 ZooKeeper 中并无 …/1001/cursor 节点,则表明该 instance 从未被消费过,可通过启动一次对应的消费者,以生成该位点信息,但记得生成位点信息后要将其停止。
本文仅以 zkCli.sh (交互模式)方式示例如何获取名为 “example” 的 instance 的位点信息:

# cd /data/zookeeper/bin
# sh zkCli.sh
[zk: localhost:2181(CONNECTED) 0] ll  (可使用的命令)
ZooKeeper -server host:port cmd args
	stat path [watch]
	set path data [version]
	ls path [watch]
	delquota [-n|-b] path
	ls2 path [watch]
	setAcl path acl
	setquota -n|-b val path
	history 
	redo cmdno
	printwatches on|off
	delete path [version]
	sync path
	listquota path
	rmr path
	get path [watch]
	create [-s] [-e] path data acl
	addauth scheme auth
	quit 
	getAcl path
	close 
	connect host:port
[zk: localhost:2181(CONNECTED) 4] get /otter/canal/destinations/example/1001/cursor  (获取位点信息)
{"@type":"com.alibaba.otter.canal.protocol.position.LogPosition","identity":{"slaveId":-1,"sourceAddress":{"address":"localhost","port":3306}},"postion":{"gtid":"","included":false,"journalName":"mysql-bin.069317","position":5963960,"serverId":833045285,"timestamp":1629962234000}}

从上述的结果可看出,位点信息是用 json 格式的字符串进行存储的,里面存放了许多信息,我们仅需要变更“journalName”和“position”两个属性值,分别对应当前的 binlog 文件名以及该文件内的具体位置。

三、查询数据位点

我们既然已经确定了变更位点需要哪些信息,那么又如何获得预期的位点信息呢?这就需要视需求而定了,其实,一般来变更位点都是往当前位置的前面调整,再次采集已同步过的数据。本文仅给出如何在 MySQL 中通过 SQL 语句查询 binlog 的位点信息示例:

1.查询 binlog 文件
# show binary logs (此处的输出结果仅为 binlog 文件名称和大小)
2.binlog 事件

binary log,顾名思义就是二进制日志文件,里面存放的信息无法直接被展示出来,但我们可以通过 MySQL 的 SQL 语句将其解析成对应的事件,通过判断事件来找出对应的位点信息。
用于查询 binlog 事件的 SQL 语法如下:

# show binlog events [in 'binlog_name'] [from pos] [limit [offset,] row_count]

在查询 binlog 事件时,强烈建议尽可能多地增加限制结果集大小的条件,以降低对 MySQL 的性能损耗,这就是有1. 查询 binlog 文件步骤的原因,为此步骤提供信息。
下述示例表示列出名为“mysql-bin.000008”的文件内从第 4 个位点开始往后的 5 条记录。

show binlog events in 'mysql-bin.000008' from 4 limit 5

当前仅能通过判断具体的事件,来确定对应的位点值(Pos)。

四、变更位点信息
1.变更

假设我们需要的目标位点信息是:名为 mysql-bin.000008 的日志文件内位点值为 4。那么通过 zkCli.sh 的 set 方法进行变更,示例如下:

set /otter/canal/destinations/example/1001/cursor {"@type":"com.alibaba.otter.canal.protocol.position.LogPosition","identity":{"slaveId":-1,"sourceAddress":{"address":"localhost","port":3306}},"postion":{"gtid":"","included":false,"journalName":"mysql-bin.000008","position":4,"serverId":1,"timestamp":1590112037000}}

注意:节点名与节点值之间使用一个半角空格进行分隔。

2.删除

或者直接删除掉旧位点信息(如删除掉旧位点信息,需要去instance配置新的位点)

[zk: localhost:2181(CONNECTED) 5] delete /otter/canal/destinations/example/1001/cursor
canal.instance.master.journal.name=mysql-bin.070764
canal.instance.master.position=120
五、启动canal服务

启动 Canal 服务端,以使新的位点生效。
如果之前通过停止消费端的方式来消除位点被覆盖,那么此时就需要通过重启 Canal 服务端将 ZooKeeper 上新的位点信息去覆盖 Canal 服务端缓存中的信息。

### 排查 'not file' 错误的方法 当遇到 `Canal` 集群异常提示 `Could not find first log file name in binary log index file` 的情况时,这通常是由于 MySQL 的二进制日志文件配置不正确或者 Canal 工具未能成功解析这些日志文件引起的。以下是针对该问题的具体分析和解决方法: #### 1. 检查 MySQL 的 Binlog 配置 确保 MySQL 实例已经启用了二进制日志功能,并且相关参数设置无误。可以通过执行以下 SQL 命令来验证当前的 binlog 状态: ```sql SHOW VARIABLES LIKE 'log_bin'; ``` 如果返回的结果显示 `log_bin=OFF`,则表示二进制日志未启用。需要修改 MySQL 配置文件(通常是 `my.cnf` 或者 `my.ini`),并添加或调整如下参数[^2]: ```ini [mysqld] server-id=1 log-bin=mysql-bin binlog-format=row expire_logs_days=7 ``` 完成上述更改后重启 MySQL 服务。 #### 2. 核实 Binary Log Index File 存在与否 确认 MySQL 数据目录下是否存在对应的索引文件 (`mysql-bin.index`) 和实际的日志文件 (`mysql-bin.xxxxxx`)。路径可通过查询变量获取: ```sql SHOW VARIABLES LIKE 'datadir'; ``` 进入指定的数据目录,检查是否有 `.index` 文件以及相应的二进制日志文件。如果没有找到任何日志文件,则可能是之前的清理操作删除了它们,或者是新安装实例尚未生成日志记录。 #### 3. 修改 Canal Server 配置 打开 Canal 的配置文件(一般位于 `conf/instance.properties` 中),重点检查以下几个字段是否匹配目标数据库的实际状态: - **master.info**: 记录主从同步位置信息。 - **meta.position**: 当前消费位点的位置。 尝试手动更新 master.info 文件内的 serverId、filename 及 position 字段至最新的有效值。例如: ```properties canal.instance.master.address=<MYSQL_HOST>:<PORT> canal.instance.dbUsername=canal_user canal.instance.dbPassword=password canal.instance.filter.regex=.*\\..* ``` #### 4. 日志调试模式开启 为了更清晰地了解错误发生的原因,在 canal-server 启动脚本中加入 `-Dfile.encoding=UTF-8 -Xdebug ...` 参数启动 JVM 调试环境;同时将日志级别设为 DEBUG 来捕获更多细节信息。编辑 application.yml 或其他日志框架配置文件实现此目的。 最后重新运行程序观察控制台输出的变化,定位具体缺失哪个文件名无法被识别到。 --- ### 提供一段 Python 示例代码用于自动化检测部分条件 下面是一段简单的Python脚本来帮助快速扫描MySQL服务器上的必要属性是否满足需求: ```python import pymysql def check_mysql_config(host, port, user, password): try: connection = pymysql.connect( host=host, port=int(port), user=user, passwd=password ) with connection.cursor() as cursor: sql_log_bin = "SHOW VARIABLES LIKE 'log_bin';" cursor.execute(sql_log_bin) result = cursor.fetchone() if result and str(result[1]).lower() != 'on': print(f"log_bin is OFF on {host}:{port}") # Additional checks can be added here... except Exception as e: print(e) if __name__ == "__main__": check_mysql_config('localhost', 3306, 'root', '') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值