开发者社区> 问答> 正文

Flink报错Deadlock found when trying to get lock; ...

已解决

Flink报错Deadlock found when trying to get lock; try restarting transaction

展开
收起
提个问题 2024-05-29 16:09:52 14 0
1 条回答
写回答
取消 提交回答
  • 开发者社区问答官方账号
    官方回答
    采纳回答
    异常信息写MySQL(TDDL/RDS)时,出现死锁(DeadLock)。说明在实时计算Flink中,下游数据库使用MySQL等关系数据库(对应的Connector为TDDL/RDS),当实时计算Flink版频繁写某个表或者资源时,存在死锁风险。死锁形成的示例假设完成一次INSERT需要依次抢占(A,B)2个锁。A是一个范围锁,有2个事务(T1,T2),表的Schema为(id(自增主键),nid(唯一键))。T1包含2条insert(null,2),(null,1),T2包含1条insert(null,2)。t时刻,T1第一条INSERT插入,此时T1持有(A,B)2个锁。t+1时刻T2开始插入,需要等待锁A来锁住(-inf,2],此时A被T1拥有,且锁住了(-inf,2],区间存在包含关系,所以T2依赖T1释放A。t+2时刻T1第二条INSERT执行,需要A锁住(-inf,1],该区间属于(-inf,2],所以需要排队等T2释放锁,所以T1依赖T2释放A。当T1和T2相互依赖且相互等待时死锁形成。RDS/TDDL、OTS数据库引擎锁的区别RDS/TDDL:InnoDB的行锁是针对索引加的锁,不是针对单条记录加的锁。所以虽然是访问不同行的记录,但是如果使用相同的索引键,会出现锁冲突,造成了整个区域的数据都无法更新。
    OTS:单行锁,不影响其他数据更新。
    解决方案:高QPS/TPS或高并发写入情况场景,建议使用OTS作为结果表,可以解决死锁的问题。通常,不建议使用TDDL或者RDS作为Flink Job的结果表。如果必须要使用MySQL等关系数据库作为Sink节点,有以下建议:确保没有其他读写业务方的干扰。如果Job的数据量不大可以尝试单并发写入。但是在高QPS/TPS、高并发情况下,写入性能会降低。尽可能不使用UniqueKey(唯一主键),带UniqueKey表的写入可能会导致死锁。如果业务要求表必须包含UniqueKey,按照字段区分能力从大到小排列来定义UniqueKey,可以大幅降低死锁出现概率。例如,可以把MD5函数放在day_time(20171010)前面,就可以使得字段区分能力从大到小排列来定义UniqueKey,从而解决死锁问题。根据业务特点做分库分表,尽可能避免单表写入,实施细节请联系对应的数据库管理员。
    2024-05-29 16:09:53
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Flink CDC Meetup PPT - 龚中强 立即下载
Flink CDC Meetup PPT - 王赫 立即下载
Flink CDC Meetup PPT - 覃立辉 立即下载