Giter Club home page Giter Club logo

yugong's Introduction

背景

2008年,阿里巴巴开始尝试使用 MySQL 支撑其业务,开发了围绕 MySQL 相关的中间件和工具,Cobar/TDDL(目前为阿里云DRDS产品),解决了单机 Oracle 无法满足的扩展性问题,当时也掀起一股去IOE项目的浪潮,愚公这项目因此而诞生,其要解决的目标就是帮助用户完成从 Oracle 数据迁移到 MySQL 上,完成去 IOE 的重要一步工作。

项目介绍

名称:   yugong

译意:   愚公移山

语言:   纯java开发

定位:   数据库迁移 (目前主要支持oracle / mysql / DRDS)

项目介绍

整个数据迁移过程,分为两部分:

  1. 全量迁移
  2. 增量迁移

过程描述:

  1. 增量数据收集 (创建oracle表的增量物化视图)
  2. 进行全量复制
  3. 进行增量复制 (可并行进行数据校验)
  4. 原库停写,切到新库

架构

{width="584" height="206"}

说明: 

  1. 一个Jvm Container对应多个instance,每个instance对应于一张表的迁移任务
  2.  instance分为三部分 a.  extractor  (从源数据库上提取数据,可分为全量/增量实现) b.  translator  (将源库上的数据按照目标库的需求进行自定义转化) c.  applier  (将数据更新到目标库,可分为全量/增量/对比的实现)

方案设计

DevDesign

快速开始

QuickStart

运维管理

AdminGuide

性能报告

Performance

相关资料

  1. yugong简单介绍ppt: ppt
  2. 分布式关系型数据库服务DRDS (前身为阿里巴巴公司的Cobar/TDDL的演进版本, 基本原理为MySQL分库分表)

沟通与交流

  1. 详见 wiki home 页

yugong's People

Contributors

agapple avatar alswl avatar bucketli avatar gjf281 avatar openzyk avatar spidersq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yugong's Issues

增量不同步的小概率事件

全量操作完以后,继续操作业务,业务代码操作MYBATIS 把 源数据库表USER_UET_CODE_INFO的某字段 VALUE 改变了,YUGONG 重起 ,发现目标数据库对应数据并没有更新,没有日志报错.这个情况概率很低. 不知道YUGONG 重起前 MLOG$_USER_UET_CODE_INFO 是否有对应的记录 ,重起前忘记查看 MLOG$_USER_UET_CODE_INFO 是否有对应的日志
我想不是事务的问题,如果是事务出错回滚, 通过查询锁表SQL应该会发现有锁表发生,如果有锁表发生 操作的源表时 会出现"假死"状态.
我在群中咨询,有其他朋友也遇到过类似的问题

