Kafka 相关
管道运行中报错:Exception during get all topics from broker
问题描述:
管道运行中报错:ERROR Exception when realtime job run - com.fr.dp.exception.FineDPException: exception during get all topics from broker.
原因分析:
Kafka 未启动,无法获得相关 topics。
解决方案:
检查传输队列的测试连接可不可以成功,同时使用 jps 命令(需要有 JDK 环境),查看 Kafka 状态。有时候 jps 命令不可用,也可使用命令:ps -ef|grep kafka 查看 Kafka 进程
jps 命令结果如下图则 Kafka 服务器启动正常:
如果无对应 Kafka 进程,则需要启动进程,详情参见: 启动Kafka
数据管道报错,但是测试连接成功
问题描述:
原因:
连接没问题,但是表存在问题,有一个表配置了 336 个字段,实际上这个表只有 289 个字段。
解决方案:
检查发现同步的表中,目标表有个同名表是已经存在的,但是表结构是不一样的,导致报错。
kafka 启动失败
问题描述:
Kafka 重新启动失败,没有进程。
原因分析:
Kafka 和 zookeeper 关闭先后顺序不对导致的问题。
解决方案:
删除 Kafka 日志文件目录下的 meta.properties 文件,重启 zookeeper 和 Kafka。
重启步骤详情参见:启动Kafka
配置传输队列时,报错connect timeout
问题描述:
传输队列测试连接失败,报错 connect timeout
原因分析:
FDL 和 Kafka 不在一台机器上,需要跨服务器访问,而 Kafka 默认是 localhost 访问,因此需要在配置文件设置 ip 进行访问。
解决方案:
在 server.properties 需要配置 listeners,取消注释,并设置为具体 ip 。
详情参见:增加配置
资源相关
管道任务报错:正在运行的任务数量达到上限
问题描述:
FDL 只能运行几个管道任务,再运行新的管道任务就报错:“正在运行的任务数量达到上限''
原因分析:
受到 资源控制 里设置的内存大小影响,一个管道任务运行占用 1024M。如资源控制的内存限制设置了 2050 M,则向下取整,最多执行 2 个管道任务。 即控制管道任务的运行数量。
定时和管道任务用的内存不会超过资源控制设定的上限,但需要注意的是因为目前定时任务和管道任务共用一个内存限制,内存限制的数值大小等于 JVM 的大小时,容易产生宕机现象。
解决方案:
在 资源控制 中根据 资源控制内存计算方式 修改内存限制。
权限相关
数据管道启动后报错:任务终止执行-Interrupt realtime task
问题描述:
前端报错如图:
fanruan.log 报错 SQL 执行失败 - No corresponding type for code: 0
原因分析:
缺少了 sys 下面的某些权限。
解决方案:
给用户赋数据库 owner 的权限。
MySQL 任务启动阶段,检查任务配置不通过-数据库实时配置未开启或无权限,当前数据库不支持管道任务同步
问题描述:
任务运行失败,日志报错:
MySQLSyntaxErrorException: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation
解决方案:
给 MySQL 数据库开启复制权限,详情参见:给指定账号开启复制权限
oracle作为来源端运行报错ORA-01287: 文件 来自于不同的数据库原型,数据库是oracle10g
问题描述:
Oracle 作为来源端运行报错ORA-01287: 文件来自于不同的数据库原型,数据库是oracle10g
原因分析:
管道解析 logminer 需要有解析 logminer 与访问日志的权限。用户没有给访问日志的权限。
同步源表结构变化
部分数据未完成同步
问题描述:
管道任务中,源端为 Oracle,运行一段时间后任务异常终止,报错如下:
抽数引擎内部异常-读取端出错-数据管道 Oracle LogMiner 遇到无法解析的数据,请根据日志中的提示信息操作活动联系技术支持人员。-无法正常解析表XX的数据,可能是由于该表表结构发生变化且在表结构发生变化前有未完成同步的数据,这部分未完成同步的数据无法正常处理
临时解决方案:请编辑任务将表XX移除,然后重启任务,让任务恢复正常运行,等运行日志中显示 offsetScn 大于295506865之后可以编辑任务把该表重新添加回来,重新进行全量+增量同步
解决方案:
该报错 DDL 无法解决。
需参考报错中的「临时解决方案」,解决这个问题。
任务执行相关
管道任务异常终止,报错: The message is 10196218 bytes when serialized which is larger than 5242880, which is the value of the max.request.size configuration.
问题描述:
管道任务异常终止:
解决方案:
MySQL 同步的单条数据所用内存超过了 Kafka 的 max.request.size 参数的值所导致的,这个参数限制了 Kafka 能够处理的最大请求大小。
该参数由 FDL 提供给 Kafka,但目前在 FDL 中默认设置为了 5MB ,无法手动调整。
需要将来源表中长度较长的字段先在同步中去掉,比如 json、longtext 等字段,将单条数据的内存量降低。
全量同步报错:duplicate key
问题描述:
数据管道任务进行同步全量阶段报错:duplicate key
原因分析:
管道中存在多个数据库,不同数据库中存在同名表。
解决方案:
此问题已经在 4.0.20 修复,用户可升级解决。
任务运行终止报错:Write table's column number[75] more than db table's column number[73]
问题描述:
任务运行报错:Write table's column number[75] more than db table's column number[73]
原因分析:
实时同步前目标库下已存在有同名表。
解决方案:
删掉目标库中的同名表后再运行管道任务。
管道任务异常中止,且fanruan日志里报错:SQL执行失败-.NET Framework运行时停止
问题描述:
fanruan日志里报错:SQL执行失败-.NET Framework运行时停止
解决方案:
排查数据库是不是在管道任务运行期间进行了重启,如果是,需要避免在管道任务运行期间重启数据库。
FDL的finedb是SQL server,数据管道报错死锁
问题描述:
任务报错:“事务进程[ID 101]与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品,请重新运行该事务。”
原因:
外置 finedb 是SQLServer,SQLServer是块锁,再进行save or update操作时,如果先查询,则会给一块的数据加共享锁,如果两个事务同时给数据加了共享锁。其中一个事务想更新的时候,因为要升级锁,就会导致死锁,就会牺牲掉一个线程,导致任务的失败。
解决方案:
方案一:
1. 设置隔离级别
hibernate.connection.isolation=8
(这个配置是使得事务之间完全隔离,互不影响)
2. 设置SqlServer的行版本控制功能打开
允许事务可以读取其他事务未提交的数据快照:
SET ALLOW_SNAPSHOT_ISOLATION ON
使读操作不会锁定数据:
方案一:SET READ_COMMITTED_SNAPSHOT ON
方案二:
if(charindex('Microsoft SQL Server 2008',@@version) > 0)
begin
declare @sql varchar(8000)
select @sql = '
ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
ALTER DATABASE ' + DB_NAME() + ' SET ALLOW_SNAPSHOT_ISOLATION ON;
ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'
Exec(@sql)
end
设置完之后可以使用查询是否设置成功:
SELECT is_read_committed_snapshot_on FROM sys.databases
WHERE name= '数据库名字'
方案二:
切换外置 FineDB 为 MySQL 或者 Oracle 。
数据写入存在延时
问题描述:
数据管道任务执行成功,但写入的数据与数据库中的数据存在差异,一些最新数据未被写入。
原因分析:
写入数据库的 update_time 与 FineDataLink 的更新时间不一致
解决方案:
用户自行修复数据库的时间设置即可。
数据管道任务运行时 SQL Server 执行缓慢
问题描述:使用了数据管道,目标库为 SQLServer。在管道任务运行时,该 SQLServer 库上的存储过程运行以及查视图等操作会阻塞,执行很慢。关掉管道任务后,运行通畅。
原因分析:
SQLServer 自身存在锁的机制,数据写入后,写入的表会上锁,读操作会等待。
该场景中管道任务高频写入,导致数据库表长时间处于锁表状态,读取操作阻塞,原本只需几分钟执行的存储过程,开启管道任务后需要 10 多个小时才能执行完成。
解决方案:
解决方案有三种,可根据情况选定。
1)存储过程加 with no lock
影响:可能会导致脏读,数据不写入。但是我们管道任务会把这部分数据记录,最终还是可以写入进去的
2)晚上执行存储过程
一般来说白天业务会比较繁忙,数据同步量大。考虑将存储过程放到晚上执行,业务不频繁,存储过程受锁的影响应该会降低。
3)设置 snapshot 快照隔离级别
操作步骤:
确认数据库兼容性级别:快照隔离要求数据库兼容性级别至少为90。可以使用以下命令检查当前数据库的兼容性级别:
SELECT compatibility_level FROM sys.databases WHERE name = 'YourDatabaseName';
如果兼容性级别低于90,可以使用以下命令将其更改为90或更高:
ALTER DATABASE YourDatabaseName SET COMPATIBILITY_LEVEL = 90;
开启快照隔离:可以使用以下命令在数据库中开启快照隔离:
ALTER DATABASE YourDatabaseName SET ALLOW_SNAPSHOT_ISOLATION ON;
确认开启成功:可以使用以下命令检查是否已经开启了快照隔离:
SELECT is_read_committed_snapshot_on FROM sys.databases WHERE name = 'YourDatabaseName';
影响:可能会产生额外的数据库存储开销,因为 SQLServer 会自动创建用于维护快照隔离的版本存储器;可能会影响写入性能。
来源端为PostgreSQL的管道任务频繁暂停
问题描述:
管道任务中,来源端为 PostgreSQL ,该任务因为不同的原因频繁异常中断。现象有以下几种:
报错数据库连接中断。
不报错但是实际数据未同步。
原因分析:
数据库中某些没有主键的表更新时(可能是非管道同步的表),会积累很多的 warning 信息,而 PostgreSQL 的 JDBC 驱动比较特别,会让 FDL 一次性读取到所有 warning 信息,这些信息让会让 FDL 花很久去处理,导致了管道出现问题,比如内存溢出,比如因为很久没和数据库通信会被认为连接中断等。
解决方案:
修改数据源的数据库账号的消息级别,减少 warning 信息。
ALTER ROLE <管道使用的数据库账号> SET client_min_messages TO 'error';
示例:
ALTER ROLE postgres SET client_min_messages TO 'error';然后重启管道任务。
待同步量显示为负数
问题描述:
管道任务待同步量为负数。如下图所示:
原因分析:
管道任务运行过程中使用 kill -9 关闭了 Kafka 进程,导致:
数据已经发送到了 Kafka,但是在 FDL 中没有计入已读取数据量中,写入端会正常写入和记录这部分数据,导致 FDL 记录的写入数据量大于读取数据量。
其中,FDL显示的「待同步数据量」=已读取数据量-已写入数据量-脏数据量,从而导致「待同步量」为负数。
解决方案:
用户若需要对 Tomcat 或者 Kafka 重启,需要提前暂停管道任务后,再进行重启。若不规范操作,可能会导致待同步量为负数。
ORA-01292: 没有为当前 LogMiner 会话指定日志文件
问题描述:
管道任务源端为 Oracle,报错:ORA-01292: 没有为当前 LogMiner 会话指定日志文件
排查步骤:
1)查看 fanruan.log 或前端运行日志,确认开始解析的 scn
//日志内容,xx为具体任务名,xxx为具体scn
INFO [standard] 管道任务名称: [xx] 从SCN[xxx]开始解析
2)数据库中查找,确认源库归档日志中是否还存在此 SCN ,由此确认日志是否被删除
SELECT *
FROM v$archived_log
WHERE first_change# <= <SCN>
AND next_change# > <SCN>;
如果查询返回结果为空,则表示没有具有指定 SCN 的归档日志 。
如果查询返回结果不为空,查看 static 列,status 为 D 代表已经删除(如果有多条可以查一下 finedb 配置,fine_conf_entity 表中 FDL.pipeline.oracle.archived.log.path 的值,添加了过滤条件,多条中仅有一条是使用中的)。若日志被删除,由此可以触发重新同步(若直接调整仅增量时间会出现数据丢失的现象)。
源端日志已过期,无法启动
管道任务暂停一段时间后,再次启动,报错:源端日志已过期,无法启动。如下图所示:
解决方案:
复制这个管道任务,同步类型选择仅增量同步即可;或者新建一个相同的管道任务,首次数据同步会清空目标数据表数据,然后全量同步数据,此后增量同步。
管道任务同步失败
问题描述:
1)2 月 20 号创建的任务,一直执行没问题,直到 26 号晚上同步断了。
2)重启有提示,但没法操作重新同步,提示:源端日志已过期,无法启动
原因分析:
阿里云的 rds 发生了主备切换导致的。
解决方案:
复制这个管道任务,同步类型选择仅增量同步即可;或者新建一个相同的管道任务,首次数据同步会清空目标数据表数据,然后全量同步数据,此后增量同步。
Oracle到Oracle乱码
问题描述:
数据管道 Oracle 同步到 Oracle 英文产生乱码。
解决方案:
1)需要确定两端 Oracle 数据库的编码是否一致:发现一致。
2)确定产生乱码的字段类型是否一致:不一致,正式环境是 NVARCHAR2(70),数仓是 VARCHAR2(70)。
3)将两端的字段类型修改成一致的类型 NVARCHAR2(70)。
报错:读取记录长度超过限制,当前限制长度为67108864
问题描述:
管道任务运行报错:create connection or statement failed.-Record size exceeds limit.-读取记录长度超过限制,当前限制长度为67108864
原因分析:
管道任务中,同步了 longtext 类型的字段。
解决方案:
不建议用户使用数据管道同步 longtext 类型的字段,否则 Kafka 会有问题,运行效率也会有问题。
可以用定时任务同步该类型字段。
管道部分字段数据为空
场景一:
问题:
来源端为 SQLServer,管道同步后,发现目标表某个字段数据为空。
原因:
确认源表是否修改过表结构,如字段类型/字段长度,若修改过需要去数据库中关闭这张表的实例,再重新开启,然后重新同步。
因为 SQLServer 数据库中每个开启实例的表,都有一张记录其对应表结构和数据变更的表。如果修改了表结构,但是不重新生成实例,会记录不到对应字段的数据。
场景二:
问题:
目标端为 Greenplum,目标表为已存在表,数据管道增量阶段,_fdl_update_timestamp_ 字段值为 NULL。
方案:
需要检查 _fdl_update_timestamp 字段是否有默认值,若没有,设置默认值(date_part('epoch'::text, now()) * 1000::double precision)::bigint
原因:
增量插入的时候不会给具体时间戳的值,而是交由数据库写入。但是这个字段没有默认值,所以写入NULL了。
日志显示
按级别筛选日志显示空白
问题描述:
管道任务中,按级别筛选日志显示空白。如下图所示:
原因分析:
FDL 是 ops 部署的,自动启用了 ES 插件,但 FDL 未适配 ES ,导致日志数据没能存下来。
解决方案:
禁用 ES 插件,重启 FDL,之后的日志会正常记录到 LogDB 。
脏数据相关
数据源为kafka,处理脏数据失败
问题描述:
管道任务中脏数据阈值为10000,数据来源为 Kafka,脏数据超过 10000 后管道任务自动停止,点击重试脏数据,报错:detached entity passed to persist: com.fr.dp.dirty.entity.DirtyDataEntity
原因分析:
当数据源是 Kafka ,不支持重新同步,且过期的脏数据若想重试,仅能通过全表重跑或手动插入脏数据后在管道处忽略脏数据。
任务运行报错-脏数据量超过设定阈值
问题描述:
MySQL-GaussDB 200 数据管道任务自动建表全部报错为脏数据
原因:
不同数据库中的中文的字符存贮长度不同,GaussDB 200 的长度是 MySQL 库的三倍,截止版本 4.0.13 ,FDL自动建表逻辑是一比一映射,导致目标表的字段长度不够,写进来的数据全部判断为脏数据。
解决方案:
在数据库修改目标表的字段长度。
运行日志显示有脏数据,但前端脏数据显示为0
问题描述:
管道任务中,来源端为 Oracle11g,目标端为 Oracle21c,管道日志一直提示有脏数据,但是前端脏数据显示为 0,数据库有未提交的事务。
原因分析:
用户来源表没有主键,来源表 ID 字段是先插入空值,再 update 更新具体的值;目标表对应字段设置了物理主键,所以解析来源表插入为空就会报错脏数据。
管道逻辑:如果指定 id 的数据是脏数据时,后面有同样 id 的数据写入成功,会移除前面的脏数据。
问题场景模拟:
1)先 insert 一个主键为 null 的数据。
2)然后更新主键。
第一条记录为脏数据,第二条更新主键变为,删除 + 插入, 删除肯定是成功的,对应的会移除第一条脏数据。
解决方案:
可忽略这个报错,或者调整来源表数据变化过程。