1 mysql 安装
1.1 拉取镜像
            
            
              shell
              
              
            
          
          docker pull mysql:8.4.41.2 创建挂载目录
            
            
              shell
              
              
            
          
          mkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/conf
            
            
              shell
              
              
            
          
          mkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/data
            
            
              shell
              
              
            
          
          mkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/log1.3 编辑配置文件
在配置文件挂载目录 /user/lzl/tool/docker/mysql/mysql_8.4.4/home/conf 编写配置文件 my.cnf 内容如下:
            
            
              shell
              
              
            
          
          [client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4'
max_connections = 5000
wait_timeout = 20000
max_user_connections = 5000
max_allowed_packet = 128M
thread_stack = 262144
# 时区设置
default-time-zone = '+08:00'
# 允许创建函数(防止报错)
log_bin_trust_function_creators = 1
# 开启慢查询日志
slow_query_log = ON
slow_query_log_file = /var/lib/mysql/slow-query.log
long_query_time = 3
log_output = FILE
# 开启主从复制(Canal 需要用到)
log-bin = mysql-bin
binlog-format = ROW
server_id = 1
以下是对该 MySQL 配置文件的按功能分析:
字符集设置
- 
配置项 : ini[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_general_ci init_connect = 'SET NAMES utf8mb4'
- 
分析 : - utf8mb4字符集:支持存储所有 Unicode 字符,避免了- utf8的三字节限制,适用于多语言和表情符号等。
- utf8mb4_general_ci排序规则:不区分大小写,适合大部分应用场景,但对于某些语言,可能有更精确的排序规则(例如- utf8mb4_unicode_ci)。
- init_connect:每次连接时都会执行- SET NAMES utf8mb4,确保客户端连接使用 UTF-8 编码。
 
连接数和性能配置
- 
配置项 : inimax_connections = 5000 wait_timeout = 20000 max_user_connections = 5000 max_allowed_packet = 128M thread_stack = 262144
- 
分析 : - 最大连接数 (max_connections = 5000):允许最多 5000 个并发连接,适合高并发应用。
- 等待超时 (wait_timeout = 20000):连接最大空闲时间为 20000 秒(大约 5.5 小时),适用于长时间运行的会话或连接。
- 每个用户最大连接数 (max_user_connections = 5000):限制每个用户的最大并发连接数为 5000,避免某个用户占用过多连接资源。
- 最大数据包大小 (max_allowed_packet = 128M):允许最大数据包为 128MB,适用于大数据量传输。
- 线程栈大小 (thread_stack = 262144):增加线程栈大小,防止在执行复杂查询或存储过程时栈溢出。
 
- 最大连接数 (
时区设置
- 
配置项 : inidefault-time-zone = '+08:00'
- 
分析 : - 设置时区为 UTC+08:00,通常用于中国和东南亚,确保时间存储和显示的一致性。
 
函数创建权限
- 
配置项 : inilog_bin_trust_function_creators = 1
- 
分析 : - 允许创建存储函数和触发器,即使启用了二进制日志功能。这个设置解决了在启用二进制日志时,无法创建涉及存储过程或触发器的函数的问题。
 
慢查询日志
- 
配置项 : inislow_query_log = ON slow_query_log_file = /var/lib/mysql/slow-query.log long_query_time = 3 log_output = FILE
- 
分析 : - 开启慢查询日志 (slow_query_log = ON):记录执行时间超过指定阈值的查询,帮助识别性能瓶颈。
- 日志文件路径 (slow_query_log_file = /var/lib/mysql/slow-query.log):慢查询日志将写入到指定文件,便于后续分析。
- 慢查询阈值 (long_query_time = 3):超过 3 秒的查询被认为是慢查询并记录下来。
- 日志输出方式 (log_output = FILE):慢查询日志输出到文件,而非其他方式(例如表格或系统日志)。
 
- 开启慢查询日志 (
主从复制配置
- 
配置项 : inilog-bin = mysql-bin binlog-format = ROW server_id = 1
- 
分析 : - 二进制日志 (log-bin = mysql-bin):启用二进制日志,通常用于主从复制和数据恢复。
- 日志格式 (binlog-format = ROW):行模式二进制日志记录,确保数据变化的精确记录,比语句模式更稳定,适用于复杂的数据变动。
- 服务器 ID (server_id = 1):设置服务器唯一标识符,在主从复制或集群环境中,每个 MySQL 实例都需要一个唯一的server_id。
 
- 二进制日志 (
1.4 运行镜像
            
            
              shell
              
              
            
          
          docker run -p 3308:3306 --name mysql_8.4.4 -v /user/lzl/tool/docker/mysql/mysql_8.4.4/home/conf/my.cnf:/etc/mysql/my.cnf -v /user/lzl/tool/docker/mysql/mysql_8.4.4/home/data:/var/lib/mysql -v /user/lzl/tool/docker/mysql/mysql_8.4.4/home/log:/var/log/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.4.41.5 检查二进制日志开启情况
进入容器
            
            
              shell
              
              
            
          
          docker exec -it 容器id /bin/bash进入容器后输入命令,登陆mysql
            
            
              shell
              
              
            
          
           mysql -uroot -p123456输入命令查看二进制日志是否开启
            
            
              shell
              
              
            
          
          show variables like 'log_bin';
1.6 创建账号供 canal 使用
1.6.1 创建用户
            
            
              shell
              
              
            
          
          create user 'canal'@'mysqlIP' identified by 'canal';1.6.2 授予权限
            
            
              shell
              
              
            
          
          grant select, replication slave, replication client on *.* to 'canal'@'mysqlIP';1.6.3 刷新权限
            
            
              shell
              
              
            
          
          FLUSH PRIVILEGES;1.6.4 删除用户命令
            
            
              shell
              
              
            
          
          drop user '用户名'@'主机';1.6.5 命令分析
这两条命令用来给用户 canal(只允许从 localhost 连接)赋予以下权限:
- select:允许查询数据库内容;
- replication slave:允许该用户从主服务器复制数据(在主从复制中常用);
- replication client:允许该用户查看主从复制相关状态信息,如主服务器的状态和从服务器连接状态。
同时,通过 identified by 'canal' 指定了该用户的密码为 canal。

2 canal 安装
2.1 拉取镜像
            
            
              shell
              
              
            
          
          docker pull canal/canal-server:v1.1.82.2 配置文件介绍
2.2.1 /home/admin/canal-server/conf/canal.properties
canal.properties 是 canal 的主要配置文件,用于配置 canal 实例的各项参数。该文件包含了连接 MySQL 数据库、消息队列、数据同步等相关的配置项。
例如 canal.destinations = example, canal 可以有多个 instance,每个实例有独立的配置文件,默认只 有一个example实例。如果需要处理多个mysql数据的话,可以复制出多个example,对其重新命名, 命令和配置文件中指定的名称一致。然后修改canal.properties 中的 canal.destinations,canal.destinations=实例 1,实例 2,实例 3
2.2.2 /home/admin/canal-server/conf/example/instance.properties
instance.properties 是 canal 中的实例配置文件,用于配置单个 canal 实例的行为。每个 canal 实例对应一个 MySQL 数据库或一个逻辑数据库的同步任务。
2.2.2.1 MySQL 连接配置
这些配置项用于 Canal 连接 MySQL 数据库,从 binlog 中获取数据。
            
            
              properties
              
              
            
          
          # MySQL serverId(一般设置为不同的唯一值,避免与 MySQL 主库的 server_id 冲突)
# v1.0.26+ 版本会自动生成
# canal.instance.mysql.slaveId=0- canal.instance.mysql.slaveId:如果 MySQL 只有一个实例,可以不配置这个参数,或者设置一个唯一的- slaveId(如- 2)。
            
            
              properties
              
              
            
          
          # MySQL 主库地址
canal.instance.master.address=127.0.0.1:3306- canal.instance.master.address:指定 Canal 连接的 MySQL 主库的地址。
            
            
              properties
              
              
            
          
          # MySQL 账号信息(需要具备 REPLICATION SLAVE 权限)
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal- canal.instance.dbUsername&- canal.instance.dbPassword:用于 Canal 访问 MySQL 读取 binlog 数据。
            
            
              properties
              
              
            
          
          # MySQL 连接字符集(一般使用 UTF-8)
canal.instance.connectionCharset = UTF-8- canal.instance.connectionCharset:设置 MySQL 连接的字符集。
2.2.2.2 GTID 相关配置
            
            
              properties
              
              
            
          
          # 是否启用 GTID(全局事务 ID),默认为 false
canal.instance.gtidon=false- canal.instance.gtidon:是否启用 MySQL 的 GTID(适用于 MySQL 5.6+),一般不需要启用。
            
            
              properties
              
              
            
          
          # GTID 相关参数(一般不需要配置)
canal.instance.master.gtid=- canal.instance.master.gtid:如果使用 GTID,可以在这里指定初始 GTID。
2.2.2.3 Binlog 读取位置
            
            
              properties
              
              
            
          
          # binlog 读取位置(如果为空,会从 MySQL 最新的 binlog 开始读取)
canal.instance.master.journal.name=
canal.instance.master.position=
canal.instance.master.timestamp=- canal.instance.master.journal.name&- canal.instance.master.position:用于指定从哪个- binlog开始读取数据(如果为空,则从最新的 binlog 位置开始)。
2.2.2.4 数据表过滤
            
            
              properties
              
              
            
          
          # 允许同步的表(正则表达式,默认匹配所有数据库和表)
canal.instance.filter.regex=.*\\..*- canal.instance.filter.regex:默认匹配 所有数据库 和 所有表 (- .*\..*表示- 所有库.所有表)。
            
            
              properties
              
              
            
          
          # 黑名单(不需要同步的表)
canal.instance.filter.black.regex=mysql\\.slave_.*- canal.instance.filter.black.regex:排除- mysql系统库中的- slave_*相关表。
2.2.2.5 备库(Standby)配置
            
            
              properties
              
              
            
          
          # 如果 Canal 需要连接备份数据库(备用数据库)
# canal.instance.standby.address=
# canal.instance.standby.journal.name=
# canal.instance.standby.position=
# canal.instance.standby.timestamp=
# canal.instance.standby.gtid=- canal.instance.standby.address:如果 Canal 需要连接一个备用 MySQL 实例(主库故障时可切换到备用库)。
2.2.2.6 时序数据库(TSDB)支持
            
            
              properties
              
              
            
          
          # 是否启用 table meta tsdb(用于存储表结构变更历史)
canal.instance.tsdb.enable=true- canal.instance.tsdb.enable:启用表结构变更的存储功能,防止因表结构变化导致 binlog 解析失败。
2.2.2.7 SSL 相关配置
            
            
              properties
              
              
            
          
          # MySQL SSL 连接配置(默认禁用)
# canal.instance.master.sslMode=DISABLED
# canal.instance.master.tlsVersions=
# canal.instance.master.trustCertificateKeyStoreType=
# canal.instance.master.trustCertificateKeyStoreUrl=
# canal.instance.master.trustCertificateKeyStorePassword=- SSL 相关配置:如果需要 MySQL 使用 SSL 连接,可配置证书路径。
2.2.2.8 Canal 消息队列(MQ)配置
Canal 支持对接 Kafka、RocketMQ、RabbitMQ 等消息队列。
            
            
              properties
              
              
            
          
          # MQ 的 topic 名称
canal.mq.topic=example- canal.mq.topic:指定 Canal 发送数据到消息队列的 Topic 名称。
            
            
              properties
              
              
            
          
          # MQ 分区
canal.mq.partition=0- canal.mq.partition:指定 Canal 数据写入到 Kafka/RocketMQ 的分区。
            
            
              properties
              
              
            
          
          # 是否启用动态队列分区
# canal.mq.enableDynamicQueuePartition=false
# canal.mq.partitionsNum=3- canal.mq.enableDynamicQueuePartition:是否启用 动态队列分区(Kafka/RocketMQ 支持)。
            
            
              properties
              
              
            
          
          # 根据表的哈希值进行分区
# canal.mq.partitionHash=test.table:id^name,.*\\..*- canal.mq.partitionHash:用于指定某些表按照- id或- name进行分区。
2.2.2.9 其他高级配置
            
            
              properties
              
              
            
          
          # 是否启用 Druid 解析数据库密码(加密存储密码)
canal.instance.enableDruid=false- canal.instance.enableDruid:是否启用 Druid 数据源解析数据库密码。
            
            
              properties
              
              
            
          
          # canal.instance.pwdPublicKey=...- canal.instance.pwdPublicKey:如果- enableDruid=true,可以配置公钥进行加密。
2.2.2.10 总结
该 instance.properties 配置文件主要包括:
- MySQL 连接信息 (canal.instance.master.address)。
- Binlog 读取控制 (canal.instance.master.journal.name、position)。
- 数据库表过滤 (canal.instance.filter.regex)。
- 备库切换 (canal.instance.standby.address)。
- 时序数据库(TSDB)支持 (canal.instance.tsdb.enable)。
- SSL 安全连接 (canal.instance.master.sslMode)。
- 消息队列(MQ)支持 (canal.mq.topic,canal.mq.partition)。
- Druid 数据源密码加密 (canal.instance.enableDruid)。
这些配置可以根据实际需求进行调整,比如:
- 如果 Canal 需要对接 Kafka,则要调整 canal.mq.topic。
- 如果 Canal 只同步特定表,需要修改 canal.instance.filter.regex。
- 如果 MySQL 启用了 GTID,需要配置 canal.instance.gtidon=true。
2.3 创建挂载目录
            
            
              shell
              
              
            
          
          mkdir -p /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/logs
            
            
              shell
              
              
            
          
          mkdir -p /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf
            
            
              shell
              
              
            
          
          mkdir -p /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/example授权:
            
            
              shell
              
              
            
          
          chmod 777 /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home运行容器:
            
            
              shell
              
              
            
          
          docker run -p 11111:11111 --name canal_server_v1.8.8 -d canal/canal-server:v1.1.8复制配置文件到挂载目录:
            
            
              shell
              
              
            
          
          docker cp canal_server_v1.1.8:/home/admin/canal-server/conf/canal.properties /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/canal.propertiesls
            
            
              shell
              
              
            
          
          docker cp canal_server_v1.1.8:/home/admin/canal-server/conf/example/instance.properties /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/example/instance.properties卸载容器:
            
            
              shell
              
              
            
          
          docker rm -f  canal_server_v1.8.82.4 修改配置文件
修改 canal.properties,如果使用默认配置不用修改
            
            
              shell
              
              
            
          
          # 默认端口 11111
# 默认输出model为tcp, mysql就使用tcp
# tcp, kafka, RocketMQ
#canal.serverMode = tcp
#################################################
######### destinations ############# 
#################################################
# canal可以有多个instance,每个实例有独立的配置文件,默认只 有一个example实例。
# 如果需要处理多个mysql数据的话,可以复制出多个example,对其重新命名,
# 命令和配置文件中指定的名称一致。然后修改canal.properties 中的 canal.destinations
# canal.destinations=实例 1,实例 2,实例 3
#canal.destinations = example修改 instance.properties,只需要修改mysql地址即可
            
            
              shell
              
              
            
          
          # 不能和mysql master重复
canal.instance.mysql.slaveId=2
# 使用mysql的虚拟ip和端口 需要改
canal.instance.master.address=172.17.0.2:3306
# 使用已创建的canal用户 默认就有
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.connectionCharset = UTF-8
# canal.instance.defaultDatabaseName =test
# 表示匹配所有的库所有的表 默认就是
canal.instance.filter.regex =.*\\..*2.5 重启 canal 容器
            
            
              shell
              
              
            
          
          docker run --name canal_server_v1.8.8 -p 11111:11111 -d \
-v /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/canal.properties:/home/admin/canal-server/conf/canal.properties \
-v /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/example/instance.properties:/home/admin/canal-server/conf/example/instance.properties \
-v /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/logs/:/home/admin/canal-server/logs/ \
canal/canal-server:v1.1.82.7 检测是否连接成功
查看实例日志(日志:/user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/logs/example/example.log),发现报错如下:
            
            
              shell
              
              
            
          
          Caused by: java.io.IOException: Error When doing Client Authentication:ErrorPacket [errorNumber=1524, fieldCount=-1, message=Plugin 'mysql_native_password' is not loaded, sqlState=HY000, sqlStateMarker=#]
	at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.negotiate(MysqlConnector.java:332)
	at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.connect(MysqlConnector.java:81)
	... 4 common frames omitted根本原因是 canal 使用 mysql_native_password 认证插件,而 mysqlc使用的认证插件为 caching_sha2_password。
mysql 查询用户认证插件:
            
            
              shell
              
              
            
          
          SELECT user, host, plugin FROM mysql.user WHERE user = 'canal';
由于高版本 mysql 默认禁用 mysql_native_password ,所以需要修改 mysql  配置文件:
            
            
              shell
              
              
            
          
          vim /user/lzl/tool/docker/mysql/mysql_8.4.4/home/conf/my.cnf
            
            
              shell
              
              
            
          
          [client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4'
max_connections = 5000
wait_timeout = 20000
max_user_connections = 5000
max_allowed_packet = 128M
thread_stack = 262144
# 时区设置
default-time-zone = '+08:00'
# 允许创建函数(防止报错)
log_bin_trust_function_creators = 1
# 开启慢查询日志
slow_query_log = ON
slow_query_log_file = /var/lib/mysql/slow-query.log
long_query_time = 3
log_output = FILE
# 开启主从复制(Canal 需要用到)
log-bin = mysql-bin
binlog-format = ROW
server_id = 1
mysql_native_password=ON重启 mysql 容器:
            
            
              shell
              
              
            
          
          docker restart mysql_8.4.4进入mysql 容器修改用户认证插件:
            
            
              shell
              
              
            
          
          docker exec -it mysql_8.4.4 /bin/bash
            
            
              shell
              
              
            
          
          mysql -uroot -p123456
            
            
              shell
              
              
            
          
          ALTER USER 'canal'@'mysqlIP' IDENTIFIED WITH mysql_native_password BY 'canal';刷新权限:
            
            
              shell
              
              
            
          
          FLUSH PRIVILEGES;下面的图只是实例,'canal'@'mysqlIP' 改成实际 ip

运行成功命令 example.log:
            
            
              shell
              
              
            
          
          2025-03-24 03:17:20.549 [main] INFO  c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example 
2025-03-24 03:17:21.220 [main] WARN  c.a.o.canal.parse.inbound.mysql.dbsync.LogEventConvert - --> init table filter : ^.*\..*$
2025-03-24 03:17:21.220 [main] WARN  c.a.o.canal.parse.inbound.mysql.dbsync.LogEventConvert - --> init table black filter : ^mysql\.slave_.*$
2025-03-24 03:17:21.226 [main] INFO  c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
2025-03-24 03:17:21.388 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> begin to find start position, it will be long time for reset or first position
2025-03-24 03:17:21.388 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - prepare to find start position just show master status
2025-03-24 03:17:21.453 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.otter.canal.parse.inbound.mysql.MysqlConnection - load MySQL @@version_comment : MySQL Community Server - GPL
2025-03-24 03:17:22.963 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> find start position successfully, EntryPosition[included=false,journalName=mysql-bin.000004,position=4,serverId=1,gtid=<null>,timestamp=1742785681000] cost : 1555ms , the next step is binlog dump
2025-03-24 03:17:23.065 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.otter.canal.parse.inbound.mysql.MysqlConnection - load MySQL @@version_comment : MySQL Community Server - GPL提示:mysql 创建 canal 用户时 不要用 localhost 直接用实际 ip ,网上有的博客使用的时 localhost,但是我的是失败的。
3 canal 同步数据到 ES
3.1 引入依赖
            
            
              java
              
              
            
          
          <!-- https://mvnrepository.com/artifact/com.alibaba.otter/canal.client -->
<dependency>
    <groupId>com.alibaba.otter</groupId>
    <artifactId>canal.client</artifactId>
    <version>1.1.8</version>
</dependency>
<dependency>
    <groupId>com.alibaba.otter</groupId>
    <artifactId>canal.protocol</artifactId>
    <version>1.1.8</version>
</dependency> 3.2 配置信息
未完待续