通过打印日志,YUGONG 在多线程情况下有问题
我有一种常景经常出现
public class UserUetCodeInfoDataTranslator extends BackTableDataTranslator implements DataTranslator {
。。。
logger.error(infor);
if (ignore) {
record.removeColumnByName("PASSWORD");
}
//ignore==false 保持不变

打印日志经常出现:
com.taobao.yugong.controller.YuGongInstance - retry 1 ,something error happened.
caused by com.taobao.yugong.exception.YuGongException:
miss columns[PASSWORD] and failed Record Data :
OracleIncrementRecord[rowId=ColumnValue [column=ColumnMeta[name=ROWID,type=-8],
value=oracle.sql.ROWID@4a6d0e95],discardType=NONE,opType=U,
schemaName=uetest,tableName=T_LOGIN_ACCOUNT,primaryKeys=[ColumnValue [column=ColumnMeta[name=F_ID,type=-5], value=25300]],
columns=[ColumnValue [column=ColumnMeta[name=LOGIN_STATUS,type=1], value=1],
ColumnValue [column=ColumnMeta[name=LAST_LOAG_TIME,type=93], value=2016-08-26 10:03:00.0],
ColumnValue [column=ColumnMeta[name=UET_CODE,type=1], value=113785],
ColumnValue [column=ColumnMeta[name=LAST_LOGIN_IP,type=12], value=null],
ColumnValue [column=ColumnMeta[name=LAST_LOGIN_DEVICE_ID,type=12], value=null]]]

高可用和position文件位置?

如果yugong作为一个中长期部署的Oracle到MySQL同步工具,如何布置高可用?

按说唯一的状态就在 positioner目录下的dat文件。

这些文件部署到高可用的文件系统上可以吗?对性能有多大影响?现在的机制是每次批量完成后更新这些dat文件?

YUGONGException

Alarm:com.taobao.yugong.exception.YUGONGException:table[null.T_TEST001] is not found
create table t_test001(id bigint,name varchar(100),age decimal(5));
Oracle 10 到 mysql 5.7.16
完全没有头绪为什么会出现这样的错误 我起初怀疑线程传目标用户名失败导致?但是没有根据。。。
在测试环境可以 ,但是换了一个测试环境(换的环境软件和配置都一样就是源数据库和目标数据库的版本不一样)就出现上面的告警,数据导入警告。
在log目录产生了一个源数据库用户名.表名的目录
我个人觉得 导入跟oracle和mysql版本没有多大区别吧

修改过滤的RUPD$开头的表

TableMetaGenerator的getTableMetasWithoutColumn方法需要过滤RUPD$_开头的表

if (!StringUtils.startsWithIgnoreCase(name, "MLOG$_") && !StringUtils.startsWithIgnoreCase(name, "RUPD$_")) {

能否升级适配guava当前的G.A

YUGONG依赖的guava pom是rc09,而当前的版本是19.0。修改后发现有许多class与当前不兼容,经检查是当前guava将当前的处理方式(如基于function的)迁移到cacheBuilder中,能否略微调整一下能适配这种改动(还是说由感兴趣的自行来修改)

从开发团队获取最新文档和技术支持,查看哪些用户在使用yugong

为了更加有效形成开源氛围,鼓励p2p知识共享,希望每位用户都能自觉登记信息,作为第一次使用时可以参看别的使用信息进行交流.

为了鼓励用户自觉登记, 作者会要求所有issue/qq/邮件的提问者提供登记信息链接,否则不予支持

yugong开源交流QQ群: 537157866

登记下客户使用信息:

  1. 所属行业 (必填)
  2. 公司信息 (非必填)
  3. 使用场景 (必填) (例子: 全量/增量, 异构表同步, 一次性迁移/每天增量迁移,同步到Mysql/DRDS/Cobar等)
  4. 联系方式 (必填) (建议为qq开源群里的名字和ID)

DataTranslator接口定义优化

  1. 表名转换和列转化,分离为两个接口,有状态和无状态. (可以为同步DRDS提前获取目标表)
  2. 提供flume api,方便快速编写转化逻辑 (比如简单的列名转化,可以是 a.table('new).column(a,b)...

GetConnectionTimeoutException

我遇到的情况是(测试环境)
1.
yugong.database.source.url=jdbc:oracle:thin:@192.168.70.199:1521:orcl
yugong.database.source.encode=UTF-8
yugong.database.source.poolSize=30

yugong.database.target.url=jdbc:mysql://192.168.10.294:3306/uetest

2.我把YUGONG 布署在 192.168.10.290 (跟target.url 同一网段)上 ,就是超时, 报 GetConnectionTimeoutException: wait millis 5000, active 0, maxActive 30
3但是
如果 我 把 YUGONG 布署 跟 source.url , 在用一网段就可以正常连接上

在正式环境
我.source.url(可以拼通的 ,做了一个跟YUGONG 不相关的例子,用C3P0 连接远程的的ORACLE 库,是可以连接上的) ,target.url 在不同网段,我 把 YUGONG 布署 在跟 source.url ,用一网段也不行, 也是报 GetConnectionTimeoutException

能否提供点思路

模式名为空

流程是这样的

  1. 新建表ORACLE
    CREATE TABLE "XT_BASECOURSE" (
    "COURSE_ID" NUMBER(16) NOT NULL ,
    "NAME" NVARCHAR2(150) NULL ,
    "SORT_NUM" NUMBER NULL ,
    "DESCRIPTION" NVARCHAR2(1000) NULL ,
    "CREATE_TIME" DATE NULL ,
    "UPDATE_TIME" DATE NULL ,
    "CREATE_USER" NUMBER(16) NULL ,
    "UPDATE_USER" NUMBER(16) NULL
    )tablespace UECHNDB;
    2.插入表
    INSERT INTO "XT_BASECOURSE" VALUES ('1', '语文', '1', null, null, null, null, null);
    INSERT INTO "XT_BASECOURSE" VALUES ('2', '数学', '2', null, null, null, null, null);
    3.新建表MYSQL
    DROP TABLE IF EXISTS T_BASE_COURSE;
    CREATE TABLE T_BASE_COURSE (
    BASE_COURSE_ID int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    BASE_COURSE_NAME varchar(32) DEFAULT NULL COMMENT '名称',
    SORT_NUM smallint(2) unsigned DEFAULT NULL COMMENT '排序',
    CREATE_TIME datetime DEFAULT NULL COMMENT '创建时间',
    PRIMARY KEY (BASE_COURSE_ID)
    ) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='基础学科';
    4.配制文件
    yugong.database.source.username=uechn2_db
    yugong.database.source.password=123
    yugong.database.source.type=ORACLE
    yugong.database.source.url=jdbc:oracle:thin:@192.168.*.21:1521:orcl
    yugong.database.source.encode=UTF-8
    yugong.database.source.poolSize=30

yugong.database.target.url=jdbc:mysql://192.168.*.204:3306/ue
yugong.database.target.username=root
yugong.database.target.password=root
yugong.database.target.type=MYSQL
yugong.database.target.encode=UTF-8
yugong.database.target.poolSize=30

yugong.table.white=uechn2_db.XT_BASECOURSE

5.XTBASECOURSEDataTranslator.java
public class XTBASECOURSEDataTranslator extends AbstractDataTranslator implements DataTranslator {

public boolean translator(Record record) {
    // 1. schema/table名不同
     record.setSchemaName("ue");
    record.setTableName("T_BASE_COURSE");
    // 源表为XT_BASECOURSE,目标表为T_BASE_COURSE

6.结果:/usr/local/yugong/conf/translator/table.log
[YuGongInstance-UECHN2_DB.XT_BASECOURSE] ERROR com.taobao.yugong.controller.YuGongInstance - retry 1 ,something error happened. caused by java.lang.RuntimeException: java.util.concurrent.ExecutionException: com.taobao.yugong.exception.YuGongException: table[null.XT_BASECOURSE] is not found

测试的的时候报错,哪位大神帮忙查一下

2017-04-07 11:32:04.583 [YuGongInstance-TRANUSR.YUGONG_EXAMPLE_ORACLE] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TRANUSR.YUGONG_EXAMPLE_ORACLE] now is CATCH_UP ...
2017-04-07 11:32:04.664 [YuGongInstance-TRANUSR.YUGONG_EXAMPLE_ORACLE] ERROR com.taobao.yugong.controller.YuGongInstance - retry 1 ,something error happened. caused by com.taobao.yugong.exception.YuGongException: table[null.YUGONG_EXAMPLE_ORACLE] is not found
at com.taobao.yugong.common.db.meta.TableMetaGenerator$1.doInConnection(TableMetaGenerator.java:76)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:342)
at com.taobao.yugong.common.db.meta.TableMetaGenerator.getTableMeta(TableMetaGenerator.java:51)
at com.taobao.yugong.applier.IncrementRecordApplier.getInsertSqlUnit(IncrementRecordApplier.java:159)
at com.taobao.yugong.applier.IncrementRecordApplier.getSqlUnit(IncrementRecordApplier.java:138)
at com.taobao.yugong.applier.IncrementRecordApplier.applyOneByOne(IncrementRecordApplier.java:86)
at com.taobao.yugong.applier.MultiThreadIncrementRecordApplier.applyBatch0(MultiThreadIncrementRecordApplier.java:240)
at com.taobao.yugong.applier.MultiThreadIncrementRecordApplier.applyBatch(MultiThreadIncrementRecordApplier.java:175)
at com.taobao.yugong.applier.MultiThreadIncrementRecordApplier.doApply(MultiThreadIncrementRecordApplier.java:104)
at com.taobao.yugong.applier.MultiThreadIncrementRecordApplier.apply(MultiThreadIncrementRecordApplier.java:92)
at com.taobao.yugong.applier.AllRecordApplier.apply(AllRecordApplier.java:60)
at com.taobao.yugong.controller.YuGongInstance$1.processTable(YuGongInstance.java:215)
at com.taobao.yugong.controller.YuGongInstance$1.run(YuGongInstance.java:145)
at java.lang.Thread.run(Thread.java:745)

translator中删除主键,记录日志数组越界异常

translator可以将主键删除(目标数据库自增主键,不需要主键id迁移),applier.apply 可以将数据插入目标数据库,之后 extractor.ack(ackRecords)需要取最后一条record的主键,会抛数组下标越界异常

全量同步+增量同步 ALL模式 数据丢失问题

同步了一张11966733条数据的表到mysql,用的ALL模式,同步期间oracle库无操作,同步完成进入增量模式后 查mysql那个表记录数为11941943,少了24790条。用CHECK模式运行了下check.log里确实检查出了这些没过去的行。 试了两次都会少几万条,但少的条数不完全一样。全量时看这张表对应的table.log会一直报com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '6337315' for key 'PRIMARY'
at sun.reflect.GeneratedConstructorAccessor12.newInstance(Unknown Source) ~[na:na]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_67]
但是报的这些主键也成功写到mysql里了。
PS:
原因可能是联合唯一索引造成的,我把mysql表上这个索引删了,只留了个主键的,数据就没丢了---
但原来oracle表上是有这个索引的,数据肯定没问题,,还没想到为啥多这个索引会导致数据丢失。。

GetConnectionTimeoutException

DEBUG 流程及数据是这样的

context.setSourceDs(initDataSource("source"));
public void setSourceDs(DataSource sourceDs) {

activeConnections   IdentityHashMap<K,V>  (id=1691) 
    keySet  null
    size    0
    values  null

{
    CreateTime:"2016-07-22 08:41:44",
    ActiveCount:0,
    PoolingCount:0,
    CreateCount:0,
    DestroyCount:0,
    CloseCount:0,
    ConnectCount:0,
    Connections:[
    ]
}  

context.setTargetDs(initDataSource("target"));
activeConnections IdentityHashMap<K,V> (id=1794)
keySet null
modCount 0
size 0
values null
{
CreateTime:"2016-07-22 08:46:43",
ActiveCount:0,
PoolingCount:0,
CreateCount:0,
DestroyCount:0,
CloseCount:0,
ConnectCount:0,
Connections:[
]
}

目的库连接
Connection con = dataSource.getConnection();
得到 : com.mysql.jdbc.JDBC4Connection@4fe13ac3

源库连接 调用
whiteTables = TableMetaGenerator.getTableMetasWithoutColumn(globalContext.getSourceDs(),
strs[0],
strs[1]);

Connection con = dataSource.getConnection();
抛GetConnectionTimeoutException: wait millis 5000, active 0, maxActive 30

迁移数据中文乱码

昨天在试着做oracle to mysql迁移的例子时,发现中文老是乱码。
yugong.properties里两个编码格式,都改过无数次了,可就是乱码。

请问一下,目标和源,应该对应数据库或服务器哪个地方的编码?

增量同步问题

增量同步问题

我的数据和流程是这样的:
insert into yugong_example_a values(1,'ljh','agapple',10.2,100, NULL , NULL ,sysdate,sysdate);
insert into yugong_example_a values(2,'yugong','yugong',16.88,2088, NULL , NULL ,sysdate,sysdate);
insert into yugong_example_a values(3,'test','test',88,188, NULL , NULL ,sysdate,sysdate);
commit;

起动YUGONG ,目标MYSQL 库是 正常同步了
现在 在源库操作
update yugong_example_a set alias_name = 'superman' where id = 1;
commit;

源库有条记录
select * from Mlog$_yugong_example_a
没有消费

代码是
public class YugongExampleADataTranslator extends AbstractDataTranslator implements DataTranslator {

private Logger logger = LoggerFactory.getLogger(YugongExampleADataTranslator.class);

public boolean translator(Record record) {

// record.setSchemaName("uetest");
record.setTableName("yugong_example_mysql_a");
// 源表为yugong_example_a,目标表为yugong_example_mysql_a

    ColumnValue id = record.getColumnByName("id");
    logger.error("======="+id.getValue());

我刚才的问题打印的日志是

17:53:35.714 [main] WARN c.t.yugong.extractor.oracle.OracleRecRecordExtractor - mlog[MLOG$_YUGONG_EXAMPLE_A] is exist, just have fun.
17:53:35.823 [main] INFO c.t.y.e.o.OracleFullRecordExtractor$ContinueExtractor - UECHN_DB.YUGONG_EXAMPLE_A start postion:0
17:53:35.829 [main] INFO com.taobao.yugong.controller.YuGongInstance - table[UECHN_DB.YUGONG_EXAMPLE_A] start successful. extractor:com.taobao.yugong.extractor.oracle.OracleAllRecordExtractor , applier:com.taobao.yugong.applier.AllRecordApplier, translator:com.taobao.yugong.translator.YugongExampleADataTranslator
17:53:36.315 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======1
17:53:36.318 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======2
17:53:36.318 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======3
17:53:36.352 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.yugong.extractor.oracle.OracleAllRecordExtractor - table [UECHN_DB.YUGONG_EXAMPLE_A] full extractor is end , next auto start inc extractor
17:53:37.812 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is CATCH_UP ...
17:53:37.908 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======3
17:53:38.079 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
17:53:39.258 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
17:53:40.397 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
17:53:41.489 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
17:53:42.493 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO com.taobao.yugong.controller.YuGongInstance - table[UECHN_DB.YUGONG_EXAMPLE_A] is end by NO_UPDATE
17:53:42.494 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO com.taobao.yugong.common.stats.StatAggregation - {总记录数:4,采样记录数:4,同步TPS:1,最长时间:1638,最小时间:510,平均时间:1074}
17:53:42.497 [pool-2-thread-1] INFO com.taobao.yugong.controller.YuGongInstance - table[UECHN_DB.YUGONG_EXAMPLE_A] stop successful.

另外 /yugong/logs/yugong/table.log 也是
19:38:37.799 [main] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} closed
19:38:37.907 [main] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-2} closed
19:38:37.908 [main] INFO com.taobao.yugong.YuGongLauncher - ## YuGong is down.
在yugong 运行过程中,修改源库表中的记录,yugong 目录下的 UECHN_DB.YUGONG_EXAMPLE_A
table.log,extractor.log,applier.log 记录并没有改变

很奇怪的是
update yugong_example_a set alias_name = 'superman' where id = 1;

为什么打印 17:53:37.908 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======3

表名配置支持下通配符定义

RT,支持下数据库like语法的表名定义
比如'%'匹配一个或者多个字符,下划线'_'匹配单个字符,可以通过单斜杠\进行转义符定义

例子:

  1. yugong_example_% (可以匹配yugong_example打头的字符串)
  2. yugong_example_test_ (可以匹配yugong_example_test1 / yugong_example_test2)

增量不同步的小概率事件

  1.  全量操作完以后,继续操作业务,业务代码操作MYBATIS 把 源数据库表USER_UET_CODE_INFO的某字段 VALUE 改变了,YUGONG 重起 ,发现目标数据库对应数据并没有更新,没有日志报错.这个情况概率很低. 不知道YUGONG 重起前 MLOG$_USER_UET_CODE_INFO 是否有对应的记录 ,重起前忘记查看 MLOG$_USER_UET_CODE_INFO 是否有对应的日志
    

    我想不是事务的问题,如果是事务出错回滚, 通过查询锁表SQL应该会发现有锁表发生,如果有锁表发生 操作的源表时 会出现"假死"状态.
    我在群中咨询,有其他朋友也遇到过类似的问题

  2.  在增量同步中有其他的问题
    代码是这样的
    
    ColumnValue UET_ID = record.getColumnByName("UET_ID");
    String infor="";
    if (UET_ID != null) {
        UET_ID.getColumn().setType(Types.BIGINT);
        UET_ID.getColumn().setName("F_ID");
        boolean ignore = false;
        boolean increase = record instanceof IncrementRecord;
        if (increase) {
            IncrementRecord incRecord = (IncrementRecord) record;
            infor="synchronize password UET_ID: " + UET_ID.getValue() + " " + incRecord.getOpType();
            if (incRecord.getOpType() == IncrementOpType.U) {
                if (UET_ID.getValue() != null) {
                    JdbcTemplate jdbcTemplate = new JdbcTemplate(sourceDs);
                    String relation = (String) jdbcTemplate.query(
                            "SELECT uc.password AS password FROM USER_UET_CODE_INFO uc, USER_USER_INFO ui WHERE uc.uet_id=ui.uet_id AND ui.user_type=2 AND uc.uet_id= "
                                    + ((BigDecimal) UET_ID.getValue()).longValue(),
                            new ResultSetExtractor() {
    
                                public Object extractData(ResultSet rs) throws SQLException, DataAccessException {
                                    if (rs != null && rs.next()) {
                                        return rs.getString("password");
                                        // return rs.getBigDecimal("uet_code");
                                    }
    
                                    return null;
                                }
                            });
                    if (relation != null) {// This is a student
                        ignore = false;
                    } else {
                        ignore = true;
                    }
                }
            } else {
                ignore = false;
            }
        }
        infor=infor+" ignore "+ignore;
        logger.error(infor);
        if (ignore) {
            record.removeColumnByName("PASSWORD");
        }
    
    报:
    打印日志经常出现:
    

    com.taobao.yugong.controller.YuGongInstance - retry 1 ,something error happened.
    caused by com.taobao.yugong.exception.YuGongException:
    miss columns[PASSWORD] and failed Record Data :
    OracleIncrementRecord[rowId=ColumnValue [column=ColumnMeta[name=ROWID,type=-8],
    value=oracle.sql.ROWID@4a6d0e95],discardType=NONE,opType=U,
    schemaName=uetest,tableName=T_LOGIN_ACCOUNT,primaryKeys=[ColumnValue [column=ColumnMeta[name=F_ID,type=-5], value=25300]],
    columns=[ColumnValue [column=ColumnMeta[name=LOGIN_STATUS,type=1], value=1],
    ColumnValue [column=ColumnMeta[name=LAST_LOAG_TIME,type=93], value=2016-08-26 10:03:00.0],
    ColumnValue [column=ColumnMeta[name=UET_CODE,type=1], value=113785],
    ColumnValue [column=ColumnMeta[name=LAST_LOGIN_IP,type=12], value=null],
    ColumnValue [column=ColumnMeta[name=LAST_LOGIN_DEVICE_ID,type=12], value=null]]]

看了YUGONG 源码 是否是
sqlUnit.applierSql = applierSql;
sqlUnit.applierIndexs = indexs;
updateSqlCache.put(names, sqlUnit);
的原因,也就是所有的记录,不能够随便减小字段

增量同步问题

增量同步问题
我的数据和流程是这样的:
insert into yugong_example_a values(1,'ljh','agapple',10.2,100, NULL , NULL ,sysdate,sysdate);
insert into yugong_example_a values(2,'yugong','yugong',16.88,2088, NULL , NULL ,sysdate,sysdate);
insert into yugong_example_a values(3,'test','test',88,188, NULL , NULL ,sysdate,sysdate);
commit;

起动YUGONG ,目标MYSQL 库是 正常同步了
现在 在源库操作
update yugong_example_a set alias_name = 'superman' where id = 1;
commit;

源库有条记录
select * from Mlog$_yugong_example_a
没有消费

代码是
public class YugongExampleADataTranslator extends AbstractDataTranslator implements DataTranslator {

private Logger logger = LoggerFactory.getLogger(YugongExampleADataTranslator.class);

public boolean translator(Record record) {
    // 1. schema/table名不同

// record.setSchemaName("uetest");
record.setTableName("yugong_example_mysql_a");
// 源表为yugong_example_a,目标表为yugong_example_mysql_a

    ColumnValue id = record.getColumnByName("id");
    logger.error("======="+id.getValue());

我刚才的问题打印的日志是

17:53:35.714 [main] WARN c.t.yugong.extractor.oracle.OracleRecRecordExtractor - mlog[MLOG$_YUGONG_EXAMPLE_A] is exist, just have fun.
17:53:35.823 [main] INFO c.t.y.e.o.OracleFullRecordExtractor$ContinueExtractor - UECHN_DB.YUGONG_EXAMPLE_A start postion:0
17:53:35.829 [main] INFO com.taobao.yugong.controller.YuGongInstance - table[UECHN_DB.YUGONG_EXAMPLE_A] start successful. extractor:com.taobao.yugong.extractor.oracle.OracleAllRecordExtractor , applier:com.taobao.yugong.applier.AllRecordApplier, translator:com.taobao.yugong.translator.YugongExampleADataTranslator
17:53:36.315 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======1
17:53:36.318 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======2
17:53:36.318 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======3
17:53:36.352 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.yugong.extractor.oracle.OracleAllRecordExtractor - table [UECHN_DB.YUGONG_EXAMPLE_A] full extractor is end , next auto start inc extractor
17:53:37.812 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is CATCH_UP ...
17:53:37.908 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======3
17:53:38.079 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
17:53:39.258 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
17:53:40.397 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
17:53:41.489 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[UECHN_DB.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
17:53:42.493 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO com.taobao.yugong.controller.YuGongInstance - table[UECHN_DB.YUGONG_EXAMPLE_A] is end by NO_UPDATE
17:53:42.494 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] INFO com.taobao.yugong.common.stats.StatAggregation - {总记录数:4,采样记录数:4,同步TPS:1,最长时间:1638,最小时间:510,平均时间:1074}
17:53:42.497 [pool-2-thread-1] INFO com.taobao.yugong.controller.YuGongInstance - table[UECHN_DB.YUGONG_EXAMPLE_A] stop successful.

很奇怪的是
update yugong_example_a set alias_name = 'superman' where id = 1;

为什么打印 17:53:37.908 [YuGongInstance-UECHN_DB.YUGONG_EXAMPLE_A] ERROR c.taobao.yugong.translator.YugongExampleADataTranslator - =======3

为什么重启就能够正常读到 ,正常过程中,跟重启在那些方面有区别吗?

日志显示已完成迁移,但是目标数据库mysql表里面没有相应数据

017-08-07 12:04:48.611 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
2017-08-07 12:04:49.201 [pool-2-thread-2] INFO com.taobao.yugong.common.stats.ProgressTracer - {未启动:0,全量中:0,增量中:0,已追上:1,异常数:0}
2017-08-07 12:04:49.202 [pool-2-thread-2] INFO com.taobao.yugong.common.stats.ProgressTracer - 已完成:[TEST.YUGONG_EXAMPLE_A]
2017-08-07 12:04:49.626 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
2017-08-07 12:04:50.641 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
2017-08-07 12:04:51.672 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
2017-08-07 12:04:52.687 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
2017-08-07 12:04:53.702 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
2017-08-07 12:04:54.718 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
2017-08-07 12:04:55.733 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...
2017-08-07 12:04:56.747 [YuGongInstance-TEST.YUGONG_EXAMPLE_A] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[TEST.YUGONG_EXAMPLE_A] now is NO_UPDATE ...

不知道是不是版本问题jdk1.7

行业 :征信行业
QQ 327467030

com.taobao.yugong.exception.YuGongException: com.taobao.yugong.exception.YuGongException: source:com.taobao.yugong.translator.YugongExampleOracleDataTranslator
at com.taobao.yugong.controller.YuGongController.choseTranslator(YuGongController.java:386)
at com.taobao.yugong.controller.YuGongController.start(YuGongController.java:173)
at com.taobao.yugong.YuGongLauncher.main(YuGongLauncher.java:32)
Caused by: com.taobao.yugong.exception.YuGongException: source:com.taobao.yugong.translator.YugongExampleOracleDataTranslator
at com.taobao.yugong.common.utils.compile.JdkCompiler.compile(JdkCompiler.java:60)
at com.taobao.yugong.common.utils.compile.JdkCompiler.compile(JdkCompiler.java:48)
at com.taobao.yugong.controller.YuGongController.buildTranslator(YuGongController.java:408)
at com.taobao.yugong.controller.YuGongController.choseTranslator(YuGongController.java:384)
... 2 more
Caused by: com.taobao.yugong.exception.YuGongException: Can't find java compiler , pls check tools.jar
at com.taobao.yugong.common.utils.compile.JdkCompiler$JdkCompileTask.(JdkCompiler.java:82)
at com.taobao.yugong.common.utils.compile.JdkCompiler.compile(JdkCompiler.java:53)
... 5 more

增量不同步的小概率事件

  1. 全量操作完以后,继续操作业务,业务代码操作MYBATIS 把 源数据库表USER_UET_CODE_INFO的某字段 VALUE 改变了,YUGONG 重起 ,发现目标数据库对应数据并没有更新,没有日志报错.这个情况概率很低.
    不知道YUGONG 重起前 MLOG$_USER_UET_CODE_INFO 是否有对应的记录 ,重起前忘记查看 MLOG$_USER_UET_CODE_INFO 是否有对应的日志

我想不是事务的问题,如果是事务出错回滚, 通过查询锁表SQL应该会发现有锁表发生,如果有锁表发生 操作的源表时 会出现"假死"状态.
我在群中咨询,有其他朋友也遇到过类似的问题

测试oracle数据源报错

java.sql.SQLException: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
The Connection descriptor used by the client was:
127.0.0.1:1521:my_base

at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) ~[ojdbc14-10.2.0.3.0.jar:Oracle JDBC Driver version - "10.2.0.3.0"]
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:261) ~[ojdbc14-10.2.0.3.0.jar:Oracle JDBC Driver version - "10.2.0.3.0"]
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:387) ~[ojdbc14-10.2.0.3.0.jar:Oracle JDBC Driver version - "10.2.0.3.0"]
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:439) ~[ojdbc14-10.2.0.3.0.jar:Oracle JDBC Driver version - "10.2.0.3.0"]
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165) ~[ojdbc14-10.2.0.3.0.jar:Oracle JDBC Driver version - "10.2.0.3.0"]
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35) ~[ojdbc14-10.2.0.3.0.jar:Oracle JDBC Driver version - "10.2.0.3.0"]
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801) ~[ojdbc14-10.2.0.3.0.jar:Oracle JDBC Driver version - "10.2.0.3.0"]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1384) ~[druid-1.0.17.jar:1.0.17]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1440) ~[druid-1.0.17.jar:1.0.17]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:1934) ~[druid-1.0.17.jar:1.0.17]

