canal
canal copied to clipboard
DML日志正常,但是数据未同步至MYSQL数据库
Question
adapter日志中每一条变更日志都有,但是变更没有同步至目标数据库
我也遇到同样的问题,版本用的是1.1.6,你解决了吗
client-adapter/rdb/src/main/java/com/alibaba/otter/canal/client/adapter/rdb/service/RdbMirrorDbSyncService.java
/**
* 初始化表配置
*
* @param key 配置key: destination.database.table
* @param baseConfigMap db sync config
* @param dml DML
*/
private void initMappingConfig(String key, MappingConfig baseConfigMap, MirrorDbConfig mirrorDbConfig, Dml dml) {
MappingConfig mappingConfig = mirrorDbConfig.getTableConfig().get(key);
if (mappingConfig == null) {
// 构造表配置
mappingConfig = new MappingConfig();
mappingConfig.setDataSourceKey(baseConfigMap.getDataSourceKey());
mappingConfig.setDestination(baseConfigMap.getDestination());
mappingConfig.setGroupId(baseConfigMap.getGroupId());
mappingConfig.setOuterAdapterKey(baseConfigMap.getOuterAdapterKey());
mappingConfig.setConcurrent(baseConfigMap.getConcurrent());
MappingConfig.DbMapping dbMapping = new MappingConfig.DbMapping();
mappingConfig.setDbMapping(dbMapping);
dbMapping.setDatabase(dml.getDatabase());
dbMapping.setTable(dml.getTable());
dbMapping.setTargetDb(dml.getDatabase());// 目标数据库
dbMapping.setTargetTable(dml.getTable());// 目标表,从dml解析,就是binlog解析出来的库和表名
dbMapping.setMapAll(true);
List<String> pkNames = dml.getPkNames();
Map<String, String> pkMapping = new LinkedHashMap<>();
pkNames.forEach(pkName -> pkMapping.put(pkName, pkName));
dbMapping.setTargetPk(pkMapping);
mirrorDbConfig.getTableConfig().put(key, mappingConfig);
}
}
mirrorDbConfigCache中的mappingConfig是rdb相关配置文件的内容,tableConfig的数据在initMappingConfig方法中赋值,数据与mappingConfig差不多,但数据库名和表名是从dml解析出来的
/**
* 批量同步Dml
*
* @param dmlList Dml列表,不包含DDL
*/
private void syncDml(List<Dml> dmlList) {
if (dmlList == null || dmlList.isEmpty()) {
return;
}
rdbSyncService.sync(dmlList, dml -> {
MirrorDbConfig mirrorDbConfig = mirrorDbConfigCache.get(dml.getDestination() + "." + dml.getDatabase());
if (mirrorDbConfig == null) {
return false;
}
// 原代码
// String table = dml.getTable();
// MappingConfig config = mirrorDbConfig.getTableConfig().get(table);
MappingConfig config = mirrorDbConfig.getMappingConfig();// 修改代码
if (config == null) {
return false;
}
rdbSyncService.appendDmlPartition(config, dml);
return true;
});
}
获取配置取的tableConfig,最终导致解析执行的sql,还是同一个库中同一张表,相当于同一个sql;陷入了死循环中。从tableConfig中取配置就可以解决,字段映射没测试,DDL语句未做处理,自行研究。初次学习canal,不知道这种使用场景对不对。 mirrorDbConfigCache中的mappingConfig与tableConfig两者的区别是啥?
我按标记的syncDml里调整,没有效果啊。是覆盖plugins目录下的那个jar包吗?