记一次死锁问题的处理

原创 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、别有侥幸心理,多测试不会死,测试不足会崩。崩了,丢人。。


解决ORACLE死锁问题

select object_name,        machine,        s.sid,        p.spid,        s.osuser,        s.program, ...
  • giianhui
  • giianhui
  • 2015年04月03日 13:14
  • 692

mysql的死锁等6个实战问题解决

mysql的死锁等6个实战问题解决锁表后的解锁当对表做dml操作时卡住,很可能是表被锁。 到数据库主机,查看进程命令: show processlist; 找到有锁的进程id,杀掉: kill...
  • ouyida3
  • ouyida3
  • 2015年08月03日 16:19
  • 1972

记一次死锁问题的排查

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

c# 通讯死锁问题 线程同步问题

第一篇文章我相信很多人不看都能做的出来,但是,用过微软SerialPort类的人,都遇到过这个尴尬,关闭串口的时候会让软件死锁。天哪,我可不是武断,算了。不要太绝对了。99.9%的人吧,都遇到过这个问...
  • c2716266
  • c2716266
  • 2012年01月18日 15:29
  • 827

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

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

封锁

封锁 ...
  • narci
  • narci
  • 2006年09月27日 14:11
  • 1435

【操作系统】处理死锁的方法

破坏死锁的四个必要条件中的一个或几个。预防死锁 破坏互斥条件 破坏请求和保持条件 破坏不可剥夺条件 破坏环路等待条件 破坏互斥条件即允许多个进程同时访问资源。但由于资源本身固有特性的限制,此方法不可行...
  • qq_28602957
  • qq_28602957
  • 2016年12月07日 17:09
  • 2285

死锁,死锁的四个必要条件以及处理策略

什么是死锁?如果一个进程集合里面的每个进程都在等待只能由这个集合中的其他一个进程(包括他自身)才能引发的事件,这种情况就是死锁。这个定义可能有点拗口,一个最简单的例子就是有资源A和资源B,都是不可剥夺...
  • wlq1983
  • wlq1983
  • 2008年10月06日 14:56
  • 12076

Oracle常见死锁发生的原因以及解决方法

一.删除和更新之间引起的死锁 造成死锁的原因就是多个线程或进程对同一个资源的争抢或相互依赖。这里列举一个对同一个资源的争抢造成死锁的实例。 CREATE TABLE testLock(  ID ...
  • fenyu8
  • fenyu8
  • 2016年12月22日 16:51
  • 8908

死锁的原因及处理方法

产生死锁的原因主要是: (1) 因为系统资源不足。 (2) 进程运行推进的顺序不合适。 (3) 资源分配不当等。 产生死锁的四个必要条件: (1)互斥条件:一个资源每次只能被一个进程...
  • as02446418
  • as02446418
  • 2015年09月09日 12:44
  • 3797
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:记一次死锁问题的处理
举报原因:
原因补充:

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