sql server死锁问题

上午看到服务器上sql server占的内存都超过90%,于是乎又手动重启了sql服务,内存占比是下降了,但是问题来了,这下好了,如何解决?

         先是一阵kill,删了一个进程又有新的进程出来?

         网上有几种解决办法。一一试过了,感觉没效果,还好,暂时这个死锁还不影响其他服务的运行,不过得想办法解决。

        首先需要了解死锁是如何产生的?

        资源竞争,在两个或多个任务中,如果每个任务锁定了其他任务试图锁定的资源,此时会造成这些任务的永久阻塞,从而出现死锁。打个比方,厨房里有两个厨师,然后只有一把菜刀,有一次,A厨师在用菜刀,B厨师也要用,那B厨师就只能等A厨师用完,再使用菜刀。

        形成死锁有四个必要条件:

        请求与保持条件:获取资源的进程可以同时申请新的资源;

        非剥夺条件:已经分配的资源不能从该进程中剥夺。(A厨师在切菜,然后就要炒了,外面客人在催菜,所以剥夺不了。)

        循环等待条件:多个进程构成环路,并且其中每个进程都在等待相邻进程;

        互斥条件:资源只能被一个进程使用。

其次如何解决死锁问题?

1、清除死锁

2、使用无锁查询

看了下书,书上淡淡的甩了一句:一般是撤掉一个最不重要的事务,释放它持有的资源,让重要的事务先运行,之后再处理这个事务。当然事先避开死锁的发生是解决死锁问题的最好方法。(这说得也没毛病,只不过实操性比较差,只是理论上讲。)

总结其中的处理步骤如下:

1、首先找到这个死锁对应的信息;

在这里可以看到blkby就是导致死锁的进程,然后command代表的是引起死锁的操作。那如何查看这个进程里具体是那个语句操作导致的呢?使用dbcc inputbuffer(spid)来查看。这里其中的evnetinfo就是导致死锁的操作语句。

2、然后需要确定你的程序里面哪里执行了这些语句,然后是否存在sp_who2查询出来的,引起死锁的command,比如,command是delete,那在程序中查找相关操作。如果在不影响业务的情况下,可以删掉这部分操作,或用其他方法代替?或改成定时任务等,优化这部分操作再试试。

就像上图,根据提示的信息,找到对应的delete语句,然后看了下这个语句对主要的业务不影响,所以索性去掉,果然解决了。

其中有几个疑问:

1、程序运行过程中出现死锁是否正常?如果出现少量死锁,过一段时间,死锁是否会自动解除?(大神说会自动解除)

2、重启sql server服务是否能解除死锁?重启服务器呢?

3、如何在程序开发中避免这种问题?sql语句如何设计才能预防这种问题?

4、此程序一直运行2-3年,都从未出现死锁问题,为何重启sql server服务后就会出现,而且还是比较顽固的存在。

这里面我也用了sql 的profiler,可以看到相关的死锁分析,但是感觉还没掌握住这个工具。

写得有点乱,一步一步整理吧。如遇到类似问题的,可以互相交流下。

其中参考学习了以下链接:https://www.cnblogs.com/yanggb/p/10944350.html 

发布了125 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/jiezhang656/article/details/103167394