mirror of
https://github.com/alibaba/canal.git
synced 2026-11-04 00:30:15 +08:00
mirror schema 完成测试
This commit is contained in:
@@ -3,6 +3,7 @@ package com.alibaba.otter.canal.client.adapter.es.config;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
@@ -19,6 +20,7 @@ public class ESSyncConfigLoader {
|
|||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(ESSyncConfigLoader.class);
|
private static Logger logger = LoggerFactory.getLogger(ESSyncConfigLoader.class);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static synchronized Map<String, ESSyncConfig> load() {
|
public static synchronized Map<String, ESSyncConfig> load() {
|
||||||
logger.info("## Start loading es mapping config ... ");
|
logger.info("## Start loading es mapping config ... ");
|
||||||
|
|
||||||
@@ -26,7 +28,9 @@ public class ESSyncConfigLoader {
|
|||||||
|
|
||||||
Map<String, String> configContentMap = MappingConfigsLoader.loadConfigs("es");
|
Map<String, String> configContentMap = MappingConfigsLoader.loadConfigs("es");
|
||||||
configContentMap.forEach((fileName, content) -> {
|
configContentMap.forEach((fileName, content) -> {
|
||||||
ESSyncConfig config = new Yaml().loadAs(content, ESSyncConfig.class);
|
Map configMap = new Yaml().loadAs(content, Map.class); // yml自带的对象反射不是很稳定
|
||||||
|
JSONObject configJson = new JSONObject(configMap);
|
||||||
|
ESSyncConfig config = configJson.toJavaObject(ESSyncConfig.class);
|
||||||
try {
|
try {
|
||||||
config.validate();
|
config.validate();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.alibaba.otter.canal.client.adapter.hbase.config;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
@@ -24,6 +25,7 @@ public class MappingConfigLoader {
|
|||||||
*
|
*
|
||||||
* @return 配置名/配置文件名--对象
|
* @return 配置名/配置文件名--对象
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static Map<String, MappingConfig> load() {
|
public static Map<String, MappingConfig> load() {
|
||||||
logger.info("## Start loading hbase mapping config ... ");
|
logger.info("## Start loading hbase mapping config ... ");
|
||||||
|
|
||||||
@@ -31,7 +33,9 @@ public class MappingConfigLoader {
|
|||||||
|
|
||||||
Map<String, String> configContentMap = MappingConfigsLoader.loadConfigs("hbase");
|
Map<String, String> configContentMap = MappingConfigsLoader.loadConfigs("hbase");
|
||||||
configContentMap.forEach((fileName, content) -> {
|
configContentMap.forEach((fileName, content) -> {
|
||||||
MappingConfig config = new Yaml().loadAs(content, MappingConfig.class);
|
Map configMap = new Yaml().loadAs(content, Map.class); // yml自带的对象反射不是很稳定
|
||||||
|
JSONObject configJson = new JSONObject(configMap);
|
||||||
|
MappingConfig config = configJson.toJavaObject(MappingConfig.class);
|
||||||
try {
|
try {
|
||||||
config.validate();
|
config.validate();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -34,7 +34,14 @@ canal.conf:
|
|||||||
groups:
|
groups:
|
||||||
- groupId: g1
|
- groupId: g1
|
||||||
outerAdapters:
|
outerAdapters:
|
||||||
# - name: logger
|
- name: logger
|
||||||
|
# - name: rdb
|
||||||
|
# key: mysql1
|
||||||
|
# properties:
|
||||||
|
# jdbc.driverClassName: com.mysql.jdbc.Driver
|
||||||
|
# jdbc.url: jdbc:mysql://192.168.0.36/mytest?useUnicode=true
|
||||||
|
# jdbc.username: root
|
||||||
|
# jdbc.password: 121212
|
||||||
# - name: rdb
|
# - name: rdb
|
||||||
# key: oracle1
|
# key: oracle1
|
||||||
# properties:
|
# properties:
|
||||||
@@ -42,13 +49,15 @@ canal.conf:
|
|||||||
# jdbc.url: jdbc:oracle:thin:@localhost:49161:XE
|
# jdbc.url: jdbc:oracle:thin:@localhost:49161:XE
|
||||||
# jdbc.username: mytest
|
# jdbc.username: mytest
|
||||||
# jdbc.password: m121212
|
# jdbc.password: m121212
|
||||||
- name: rdb
|
# - name: rdb
|
||||||
key: mysql1
|
# key: postgres1
|
||||||
properties:
|
# properties:
|
||||||
jdbc.driverClassName: com.mysql.jdbc.Driver
|
# jdbc.driverClassName: org.postgresql.Driver
|
||||||
jdbc.url: jdbc:mysql://192.168.100.36/mytest?useUnicode=true
|
# jdbc.url: jdbc:postgresql://localhost:5432/postgres
|
||||||
jdbc.username: root
|
# jdbc.username: postgres
|
||||||
jdbc.password: Ambari-123
|
# jdbc.password: 121212
|
||||||
|
# threads: 1
|
||||||
|
# commitSize: 3000
|
||||||
# - name: hbase
|
# - name: hbase
|
||||||
# properties:
|
# properties:
|
||||||
# hbase.zookeeper.quorum: 127.0.0.1
|
# hbase.zookeeper.quorum: 127.0.0.1
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import com.alibaba.druid.pool.DruidDataSource;
|
|||||||
import com.alibaba.otter.canal.client.adapter.OuterAdapter;
|
import com.alibaba.otter.canal.client.adapter.OuterAdapter;
|
||||||
import com.alibaba.otter.canal.client.adapter.rdb.config.ConfigLoader;
|
import com.alibaba.otter.canal.client.adapter.rdb.config.ConfigLoader;
|
||||||
import com.alibaba.otter.canal.client.adapter.rdb.config.MappingConfig;
|
import com.alibaba.otter.canal.client.adapter.rdb.config.MappingConfig;
|
||||||
|
import com.alibaba.otter.canal.client.adapter.rdb.config.MirrorDbConfig;
|
||||||
import com.alibaba.otter.canal.client.adapter.rdb.monitor.RdbConfigMonitor;
|
import com.alibaba.otter.canal.client.adapter.rdb.monitor.RdbConfigMonitor;
|
||||||
import com.alibaba.otter.canal.client.adapter.rdb.service.RdbEtlService;
|
import com.alibaba.otter.canal.client.adapter.rdb.service.RdbEtlService;
|
||||||
import com.alibaba.otter.canal.client.adapter.rdb.service.RdbMirrorDbSyncService;
|
import com.alibaba.otter.canal.client.adapter.rdb.service.RdbMirrorDbSyncService;
|
||||||
@@ -37,7 +38,7 @@ public class RdbAdapter implements OuterAdapter {
|
|||||||
|
|
||||||
private Map<String, MappingConfig> rdbMapping = new ConcurrentHashMap<>(); // 文件名对应配置
|
private Map<String, MappingConfig> rdbMapping = new ConcurrentHashMap<>(); // 文件名对应配置
|
||||||
private Map<String, Map<String, MappingConfig>> mappingConfigCache = new ConcurrentHashMap<>(); // 库名-表名对应配置
|
private Map<String, Map<String, MappingConfig>> mappingConfigCache = new ConcurrentHashMap<>(); // 库名-表名对应配置
|
||||||
private Map<String, MappingConfig> mirrorDbConfigCache = new ConcurrentHashMap<>(); // 镜像库配置
|
private Map<String, MirrorDbConfig> mirrorDbConfigCache = new ConcurrentHashMap<>(); // 镜像库配置
|
||||||
|
|
||||||
private DruidDataSource dataSource;
|
private DruidDataSource dataSource;
|
||||||
|
|
||||||
@@ -54,6 +55,10 @@ public class RdbAdapter implements OuterAdapter {
|
|||||||
return mappingConfigCache;
|
return mappingConfigCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, MirrorDbConfig> getMirrorDbConfigCache() {
|
||||||
|
return mirrorDbConfigCache;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化方法
|
* 初始化方法
|
||||||
*
|
*
|
||||||
@@ -73,7 +78,7 @@ public class RdbAdapter implements OuterAdapter {
|
|||||||
for (Map.Entry<String, MappingConfig> entry : rdbMapping.entrySet()) {
|
for (Map.Entry<String, MappingConfig> entry : rdbMapping.entrySet()) {
|
||||||
String configName = entry.getKey();
|
String configName = entry.getKey();
|
||||||
MappingConfig mappingConfig = entry.getValue();
|
MappingConfig mappingConfig = entry.getValue();
|
||||||
if (!mappingConfig.getDbMapping().isMirrorDb()) {
|
if (!mappingConfig.getDbMapping().getMirrorDb()) {
|
||||||
Map<String, MappingConfig> configMap = mappingConfigCache.computeIfAbsent(
|
Map<String, MappingConfig> configMap = mappingConfigCache.computeIfAbsent(
|
||||||
StringUtils.trimToEmpty(mappingConfig.getDestination()) + "." + mappingConfig.getDbMapping()
|
StringUtils.trimToEmpty(mappingConfig.getDestination()) + "." + mappingConfig.getDbMapping()
|
||||||
.getDatabase() + "." + mappingConfig.getDbMapping().getTable(),
|
.getDatabase() + "." + mappingConfig.getDbMapping().getTable(),
|
||||||
@@ -81,9 +86,10 @@ public class RdbAdapter implements OuterAdapter {
|
|||||||
configMap.put(configName, mappingConfig);
|
configMap.put(configName, mappingConfig);
|
||||||
} else {
|
} else {
|
||||||
// mirrorDB
|
// mirrorDB
|
||||||
|
|
||||||
mirrorDbConfigCache.put(StringUtils.trimToEmpty(mappingConfig.getDestination()) + "."
|
mirrorDbConfigCache.put(StringUtils.trimToEmpty(mappingConfig.getDestination()) + "."
|
||||||
+ mappingConfig.getDbMapping().getDatabase(),
|
+ mappingConfig.getDbMapping().getDatabase(),
|
||||||
mappingConfig);
|
MirrorDbConfig.create(configName, mappingConfig));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.alibaba.otter.canal.client.adapter.rdb.config;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
@@ -24,6 +25,7 @@ public class ConfigLoader {
|
|||||||
*
|
*
|
||||||
* @return 配置名/配置文件名--对象
|
* @return 配置名/配置文件名--对象
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static Map<String, MappingConfig> load() {
|
public static Map<String, MappingConfig> load() {
|
||||||
logger.info("## Start loading rdb mapping config ... ");
|
logger.info("## Start loading rdb mapping config ... ");
|
||||||
|
|
||||||
@@ -31,7 +33,9 @@ public class ConfigLoader {
|
|||||||
|
|
||||||
Map<String, String> configContentMap = MappingConfigsLoader.loadConfigs("rdb");
|
Map<String, String> configContentMap = MappingConfigsLoader.loadConfigs("rdb");
|
||||||
configContentMap.forEach((fileName, content) -> {
|
configContentMap.forEach((fileName, content) -> {
|
||||||
MappingConfig config = new Yaml().loadAs(content, MappingConfig.class);
|
Map configMap = new Yaml().loadAs(content, Map.class); // yml自带的对象反射不是很稳定
|
||||||
|
JSONObject configJson = new JSONObject(configMap);
|
||||||
|
MappingConfig config = configJson.toJavaObject(MappingConfig.class);
|
||||||
try {
|
try {
|
||||||
config.validate();
|
config.validate();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ public class MappingConfig {
|
|||||||
if (dbMapping.database == null || dbMapping.database.isEmpty()) {
|
if (dbMapping.database == null || dbMapping.database.isEmpty()) {
|
||||||
throw new NullPointerException("dbMapping.database");
|
throw new NullPointerException("dbMapping.database");
|
||||||
}
|
}
|
||||||
if (!dbMapping.isMirrorDb() && (dbMapping.table == null || dbMapping.table.isEmpty())) {
|
if (!dbMapping.getMirrorDb() && (dbMapping.table == null || dbMapping.table.isEmpty())) {
|
||||||
throw new NullPointerException("dbMapping.table");
|
throw new NullPointerException("dbMapping.table");
|
||||||
}
|
}
|
||||||
if (!dbMapping.isMirrorDb() && (dbMapping.targetTable == null || dbMapping.targetTable.isEmpty())) {
|
if (!dbMapping.getMirrorDb() && (dbMapping.targetTable == null || dbMapping.targetTable.isEmpty())) {
|
||||||
throw new NullPointerException("dbMapping.targetTable");
|
throw new NullPointerException("dbMapping.targetTable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,8 +91,8 @@ public class MappingConfig {
|
|||||||
|
|
||||||
private Map<String, String> allMapColumns;
|
private Map<String, String> allMapColumns;
|
||||||
|
|
||||||
public boolean isMirrorDb() {
|
public Boolean getMirrorDb() {
|
||||||
return mirrorDb == null ? false : mirrorDb;
|
return mirrorDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMirrorDb(Boolean mirrorDb) {
|
public void setMirrorDb(Boolean mirrorDb) {
|
||||||
@@ -123,8 +123,8 @@ public class MappingConfig {
|
|||||||
this.targetPk = targetPk;
|
this.targetPk = targetPk;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMapAll() {
|
public Boolean getMapAll() {
|
||||||
return mapAll == null ? false : mapAll;
|
return mapAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMapAll(Boolean mapAll) {
|
public void setMapAll(Boolean mapAll) {
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.alibaba.otter.canal.client.adapter.rdb.config;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class MirrorDbConfig {
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
private MappingConfig mappingConfig;
|
||||||
|
Map<String, MappingConfig> tableConfig = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static MirrorDbConfig create(String fileName, MappingConfig mappingConfig) {
|
||||||
|
return new MirrorDbConfig(fileName, mappingConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MirrorDbConfig(String fileName, MappingConfig mappingConfig){
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.mappingConfig = mappingConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MappingConfig getMappingConfig() {
|
||||||
|
return mappingConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMappingConfig(MappingConfig mappingConfig) {
|
||||||
|
this.mappingConfig = mappingConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, MappingConfig> getTableConfig() {
|
||||||
|
return tableConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableConfig(Map<String, MappingConfig> tableConfig) {
|
||||||
|
this.tableConfig = tableConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import java.io.File;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.alibaba.otter.canal.client.adapter.rdb.config.MirrorDbConfig;
|
||||||
import org.apache.commons.io.filefilter.FileFilterUtils;
|
import org.apache.commons.io.filefilter.FileFilterUtils;
|
||||||
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
|
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
|
||||||
import org.apache.commons.io.monitor.FileAlterationMonitor;
|
import org.apache.commons.io.monitor.FileAlterationMonitor;
|
||||||
@@ -83,7 +84,8 @@ public class RdbConfigMonitor {
|
|||||||
try {
|
try {
|
||||||
if (rdbAdapter.getRdbMapping().containsKey(file.getName())) {
|
if (rdbAdapter.getRdbMapping().containsKey(file.getName())) {
|
||||||
// 加载配置文件
|
// 加载配置文件
|
||||||
String configContent = MappingConfigsLoader.loadConfig(adapterName + File.separator + file.getName());
|
String configContent = MappingConfigsLoader
|
||||||
|
.loadConfig(adapterName + File.separator + file.getName());
|
||||||
MappingConfig config = new Yaml().loadAs(configContent, MappingConfig.class);
|
MappingConfig config = new Yaml().loadAs(configContent, MappingConfig.class);
|
||||||
config.validate();
|
config.validate();
|
||||||
if ((key == null && config.getOuterAdapterKey() == null)
|
if ((key == null && config.getOuterAdapterKey() == null)
|
||||||
@@ -118,13 +120,19 @@ public class RdbConfigMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addConfigToCache(File file, MappingConfig config) {
|
private void addConfigToCache(File file, MappingConfig mappingConfig) {
|
||||||
rdbAdapter.getRdbMapping().put(file.getName(), config);
|
rdbAdapter.getRdbMapping().put(file.getName(), mappingConfig);
|
||||||
Map<String, MappingConfig> configMap = rdbAdapter.getMappingConfigCache()
|
Map<String, MappingConfig> configMap = rdbAdapter.getMappingConfigCache()
|
||||||
.computeIfAbsent(StringUtils.trimToEmpty(config.getDestination()) + "."
|
.computeIfAbsent(StringUtils.trimToEmpty(mappingConfig.getDestination()) + "."
|
||||||
+ config.getDbMapping().getDatabase() + "." + config.getDbMapping().getTable(),
|
+ mappingConfig.getDbMapping().getDatabase() + "."
|
||||||
|
+ mappingConfig.getDbMapping().getTable(),
|
||||||
k1 -> new HashMap<>());
|
k1 -> new HashMap<>());
|
||||||
configMap.put(file.getName(), config);
|
configMap.put(file.getName(), mappingConfig);
|
||||||
|
|
||||||
|
Map<String, MirrorDbConfig> mirrorDbConfigCache = rdbAdapter.getMirrorDbConfigCache();
|
||||||
|
mirrorDbConfigCache.put(StringUtils.trimToEmpty(mappingConfig.getDestination()) + "."
|
||||||
|
+ mappingConfig.getDbMapping().getDatabase(),
|
||||||
|
MirrorDbConfig.create(file.getName(), mappingConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteConfigFromCache(File file) {
|
private void deleteConfigFromCache(File file) {
|
||||||
@@ -136,6 +144,12 @@ public class RdbConfigMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rdbAdapter.getMirrorDbConfigCache().forEach((key, mirrorDbConfig) -> {
|
||||||
|
if (mirrorDbConfig.getFileName().equals(file.getName())) {
|
||||||
|
rdbAdapter.getMirrorDbConfigCache().remove(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
@@ -14,7 +13,10 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
import com.alibaba.otter.canal.client.adapter.rdb.config.MappingConfig;
|
import com.alibaba.otter.canal.client.adapter.rdb.config.MappingConfig;
|
||||||
|
import com.alibaba.otter.canal.client.adapter.rdb.config.MirrorDbConfig;
|
||||||
import com.alibaba.otter.canal.client.adapter.rdb.support.SingleDml;
|
import com.alibaba.otter.canal.client.adapter.rdb.support.SingleDml;
|
||||||
import com.alibaba.otter.canal.client.adapter.support.Dml;
|
import com.alibaba.otter.canal.client.adapter.support.Dml;
|
||||||
|
|
||||||
@@ -28,13 +30,11 @@ public class RdbMirrorDbSyncService {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RdbMirrorDbSyncService.class);
|
private static final Logger logger = LoggerFactory.getLogger(RdbMirrorDbSyncService.class);
|
||||||
|
|
||||||
private Map<String, MappingConfig> mirrorDbConfigCache; // 镜像库配置
|
private Map<String, MirrorDbConfig> mirrorDbConfigCache; // 镜像库配置
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
private RdbSyncService rdbSyncService; // rdbSyncService代理
|
private RdbSyncService rdbSyncService; // rdbSyncService代理
|
||||||
|
|
||||||
private final Map<String, MappingConfig> tableDbConfigCache = new ConcurrentHashMap<>(); // 自动生成的库表配置缓存
|
public RdbMirrorDbSyncService(Map<String, MirrorDbConfig> mirrorDbConfigCache, DataSource dataSource,
|
||||||
|
|
||||||
public RdbMirrorDbSyncService(Map<String, MappingConfig> mirrorDbConfigCache, DataSource dataSource,
|
|
||||||
Integer threads, Map<String, Map<String, Integer>> columnsTypeCache){
|
Integer threads, Map<String, Map<String, Integer>> columnsTypeCache){
|
||||||
this.mirrorDbConfigCache = mirrorDbConfigCache;
|
this.mirrorDbConfigCache = mirrorDbConfigCache;
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
@@ -52,27 +52,32 @@ public class RdbMirrorDbSyncService {
|
|||||||
for (Dml dml : dmls) {
|
for (Dml dml : dmls) {
|
||||||
String destination = StringUtils.trimToEmpty(dml.getDestination());
|
String destination = StringUtils.trimToEmpty(dml.getDestination());
|
||||||
String database = dml.getDatabase();
|
String database = dml.getDatabase();
|
||||||
MappingConfig configMap = mirrorDbConfigCache.get(destination + "." + database);
|
MirrorDbConfig mirrorDbConfig = mirrorDbConfigCache.get(destination + "." + database);
|
||||||
if (configMap == null) {
|
if (mirrorDbConfig == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dml.getSql() != null) {
|
if (StringUtils.isNotEmpty(dml.getSql())) {
|
||||||
// DDL
|
// DDL
|
||||||
executeDdl(dml);
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("DDL: {}", JSON.toJSONString(dml, SerializerFeature.WriteMapNullValue));
|
||||||
|
}
|
||||||
|
executeDdl(mirrorDbConfig, dml);
|
||||||
rdbSyncService.getColumnsTypeCache().remove(destination + "." + database + "." + dml.getTable());
|
rdbSyncService.getColumnsTypeCache().remove(destination + "." + database + "." + dml.getTable());
|
||||||
tableDbConfigCache.remove(destination + "." + database + "." + dml.getTable()); // 删除对应库表配置
|
mirrorDbConfig.getTableConfig().remove(dml.getTable()); // 删除对应库表配置
|
||||||
} else {
|
} else {
|
||||||
// DML
|
// DML
|
||||||
initMappingConfig(destination + "." + database + "." + dml.getTable(), configMap, dml);
|
initMappingConfig(dml.getTable(), mirrorDbConfig.getMappingConfig(), mirrorDbConfig, dml);
|
||||||
dmlList.add(dml);
|
dmlList.add(dml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!dmlList.isEmpty()) {
|
if (!dmlList.isEmpty()) {
|
||||||
rdbSyncService.sync(dmlList, dml -> {
|
rdbSyncService.sync(dmlList, dml -> {
|
||||||
|
MirrorDbConfig mirrorDbConfig = mirrorDbConfigCache
|
||||||
|
.get(dml.getDestination() + "." + dml.getDatabase());
|
||||||
String destination = StringUtils.trimToEmpty(dml.getDestination());
|
String destination = StringUtils.trimToEmpty(dml.getDestination());
|
||||||
String database = dml.getDatabase();
|
String database = dml.getDatabase();
|
||||||
String table = dml.getTable();
|
String table = dml.getTable();
|
||||||
MappingConfig config = tableDbConfigCache.get(destination + "." + database + "." + table);
|
MappingConfig config = mirrorDbConfig.getTableConfig().get(table);
|
||||||
|
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -108,10 +113,10 @@ public class RdbMirrorDbSyncService {
|
|||||||
* @param baseConfigMap db sync config
|
* @param baseConfigMap db sync config
|
||||||
* @param dml DML
|
* @param dml DML
|
||||||
*/
|
*/
|
||||||
private void initMappingConfig(String key, MappingConfig baseConfigMap, Dml dml) {
|
private void initMappingConfig(String key, MappingConfig baseConfigMap, MirrorDbConfig mirrorDbConfig, Dml dml) {
|
||||||
MappingConfig mappingConfig = tableDbConfigCache.get(key);
|
MappingConfig mappingConfig = mirrorDbConfig.getTableConfig().get(key);
|
||||||
if (mappingConfig == null) {
|
if (mappingConfig == null) {
|
||||||
// 构造一个配置
|
// 构造表配置
|
||||||
mappingConfig = new MappingConfig();
|
mappingConfig = new MappingConfig();
|
||||||
mappingConfig.setDataSourceKey(baseConfigMap.getDataSourceKey());
|
mappingConfig.setDataSourceKey(baseConfigMap.getDataSourceKey());
|
||||||
mappingConfig.setDestination(baseConfigMap.getDestination());
|
mappingConfig.setDestination(baseConfigMap.getDestination());
|
||||||
@@ -129,7 +134,7 @@ public class RdbMirrorDbSyncService {
|
|||||||
pkNames.forEach(pkName -> pkMapping.put(pkName, pkName));
|
pkNames.forEach(pkName -> pkMapping.put(pkName, pkName));
|
||||||
dbMapping.setTargetPk(pkMapping);
|
dbMapping.setTargetPk(pkMapping);
|
||||||
|
|
||||||
tableDbConfigCache.put(key, mappingConfig);
|
mirrorDbConfig.getTableConfig().put(key, mappingConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,11 +143,11 @@ public class RdbMirrorDbSyncService {
|
|||||||
*
|
*
|
||||||
* @param ddl DDL
|
* @param ddl DDL
|
||||||
*/
|
*/
|
||||||
private void executeDdl(Dml ddl) {
|
private void executeDdl(MirrorDbConfig mirrorDbConfig, Dml ddl) {
|
||||||
try (Connection conn = dataSource.getConnection(); Statement statement = conn.createStatement()) {
|
try (Connection conn = dataSource.getConnection(); Statement statement = conn.createStatement()) {
|
||||||
statement.execute(ddl.getSql());
|
statement.execute(ddl.getSql());
|
||||||
// 移除对应配置
|
// 移除对应配置
|
||||||
tableDbConfigCache.remove(ddl.getDatabase() + "." + ddl.getDatabase() + "." + ddl.getTable());
|
mirrorDbConfig.getTableConfig().remove(ddl.getTable());
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Execute DDL sql: {} for database: {}", ddl.getSql(), ddl.getDatabase());
|
logger.trace("Execute DDL sql: {} for database: {}", ddl.getSql(), ddl.getDatabase());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ public class RdbSyncService {
|
|||||||
public void sync(Map<String, Map<String, MappingConfig>> mappingConfig, List<Dml> dmls) {
|
public void sync(Map<String, Map<String, MappingConfig>> mappingConfig, List<Dml> dmls) {
|
||||||
try {
|
try {
|
||||||
sync(dmls, dml -> {
|
sync(dmls, dml -> {
|
||||||
if (dml.getSql() != null) {
|
if (StringUtils.isNotEmpty(dml.getSql())) {
|
||||||
// DDL
|
// DDL
|
||||||
columnsTypeCache.remove(dml.getDestination() + "." + dml.getDatabase() + "." + dml.getTable());
|
columnsTypeCache.remove(dml.getDestination() + "." + dml.getDatabase() + "." + dml.getTable());
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class SyncUtil {
|
|||||||
|
|
||||||
public static Map<String, String> getColumnsMap(MappingConfig.DbMapping dbMapping, Collection<String> columns) {
|
public static Map<String, String> getColumnsMap(MappingConfig.DbMapping dbMapping, Collection<String> columns) {
|
||||||
Map<String, String> columnsMap;
|
Map<String, String> columnsMap;
|
||||||
if (dbMapping.isMapAll()) {
|
if (dbMapping.getMapAll()) {
|
||||||
if (dbMapping.getAllMapColumns() != null) {
|
if (dbMapping.getAllMapColumns() != null) {
|
||||||
return dbMapping.getAllMapColumns();
|
return dbMapping.getAllMapColumns();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,27 @@
|
|||||||
dataSourceKey: defaultDS
|
dataSourceKey: defaultDS
|
||||||
destination: example
|
destination: example
|
||||||
outerAdapterKey: mysql1
|
outerAdapterKey: oracle1
|
||||||
concurrent: true
|
concurrent: true
|
||||||
dbMapping:
|
dbMapping:
|
||||||
mirrorDb: true
|
|
||||||
database: mytest
|
database: mytest
|
||||||
# table: user
|
table: user
|
||||||
# targetTable: mytest.tb_user
|
targetTable: mytest.tb_user
|
||||||
# targetPk:
|
targetPk:
|
||||||
# id: id
|
id: id
|
||||||
# mapAll: true
|
mapAll: true
|
||||||
# targetColumns:
|
# targetColumns:
|
||||||
# id:
|
# id:
|
||||||
# name:
|
# name:
|
||||||
# role_id:
|
# role_id:
|
||||||
# c_time:
|
# c_time:
|
||||||
# test1:
|
# test1:
|
||||||
|
|
||||||
|
|
||||||
|
# Mirror schema synchronize config
|
||||||
|
#dataSourceKey: defaultDS
|
||||||
|
#destination: example
|
||||||
|
#outerAdapterKey: mysql1
|
||||||
|
#concurrent: true
|
||||||
|
#dbMapping:
|
||||||
|
# mirrorDb: true
|
||||||
|
# database: mytest
|
||||||
|
|||||||
Reference in New Issue
Block a user