设为首页 收藏本站
查看: 1020|回复: 0

[经验分享] postgresql锁

[复制链接]

尚未签到

发表于 2016-11-19 06:41:56 | 显示全部楼层 |阅读模式
  postgresql 锁测试
文章分类:IT生活
PostgreSQL 手册提供锁的定义与解释:
  在附件中将对各个级别的锁进行测试跟踪。
  
PostgreSQL 提供了各种各样的锁模式用于控制对表中的数据的并发访问。 这些模式可以用于在 MVCC 无法给出期望的行为的时候用于应用控制的锁定。 同样,大多数 PostgreSQL 命令自动施加恰当的锁以保证被引用的表在命令执行的时候不会以一种不兼容的方式被删除或者修改。 (比如,在存在其它并发操作的时候,ALTER TABLE 是不能在同一个表上面执行的。)
  要检查一列当前数据库服务器里正在持有的锁,我们可以使用系统视图 pg_locks (Section 41.33)。有关监控锁管理器子系统的状态的更多信息,请参考 Chapter 23。
  
12.3.1. 表级锁
下 面的列表显示了可用的锁模式和它们被 PostgreSQL 自动使用的环境。 你也可以用命令 LOCK 明确获取这些锁。请注意所有这些锁模式都是表级锁,即使它们的名字包含单词 "row";这些锁模式的名称是历史造成的。从某种角度而言,这些名字反应了每种锁模式的典型用法 — 但是语意都是一样的。 两种锁模式之间真正的区别是它们有着不同的冲突锁集合。两个事务在同一时刻不能在同一个表上持有相互冲突的锁。 (不过,一个事务决不会和自身冲突。比如,它可以在一个表上请求 ACCESS EXCLUSIVE 然后稍后的时候请求 ACCESS SHARE。) 非冲突锁模式可以由许多事务并发地持有。 请特别注意有些锁模式是自冲突的(比如,在任意时刻 ACCESS EXCLUSIVE 模式就不能够被多个事务拥有) 而其它地都不是自冲突的(比如,ACCESS SHARE 可以被多个事务持有)。 一旦请求到了某种锁,那么该锁模式将持续到事务结束。
  表级锁模式
  ACCESS SHARE
  只与 ACCESS EXCLUSIVE 冲突。
  SELECT 和 ANALYZE 命令在被引用的表上请求一个这种锁。通常,任何只读取表而不修改它的命令都请求这种锁模式。
  ROW SHARE
  与EXCLUSIVE和ACCESS EXCLUSIVE模式冲突。
  SELECT FOR UPDATE 命令在目标表上需要一个这样模式的锁(加上在所有被引用但没有 FOR UPDATE 的表上的 ACCESS SHARE 锁)。
  ROW EXCLUSIVE
  与 SHARE,SHARE ROW EXCLUSIVE, EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。
  命令 UPDATE,DELETE, 和 INSERT 自动请求这个锁模式。 (加上所有其它被引用的表上的 ACCESS SHARE 锁)。 通常,这种锁将被任何修改表中数据的查询请求。
  SHARE UPDATE EXCLUSIVE
  和 SHARE UPDATE EXCLUSIVE,SHARE, SHARE ROW EXCLUSIVE,EXCLUSIVE, 和 ACCESS EXCLUSIVE 模式冲突。 这个模式保护一个表不被并发模式改变和 VACUUM。
  VACUUM(不带 FULL 选项)请求这样的锁。
  SHARE
  与 ROW EXCLUSIVE,SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。 这个模式避免表的并发数据修改。
  CREATE INDEX 语句要求这样的锁模式。
  SHARE ROW EXCLUSIVE
  与 ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,SHARE, SHARE ROW EXCLUSIVE,EXCLUSIVE,和 ACCESS EXCLUSIVE 模式冲突。
  任何 PostgreSQL 命令都不会自动请求这样的锁模式。
  EXCLUSIVE LOCK
  与 ROW SHARE,ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE,SHARE ROW EXCLUSIVE, EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。 这个模式只允许并发 ACCESS SHARE 锁,也就是说, 只有对表的读动作可以和持有这个锁模式的事务并行执行。
  任何 PostgreSQL 命令都不会自动请求这样的锁模式.
  ACCESS EXCLUSIVE
  与 所有模式冲突。 ( ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, 和 ACCESS EXCLUSIVE). 这个模式保证其所有者(事务)是可以用任意方式访问该表的唯一事务。
  ALTER TABLE, DROP TABLE,REINDEX,CLUSTER和 VACUUM FULL 命令要求这样的锁。 在 LOCK TABLE 命令没有明确声明需要的锁模式时,它也是缺省锁模式。
  提示: 只有 ACCESS EXCLUSIVE 阻塞 SELECT (没有 FOR UPDATE语句)。
  12.3.2. 行级锁