2016-12-28

Oracle(Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi)数据同步到MySQL报错

报错描述:
Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select * from (select rowid,OLD_NEW$$,ID,SNAPTIME$$,DMLTYPE$$,CHANGE_VECTOR$$ from MODELHOME.MLOG$_YUGONG_EXAMPLE_ORACL order by sequence$$ asc) where rownum <= ?]; nested exception is java.sql.SQLException: ORA-00904: "SEQUENCE$$": invalid identifier

at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:220)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:607)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:619)
at com.taobao.yugong.extractor.oracle.OracleMaterializedIncRecordExtractor.getMlogRecord(OracleMaterializedIncRecordExtractor.java:162)
at com.taobao.yugong.extractor.oracle.OracleMaterializedIncRecordExtractor.extract(OracleMaterializedIncRecordExtractor.java:121)
at com.taobao.yugong.extractor.oracle.OracleAllRecordExtractor.extract(OracleAllRecordExtractor.java:108)
at com.taobao.yugong.controller.YuGongInstance$1.processTable(YuGongInstance.java:189)
... 2 more

Caused by: java.sql.SQLException: ORA-00904: "SEQUENCE$$": invalid identifier

at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:810)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1039)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:850)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1134)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3339)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3384)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeQuery(DruidPooledPreparedStatement.java:227)
at com.taobao.yugong.extractor.oracle.OracleMaterializedIncRecordExtractor$2.doInPreparedStatement(OracleMaterializedIncRecordExtractor.java:168)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:591)
... 7 more

