ITPub博客

首页 > 数据库 > 数据库开发技术 > YashanDB|insert 写入乱码字符,CPU 占满、线程卡死?你可能踩到了 lex 死循环的坑

YashanDB|insert 写入乱码字符,CPU 占满、线程卡死?你可能踩到了 lex 死循环的坑

原创 数据库开发技术 作者:makabala 时间:2025-05-12 20:56:52 0 删除 编辑

【问题现象】

在 GBK 编码的 YashanDB 数据库中,执行某条 insert 语句后:

SQL 长时间无响应

CPU 资源占满(单核 99.9%)

kill session 后也无法释放

查看线程状态,发现 yasdb worker 长时间占用 CPU,而会话处于 killed 状态却无法销毁。

【影响版本】

YashanDB 22.2.16.1

YashanDB 23.3.0.61 及更早版本

【根因分析】

✳ 问题本质:编码非法字符导致 lex 模块陷入死循环

分析表明,该问题由 SQL 中存在非法编码字符引起。示例中数据包含如下非法片段:

0x83. 0x36. 0xCA, 0x33

这些字符既不是 GBK 编码,也不属于 UTF 编码范围。

服务端在解析 SQL 过程中进入:

lex → gbkNextCharLengthb

第一个非法字符(如 0x83)返回 mblen = -1

系统尝试后退 1 位继续识别(回到 '.'),再前进,又重新识别 0x83

于是形成  循环调用 → 无法退出 → 死循环

【复现路径】

由于普通 SQL 编写无法打出这些非法字符,测试人员通过 C 驱动+16进制写入构造场景进行复现。

【风险说明】

【解决方案】

暂时恢复方法

yasboot cluster restart -c yashandb -d

通过重启数据库集群,释放死循环线程,恢复系统状态。

长期解决建议

后续版本已修复 lex 处理非法编码导致死循环的 bug;

如使用旧版本,建议避免插入非法编码内容;

数据迁移前请统一字符集编码规范。

【预防建议】

【经验总结】

lex 层属于语法解析器的核心组件,一旦陷入循环会导致整个 SQL 处理栈无法退出;

编码错误是极易被忽视但影响深远的隐患;

数据处理工具链、接口数据源建议统一使用 UTF-8;

若必须使用 GBK,应明确字符支持范围,并在 ETL 前做字符合法性清洗。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70045450/viewspace-3083985/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2025-04-10

  • 博文量
    231
  • 访问量
    229269