问题现象

insert语句卡住,yasdb worker线程cpu占用99.9%

【YashanDB知识库】insert语句有编码不识别字,执行卡住问题_崖山数据库

【YashanDB知识库】insert语句有编码不识别字,执行卡住问题_yashandb_02

问题风险及影响

sql执行不了

问题影响版本

22.2.16.1、23.3.0.61及之前版本

问题发生原因

lex解析时,对于不能识别字符的特殊场景,形成死循环。

1、alter system kill session '22,26'; kill掉session后,发现session显示状态为killed,但是session一直存在,未退出。

【YashanDB知识库】insert语句有编码不识别字,执行卡住问题_yashandb_03

2、由于session kill后,一直未销毁,cpu也被占用,猜测sql跑某个步骤未退出。用堆栈调试,发现lex解析时,陷入死循环。

发现数据如下图,'.\\203\\066\\312\\063',换成16进制为0x83,0x36,0xCA,0x33,这些字符既不是gbk、也不是utf编码。

解决方法及规避方式

1、yasboot cluster restart -c yashandb -d

2、输入正常的字符编码的sql

问题分析和处理过程

复现用例,这些字符既不是gbk、也不是utf编码,正常写insert sql是写不出来的,所以使用16进制替换字符的方式,使用c驱动来复现。

【YashanDB知识库】insert语句有编码不识别字,执行卡住问题_yashandb_04

'.'字符是普通字符

0x83,0x36,0xCA,0x33这四个字符组成的数据既不是gbk编码、也不是utf编码的字符。

服务端是gbk编码,lex解析时,在gbkNextCharLengthb处,在0x83字符mblen为-1,往前走1位,'.'字符mblen为1,往后走1,形成死循环。

内核代码bug,修改代码即可。

经验总结

1、数据同步迁移时,数据转换的编码最好先约定好,对于编码格式不能识别的字符,转换为能识别的编码。

2、终端、客户端编码需要一致。