原因分析:
将MLOG_EXTRACT_FORMAT 修改为 "select rowid,{0} from {1}.{2} where rownum <= ?" 执行就正常了

查看代码提交记录2016.06.06号的一次提交中,将MLOG_EXTRACT_FORMAT做了修改为"select * from (select rowid,{0} from {1}.{2} order by sequence$$ asc) where rownum <= ?";
该次修改在10.2.0.4.0 Oracle版本上是否存在兼容问题?

oracle clob字段无法用yugong做同步

您好:
我使用yugong做oracle到oracle的同步时,发现含clob字段的表无法进行数据同步。
以下就是我们运行时候的报错,麻烦帮忙解决下。
[oracle@dell-oracle GDSIGNAL.FLOW_INPUT]$ more table.log
2016-12-28 10:49:10.365 [main] WARN c.t.yugong.extractor.oracle.OracleRecRecordExtractor - mlog[MLOG$_FLOW_INPUT] is exist, just have fun.
2016-12-28 10:49:10.538 [main] INFO c.t.y.e.o.OracleFullRecordExtractor$ContinueExtractor - GDSIGNAL.FLOW_INPUT start postion:9
2016-12-28 10:49:10.540 [main] INFO com.taobao.yugong.controller.YuGongInstance - table[GDSIGNAL.FLOW_INPUT] start successful. extractor:com.taobao.yugong.extractor.oracle.OracleAllRecord
Extractor , applier:com.taobao.yugong.applier.AllRecordApplier, translator:NULL
2016-12-28 10:49:12.462 [MultiThreadFullRecordApplier-GDSIGNAL.FLOW_INPUT] INFO o.s.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [org/
springframework/jdbc/support/sql-error-codes.xml]
2016-12-28 10:49:12.687 [MultiThreadFullRecordApplier-GDSIGNAL.FLOW_INPUT] INFO org.springframework.jdbc.support.SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Inform
ix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
2016-12-28 10:49:12.711 [MultiThreadFullRecordApplier-GDSIGNAL.FLOW_INPUT] ERROR com.alibaba.druid.pool.DruidDataSource - recyle error
java.lang.InterruptedException: null
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1219) ~[na:1.7.0_79]
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:340) ~[na:1.7.0_79]
at com.alibaba.druid.pool.DruidDataSource.recycle(DruidDataSource.java:1297) ~[druid-1.0.17.jar:1.0.17]
at com.alibaba.druid.pool.DruidPooledConnection.recycle(DruidPooledConnection.java:297) [druid-1.0.17.jar:1.0.17]
at com.alibaba.druid.pool.DruidPooledConnection.close(DruidPooledConnection.java:247) [druid-1.0.17.jar:1.0.17]
at org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:313) [spring-2.5.6.jar:2.5.6]
at org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(DataSourceUtils.java:274) [spring-2.5.6.jar:2.5.6]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605) [spring-2.5.6.jar:2.5.6]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:619) [spring-2.5.6.jar:2.5.6]
at com.taobao.yugong.applier.FullRecordApplier.applierByBatch(FullRecordApplier.java:103) [yugong-1.0.2.jar:na]
at com.taobao.yugong.applier.FullRecordApplier.doApply(FullRecordApplier.java:89) [yugong-1.0.2.jar:na]
at com.taobao.yugong.applier.MultiThreadFullRecordApplier$1.run(MultiThreadFullRecordApplier.java:93) [yugong-1.0.2.jar:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_79]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_79]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_79]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_79]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_79]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_79]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]
2016-12-28 10:49:12.711 [YuGongInstance-GDSIGNAL.FLOW_INPUT] ERROR com.taobao.yugong.controller.YuGongInstance - retry 1 ,something error happened. caused by java.lang.RuntimeException: ja
va.util.concurrent.ExecutionException: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [insert into GDSIGNAL.FLOW_INPUT(PA
TH , FLOW_EXEC_ID , INPUTINDEX , INPUTSIZE , NAME , CDO_NAME , RECORDS , CHANNEL_KEY , ID) values (? , ? , ? , ? , ? , ? , ? , ? , ?)]; SQL state [null]; error code [0]; Error; nested exception is
java.sql.SQLException: Error
at com.taobao.yugong.common.utils.thread.ExecutorTemplate.waitForResult(ExecutorTemplate.java:79)
at com.taobao.yugong.applier.MultiThreadFullRecordApplier.apply(MultiThreadFullRecordApplier.java:103)
at com.taobao.yugong.applier.AllRecordApplier.apply(AllRecordApplier.java:58)
at com.taobao.yugong.controller.YuGongInstance$1.processTable(YuGongInstance.java:215)
at com.taobao.yugong.controller.YuGongInstance$1.run(YuGongInstance.java:145)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.concurrent.ExecutionException: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [insert into GDSIGNAL.
FLOW_INPUT(PATH , FLOW_EXEC_ID , INPUTINDEX , INPUTSIZE , NAME , CDO_NAME , RECORDS , CHANNEL_KEY , ID) values (? , ? , ? , ? , ? , ? , ? , ? , ?)]; SQL state [null]; error code [0]; Error; nested
exception is java.sql.SQLException: Error
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:188)
at com.taobao.yugong.common.utils.thread.ExecutorTemplate.waitForResult(ExecutorTemplate.java:77)
... 5 more
Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [insert into GDSIGNAL.FLOW_INPUT(PATH , FLOW_EXEC_ID , INPUTIND
EX , INPUTSIZE , NAME , CDO_NAME , RECORDS , CHANNEL_KEY , ID) values (? , ? , ? , ? , ? , ? , ? , ? , ?)]; SQL state [null]; error code [0]; Error; nested exception is java.sql.SQLException: Error
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:607)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:619)
at com.taobao.yugong.applier.FullRecordApplier.applyOneByOne(FullRecordApplier.java:145)
at com.taobao.yugong.applier.FullRecordApplier.applierByBatch(FullRecordApplier.java:136)
at com.taobao.yugong.applier.FullRecordApplier.doApply(FullRecordApplier.java:89)
at com.taobao.yugong.applier.MultiThreadFullRecordApplier$1.run(MultiThreadFullRecordApplier.java:93)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
... 1 more
Caused by: java.sql.SQLException: Error
at com.alibaba.druid.pool.DruidDataSource.handleConnectionException(DruidDataSource.java:1211)
at com.alibaba.druid.pool.DruidPooledConnection.handleException(DruidPooledConnection.java:132)
at com.alibaba.druid.pool.DruidPooledStatement.checkException(DruidPooledStatement.java:68)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.setObject(DruidPooledPreparedStatement.java:467)
at com.taobao.yugong.applier.FullRecordApplier$3.doInPreparedStatement(FullRecordApplier.java:153)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:591)
... 12 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to oracle.sql.CLOB
at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:9198)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8812)
at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:9285)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.setObject(DruidPooledPreparedStatement.java:465)
... 14 more

