问题现象

insert 语句卡住,yasdb worker 线程 cpu 占用 99.9%
图片.png
图片.png
问题风险及影响

sql 执行不了

问题影响版本

22.2.16.1、23.3.0.61 及之前版本

问题发生原因

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

1、alter system kill session '22,26'; kill 掉 session 后,发现 session 显示状态为 killed,但是 session 一直存在,未退出。
图片.png
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 驱动来复现。
图片.png
'.'字符是普通字符

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

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

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

经验总结

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

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


qiaoyikefu
1 声望0 粉丝