使用clickhouse-jdbc-bridge迁移ClickHouse至Oracle的异常问题求助
基于clickhouse-jdbc-bridge向Oracle迁移数据的异常排查与解决
环境信息
- Oracle: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit
- ClickHouse: 24.1.4.20
- clickhouse-jdbc-bridge: 2.1.0-1
- 数据源配置文件路径:
/etc/clickhouse-jdbc-bridge/config/datasources/ora.json,配置内容:
{"$schema": "/etc/clickhouse-jdbc-bridge/config/datasource.jschema", "ora": { "driverUrls": [ "/u01/drivers/ojdbc8-19.3.0.0.jar" ], "connectionTestQuery": "select 1 from dual", "driverClassName": "oracle.jdbc.driver.OracleDriver", "jdbcUrl": "jdbc:oracle:thin:@//1.2.3.4:1521/nsser", "username": "usr", "password": "pwd", "maximumPoolSize": 20, "MaxLifetime": 720000 } }
表结构与操作
ClickHouse源表
源表mac.ch_cfc_str共1857428行,表结构:
CREATE TABLE mac.ch_cfc_str ( id_contract Int64, lot_id Int64, doc_num FixedString(19),--String, customer Int64, sign_date DateTime, sign_number FixedString(100),--String, version Int64, type_info Int64, date_cache Int64, datecalc_cache Int64 ) ENGINE = MergeTree ORDER BY (datecalc_cache, date_cache, type_info) ---- м.б. doc_num сюда SETTINGS index_granularity = 8192;
ClickHouse JDBC引擎表(关联Oracle目标表)
CREATE TABLE mac.ora_cfc( sign_date DateTime, sign_number String, doc_num String, datecalc_cache Decimal(10,4), date_cache Decimal(10,4), type_info Decimal(10,4), version Decimal(10,4) ) ENGINE JDBC('ora','mac','ora_cfc');
Oracle目标表
create table mac.ora_cfc ( sign_date date not null, sign_number varchar2(256) not null, doc_num varchar2(256) not null, datecalc_cache number not null, date_cache number not null, type_info number not null, version number not null );
复制执行语句
insert into mac.ora_cfc(sign_date,sign_number,doc_num,datecalc_cache,date_cache,type_info,version) select sign_date,sign_number,doc_num,datecalc_cache,date_cache,type_info,version from mac.ch_cfc_str
异常现象
- 复制完成后Oracle表数据量达3132400行,远多于源表;
- 复制过程偶发冻结、无法启动或仅复制部分数据;
- 出现多种错误:
ORA-01400: cannot insert NULL into ("mac"."ora_cfc"."DOC_NUM") ORA-01461: can bind a LONG value only for insert into a LONG column HTTP status code: 500 Internal Server Error, body: Invalid LEB128 sequence. HTTP status code: 500 Internal Server Error, body: index: 173050309, length: 136620051
- 测试发现:移除所有字符串字段或仅保留字符串字段时,复制可成功。
排查与解决建议
1. 修正字段类型映射
- 数值字段:ClickHouse源表的
Int64类型直接对应Oracle的NUMBER,无需在JDBC引擎表中转为Decimal(10,4)。修改JDBC引擎表结构,将datecalc_cache、date_cache、type_info、version改为Int64,避免类型转换导致的绑定错误(如ORA-01461)。
修改后的JDBC引擎表语句:CREATE TABLE mac.ora_cfc( sign_date DateTime, sign_number String, doc_num String, datecalc_cache Int64, date_cache Int64, type_info Int64, version Int64 ) ENGINE JDBC('ora','mac','ora_cfc'); - 字符串字段:ClickHouse的
FixedString会自动填充空字符至固定长度,而Oracle将空字符串识别为NULL,触发NOT NULL约束报错(ORA-01400)。插入时需去除尾部空字符,将select语句改为:insert into mac.ora_cfc(sign_date,sign_number,doc_num,datecalc_cache,date_cache,type_info,version) select sign_date, trim(sign_number) as sign_number, trim(doc_num) as doc_num, datecalc_cache, date_cache, type_info, version from mac.ch_cfc_str
2. 修正JDBC Bridge连接池配置
配置文件中MaxLifetime参数大小写错误,应为maxLifetime(驼峰命名,小写开头)。参数错误会导致连接池管理异常,引发重复插入、冻结等问题。修正后的配置片段:
"maximumPoolSize": 10, "maxLifetime": 720000
同时建议将maximumPoolSize调整为10,避免并发连接过高超出Oracle的连接限制。
3. 分批插入避免内存/协议错误
全量插入大表时,JDBC Bridge可能因内存不足或数据传输协议问题抛出Invalid LEB128 sequence等错误。采用分批插入方式,示例:
-- 分批插入,每次处理10000行 SET max_insert_threads = 2; INSERT INTO mac.ora_cfc(...) SELECT ... FROM mac.ch_cfc_str LIMIT 10000 OFFSET 0; INSERT INTO mac.ora_cfc(...) SELECT ... FROM mac.ch_cfc_str LIMIT 10000 OFFSET 10000; -- 依次类推直到完成
4. 验证驱动与版本兼容性
- 确认ojdbc8驱动与Oracle 12c的兼容性,可尝试替换为ojdbc12驱动(适配Oracle 12c的官方驱动);
- 升级clickhouse-jdbc-bridge至最新稳定版,修复已知的兼容性问题。
内容的提问来源于stack exchange,提问作者Aleksey N Yakushev
相关产品推荐
相关产品推荐

