otter跨数据库同步:MySQL到Oracle方案实现
【免费下载链接】otter 阿里巴巴分布式数据库同步系统(解决中美异地机房) 项目地址: https://gitcode.com/gh_mirrors/ot/otter
引言:跨数据库同步的挑战与解决方案
在企业级应用中,多数据库架构(如MySQL与Oracle并存)常导致数据孤岛问题。阿里巴巴开源的分布式数据库同步系统Otter(水獭)通过基于日志的增量同步技术,解决了中美异地机房的跨数据库同步难题。本文将详细解析如何利用Otter构建MySQL到Oracle的实时数据同步通道,涵盖环境部署、核心配置、数据转换与冲突处理等关键环节。
一、Otter核心架构与同步原理
1.1 系统架构概览
Otter采用Manager+Node分布式架构,结合ZooKeeper实现集群协调:
- Manager:负责同步任务配置、节点管理与监控
- Node:执行具体的数据抽取(基于Canal)、转换和加载操作
- ZooKeeper:维护分布式锁、节点状态与配置一致性
1.2 MySQL到Oracle同步流程
Otter基于数据库日志解析实现增量同步,核心流程如下:
关键技术点:
- 使用Canal解析MySQL的binlog日志
- 通过自定义转换器实现数据类型映射
- 采用Oracle MERGE语句实现UPSERT操作
- 基于ZooKeeper的分布式事务保证
二、环境部署与前置条件
2.1 基础环境要求
| 组件 | 版本要求 | 说明 |
|---|---|---|
| JDK | 1.8+ | 必须使用64位版本 |
| Maven | 3.2+ | 用于源码编译 |
| MySQL | 5.6+ | 开启binlog(ROW格式) |
| Oracle | 11g+ | 开启归档日志模式 |
| ZooKeeper | 3.4.x | 集群模式需3+节点 |
2.2 部署步骤
2.2.1 环境准备
# 1. 安装依赖库
cd /data/web/disk1/git_repo/gh_mirrors/ot/otter/lib
bash install.sh
# 2. 编译项目
cd ..
mvn clean install -Dmaven.test.skip -Denv=release
# 3. 部署Manager
tar zxvf target/manager/deployer/otter-manager.deployer-4.2.15.tar.gz -C /opt/otter/manager
# 4. 部署Node
tar zxvf target/node/deployer/otter-node.deployer-4.2.15.tar.gz -C /opt/otter/node
2.2.2 数据库配置
MySQL配置(my.cnf):
[mysqld]
server-id=1
log_bin=mysql-bin
binlog_format=ROW
binlog_row_image=FULL
expire_logs_days=7
Oracle配置:
-- 开启归档日志
ALTER SYSTEM SET log_archive_dest_1='LOCATION=/archivelog';
ALTER DATABASE ARCHIVELOG;
-- 创建同步用户
CREATE USER otter IDENTIFIED BY Otter_123;
GRANT CONNECT, RESOURCE, DBA TO otter;
三、同步任务配置详解
3.1 核心配置流程
通过Manager控制台创建同步任务需完成以下步骤:
3.2 关键配置项说明
3.2.1 数据源配置
MySQL数据源:
{
"name": "mysql-source",
"type": "MYSQL",
"url": "jdbc:mysql://192.168.1.100:3306/orders?useSSL=false",
"username": "sync_user",
"password": "EncryptedPassword",
"connectionProperties": {
"useUnicode": "true",
"characterEncoding": "UTF-8"
}
}
Oracle数据源:
{
"name": "oracle-target",
"type": "ORACLE",
"url": "jdbc:oracle:thin:@192.168.1.200:1521/ORCLPDB",
"username": "otter",
"password": "EncryptedPassword",
"connectionProperties": {
"defaultNChar": "true"
}
}
3.2.2 数据表映射规则
配置MySQL与Oracle表结构映射时需注意类型转换:
| MySQL类型 | Oracle类型 | 转换说明 |
|---|---|---|
| VARCHAR(255) | VARCHAR2(255) | 需注意Oracle长度限制 |
| DATETIME | TIMESTAMP(6) | 保留毫秒级精度 |
| INT UNSIGNED | NUMBER(20) | 无符号整数映射 |
| DECIMAL(18,2) | NUMBER(18,2) | 保持精度一致 |
| TEXT | CLOB | 大文本类型映射 |
映射配置示例:
<dataMediaPair>
<sourceMedia>
<schemaName>orders</schemaName>
<tableName>user_info</tableName>
</sourceMedia>
<targetMedia>
<schemaName>OTTER</schemaName>
<tableName>USER_INFO</tableName>
</targetMedia>
<columnPairs>
<columnPair>
<sourceColumn>user_id</sourceColumn>
<targetColumn>USER_ID</targetColumn>
</columnPair>
<columnPair>
<sourceColumn>register_time</sourceColumn>
<targetColumn>REGISTER_TIME</targetColumn>
</columnPair>
</columnPairs>
</dataMediaPair>
四、数据转换与适配实现
4.1 类型转换机制
Otter通过DbDialect接口实现数据库特性适配,Oracle专用实现类OracleDialect提供以下关键功能:
public class OracleDialect extends AbstractDbDialect {
// 支持MERGE语句实现UPSERT
@Override
public boolean isSupportMergeSql() {
return true;
}
// 获取当前Schema
@Override
public String getDefaultSchema() {
return jdbcTemplate.queryForObject(
"SELECT sys_context('USERENV', 'CURRENT_SCHEMA') FROM dual",
String.class
);
}
}
4.2 DML语句转换
Otter将MySQL的INSERT/UPDATE/DELETE转换为Oracle兼容语法,核心通过CanalOracleInterceptor实现:
public class CanalOracleInterceptor extends AbstractOperationInterceptor {
// MERGE语句模板
public static final String mergeofOracleSql =
"merge /*+ use_nl(a b)*/ into {0} a " +
"using (select ? as id, ? as {1} from dual) b " +
"on (a.id=b.id) " +
"when matched then update set a.{1}=b.{1} " +
"when not matched then insert (a.id, a.{1}) values (b.id, b.{1})";
}
转换示例:
- MySQL插入:
INSERT INTO user_info(id,name) VALUES(1,'test') - Oracle转换:
MERGE INTO USER_INFO a USING (SELECT 1 AS id, 'test' AS NAME FROM dual) b ...
4.3 DDL语句适配
对于DDL同步,需注意MySQL与Oracle语法差异:
| 操作 | MySQL语法 | Oracle语法 | Otter转换策略 |
|---|---|---|---|
| 创建表 | AUTO_INCREMENT | SEQUENCE+TRIGGER | 自动生成序列与触发器 |
| 索引 | INDEX idx_name | CREATE INDEX | 自动转换索引类型 |
| 注释 | COMMENT ON COLUMN | COMMENT ON COLUMN | 保持注释同步 |
五、冲突处理与性能优化
5.1 数据冲突解决方案
Otter提供三种冲突解决策略,可在同步配置中指定:
- 覆盖策略:以源库数据为准
- 忽略策略:保留目标库现有数据
- 自定义策略:通过Groovy脚本实现业务规则
自定义冲突处理示例(Groovy脚本):
// 当目标数据更新时间晚于源数据时保留目标数据
if (targetRow.UPDATE_TIME > sourceRow.UPDATE_TIME) {
return ConflictPolicy.IGNORE;
} else {
return ConflictPolicy.OVERWRITE;
}
5.2 同步性能调优
5.2.1 JVM参数优化
# Node节点JVM配置(otter-node/conf/wrapper.conf)
wrapper.java.additional.1=-Xms2048m
wrapper.java.additional.2=-Xmx2048m
wrapper.java.additional.3=-XX:+UseG1GC
5.2.2 批量同步配置
<syncConfig>
<extract>
<batchSize>1000</batchSize>
<fetchSize>100</fetchSize>
</extract>
<load>
<batchSize>500</batchSize>
<commitSize>1000</commitSize>
</load>
</syncConfig>
5.2.3 并行同步策略
通过拆分表或分库分表实现并行同步:
六、监控与问题排查
6.1 关键监控指标
| 指标名称 | 说明 | 告警阈值 |
|---|---|---|
| 同步延迟(ms) | 日志产生到同步完成时间 | >3000ms |
| 吞吐量(tps) | 每秒同步事务数 | <100tps |
| 失败率(%) | 同步失败事务占比 | >0.1% |
6.2 常见问题排查
6.2.1 数据类型不兼容
现象:Oracle端报ORA-01722: invalid number
排查:检查源库字符串字段是否包含非数字字符,配置字段级转换:
<columnPair>
<sourceColumn>phone</sourceColumn>
<targetColumn>PHONE</targetColumn>
<transformer>
<type>TRIM</type>
</transformer>
</columnPair>
6.2.2 同步延迟增大
排查流程:
- 检查Manager控制台"同步延迟"监控面板
- 查看Node节点日志:
tail -f otter-node/logs/otter.log - 分析慢SQL:Oracle端执行
SELECT * FROM v$sql WHERE elapsed_time > 1000000
七、部署架构最佳实践
7.1 生产环境部署架构
7.2 容灾策略
- 多活部署:Node节点跨可用区部署
- 数据校验:定期执行全量对比任务
- 故障自动转移:配置ZooKeeper会话超时自动切换
八、总结与展望
Otter通过成熟的日志解析技术和灵活的转换机制,为MySQL到Oracle的跨数据库同步提供了企业级解决方案。随着分布式数据库的普及,未来可重点关注:
- 适配更多数据库类型(如PostgreSQL、MongoDB)
- 引入流计算引擎实现复杂数据清洗
- 基于AI的异常检测与自动修复
通过本文介绍的方案,企业可快速构建稳定、高效的跨数据库同步通道,打破数据孤岛,支撑业务全球化发展。
附录:参考资源
【免费下载链接】otter 阿里巴巴分布式数据库同步系统(解决中美异地机房) 项目地址: https://gitcode.com/gh_mirrors/ot/otter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



