曹工改bug--本来以为很简单的数据库字段长度不足的问题,最后竟然靠抓包才解决
问题描述
这两天本来忙着新功能开发,结果之前的一个项目最近要上了,然后又在测试,然后就喜提bug一枚(not mine),看bug描述,很简单,而且本地环境也重现了,只要刷入2000个英文字符就可以复现。
核心就是:
当任务描述输入最大字符2000时,报未知异常
问题定位
这种字符数限制的,一般就是数据库的字段长度短了,于是我直接找到ssh,找到对应的日志看了一下,果然是这个问题。
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'feedback_content' at row 1
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3931)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3869)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2675)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2465)
还能说啥,直接上去改呗,于是连上数据库,打开表,查看表结构,发现好像没啥问题:

这不就是设置的2000吗,难道后面的字符集有问题吗,因为表是用的utf8mb4,难道有影响?然后改成了下面这样:
`feedback_content` varchar(2000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '反馈内容',
结果并没有用,果然不应该怀疑这个的,utf8 和 utf8mb4,差距也没那么大,这里又没有特殊字符。
另外就是,中途也试了直接用工具改表,好像没啥问题。
中途甚至怀疑连错库了,用命令查看了java进程(开发环境,java进程和数据库在同一台机器)的连接,确认库没连错。
netstat -ntp|grep 1279

然后我尝试着用1999、1998字符去验证,还是有问题,想着哥见过的bug多了,还能栽在这儿吗,实在不行就开idea,本地debug一下吧。
这样想着,到了午饭时间,就去吃饭了。
再次定位
吃完饭后,中午并没有看bug,不过有个大概思路准备试一下。
思路就是,服务器上用tcpdump抓应用程序和mysql之间的包,然后看看情况,看看到底是哪里有问题吧。
然后下午空了一会,就在服务器上开了抓包:
tcpdump -i lo tcp port 3306 -Ann
- -i 抓环回网卡,因为我java服务和mysql在一台上
- tcp port 3306 这个是捕获表达式,意思是,抓的包,其端口(不管是source还是destination,其端口需要是3306)
- -A Print each packet (minus its link level header) in ASCII. Handy for capturing web pages. 意为直接asicc打印包的内容,因为mysql不是完全看不懂的二进制协议,所以可以直接打印
- -nn Don't convert protocol and port numbers etc. to names either. 端口显示数字就好,不用把知名端口转换为可读的文本
开了抓包后,然后马上去操作了一把,然后这边马上看到,包已经打印出来了(包如果很多,记得赶快ctrl c中断抓包):

可以看到,确实是mysql 服务器报错了,和我们客户端没半毛钱关系。
但是,还是很奇怪,不知道为啥报错。
于是,我重新抓了一次包。
tcpdump -i lo tcp port 3306 -w test.pcap
这里没指定-Ann了,因为我们这次是要保存下来,到test.pcap这个文件。
然后再去测了一下,然后回来ctrl c,可以看到如下信息:

(这里仅供演示,没再去测试了,我把下午抓的包给大家看)
wireshark分析
用wireshark打开该test.pcap,可以看到:

可以发现,wireshark直接内置了mysql的解析协议,很方便,我们这里隐去了一些表信息。大家学着用一下,很简单。
但是现在还没看出来问题,我仔细观察了一下,

上图中,我发现,每一列后,都会跟个逗号来分隔;但是,我们反馈内容那一列,前面怎么那么多个点呢?
然后基本可以肯定,是程序在里面加料了,然后去看了代码逻辑,果然,程序里,对前端传过来的内容,前面还拼了一些东西进去,然后基本就这样找到问题了。
实际上,我们也可以这样看,对着这个包,点右键,follow stream,就会把这个socket 四元组的通信都过滤出来。

注意,上图是asicc显示的,我们切换为utf8看一下,就很明显了。

总结
问题本身很简单,因为惯性思维,我也没有第一时间去看业务逻辑,本能地开始怀疑mysql那边的问题去了,其实还是应该先看看业务。
另外,tcpdump、wireshark这类神器,大家一定要掌握,缩小问题边界、不同服务间问题甩锅啥的,就靠它了。
曹工改bug--本来以为很简单的数据库字段长度不足的问题,最后竟然靠抓包才解决的更多相关文章
- 曹工改bug:cpu狂飙,old gc频繁,线程神秘死亡连环案件调查报告
曹工改bug:cpu狂飙,old gc频繁,线程神秘死亡连环案件调查报告 前言 前两天,访问开发环境上一个java服务,发现一直转圈圈,因为我开着fiddler,可以看到的现象是,接口一直没返回:本来 ...
- 曹工改bug:centos下,mongodb开机不能自启动,systemctl、rc.local都试了,还是不行,要不要放弃?
问题背景 最近装个centos 7.6的环境,其中,基础环境包括,redis.nginx.mongodb.fastdfs.mysql等,其中,自启动使用的是systemctl,其他几个组件,都没啥问题 ...
- 曹工改bug--这次,我遇到了一个难缠的栈溢出bug,还是日志相关的,真的难
前言 前几天,在linux上部署一个war包应用时,tomcat直接起不来,查看tomcat的日志,catalina.out里没啥特别的,但是查看localhost日志,发现栈溢出了. [root@l ...
- 最长单词(一星级题目) 本来是很简单的,其实就是加个flag
随机了一个题目: 给一个词典,找出其中所有最长的单词. 这道题对于初学者还是很有用的,毕竟用的逻辑是比较复杂的 样例 在词典 { "dog", "google" ...
- MySQL入门很简单: 1 数据库概述
1. 数据库概述 1.1 数据存储方式: 1)人工管理阶段 2)文件系统阶段: 文件系统通过文件的存储路径和文件名称访问文件中的数据 3)数据库系统阶段:Oracle, SQL Server, MyS ...
- 曹工杂谈--使用mybatis的同学,进来看看怎么在日志打印完整sql吧,在数据库可执行那种
前言 今天新年第一天,给大家拜个年,祝大家新的一年里,技术突突突,头发长长长! 咱们搞技术的,比较直接,那就开始吧.我给大家看看我demo工程的效果(代码下边会给大家的): 技术栈是mybatis/m ...
- YTU 2457: 很简单的一道题
2457: 很简单的一道题 时间限制: 1 Sec 内存限制: 128 MB 提交: 261 解决: 80 [提交][状态][讨论版] 题目描述 有一个简单的函数数学公式,如下 输入 重复输入多组 ...
- 曹工杂谈:为什么很少需要改Spring源码,因为扩展点太多了,说说Spring的后置处理器
前言 最近发了好几篇,都是覆盖框架源码,但是spring的代码,我是从没覆盖过,毕竟,如果方便扩展,没谁想去改源码,而spring就是不需要改源码的那个,真的是"对扩展开放,对修改关闭&qu ...
- 曹工说Spring Boot源码(28)-- Spring的component-scan机制,让你自己来进行简单实现,怎么办
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
随机推荐
- map处理:map(str,[1,2,3,4,5,6])
#map(s1,s2)传入两个参数,s1是对该Iterable每个参数做处理的参数,s2是该Iterable print(list(map(str,[1,2,3,4,5,6]))) #map()传入的 ...
- 几种颜色模型(颜色空间):HSV CMYK RGB
RGB和CMY颜色模型都是面向硬件的,而HSV(Hue Saturation Value)颜色模型是面向用户的. HSV(Hue, Saturation, Value)是根据颜色的直观特性由A. R. ...
- jsc和luac文件 xxtea 解密.
# -*- coding: utf-8 -*- import xxtea import os src = "./assets/src" dst = "./assets/s ...
- 多语言工作者の十日冲刺<7/10>
这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 团队进行Alpha冲刺--第七天(05.06) 作业正文 ...
- HTML躬行记(1)——SVG
<svg>是矢量图的根元素,通过xmlns属性声明命名空间,从而告诉用户代理标记名称属于哪个XML方言.在下面的示例中,为<svg>元素声明了宽度和高度(默认以像素为单位),其 ...
- Windows安装C的编译环境
对于java开发者来说安装C的编译环境不是非常熟悉,因此本文对C的安装环境进行介绍以及windows编译Redis和Zookeeper的过程.MinGW主要用于按照gcc.make等环境,cywin用 ...
- 黎活明8天快速掌握android视频教程--16_采用SharedPreferences保存用户偏好设置参数
SharedPreferences保存的数据是xml格式,也是存在数据保存的下面四种权限: 我们来看看 我们来看看具体的业务操作类: /** * 文件名:SharedPrecences.java * ...
- 尚硅谷maven视频教程笔记
07.尚硅谷_Maven_部署Maven核心程序.avi 第一步先安装jdk 第二步下载maven 特别需要注意的是maven不能存储在有中文和空格的目录下面 3.调试是否安装成功,在cmd中输入 m ...
- 10、一个action中处理多个方法的调用第二种方法method的方式
在实际的项目中,经常采用现在的第二种方式在struct.xml中采用清单文件的方式 我们首先来看action package com.bjpowernode.struts2; import com.o ...
- Javascript的单线程和异步编程
运行时概念 下面的内容解释了一个理论上的模型.现代 JavaScript 引擎着重实现和优化了描述的几个语义. 可视化描述 栈 函数调用形成了一个栈帧. function foo(b) { var a ...