使用canal读取mysql8.0.20版本的binlog,同步新增数据到doris中
1.mysql信息
版本:8.0.20
已开启binlog配置:
[mysqld]
server_id = 1
log-bin = mysql-bin
binlog-format = ROW
创建canal使用的读取binlog的用户及设置权限等
create user 'canal_deploy'@'%' identified with mysql_native_password by '3Hd8plPcOl2zept1';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal_deploy'@'%';
flush privileges;
创建mysql测试使用的数据库和数据表
create database source_database;
use source_database;
CREATE TABLE `source_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`gender` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2.cancal信息
版本:canal.deployer-1.1.6.tar.gz
注意:解压缩后需要替换lib目录下连接mysql使用的jar包,后面步骤会详细讲述
mysql-connector-java-8.0.20.jar下载地址:https://downloads.mysql.com/archives/c-j/
https://downloads.mysql.com/archives/get/p/3/file/mysql-connector-java-8.0.20.tar.gz
3.doris信息
版本:1.2.4.1
创建跟mysql中source_database数据库的数据表source_table同结构的数据表
Binlog Load只能支持Unique类型的目标表,且必须激活目标表的Batch Delete功能。
开启Batch Delete的方法可以参考help alter table中的批量删除功能。
mysql -uroot -P9030 -h127.0.0.1
CREATE DATABASE dest_database;
use dest_database;
CREATE TABLE `dest_table` (
`id` int(11) NOT NULL ,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`gender` varchar(255) DEFAULT NULL
)
COMMENT "Doris Table"
unique key(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_num" = "1"
);
# 再开启BATCH_DELETE功能 (会提示开启失败,已经开启这个功能了)
ALTER TABLE dest_database.dest_table ENABLE FEATURE "BATCH_DELETE";
4.zookeeper配置
tar -zxv -f apache-zookeeper-3.7.1-bin.tar.gz
cd apache-zookeeper-3.7.1-bin
cp conf/zoo_sample.cfg conf/zoo.cfg
sh bin/zkServer.sh start
5.canal配置
mkdir /opt/canal-deploy && cd /opt/canal-deploy
cp /usr/local/src/canal.deployer-1.1.6.tar.gz .
tar -zxv -f canal.deployer-1.1.6.tar.gz
# 更新连接mysql使用的jar包
mv lib/mysql-connector-java-5.1.48.jar lib/mysql-connector-java-5.1.48.jar.bak
cp mysql-connector-java-8.0.20.jar lib/
chmod 777 lib/mysql-connector-java-8.0.20.jar
chown u+s lib/mysql-connector-java-8.0.20.jar
chown u+t lib/mysql-connector-java-8.0.20.jar
# 修改配置文件
mkdir conf/binlogload
cp conf/example/instance.properties conf/binlogload/
vim conf/canal.properties
canal.zkServers = 127.0.0.1:2181 # 修改这行,加上zookeeper的地址和端口
canal.destinations = binlogload # 修改这行,把example修改成binlogload
vim conf/binlogload/instance.properties
canal.instance.mysql.slaveId=202 # 修改这行,跟mysql的master id不一样
canal.instance.master.address=127.0.0.1:3306 # mysql的连接地址
canal.instance.dbUsername=canal_deploy # 上面步骤创建的访问mysql的binlog日志的用户名
canal.instance.dbPassword=3Hd8plPcOl2zept1 # 上面步骤创建的访问mysql的binlog日志的用户名
# 启动cancal.deploy
sh bin/startup.sh
tail -100f logs/binlogload/binlogload.log
tail -100f logs/canal/canal.log
要是在canal.log日志中查看到有如下报错:
2023-06-16 10:05:04.334 [New I/O server worker #1-1] ERROR c.a.otter.canal.server.netty.handler.SessionHandler - something goes wrong with channel:[id: 0x7b47aa37, /127.0.0.1:55898 => /127.0.0.1:11111], exception=java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
at sun.nio.ch.IOUtil.read(IOUtil.java:192)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:322)
at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:281)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:201)
at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
解决办法:
参考网址:https://blog.csdn.net/weixin_39970883/article/details/125842642
直接修改meta.dat中关于mysql的binlog的定位信息
先停止canal
sh bin/stop.sh
修改配置文件下的meta.dat文件
主要是修改position和timestamp
position从mysql中查看
mysql> show master status;
timestamp是当前时间戳,在mysql命令行中执行:select UNIX_TIMESTAMP(); 获取
mysql> select UNIX_TIMESTAMP();
然后再启动canal,canal.log日志文件中就不会再报:exception=java.io.IOException: Connection reset by peer错误了
手动往mysql表中插入一条数据,会发现如下俩日志文件中都没有报错信息,此时就算使用canal成功读取到binlog数据了 (这点有别于旧版本,在旧版本中可以在日志中查看到更新的binlog数据等)
tail -100f logs/binlogload/binlogload.log
tail -100f logs/canal/canal.log
6.doris中创建同步作业
数据同步(Sync Job)功能,支持用户提交一个常驻的数据同步作业,通过从指定的远端地址读取Binlog日志,增量同步用户在Mysql数据库的对数据更新操作的CDC(Change Data Capture)功能。 目前数据同步作业只支持对接Canal,从Canal Server上获取解析好的Binlog数据,导入到Doris内。 用户可通过 SHOW SYNC JOB
查看数据同步作业状态。 语法:
CREATE SYNC [db.]job_name
(
channel_desc,
channel_desc
...
)
binlog_desc
-
job_name
同步作业名称,是作业在当前数据库内的唯一标识,相同job_name
的作业只能有一个在运行。 -
channel_desc
作业下的数据通道,用来描述mysql源表到doris目标表的映射关系。
语法:
FROM mysql_db.src_tbl INTO des_tbl
[partitions]
[columns_mapping] -
mysql_db.src_tbl
指定mysql端的数据库和源表。des_tbl
指定doris端的目标表,只支持Unique表,且需开启表的batch delete功能(开启方法请看help alter table的'批量删除功能')。partitions
指定导入目的表的哪些 partition 中。如果不指定,则会自动导入到对应的 partition 中。
示例:
PARTITION(p1, p2, p3)column_mapping
指定mysql源表和doris目标表的列之间的映射关系。如果不指定,FE会默认源表和目标表的列按顺序一一对应。
不支持 col_name = expr 的形式表示列。
示例:
假设目标表列为(k1, k2, v1),
改变列k1和k2的顺序
COLUMNS(k2, k1, v1)
忽略源数据的第四列
COLUMNS(k2, k1, v1, dummy_column)
-
binlog_desc
用来描述远端数据源,目前仅支持canal一种。
语法:
FROM BINLOG
(
"key1" = "value1",
"key2" = "value2"
) -
-
Canal 数据源对应的属性,以
canal.
为前缀 -
- canal.server.ip: canal server的地址
- canal.server.port: canal server的端口
- canal.destination: instance的标识
- canal.batchSize: 获取的batch大小的最大值,默认8192
- canal.username: instance的用户名
- canal.password: instance的密码
- canal.debug: 可选,设置为true时,会将batch和每一行数据的详细信息都打印出来 Examples:
-
为 dest_database 的 dest_table 创建一个名为 job1 的数据同步作业,连接本地的Canal服务器,对应Mysql源表 source_database.source_table
创建同步任务之前,首先要在fe.conf里配置enable_create_sync_job=true,这个默认是false不启用,否则就不能创建同步任务 (好像不用设置就能创建同步任务)
mysql -uroot -P9030 -h127.0.0.1
CREATE SYNC `dest_database`.`job1` # 目的库中的job
(
FROM `source_database`.`source_table` INTO `dest_table` # 来源库,来源表,目的表
(id,name,age,gender) # 表结构字段,有些文章中讲的不用写这个表结构 (亲测,不加表结构字段也能使用)
)
FROM BINLOG
(
"type" = "canal",
"canal.server.ip" = "127.0.0.1",
"canal.server.port" = "11111",
"canal.destination" = "binlogload", # 跟canal中配置保持一致
"canal.username" = "canal", # 默认的用户名和密码
"canal.password" = "canal"
);
查看同步任务
SHOW SYNC JOB from job1\G;
# 查看Status状态,一开始是Status: position:N/A,手动往mysql的源库源表中新增一条数据后,在doris中的目的库目的表能查询到这条数据,这个status状态也就随着更新发生变化了
#暂停同步任务,jobname为提交的job名称
PAUSE SYNC JOB jobname; #暂停同步任务
RESUME SYNC JOB jobname; #恢复同步任务
STOP SYNC JOB jobname; #停止同步任务 (停止任务后还没找到启动同步任务的命令,不建议使用停止命令,建议暂停命令)
7.多表同步
注意:"canal.destination" = "binlogload"已经被使用的话就不能再次使用配置同步任务了,可以先把之前的同步任务停止掉,然后再新创建一个多表同步的(加上原来要同步的表)
CREATE SYNC dest_database.doris_mysql_binlog_demo_job
(
FROM source_database.source_table1 INTO dest_table1,
FROM source_database.source_table2 INTO dest_table2,
FROM source_database.source_table3 INTO dest_table3,
FROM source_database.source_table4 INTO dest_table4
)
FROM BINLOG
(
"type" = "canal",
"canal.server.ip" = "172.31.128.5",
"canal.server.port" = "11111",
"canal.destination" = "binlogload",
"canal.username" = "canal",
"canal.password" = "canal"
);