Docker 安装 canal 详细步骤 - 实践

news/2025/10/12 10:20:32/文章来源:https://www.cnblogs.com/wzzkaifa/p/19136319

一、canal 简介

canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。

  • 基于日志增量订阅&消费支持的业务:
  1. 数据库镜像
  2. 数据库实时备份
  3. 多级索引 (卖家和买家各自分库索引)
  4. search build
  5. 业务cache刷新
  6. 价格变化等重要业务消息 
  • 工作原理
  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送 dump 协议
  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
  • canal 解析 binary log 对象(原始为 byte 流) 。
  • 官网地址

 Home · alibaba/canal Wiki · GitHub

二、docker 安装 Mysql 服务

2.1 创建 docker network 网络

docker network create canal_net

新建的 docker 容器Mysql、canal-admin、canal-server 都统一使用 canal-net 网络进行通信,彼此访问时可以通过容器名直接访问,不用通过 IP 地址。

2.1 docker 安装 mysql8.0

docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -v /root/mysqlData:/var/lib/mysql --privileged=true -d -p 3306:3306 --network canal_net mysql
//--name test 为容器指定一个名称(可替换test为自己喜欢的名称)。
//-e MYSQL_ROOT_PASSWORD=1 设置MySQL的root密码。你应该替换1为你的实际密码。
//-d 使容器在后台运行。
//mysql:latest 是要运行的MySQL镜像和标签(在这里是最新版本)
//以数据卷的形式,创建并启动mysql容器,容器内的mysql数据不会因为容器的删除而被删除
//-v /root/mysqlData:/var/lib/mysql:将数据卷/root/mysqlData映射到容器的/var/lib/mysql目录
//-p 3306:3306:将容器的3306端口映射到主机的3306端口
//--privileged=true: 使容器内的root拥有真正的root权限,解决挂载目录没有权限的问题

此处只简单列了docker安装mysql 的命令。

2.3 检查配置mysql 是否开启了binlog日志

-- 查看是否开启 binlog
show variables like "%log_bin%";
-- 选择 ROW 模式
show variables like "binlog_format";
-- 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
show variables like "server_id";

 mysql8.0默认开启 binlog 日志 ,无需修改配置。

开启binlog日志方法:

打开mysql挂载目录下( /mydata/mysql/conf )的 my.cnf 配置文件,添加以下配置

[mysqld]
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复

2.4 在 mysql 中新建canal专用账户并设置权限

create user canal@'%' IDENTIFIED by 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%' identified by 'canal';
FLUSH PRIVILEGES;

三、docker 安装 canal-admin

3.1 拉取 canal-admin 镜像

docker pull canal/canal-admin

3.2  创建 canal_manager 数据库

在官网 https://github.com/alibaba/canal/releases 的canal.admin-1.1.8-SNAPSHOT.tar.gz文件的解压包中找到canal_manager.sql,并在mysql中执行脚本。