支持目标库为DRDS的拆分键变更

比如源库为oracle,目标库为DRDS,拆分字段为userId,原始表主键为ID.
基于物化视图模式,针对主键变更会演化为DELETE+INSERT,针对拆分字段的变更,需要在yugong层面进行裂变为DELETE+INSERT

通过mycat增量更新问题

背景:mysql做了分片,通过mycat同步数据,但表的分片字段不是主键。比如在新增100条数据时,会有一部分能同步过来,剩下的就同步失败。查看错误日志,发现是insert into on duplicate key update这种sql导致的,因为update中有分片字段,但是mycat不支持分片字段更新,因此yugong得到mycat的异常导致同步失败。我看了下MLOG$表,里面的DMLTYPE$$全是I,没有D或U。现在不明白的是,DMLTYPE$$全是I,有一部分直接插入了,为什么剩下的是insert into on duplicate key update这种模式来增量。不是应该在DMLTYPE$$为U时,才使用insert into on duplicate key update吗。

not found mlog table for table_name

我的需求是 Oracle>MySQL 全量+增量同步

遇到报错如下:
ERROR com.taobao.yugong.common.alarm.LogAlarmService - Alarm:com.taobao.yugong.exception.YuGongException: com.taobao.yugong.exception.YuGongException: not found mlog table for [ZHWLDEV.EB_LOCATION]
at com.taobao.yugong.controller.YuGongInstance$1.processTable(YuGongInstance.java:269)
at com.taobao.yugong.controller.YuGongInstance$1.run(YuGongInstance.java:145)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.taobao.yugong.exception.YuGongException: not found mlog table for [ZHWLDEV.EB_LOCATION]
at com.taobao.yugong.extractor.oracle.OracleMaterializedIncRecordExtractor.start(OracleMaterializedIncRecordExtractor.java:86)
at com.taobao.yugong.extractor.oracle.OracleAllRecordExtractor.extract(OracleAllRecordExtractor.java:104)
at com.taobao.yugong.controller.YuGongInstance$1.processTable(YuGongInstance.java:189)
... 2 more

