记一次死锁问题的处理

原创 2015年07月10日 00:13:08

总想写点技术积累。因为最近工作比较忙,一忙一懒,找足了借口 :(

今天想简单记录一下前段时间发现在做数据清洗时遇到的问题,在处理这件事情上,感受到了许多。

大概需求是这样的:有两组数据库,每组都是分库分表的结构。从两组库中查出数据,根据规则再进行入库、清除缓存、发送消息队列。数据有几千万。

遇到这样的问题,首先想到的就是在保证数据准确的情况下做并行处理,其次想到的是尽量降低数据库的压力,再次就是可重复执行。

大概是这么写的。伪代码:

staic Connection connA = new LongDbConnectionA();   // 不做自动关闭,只做查询操作

static Connection connB = new LongDbConnectinoB();   // 不做自动关闭,只做查询操作

CountDownLatch latch = new CountDownLatch(dbACount + dbBCount);

ExecutorService service = Executors.newFixedThreadPool(MAX_THREAD_NUM);

for(a;b;c) {

     service.submit(new BizRunnable()); // 具体的业务逻辑

}

latch.await();

service.shutdown();

log.info(result);


我使用了4个线程在本地做运行测试,在测试过程中偶尔发生程序hung住的问题。正好其他同学在这段时间反馈研发环境的数据库访问特别慢,所以我认为hung住也是数据库搞的鬼,也没去深究。

于是后续去线上执行了3次预跑,程序运行的很好,很快,根据日志分析也很ok,40个线程几分钟就跑完了。然后信心满满的去正式跑。

刚运行一会发现在服务器上神奇的hung住了!开始不相信是代码的问题,kill -9 pid,重来,因为可重复跑嘛。这次终于执行完成了,验证后数据正常。完事后手动clear了cache,发送消息队列。一番周章,有惊无险的搞定了事情。

但是这次在服务器上hung住绝对不可能认为是数据库的问题,那自然而然。于是跟我的头一起看代码,看了半天也没发现哪里出现了问题,感觉似乎都很正常,中规中矩的代码。

既然代码看不出来了,只能想别的办法了。回到研发环境我反复跑了几次,问题终于复现了,又见hung住。我确认还是代码的问题。于是再多次运行直到hung状态。用stack打印当前堆栈。果然,发现了deadlock。原来是最外层那个想节省数据库链接的主意导致了Connection的死锁:

Found one Java-level deadlock:
=============================
"pool-1-thread-4":
  waiting to lock monitor 0x000000000d8fb7d8 (object 0x000000078176ea50, a com.mysql.jdbc.JDBC4Connection),
  which is held by "pool-1-thread-1"
"pool-1-thread-1":
  waiting to lock monitor 0x000000000d8f8918 (object 0x00000007d75838b0, a com.mysql.jdbc.JDBC4ResultSet),
  which is held by "pool-1-thread-3"
"pool-1-thread-3":
  waiting to lock monitor 0x000000000d8f89c8 (object 0x00000007d7581ea0, a com.mysql.jdbc.JDBC4PreparedStatement),
  which is held by "pool-1-thread-1"



今天翻文件的时候


工作完成后,才定位到问题,这事是第一次用到。也有一些感悟:

1、不要太相信自己的代码;

2、遇到异常不要想当然,要真正的去定位问题,而不是凭借主观意识去决断;多做一步,消灭BUG;

3、不容易定位的死锁问题使用jstack可以很方便的找到根源;

4、别有侥幸心理,多测试不会死,测试不足会崩。崩了,丢人。。


相关文章推荐

典型的顺序死锁

package com.thread.deadlock; import java.util.concurrent.ExecutorService; import java.util.concurre...

线程饥饿死锁

线程饥饿死锁:       在一个线程池中,如果一个任务依赖于其他任务的执行,就可能产生死锁。对应一个单线程话的Executor,一个任务将另一个任务提交到相同的Executor中,并等待新提交...

Java并发编程:死锁及解决方法

1 什么是死锁  死锁是多个进程\线程为了完成任务申请多个不可剥夺的资源并且以不正确的方式推进导致的一直互相等待对方释放资源的状态。下面以经典的哲学家就餐问题为例,描述死锁产生的场景。2 哲学家就餐问...

记一次死锁问题的排查和解决

说起来这个事情还是挺悲催的,记得上周忙的不亦乐乎,目标是修改之前另外一个团队留下来的一坨代码中的一些bug,这个项目是做OLAP分析的,分为两个模块,逻辑服务器主要负责一些元数据的操作,例如页面上展示...

记一次死锁问题的排查

最近遇到了一个死锁问题, 记录一下排查的过程. SQL Server中的死锁是DBA们经常会遇到的问题.  常有人混淆了死锁和阻塞, 其实他们的区别还是很明显的.  阻塞的一般原因可能是...

记一次:c3p0连接池死锁的问题

在公司的项目开发中,我负责数据层接口的代码编写工作。为提供性能,也使用了C3P0这个连接池技术。但和很多网友一样,碰到了死锁的这个问题,信息类似如下:        WARNING: com.mcha...

记录一次logstash 死锁问题

这个问题一年前遇到,写出来mark一下 问题描述:logstash 经常在运行一小段时间内挂起,不再消费任何input数据,也不再输出任何数据。logstash 版本:1.5.0 由于年代久远,系统...

一次死锁追踪经历

  • 2011年10月24日 23:27
  • 417KB
  • 下载

【开卷有益】记录一次高并发下的死锁解决思考过程

文章可能看不出来我在做什么事情,只是记录自己的一个排除死锁的过程。

一次spinlock死锁故障的定位(太经典,收藏!)

一次spinlock死锁故障的定位 1350阅读 0评论2015-07-21 humjb_1983 分类:LINUX 本文讲述一次spinlock死锁故障的定位过程,目的不在于问题本...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:记一次死锁问题的处理
举报原因:
原因补充:

(最多只允许输入30个字)