【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、终端、客户端编码需要一致。
版权声明: 本文为 InfoQ 作者【YashanDB】的原创文章。
原文链接:【http://xie.infoq.cn/article/34f8871fe183ef97a8a635822】。文章转载请联系作者。
评论