源库目标库均有CRUD权限 、源库物化视图创建删除权限也给了

谢谢。。。

oracle迁移至mysql,从mycat导入

群主,你好,想咨询下,利用yugong从oracle迁移数据至分布式mysql,能否实现在提前设计好分片规则的条件下,将数据先全量再增量从oracle导入至mysql,导入口是mycat,最终只需要应用切割数据源?yugong对于mycat的兼容性如何呢?
谢谢!

record not found,MYSQL目标表没有数据导入

步骤
1。ORACLE:
drop table yugong_example_a purge;
create table yugong_example_a(
id NUMBER(11) ,
name varchar2(32) ,
alias_name char(32) default ' ' not null,
amount number(11,2),
score number(20),
text_b blob,
text_c clob,
gmt_create date not null,
gmt_modified date not null,
CONSTRAINT yugong_example_oracle_pk_id PRIMARY KEY (id)
)tablespace UECHNDB;
insert into yugong_example_a values(1,'ljh','agapple',10.2,100, NULL , NULL ,sysdate,sysdate);
insert into yugong_example_a values(2,'yugong','yugong',16.88,2088, NULL , NULL ,sysdate,sysdate);
commit;
2.MYSQL
DROP TABLE IF EXISTS yugong_example_mysql_a;
create table yugong_example_mysql_a
( id bigint(20) unsigned auto_increment,
display_name varchar(128) ,
amount varchar(32),
score bigint(20) unsigned ,
text_b blob,
text_c text,
gmt_create timestamp not null,
gmt_modified timestamp not null,
gmt_move timestamp not null,
CONSTRAINT yugong_example_mysql_pk_id PRIMARY KEY (id)
);
3.yugong.properties
yugong.database.source.username=*_db
yugong.database.source.password=123
yugong.database.source.type=ORACLE
yugong.database.source.url=jdbc:oracle:thin:@192.168.20.191:1521:orcl
yugong.database.source.encode=UTF-8
yugong.database.source.poolSize=30

