注意PostgreSQL“隐式”锁请求

周正中 2015-11-30 10:42:14

我们在使用数据库时,经常遇到锁等待的事情。例如一个用户在更新一条记录时,另一个会话要更新同一条记录就需要等待。这种锁等待是比较显而易见的,有一些锁等待你可能会觉得匪夷所思。下面就由DBA+社群联合发起人周正中,跟大家聊聊这些“隐式”锁请求。

 

专家简介

 
 


周正中

网名:德哥@Digoal

DBA+社群联合发起人


PostgreSQL中国社区发起人之一,负责杭州分会,兼任社区CTO一职。曾就职于斯凯网络,负责数据库部门。现就职于阿里巴巴,负责RDS PG内核组事务。

 

 

 

例如:


会话A:



会话B:


select * from pg_get_indexdef('test_pkey'::regclass);  -- 查询索引的定义

如果test_pkey是test的一个索引,它会进入等待状态。



我们来跟踪一下

首先请按照 http://blog.163.com/digoal@126/blog/static/163877040201422083228624  提供的方法开启LOCK DEBUG。


会话A:



会话B:



等待中。

使用 https://github.com/digoal/pgsql_admin_script/blob/master/generate_report.sh  提供的方法可以查询到锁等待如下:



此时提交或回归会话A,然后会话B可以继续:



正常情况下,查询索引定义如果没有被堵塞,观察到的锁是这样的:



还有很多获得对象定义的函数,使用时需要注意。



例如:

获取规则定义也要请求表的AccessShareLock。



会话A:



会话B:



pg_get_viewdef也有这个问题,需要获得视图引用的表的AccessShareLock。



另外再提供一个需要注意的点,PG对未获得,但是在等待中的锁也在冲突列表中。


例如用户1对A表在做一个比较大的查询,另一个用户2需要对A表执行DDL,那么显然用户2的DDL无法获得排它锁在等待用户1的状态。此后,用户3或其他用户发起对A的查询请求也会被用户2堵塞,这是非常危险的,如果用户1不释放锁,那么用户2就会一直等待,同时会堵塞所有对A表的任何请求。


所以建议用户在执行DDL操作时,加一个锁超时的参数,防止出现以上情况。


set lock_timeout='1s';


还有一种autocommit的场景下,建议对需要持有大锁的SQL在执行前加上语句超时,防止长时间持锁或等待锁,在某些场景甚至可能造成拥塞,例如短连接的场景,用户可能不断发起请求,把数据库连接用完。


set statement_timeout ='1s';


以上锁DEBUG信息都可以参考src/include/storage/lock.h获得详细的描述。


本文由作者周正中授权DBA+社群发布,选自作者网易博客

即日起,凡是推送在【DBAplus社群】平台的文章,阅读量超过1000,该文章作者可获得赠书一本。大家如有好的干货文章也可以向我们的订阅号投稿,投稿邮箱:1017465571@qq.com。近期赠书有:白鳝《思想的天空》、杨志洪《Oracle核心技术》……

 

小编精心为大家挑选了近日最受欢迎的几篇热文:

回复001,看丁俊的《【重磅干货】看了此文,Oracle SQL优化文章不必再看!》;

回复002,看《灾备故障上了红头文件,容灾技术到底哪家强?》;

回复003,看吕海波的《去不去O,谁说了算?》;

回复004,看胡怡文《PG,一道横跨oltp到olap的梦想之桥》;

回复005,看付新《达梦专家解读:国产数据库也疯狂》;

回复006,看郭耀龙《假事务之名,深入研究UNDO与REDO》;

回复007,看宋日杰《Oracle后台专家解决library cache锁争用的终极武器》;

回复008,看周俊《被埋没的SQL优化利器——Oracle SQL monitor》。

 

关于DBA+社群

DBA+社群是全中国最大的涵盖各种数据库、中间件及架构师线条的微信社群!有100+专家发起人,建有15大城市微信群,6大专业产品群,多达10000+跨界DBA加入队伍。每天1个热议话题,每周2次线上技术分享,不定期线下聚会与原创专家团干货分享,更多精彩,欢迎关注dbaplus微信订阅号!

扫码关注

DBAplus社群

超越DBA圈子,连接的不仅仅是DBA


活动预告