canal java_canal使用小结

一、基本概念

mysql本身支持主从备份,原理就是主库master生成的binlog文件记录了所有的增删改操作语句,然后slave向master发送dump协议,master将binlog日志文件推送给从库slave解析执行,达到数据一致备份的目的。

canal,基于java开发,伪装成一个slave,去监听获取增量的binlog日志文件,然后解析处理获得的相关数据(过程中可以加入自由的加入一些额外的功能性代码需求),利用获得的数据,可以用其他不同用途,比如同步到es中做搜索相关。

二、canal基本配置使用

测试环境:windows、mysql 5.7.26、canal 1.1.3、Navicat for MySQL。

1、mysql安装和配置

1.1、下载安装解压忽略。进入mysql解压后目录,新增data文件夹。

1.2、新增my.ini文件,添加配置:

[client]

# 设置mysql客户端连接服务端时默认使用的端口

port=3311

[mysql]

default-character-set=utf8

[mysqld]

character-set-server=utf8

port=3311

# 默认存储引擎innoDB

default-storage-engine=INNODB

# Server Id.数据库服务器id,这个id用来在主从服务器中标记唯一mysql服务器

server-id=1

datadir=E:\\soft\\mysql2\\data

bind-address=0.0.0.0

# 开启binlog日志

log-bin=mysql-bin

binlog_format = ROW

1.3、cmd进入并目录,启动/关闭 mysql:

//启动

net start mysql

//关闭

net stop mysql

1.4、连接mysql并设置密码

连接:mysql -uroot -p,初始密码为空,一直按enter即可进入mysql命令行。

进入后设置密码:

// 切换库

use mysql;

// 设置密码

update user set authentication_string=PASSWORD("123456") where user="root";

// 刷新生效

flush privileges;

设置成功后,quit退出重进,输入密码123456。

1.5、新增个canal的访问账户

// 新增用户

CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';

// 授权

GRANT SHOW VIEW, SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';

// 刷新

FLUSH PRIVILEGES;

2、canal安装配置

2.1、目录结构

433db0050c4444004a19f419e98ae360.png

其中cfang是拷贝example,需要多个instance可继续拷贝,再修改每个instance中的配置文件。

2.1、配置canal.properties

9b176f3c21e21a59ff7ff27025231baf.png

port可自定义,用于canal对外服务接口。destinations配置instance列表(连接db)。

2.2、配置instance.properties

520ee867674936fbb263be456664b074.png

其中canal.instance.defaultDatabaseName可不配置,全库扫描。

2.3、启动

bin目录,点击startup.bat,查看/logs/canal/canal.log日志文件,出现以下则为开启成功:

4b2f63d7a5316b950ed40421b37a659b.png

2.4、canal数据格式:

Entry

Header

logfileName [binlog文件名]

logfileOffset [binlog position]

executeTime [发生的变更]

schemaName

tableName

eventType [insert/update/delete类型]

entryType [事务头BEGIN/事务尾END/数据ROWDATA]

storeValue [byte数据,可展开,对应的类型为RowChange]

RowChange

isDdl [是否是ddl变更操作,比如create table/drop table]

sql [具体的ddl sql]

rowDatas [具体insert/update/delete的变更数据,可为多条,1个binlog event事件可对应多条变更,比如批处理]

beforeColumns [Column类型的数组]

afterColumns [Column类型的数组]

Column

index

sqlType [jdbc type]

name [column name]

isKey [是否为主键]

updated [是否发生过变更]

isNull [值是否为null]

value [具体的内容,注意为文本]

2.5、java程序测试

pom导入:

com.alibaba.otter

canal.client

1.1.3

java测试:

package com.cfang.prebo;

import java.net.InetSocketAddress;

import java.util.List;

import java.util.stream.Collectors;

import com.alibaba.otter.canal.client.CanalConnector;

import com.alibaba.otter.canal.client.CanalConnectors;

import com.alibaba.otter.canal.protocol.CanalEntry.Column;

import com.alibaba.otter.canal.protocol.CanalEntry.Entry;

import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;

import com.alibaba.otter.canal.protocol.CanalEntry.EventType;

import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;

import com.alibaba.otter.canal.protocol.CanalEntry.RowData;

import com.alibaba.otter.canal.protocol.Message;

public class CanalTest {

public static void main(String[] args) throws Exception {

CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("127.0.0.1", 11111), "cfang", "", "");

connector.connect();

connector.subscribe(".*\\..*");

connector.rollback();

while (true) {

Message message = connector.getWithoutAck(100); // 获取指定数量的数据

long batchId = message.getId();

if (batchId == -1 || message.getEntries().isEmpty()) {

Thread.sleep(1000);

continue;

}

// System.out.println(message.getEntries());

printEntries(message.getEntries());

connector.ack(batchId);// 提交确认,消费成功,通知server删除数据

// connector.rollback(batchId);// 处理失败, 回滚数据,后续重新获取数据

}

}

private static void printEntries(List entries) throws Exception {

for (Entry entry : entries) {

if (entry.getEntryType() != EntryType.ROWDATA) {

continue;

}

RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());

EventType eventType = rowChange.getEventType();

System.out.println(String.format("================> binlog[%s:%s] , name[%s,%s] , eventType : %s",

entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),

entry.getHeader().getSchemaName(), entry.getHeader().getTableName(), eventType));

for (RowData rowData : rowChange.getRowDatasList()) {

switch (rowChange.getEventType()) {

case INSERT:

System.out.println("INSERT ");

printColumns(rowData.getAfterColumnsList());

break;

case UPDATE:

System.out.println("UPDATE ");

printColumns(rowData.getAfterColumnsList());

break;

case DELETE:

System.out.println("DELETE ");

printColumns(rowData.getBeforeColumnsList());

break;

default:

break;

}

}

}

}

private static void printColumns(List columns) {

for(Column column : columns) {

System.out.println(column.getName() + " : " + column.getValue() + " update=" + column.getUpdated());

}

}

}

Navicat中进行相关操作的时候,可在控台看到输出,例如:

67772625bb8af7cb42e96a754f4fb8b5.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值