【YashanDB知识库】insert语句有编码不识别字,执行卡住问题
问题现象
insert语句卡住,yasdb worker线程cpu占用99.9%
问题风险及影响
sql执行不了
问题影响版本
22.2.16.1、23.3.0.61及之前版本
问题发生原因
lex解析时,对于不能识别字符的特殊场景,形成死循环。
1、alter system kill session ‘22,26’; kill掉session后,发现session显示状态为killed,但是session一直存在,未退出。
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驱动来复现。
'.'字符是普通字符
0x83,0x36,0xCA,0x33这四个字符组成的数据既不是gbk编码、也不是utf编码的字符。
服务端是gbk编码,lex解析时,在gbkNextCharLengthb处,在0x83字符mblen为-1,往前走1位,'.'字符mblen为1,往后走1,形成死循环。
内核代码bug,修改代码即可。
经验总结
1、数据同步迁移时,数据转换的编码最好先约定好,对于编码格式不能识别的字符,转换为能识别的编码。
2、终端、客户端编码需要一致。