一个 VARCHAR(1) 的字段,卡住了整条 DTU 数据链路

一个 VARCHAR(1) 的字段,把整条 DTU 数据链路卡住了。问题不在代码逻辑,而在数据库一个列宽------它只够存一个字符。

一、现象:秤上放了重物,前端数字不动

场景是给加工环节接电子秤:DTU 透传秤的串口数据 → EMQX → 服务端消费解析 → 写回加工任务那行 → 前端轮询显示实时重量。

联调测试的时候,我在秤上放了重物,前端那个重量数字却一动不动。

它不崩、不白屏,也不报错,只是这一路数据默默没了。这种「不报错但数据不对」的问题,比直接抛异常难查得多。

二、排查:三层链路逐层确认

我按链路往下查,一层层排除:

层 查什么 结论
MQTT 帧到底有没有上来 通 ------ 帧正常到达
解析 帧里的重量和稳定标志有没有解析出来 通 ------ 都解析出来了
落库 UPDATE 有没有真的执行成功 问题在这一层

前两层之所以能直接排除,是因为报错本身就是从 UPDATE 抛出来的------数据既然走到了落库这一步,说明前面两段链路是活的。这也是排查这类问题的省力办法:先看报错发生在哪一层,就说明它前面的都是通的。

三、根因:列宽只够一个字符

最后在数据库这层找到了:

sql 复制代码
Data too long for column 'stable_status' at row 1

这个列的原始定义是:

sql 复制代码
ADD COLUMN stable_status VARCHAR(1) DEFAULT '0'
  COMMENT '设备稳定状态:0波动中/1已稳定'

VARCHAR(1)------只够存一个字符 ,设计意图就是存 0 或 1。

但落到这个列上的值,并不总是单个字符。

这里有个容易被忽略的设计:电子秤的「稳定标志」其实有两个来源------

  1. 帧里自带 :DTU 透传上来的报文里可能带稳定标志位。解析器按配置的取值集合判定什么算「已稳定」(默认 1 / true / st / stable / ok / stable-ok 都算)。
  2. 服务端判定:帧里不带标志时,由服务端按「N 秒内重量变化不超过阈值」自行判断(默认窗口 3 秒、容差 0.5kg,容差是留给秤末位抖动的)。

两条路径如果产出的标志格式不统一,就会有一路写出超过一个字符 的值,直接撞上 VARCHAR(1) 的墙。

这个坑的关键不在于「谁写错了」,而在于这个字段允许两套格式并存。

四、为什么难查:三个障眼法

障眼法 表现
报错位置和现象位置隔了三层 帧 → 解析 → 落库,报错在最后一层,现象在最前面
异步链路吞异常 消费线程抛的异常只进日志,业务侧完全无感
前端「假装正常」 轮询照跑、页面不报错,看不出是断了

五、修法:统一口径,不动表结构

把该列的取值统一成数字字典 0 / 1------4 个文件、5 处调用全部对齐,不用改表结构。

(经验:改之前先把这个字段的所有写入点 grep 一遍。只看你眼前那一处,一定会漏。)

六、复盘:怎么防

  1. 字典类字段,值和列宽一次性定死 ------VARCHAR(1) 这种「刚好够」的设计,一旦有人往里塞别的格式,立刻炸
  2. 多来源的同一个字段,写库前强制归一化------帧里来的、服务端算的、前端传的,出口只留一种格式
  3. 异步消费端必须有兜底 + 告警------异常不能只写日志,要能叫醒人
  4. 给链路加「静默失败」监控------多久没数据就告警,别等用户来投诉
  5. MySQL 严格模式别关------它报错是在救你;关了它只会静默截断,脏数据悄悄进去更麻烦

附:这套采集里几个真实的取舍

这几个是联调时才想明白的,比技术本身更值钱:

  • 写库节流 500ms:秤是高频上报的(一秒好几帧),不做节流会把数据库打满
  • 自动兜底默认关闭:现场是「一样料分多趟加」,中途静止会被误判成「加完了」。宁可留空让人补录,也不自动串位
  • 租户隔离红线 :采集线程没有登录上下文,必须先按设备反查绑定的是哪个任务、再切到那个任务的租户落库,否则数据会写进 tenant=0(平台层),造成跨租户污染

(本文用「某 SaaS 平台」代指实际项目,表名、字段名、配置项均已替换,不含任何真实客户信息。)

相关推荐
仿生joe会梦见漫天的大雪吗1 小时前
CTF Misc 工具选型指南:按题型分类的工具、原理与限制
后端·安全
南丘山1 小时前
多租户隔离失效,我踩过的 3 个坑
后端
IT_陈寒1 小时前
Java缓存踩坑记:明明设置了过期时间,怎么还是读到脏数据?
前端·人工智能·后端
用户8662978480081 小时前
数据库报错"坏块"别急着删库重来,试试 KingbaseES 的离线修复工具
后端
jose1 小时前
URL 里多写了一个端口,为什么请求还能调通?
java·后端
用户8356290780511 小时前
使用 Python 在 Excel 中识别并高亮重复数据与唯一数据
后端·python
CCblandy1 小时前
Agent 工具调用怎么编排?本机实测:并行只到 2.63 倍,慢的先发省 30ms,CPU 活加 worker 无效
人工智能·后端·python·性能优化
茉莉玫瑰花茶1 小时前
GO [ 标准库 ]
开发语言·后端·golang
用户8356290780511 小时前
使用 Python 在 Excel 中查找、替换数据并高亮显示
后端·python