yugong.database.target.url=jdbc:mysql://192.168.20.204:3306/ue
yugong.database.target.username=root
yugong.database.target.password=root
yugong.database.target.type=MYSQL
yugong.database.target.encode=UTF-8
yugong.database.target.poolSize=30
yugong.table.white=dev_uechn_db.yugong_example_a
yugong.table.mode=CHECK,FULL
4./usr/local/yugong/conf/positioner 目录已清空
5.public class YugongExampleADataTranslator extends AbstractDataTranslator implements DataTranslator {

public boolean translator(Record record) {
    // 1. schema/table名不同
    record.setSchemaName("ue");
    record.setTableName("yugong_example_mysql_a");
    // 源表为yugong_example_a,目标表为yugong_example_mysql_a

6.check.log

- Schema: ue , Table: yugong_example_mysql_a

---Pks
ColumnValue [column=ColumnMeta[name=ID,type=3], value=1]
---diff
record not found


- Schema: ue , Table: yugong_example_mysql_a

---Pks
ColumnValue [column=ColumnMeta[name=ID,type=3], value=2]
---diff
record not found
也就是MYSQL目标表没有数据导入

代码错误? NullPointer Exception

同步时碰到如下NullPointerException 错误

2017-01-03 13:59:05.307 [YuGongInstance-JKCITY.HOSPINFO] ERROR com.taobao.yugong.controller.YuGongInstance - retry 1 ,something error happened. caused by java.lang.NullPointerException
        at com.taobao.yugong.common.db.RecordDiffer.diff(RecordDiffer.java:49)
        at com.taobao.yugong.applier.CheckRecordApplier.diff(CheckRecordApplier.java:347)
...

看 CheckRecordApplier.java:347 行

            RecordDiffer.diff(null, record2);

同时 com.taobao.yugong.common.db.RecordDiffer.diff的实现(包含49行)

    public static void diff(Record record1, Record record2) {
        if (record2 == null) {
            diffLogger.info(diffMessage(record1.getSchemaName(),
                record1.getTableName(),
                record1.getPrimaryKeys(),
                "record not found"));
            return;
        }

        if (record1.getColumns().size() > record2.getColumns().size()) {
            diffLogger.info(diffMessage(record1.getSchemaName(),
                record1.getTableName(),
                record1.getPrimaryKeys(),
                "column size is great than target column size"));

            return;
        }

这样的话,如果执行到这个逻辑,必然触发 record1 为 null 的exception?

支持 SQL Server <-> MySQL

@agapple
我现在开发了 MySQL <-> SQL Server 的模块特性如下:

DB 支持:

  • 支持 MySQL <-> SQL Server,支持 CHECK / FULL 模式

运行环境:

  • 部署模式调整为 fat jar 模式
  • 新增特性的配置文件使用 YAML 配置

Translator 方面:

  • 支持了 MySQL 5.7 的 JSON 字段 Compress / Extract,可以将多个字段压缩进去。
  • 支持字段 NameStyle 的变化,比如将 UPPER_CAMEL 转换为 LOWER_UNDERSCORE
  • 支持了字段批量 replace 操作,比如 ID -> Id

目前已经运用到生产环境。
但是改动较大,想咨询一下,以什么样的方式提交 PR。

om.taobao.yugong.exception.YuGongException: table[null.BASE_YD_MSG] is not found

权限已经给了,转换器也按照模板进行编写了,放到了conf\translator路径下了,MySQL大小写不敏感 ,请问下,这是什么问题?
2017-08-13 11:21:54.893 [main] INFO com.taobao.yugong.controller.YuGongInstance - table[SYSTEM.BASE_YD_MSG] start successful. extractor:com.taobao.yugong.extractor.oracle.OracleAllRecordExtractor , applier:com.taobao.yugong.applier.AllRecordApplier, translator:NULL
2017-08-13 11:21:54.943 [YuGongInstance-SYSTEM.BASE_YD_MSG] INFO c.t.y.e.oracle.OracleMaterializedIncRecordExtractor - table[SYSTEM.BASE_YD_MSG] now is CATCH_UP ...
2017-08-13 11:21:55.041 [YuGongInstance-SYSTEM.BASE_YD_MSG] ERROR com.taobao.yugong.controller.YuGongInstance - retry 1 ,something error happened. caused by com.taobao.yugong.exception.YuGongException: table[null.BASE_YD_MSG] is not found
at com.taobao.yugong.common.db.meta.TableMetaGenerator$1.doInConnection(TableMetaGenerator.java:75)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:342)
at com.taobao.yugong.common.db.meta.TableMetaGenerator.getTableMeta(TableMetaGenerator.java:51)
at com.taobao.yugong.applier.IncrementRecordApplier.getInsertSqlUnit(IncrementRecordApplier.java:159)
at com.taobao.yugong.applier.IncrementRecordApplier.getSqlUnit(IncrementRecordApplier.java:138)
at com.taobao.yugong.applier.IncrementRecordApplier.applyOneByOne(IncrementRecordApplier.java:86)
at com.taobao.yugong.applier.MultiThreadIncrementRecordApplier.applyBatch0(MultiThreadIncrementRecordApplier.java:240)
at com.taobao.yugong.applier.MultiThreadIncrementRecordApplier.applyBatch(MultiThreadIncrementRecordApplier.java:175)
at com.taobao.yugong.applier.MultiThreadIncrementRecordApplier.doApply(MultiThreadIncrementRecordApplier.java:104)
at com.taobao.yugong.applier.MultiThreadIncrementRecordApplier.apply(MultiThreadIncrementRecordApplier.java:92)
at com.taobao.yugong.applier.AllRecordApplier.apply(AllRecordApplier.java:60)
at com.taobao.yugong.controller.YuGongInstance$1.processTable(YuGongInstance.java:215)
at com.taobao.yugong.controller.YuGongInstance$1.run(YuGongInstance.java:145)
at java.lang.Thread.run(Unknown Source)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.