PostgreSQL高并发单行更新发生死锁 2015
2015-10-24 10:09
369 查看
这么简单的一条SQL,100个并发时居然会发生死锁,太不可思议了。
发生死锁的SQL
update_smallrange.sql:
\setrandom id 1 10000
update maintb set name
= 'aaaaa12345'
where id=:id;
服务端日志:
点击(此处)折叠或打开
< 2015-01-16 20:56:44.189
CST >错误: 检测到死锁
< 2015-01-16 20:56:44.189 CST
>详细信息: 进程4880等待在事务 4074284上的ShareLock; 由进程4910阻塞.
进程4910等待在事务 4080369上的ShareLock; 由进程4880阻塞.
进程 4880: update maintb
set name =
'aaaaa12345' where id=9692;
进程 4910: update maintb
set name =
'aaaaa12345' where id=9692;
< 2015-01-16 20:56:44.189 CST
>提示: 详细信息请查看服务器日志.
< 2015-01-16 20:56:44.189 CST
>语句:
update maintb set name
= 'aaaaa12345'
where id=9692;
从日志中可以看出,2个进程更新同一行记录时发生了死锁。
但是我的case也不是每次再现,之前测试的时候几乎100%的再现概率,但是过了几天,相同的环境却一次也没再现过。
今天偶然翻了下社区的邮件列表,发现这是个已知的BUG。
http://www.postgresql.org/message-id/20140731233051.GN17765@andrew-ThinkPad-X230
这个BUG报告中的错误消息有两种,其中一种和我的是一样的
死锁错误1:
点击(此处)折叠或打开
2014-07-30 09:41:54 PDT PID:4729 XID:25780
ERROR: deadlock detected
2014-07-30 09:41:54 PDT PID:4729 XID:25780
DETAIL: Process 4729 waits
for ShareLock on transaction 25779; blocked by process 4727.
2014-07-30 09:41:54 PDT PID:4729 XID:25780
HINT: See server log
for query details.
2014-07-30 09:41:54 PDT PID:4729 XID:25780
STATEMENT: UPDATE
"z8z6px927zu6qzzbnb5ntgghxg"."access_grants" ag SET last_issued=DEFAULT FROM
"z8z6px927zu6qzzbnb5ntgghxg"."oauth_clients" oc WHERE oc.id
= ag.client_id
AND ag.entity_name
= 'user'
AND ag.entity_id
= 129 AND oc.client_id
= '3hp45h9d4f9wwtx7cvpus6rdb4s5kb9f' RETURNING ag.id
死锁错误2:
点击(此处)折叠或打开
2014-07-30 09:41:56 PDT PID:4739 XID:25806
ERROR: deadlock detected
2014-07-30 09:41:56 PDT PID:4739 XID:25806
DETAIL: Process 4739 waits
for ExclusiveLock on tuple (1,98)
of relation 16553
of database 16385; blocked by process 4738.
2014-07-30 09:41:56 PDT PID:4739 XID:25806
HINT: See server log
for query details.
这个BUG在9.3.x(9.3.4和9.3.5)上会存在,9.0和9.1等早期版本没有问题。用我们公司的术语说就是LevelDown了。
点击(此处)折叠或打开
好消息是已经有这个BUG的Patch出来了,相信下次的PG版本发布会解决这个问题。
发生死锁的SQL
update_smallrange.sql:
\setrandom id 1 10000
update maintb set name
= 'aaaaa12345'
where id=:id;
服务端日志:
点击(此处)折叠或打开
< 2015-01-16 20:56:44.189
CST >错误: 检测到死锁
< 2015-01-16 20:56:44.189 CST
>详细信息: 进程4880等待在事务 4074284上的ShareLock; 由进程4910阻塞.
进程4910等待在事务 4080369上的ShareLock; 由进程4880阻塞.
进程 4880: update maintb
set name =
'aaaaa12345' where id=9692;
进程 4910: update maintb
set name =
'aaaaa12345' where id=9692;
< 2015-01-16 20:56:44.189 CST
>提示: 详细信息请查看服务器日志.
< 2015-01-16 20:56:44.189 CST
>语句:
update maintb set name
= 'aaaaa12345'
where id=9692;
从日志中可以看出,2个进程更新同一行记录时发生了死锁。
但是我的case也不是每次再现,之前测试的时候几乎100%的再现概率,但是过了几天,相同的环境却一次也没再现过。
今天偶然翻了下社区的邮件列表,发现这是个已知的BUG。
http://www.postgresql.org/message-id/20140731233051.GN17765@andrew-ThinkPad-X230
这个BUG报告中的错误消息有两种,其中一种和我的是一样的
死锁错误1:
点击(此处)折叠或打开
2014-07-30 09:41:54 PDT PID:4729 XID:25780
ERROR: deadlock detected
2014-07-30 09:41:54 PDT PID:4729 XID:25780
DETAIL: Process 4729 waits
for ShareLock on transaction 25779; blocked by process 4727.
2014-07-30 09:41:54 PDT PID:4729 XID:25780
HINT: See server log
for query details.
2014-07-30 09:41:54 PDT PID:4729 XID:25780
STATEMENT: UPDATE
"z8z6px927zu6qzzbnb5ntgghxg"."access_grants" ag SET last_issued=DEFAULT FROM
"z8z6px927zu6qzzbnb5ntgghxg"."oauth_clients" oc WHERE oc.id
= ag.client_id
AND ag.entity_name
= 'user'
AND ag.entity_id
= 129 AND oc.client_id
= '3hp45h9d4f9wwtx7cvpus6rdb4s5kb9f' RETURNING ag.id
死锁错误2:
点击(此处)折叠或打开
2014-07-30 09:41:56 PDT PID:4739 XID:25806
ERROR: deadlock detected
2014-07-30 09:41:56 PDT PID:4739 XID:25806
DETAIL: Process 4739 waits
for ExclusiveLock on tuple (1,98)
of relation 16553
of database 16385; blocked by process 4738.
2014-07-30 09:41:56 PDT PID:4739 XID:25806
HINT: See server log
for query details.
这个BUG在9.3.x(9.3.4和9.3.5)上会存在,9.0和9.1等早期版本没有问题。用我们公司的术语说就是LevelDown了。
点击(此处)折叠或打开
I think this is a regression as we only see the behavior under postgres 9.3.x (reproduced locally on 9.3.4 and 9.3.5 in a VMWare VM running Ubuntu 11.04, but also evident in 9.3.3 on Amazon RDS). I am unable to reproduce in the earlier versions I've been able to test against (9.0.something and 9.1.9).
好消息是已经有这个BUG的Patch出来了,相信下次的PG版本发布会解决这个问题。
相关文章推荐
- MySQL数据库的同步配置+MySql读写分离
- 使用sql 来生成sql
- Aix db2 经user a using b连接时报SQL30082N Security processing failed with reason "42"
- oracle 日期 毫秒转换日期
- oracle修改表结构
- 在 SQL Server 2008 中新建用户登录并指定该用户的数据库
- Oracle数据库的基本概念(转)
- SQL Server 2008 Express如何开启远程访问
- 3.5 unicodedata--Unicode数据库
- 3.5 unicodedata--Unicode数据库
- 【从翻译mos文章】rac数据库,HC_<SID>.dat其他文件Oracle_Home用例下。
- linux 卸载oracle 11.2.0.4
- (二)redis的启动和关闭
- (一)使用源码包方式安装redis-2.8.13
- Joomla 3.2.0 - 3.4.4 无限制SQL注入漏洞
- spark on hive 配置hive的metastore为mysql
- SQLServer varbinary 存储16进制末尾的"0"丢失
- mysql -u root -p 出错(ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/li)
- MYSQL5.5.19卸载过程中的问题整理
- 数据库里写了很多存储过程,想用SQL语句查出哪些存储过程包含字段(如:user_id)