除 了表级锁以外,还有行级锁。 特定行上的行级锁是在行被更新的时候自动请求的(或者被删除时或标记为更新)。 锁一直保持到事务提交或者回滚。 行级锁不影响对数据的查询;它们只阻塞对同一行的写入。 要在不修改某行的前提下请求在该行的行级锁,用 SELECT FOR UPDATE 选取该行。请注意一旦我们请求了特定的行级锁, 那么该事务就可以多次对该行进行更新而不用担心冲突。
  PostgreSQL 不会在内存里保存任何关于已修改行的信息, 因此对一次锁定的行数没有限制。 不过,锁住一行会导致一次磁盘写;因此,象 SELECT FOR UPDATE 将修改选中的行以标记它们, 因此会导致磁盘写。
  除了表级别的和行级别的锁以外, 页面级别的共享/排他销也用于控制对共享缓冲池中表页面的读/写访问。 这些锁在抓取或者更新一行后马上被释放。 应用程序员通常不需要关心页级锁,我们在这里提到它们只是为了完整。
  12.3.3. 死锁
明 确锁定的使用可能会增加死锁的可能性, 死锁是是指两个(或多个)事务相互持有对方期待的锁。比如,如果事务 1 在表 A上持有一个排他锁, 同时试图请求一个在表 B 上的排他锁, 而事务 2 已经持有表B的排他锁,而却正在请求在表 A上的一个排他锁,那么两个事务就都不能执行。 PostgreSQL 自动侦测到死锁条件并且会通过退出一个当事的事务来解决这个问题, 以此来允许其它事务完成。(具体哪个事务会被退出是很难预计的,而且也不应该依靠这样的预计。)
  要注意的是死锁也可能会因为行级锁而发生(因此,即使是没有使用明确的锁定,也可能发生)。 考虑这样一种情况,两个并发事务在修改一个表。第一个事务执行了:
  UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111;这样就在指定帐号的行上请求了一个行级锁。然后,第二个事务执行:
  UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222;UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111;第一个 UPDATE 语句成功地在指定行上请求到了一个行级锁,因此它成功更新了该行。但是第二个 UPDATE 语句发现它试图更新地行已经被锁住了,因此它等待持有该锁的事务结束。事务二现在就在等待事务一结束,然后再继续执行。 现在,事务一执行:
  UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;事务一企图在指定行上请求一个行级锁,但是它得不到:事务二已经持有这样的锁了。 所以它等待事务二完成。因此,事务一在事务二上阻塞住了,而事务二在事务一上阻塞住了:这就是一个死锁条件。 PostgreSQL 将侦测这样的条件并退出其中一个事务。
  防止死锁的最好方法通常是保证所有使用一个数据库的应用都以一致的顺序在多个对象上请求锁定。 在上面的例子里,如果两个事务以同样的顺序更新那些行,那么就不会发生死锁。我们也要保证在一个对象上请求的第一个锁是该对象需要的最高的锁模式。 如果我们无法提前核实这些问题,那么我们可以通过在现场重新尝试因死锁而退出的事务的方法来处理。
  只要没有检测到死锁条件,一个等待表级锁或者行级锁的事务将等待冲突锁的释放不确定的时间。 这就意味着一个应用持有打开的事务时间太长可不是什么好事情(比如锁,等待用户输入)。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-302266-1-1.html 上篇帖子: PostgreSQL培训 下篇帖子: postgresql-常量
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表