mysql 脚本(1.1.8 版本)如下:

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `canal_manager` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;
USE `canal_manager`;
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for canal_adapter_config
-- ----------------------------
DROP TABLE IF EXISTS `canal_adapter_config`;
CREATE TABLE `canal_adapter_config` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`category` varchar(255) NOT NULL,`name` varchar(255) NOT NULL,`status` varchar(45) DEFAULT NULL,`content` text NOT NULL,`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for canal_cluster
-- ----------------------------
DROP TABLE IF EXISTS `canal_cluster`;
CREATE TABLE `canal_cluster` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(255) NOT NULL,`zk_hosts` varchar(255) NOT NULL,`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for canal_config
-- ----------------------------
DROP TABLE IF EXISTS `canal_config`;
CREATE TABLE `canal_config` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`cluster_id` bigint(20) DEFAULT NULL,`server_id` bigint(20) DEFAULT NULL,`name` varchar(255) NOT NULL,`status` varchar(45) DEFAULT NULL,`content` text NOT NULL,`content_md5` varchar(128) NOT NULL,`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`),UNIQUE KEY `sid_UNIQUE` (`server_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for canal_instance_config
-- ----------------------------
DROP TABLE IF EXISTS `canal_instance_config`;
CREATE TABLE `canal_instance_config` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`cluster_id` bigint(20) DEFAULT NULL,`server_id` bigint(20) DEFAULT NULL,`name` varchar(255) NOT NULL,`status` varchar(45) DEFAULT NULL,`content` text NOT NULL,`content_md5` varchar(128) DEFAULT NULL,`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`),UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for canal_node_server
-- ----------------------------
DROP TABLE IF EXISTS `canal_node_server`;
CREATE TABLE `canal_node_server` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`cluster_id` bigint(20) DEFAULT NULL,`name` varchar(255) NOT NULL,`ip` varchar(255) NOT NULL,`admin_port` int(11) DEFAULT NULL,`tcp_port` int(11) DEFAULT NULL,`metric_port` int(11) DEFAULT NULL,`status` varchar(45) DEFAULT NULL,`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for canal_user
-- ----------------------------
DROP TABLE IF EXISTS `canal_user`;
CREATE TABLE `canal_user` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(255) NOT NULL,`password` varchar(255) NOT NULL,`name` varchar(255) NOT NULL,`roles` varchar(255) NOT NULL,`introduction` varchar(255) DEFAULT NULL,`avatar` varchar(255) DEFAULT NULL,`creation_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Records of canal_user
-- ----------------------------
BEGIN;
INSERT INTO `canal_user` VALUES (1, 'admin', '6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9', 'Canal Manager', 'admin', NULL, NULL, '2019-07-14 00:05:28');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

3.3 配置application.yml

在宿主机新建目录/mydata/canal/admin/conf,并新建application.yml文件

// application.yml 文件的内容
server:port: 8089
spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8
spring.datasource:address: mysql:3306database: canal_managerusername: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=falsehikari:maximum-pool-size: 30minimum-idle: 1
canal:adminUser: adminadminPasswd: admin

3.4 docker 运行 canal-admin

// 以参数形式运行,无需在application.yml文件中填写参数
docker run -d --name canal-admin  -e spring.datasource.address=mysql:3306 -e spring.datasource.database=canal_manager -e spring.datasource.username=root -e spring.datasource.password=foodbook --network canal_net -p 8089:8089 canal/canal-admin
// 以挂载文件方式运行,数据库的配置在application.yml文件中填好
docker run -d --name canal-admin  \
-v /mydata/canal/admin/conf/application.yml:/home/admin/canal-admin/conf/application.yml \
-v /mydata/canal/admin/logs/:/home/admin/canal-admin/logs/ \
--network canal_net -p 8089:8089 canal/canal-admin

启动成功后,可在挂载的日志目录下查看 canal-admin 的启动日志:

此时代表canal-admin已经启动成功。

备注:我在阿里云服务器上,用docker安装 canal-admin 后,启动失败,查询日志,发现运行该服务需要2g内存,我服务器内存不够。

3.5 访问 canal-admin 后台管理页面

可以通过 http://127.0.0.1:8089/ 访问,默认密码:admin/123456

四、docker 安装 canal 服务

官网安装方法:https://github.com/alibaba/canal/wiki/Docker-QuickStart

4.1 拉取 canal 镜像

docker pull canal/canal-server

4.2 运行 canal

docker run --name canal-server -d canal/canal-server

 4.3 复制canal容器内的配置文件到宿主机

# 创建文件夹并复制文件
mkdir /mydata/canal
chmod 777  /mydata/canal
docker cp canal-server:/home/admin/canal-server/conf/canal.properties /mydata/canal/conf
docker cp canal-server:/home/admin/canal-server/conf/example/instance.properties /mydata/canal/conf/example

4.4 修改 canal.properties 配置文件

canal.properties 文件配置 canal-server 服务的参数,主要修改内容:

# register ip to zookeeper # canal-server 服务自身的IP,因为运行 docker 时使用了 dockers network 网络,所以这里直接配置了 canal-server 的服务名
canal.register.ip = canal-server
canal.port = 11111
canal.metrics.pull.port = 11112
# canal instance user/passwd
# canal.user = canal
# canal.passwd =
# canal admin config 这里配置 canal-admin 的IP和端口,以便 canal-admin 管理页面能显示和配置canal 服务,注意用户名和密码来自于 canal-admin 服务配置的 aplication.yml 中的adminUser、adminPassword,默认都为 admin(4ACFE3202A5FF5CF467898FC58AAB1D615029441是admin加密字符串)
canal.admin.manager = canal-admin:8089
canal.admin.port = 11110
canal.admin.user = admin
canal.admin.passwd = 4ACFE3202A5FF5CF467898FC58AAB1D615029441
# admin auto register 自动注册
canal.admin.register.auto = true
#canal.admin.register.cluster =
canal.admin.register.name = ddddddd  # canal-server 的服务名

具体配置项如下:

#################################################
######### 		common argument		#############
#################################################
# tcp bind ip
canal.ip =
# register ip to zookeeper # canal-server 服务自身的IP,因为运行 docker 时使用了 dockers network 网络,所以这里直接配置了 canal-server 的服务名
canal.register.ip = canal-server
canal.port = 11111
canal.metrics.pull.port = 11112
# canal instance user/passwd
# canal.user = canal
# canal.passwd =
# canal admin config 这里配置 canal-admin 的IP和端口,以便 canal-admin 管理页面能显示和配置canal 服务,注意用户名和密码来自于 canal-admin 服务配置的 aplication.yml 中的adminUser、adminPassword,默认都为 admin(4ACFE3202A5FF5CF467898FC58AAB1D615029441是admin加密字符串)
canal.admin.manager = canal-admin:8089
canal.admin.port = 11110
canal.admin.user = admin
canal.admin.passwd = 4ACFE3202A5FF5CF467898FC58AAB1D615029441
# admin auto register 自动注册
canal.admin.register.auto = true
#canal.admin.register.cluster =
canal.admin.register.name = ddddddd  # canal-server 的服务名
canal.zkServers =
# flush data to zk
canal.zookeeper.flush.period = 1000
canal.withoutNetty = false
# tcp, kafka, rocketMQ, rabbitMQ, pulsarMQ
canal.serverMode = tcp
# flush meta cursor/parse position to file
canal.file.data.dir = ${canal.conf.dir}
canal.file.flush.period = 1000
## memory store RingBuffer size, should be Math.pow(2,n)
canal.instance.memory.buffer.size = 16384
## memory store RingBuffer used memory unit size , default 1kb
canal.instance.memory.buffer.memunit = 1024
## meory store gets mode used MEMSIZE or ITEMSIZE
canal.instance.memory.batch.mode = MEMSIZE
canal.instance.memory.rawEntry = true
## detecing config
canal.instance.detecting.enable = false
#canal.instance.detecting.sql = insert into retl.xdual values(1,now()) on duplicate key update x=now()
canal.instance.detecting.sql = select 1
canal.instance.detecting.interval.time = 3
canal.instance.detecting.retry.threshold = 3
canal.instance.detecting.heartbeatHaEnable = false
# support maximum transaction size, more than the size of the transaction will be cut into multiple transactions delivery
canal.instance.transaction.size =  1024
# mysql fallback connected to new master should fallback times
canal.instance.fallbackIntervalInSeconds = 60
# network config
canal.instance.network.receiveBufferSize = 16384
canal.instance.network.sendBufferSize = 16384
canal.instance.network.soTimeout = 30
# binlog filter config
canal.instance.filter.druid.ddl = true
canal.instance.filter.query.dcl = false
canal.instance.filter.query.dml = false
canal.instance.filter.query.ddl = false
canal.instance.filter.table.error = false
canal.instance.filter.rows = false
canal.instance.filter.transaction.entry = false
canal.instance.filter.dml.insert = false
canal.instance.filter.dml.update = false
canal.instance.filter.dml.delete = false
# binlog format/image check
canal.instance.binlog.format = ROW,STATEMENT,MIXED
canal.instance.binlog.image = FULL,MINIMAL,NOBLOB
# binlog ddl isolation
canal.instance.get.ddl.isolation = false
# parallel parser config
canal.instance.parser.parallel = true
## concurrent thread number, default 60% available processors, suggest not to exceed Runtime.getRuntime().availableProcessors()
#canal.instance.parser.parallelThreadSize = 16
## disruptor ringbuffer size, must be power of 2
canal.instance.parser.parallelBufferSize = 256
# table meta tsdb info
canal.instance.tsdb.enable = true
canal.instance.tsdb.dir = ${canal.file.data.dir:../conf}/${canal.instance.destination:}
canal.instance.tsdb.url = jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
canal.instance.tsdb.dbUsername = canal
canal.instance.tsdb.dbPassword = canal
# dump snapshot interval, default 24 hour
canal.instance.tsdb.snapshot.interval = 24
# purge snapshot expire , default 360 hour(15 days)
canal.instance.tsdb.snapshot.expire = 360
#################################################
######### 		destinations		#############
#################################################
canal.destinations = example
# conf root dir
canal.conf.dir = ../conf
# auto scan instance dir add/remove and start/stop instance
canal.auto.scan = true
canal.auto.scan.interval = 5
# set this value to 'true' means that when binlog pos not found, skip to latest.
# WARN: pls keep 'false' in production env, or if you know what you want.
canal.auto.reset.latest.pos.mode = false
canal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml
#canal.instance.tsdb.spring.xml = classpath:spring/tsdb/mysql-tsdb.xml
canal.instance.global.mode = spring
canal.instance.global.lazy = false
canal.instance.global.manager.address = ${canal.admin.manager}
#canal.instance.global.spring.xml = classpath:spring/memory-instance.xml
canal.instance.global.spring.xml = classpath:spring/file-instance.xml
#canal.instance.global.spring.xml = classpath:spring/default-instance.xml
##################################################
######### 	      MQ Properties      #############
##################################################
# aliyun ak/sk , support rds/mq
canal.aliyun.accessKey =
canal.aliyun.secretKey =
canal.aliyun.uid=
canal.mq.flatMessage = true
canal.mq.canalBatchSize = 50
canal.mq.canalGetTimeout = 100
# Set this value to "cloud", if you want open message trace feature in aliyun.
canal.mq.accessChannel = local
canal.mq.database.hash = true
canal.mq.send.thread.size = 30
canal.mq.build.thread.size = 8
##################################################
######### 		     Kafka 		     #############
##################################################
kafka.bootstrap.servers = 127.0.0.1:9092
kafka.acks = all
kafka.compression.type = none
kafka.batch.size = 16384
kafka.linger.ms = 1
kafka.max.request.size = 1048576
kafka.buffer.memory = 33554432
kafka.max.in.flight.requests.per.connection = 1
kafka.retries = 0
kafka.kerberos.enable = false
kafka.kerberos.krb5.file = ../conf/kerberos/krb5.conf
kafka.kerberos.jaas.file = ../conf/kerberos/jaas.conf
# sasl demo
# kafka.sasl.jaas.config = org.apache.kafka.common.security.scram.ScramLoginModule required \\n username=\"alice\" \\npassword="alice-secret\";
# kafka.sasl.mechanism = SCRAM-SHA-512
# kafka.security.protocol = SASL_PLAINTEXT
##################################################
######### 		    RocketMQ	     #############
##################################################
rocketmq.producer.group = test
rocketmq.enable.message.trace = false
rocketmq.customized.trace.topic =
rocketmq.namespace =
rocketmq.namesrv.addr = 127.0.0.1:9876
rocketmq.retry.times.when.send.failed = 0
rocketmq.vip.channel.enabled = false
rocketmq.tag =
##################################################
######### 		    RabbitMQ	     #############
##################################################
rabbitmq.host =
rabbitmq.virtual.host =
rabbitmq.exchange =
rabbitmq.username =
rabbitmq.password =
rabbitmq.queue =
rabbitmq.routingKey =
rabbitmq.deliveryMode =
##################################################
######### 		      Pulsar         #############
##################################################
pulsarmq.serverUrl =
pulsarmq.roleToken =
pulsarmq.topicTenantPrefix =

4.5 修改 example 文件夹下的 instance.properties 配置参数

server:port: 8089
spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8
spring.datasource:address: mysql:3306database: canal_managerusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=falsehikari:maximum-pool-size: 30minimum-idle: 1
canal:adminUser: adminadminPasswd: admin

4.6 删除canal容器

docker rm -f canal-server

4.7 以挂载文件的方式运行 canal 容器

// 重要:注意挂载日志文件到宿主机,方便查看容器运行日志
docker run --name canal-server -p 11111:11111 -d \
-v /mydata/canal/conf/example/instance.properties:/home/admin/canal-server/conf/example/instance.properties \
-v /mydata/canal/conf/canal.properties:/home/admin/canal-server/conf/canal.properties \
-v /mydata/canal/logs/:/home/admin/canal-server/logs/  \
--network canal_net \
canal/canal-server

备注:canal 容器中日志文件路径为:/home/admin/canal-server/logs/

注意:如果在宿主机上配置好了 instance.properties 文件内容,就无需进行4.2到4.6步骤,直接执行4.7步骤即可。

4.8 canal-admin 后台页面中管理服务及实例

可以在 【instance 管理】中新增或修改 instance 实例,在此新增的实例会将配置文件信息保存到 canal-manager 数据库的表 canal_instance_config 中。

在 canal-manager 数据库中查看新配置的实例,如下:

五、基于 go 语言订阅消费 canal-server

参考 github 库:https://github.com/withlin/canal-go

5.1 go 代码

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import ("fmt""log""os""time""github.com/withlin/canal-go/client"pbe "github.com/withlin/canal-go/protocol/entry""google.golang.org/protobuf/proto"
)
func main() {// 192.168.199.17 替换成你的canal server的地址// example 替换成-e canal.destinations=example 你自己定义的名字connector := client.NewSimpleCanalConnector("172.28.203.173", 11111, "", "", "example", 60000, 60*60*1000)err := connector.Connect()if err != nil {log.Println(err)os.Exit(1)}// https://github.com/alibaba/canal/wiki/AdminGuide//mysql 数据解析关注的表,Perl正则表达式.////多个正则之间以逗号(,)分隔,转义符需要双斜杠(\\)////常见例子:////  1.  所有表:.*   or  .*\\..*//	2.  canal schema下所有表: canal\\..*//	3.  canal下的以canal打头的表:canal\\.canal.*//	4.  canal schema下的一张表:canal\\.test1//  5.  多个规则组合使用:canal\\..*,mysql.test1,mysql.test2 (逗号分隔)err = connector.Subscribe(".*\\..*")if err != nil {log.Println(err)os.Exit(1)}for {message, err := connector.Get(100, nil, nil)if err != nil {log.Println(err)os.Exit(1)}batchId := message.Idif batchId == -1 || len(message.Entries) <= 0 {time.Sleep(300 * time.Millisecond)fmt.Println("===没有数据了===")continue}printEntry(message.Entries)}
}
func printEntry(entrys []pbe.Entry) {for _, entry := range entrys {if entry.GetEntryType() == pbe.EntryType_TRANSACTIONBEGIN || entry.GetEntryType() == pbe.EntryType_TRANSACTIONEND {continue}rowChange := new(pbe.RowChange)err := proto.Unmarshal(entry.GetStoreValue(), rowChange)checkError(err)if rowChange != nil {eventType := rowChange.GetEventType()header := entry.GetHeader()fmt.Println(fmt.Sprintf("================> binlog[%s : %d],name[%s,%s], eventType: %s", header.GetLogfileName(), header.GetLogfileOffset(), header.GetSchemaName(), header.GetTableName(), header.GetEventType()))for _, rowData := range rowChange.GetRowDatas() {if eventType == pbe.EventType_DELETE {printColumn(rowData.GetBeforeColumns())} else if eventType == pbe.EventType_INSERT {printColumn(rowData.GetAfterColumns())} else {fmt.Println("-------> before")printColumn(rowData.GetBeforeColumns())fmt.Println("-------> after")printColumn(rowData.GetAfterColumns())}}}}
}
func printColumn(columns []*pbe.Column) {for _, col := range columns {fmt.Println(fmt.Sprintf("%s : %s  update= %t", col.GetName(), col.GetValue(), col.GetUpdated()))}
}
func checkError(err error) {if err != nil {fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())os.Exit(1)}
}

5.2 效果演示

更新数据库表中的数据,可以看到 go 程序打印出 mysql 数据更新前后的变化:

六、报错问题

6.1 canal 服务运行后闪退

如何查看详细错误日志?

docker 运行 canal 服务时,将容器的错误日志(canal容器日志文件默认路径:/home/admin/canal-server/logs/)挂载到宿主机上, 即可查看详细日志:

发现是宿主机运行内存不够,用 docker status 查看,果然剩余内存不够运行 canal 服务,停止暂时不用的容器,再启动 canal-server,成功运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/935270.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UE网络编程完全指南:UDP TCP WebSocket实现详解

前言 在UE项目开发中,最常用的网络通讯协议主要是 UDP、TCP、WebSocket 这三种。它们能够覆盖绝大部分应用场景:UDP适合高频低延迟传输,TCP用于可靠双向通讯,WebSocket则擅长跨平台实时交互。 本文将展示这三种协议在U…

从十五岁的今天写给十六岁的明天

这真是一件奇怪的事情。 落款的日期一点一点改变,依旧是忙忙碌碌。 集训、作业、考试、面试…… 忧喜参半的日子,忙得抬不起头的日子,没有星星的日子。 就在这平淡的日子流逝时,不知是哪个“不开眼”的数字或是朋友…

kali U盘启动持久化

kali live 制作U盘启动设置持久化kali live 制作U盘启动设置持久化0-准备工作 1-写入镜像 2-创建持久化分区2.1-不加密2.1.1-创建分区 2.1.2-格式化分区(创建文件系统) 2.1.3-写入持久化配置文件2.2-加密2.2.1-创建分…

深入解析:Telerik UI for ASP.NET MVC 2025 Q3

深入解析:Telerik UI for ASP.NET MVC 2025 Q3pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…

配置Nginx服务器在Ubuntu平台上

安装Nginx更新软件包索引: sudo apt update安装Nginx: sudo apt install nginx启动Nginx服务: sudo systemctl start nginx.service 设置开机启动: sudo systemctl enable nginx.service 检查安装状态:通过访问服务…

缓存一致性验证秘笈

在多核 SoC 设计中,缓存一致性(Cache Coherence)验证 是保障数据一致性与系统性能的基石。本文深入解析高级验证策略,结合实战案例,系统讲解如何在设计早期高效捕捉潜在一致性问题。 1、形式验证 — 数学级确保一…

Java依记 DAY02 - I

计算机软件分为系统软件和应用软件 系统软件 DOS(磁盘操作系统) Windows Linux unix MAC Android ios 应用软件 微信 QQ.... 快捷键 win+E 打开资源管理器 win+R 打开命令提示符 DOS命令 打开命令提示符 1.打开控制…

元推理:汉字的发音,同音也是某种同构?

ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891 这是对汉字音韵逻辑的深度洞察! 观察完全正确——汉字发音确实遵循着严格的宇宙逻辑,同音现象正是语义同构在声学维度的精确映射。 一、发音逻辑的数学结构…

题解:qoj7759 Permutation Counting 2

我是容斥低低手,该训容斥了。 题意:给出 \(n\),计算对于 \(x,y\in[0,n)\),有多少个排列满足: \[\sum_{i=1}^{n-1}[p_i<p_{i+1}] = x \]\[\sum_{i=1}^{n-1}[p_{i}^{-1}<p_{i+1}^{-1}] = y \]\(n\le 500\)。 …

WAV 转 flac 格式

WAV 转 flac 格式 刘姐的歌版权掉了之前网盘里有 WAV 文件,只好再搞下了文件转换 https://www.freeconvert.com/zh/wav-to-flac 歌词封面(MusicTag)wav ===> flac 格式后,文件体积变小 WAV 是最原始的音频数据格…

EtherCAT芯片没有倍福授权的风险

使用未获得倍福授权的EtherCAT芯片可能面临多维度风险,尤其在技术合规性、市场准入和长期业务稳定性方面。以下是具体分析: 一、法律与专利风险 1.专利侵权责任 EtherCAT 技术的核心专利虽已到期,但EtherCAT技术协会…

为何是「对话式」智能体?因为人类本能丨对话式智能体专场,Convo AIRTE2025

在文字诞生之前,人类通过对话交换情感和思想——充满温度与实时反馈。今天,AI 与实时互动技术正引领一场「对话式社会」复兴,让沟通回归本能。从智能终端、儿童 AI 导师到智能客服,语音交互技术正让「对话式智能体…

2014-2024高考真题考点分布详细分析(另附完整高考真题下载) - 详解

2014-2024高考真题考点分布详细分析(另附完整高考真题下载) - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &qu…

详细介绍:MySQL专用服务器自动调优指南

详细介绍:MySQL专用服务器自动调优指南2025-10-12 09:50 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block …

P4147 玉蟾宫(最大子矩形)

思路 可以利用悬线法,处理对于每个点在高度为 \(h\) 时的左右边界,然后随着高度增加,这个边界表示的范围一定是单调不增的,但是高度又在增加,所以一直取 \(max\) 就对了 最后注意输出答案的三倍 \(C++\) \(AC\) …

【实录】应用 Verdaccio 从零搭建私有 npm 仓库(含完整步骤及避坑指南)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

CentOS 7 安装 bzip2-libs-1.0.6-13.el7.x86_64.rpm 的详细步骤

CentOS 7 安装 bzip2-libs-1.0.6-13.el7.x86_64.rpm 的详细步骤​它是 ​CentOS 7 系统里的一个 ​基础库文件包​(名字叫 bzip2-libs),主要作用是为其他需要压缩/解压功能的软件(比如 bzip2命令行工具或其他依赖它…

2025 年 10 月西安房屋鉴定公司最新推荐排行榜:覆盖房屋安全评估、结构检测、承载力鉴定、危房鉴定领域,助您选专业机构

随着房地产行业不断发展,房屋安全成为民众与企业关注的重点,房屋鉴定作为保障房屋安全的核心环节,其重要性愈发凸显。但当前行业内存在诸多问题,部分机构资质不全、技术团队专业度不足、仪器设备落后,还有些服务流…

完整教程:HAProxy 完整指南:简介、负载均衡原理与安装配置

完整教程:HAProxy 完整指南:简介、负载均衡原理与安装配置pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

单片机学习日记 - 详解

单片机学习日记 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &quo…