【生产问题】:邮件无法查看全部、甚至整个邮件都没了(表数据无法查询全部,否则一直卡查询状态)
概要描述:邮件无法查看全部、甚至整个邮件都没了(表数据无法查询全部,否则一直卡查询状态)
详细描述:
(1)用户状态:当使用完某个sp进行邮件发放之后,该用户对于自己的邮件一直查不到历史邮件,甚至所有邮件都无法查看到。
(2)DB状态:表数据无法查询全部,否则一直卡查询状态
原因思考:
(1)思考做了什么操作:想想什么时候开始发生这个情况,想想这段时间前后非业务正常操作做了什么
在这之前,我用了一个发邮件的sp去由于参数规避的问题,该SP一直有问题。场景如下;
【1】运行sql为null或者为空字符 【2】用 空字符 '' 字符拼接其他字符串
(2)根据现象思考本质
思考现象有2个,1个是所有邮件都无法查看到,2个是只能查到某部分邮件,由此可以推断出问题出现在锁上,可能是有锁占用或者锁阻塞了
【1】是不是有进程阻塞:尝试如下
所有代码在这:https://www.cnblogs.com/gered/p/9359031.html
--查看进程状态
--查看表锁
--看查调用语句与父语句以及来源情况
--查看阻塞
结果发现,查询记录都是空
【2】是不是有锁占用:尝试如下
--sp_who
--sp_lock
然后最终从sp_lock中找到邮件表对应的objectid了,发现某个进程在对这个objectid进行key锁。
那么问题就确定了,因为有key锁,所有如果要查全部邮件的,肯定要被锁等待,所以一直就查不出来。
部分邮件可以显示的,是因为只查了部分数据,然后数据中没有涉及到被锁的key,所以可以显示。(因为已经解决了,这里不再复现,随便找个数据演示一下)
类似于这样,很明显73ID进行了KEY锁,我们邮件表对应的objId可以同构select object_id('email_tableName')获取。看与objId中的ID是否对应。
找是找到了,但我们不能随便kill spid啊,因为我们不知道这个spid对应的进程是什么,万一是线上进程不就把业务给干掉了?于是我们可以这样
由此看到进程对应的连接账户,这里显示的是tank77登录db_tank库,线上我们业务用的是tank77作为连接账户,所以这个不能删。
而在我的实际问题中,这里是用的windows域账户登录的,而且对应的库名也是邮件表所在的库,这就对应符合了我们的故障逻辑。
而且windows域账户登录的,证明是人为操作的而非业务,那么估计就是我操作发邮件引起的。就可以安心干掉这个进程。
直接kill 73
然后再次查询邮件表,发现可以查询全部了,业务上使用也恢复正常了。OK,到此完篇~问题解决。