锁管理(LOCK MANAGEMENT)类别参数

本文档介绍了系统配置参数中 锁管理类别的相关参数。

YMatrix 中存在以下两种死锁检测机制:

  • 死锁检测机制
    • (局部)死锁:指两个(或多个)事务相互持有对方想要的锁。例如,如果事务 1 在表 A 上获得一个排他锁,同时试图获取一个在表 B 上的排他锁,而事务 2 已经持有表 B 的排他锁,同时却正在请求表 A 上的一个排他锁,那么两个事务就都不能进行下去。
    • 局部死锁发生在具体某一个 Segment 节点实例内部,不同的事务直接互相等候。Postgres 进程有完善的机制能够自动检测到死锁情况,并且通过中断其中一个事务从而允许其它事务完成来解决这个问题。
  • 全局死锁检测机制
    • 全局死锁:指 YMatrix 集群中任何一个局部 Segment 节点实例内都没有局部死锁,但是在不同的 Segment 之间发生了循环等待,使得死锁的全局事务都无法推进的情况。
    • 全局死锁检测机制是针对分布式数据库集群而设计的,需通过 Master 设置全局死锁检测进程,周期性采集各个 Segment(及 Master) 的数据库对象锁的等待关系,并利用 GDD(Global Deadlock Detector)检测是否发生死锁。如果发现死锁,则利用既定策略(如结束最年轻的事务等)来破解死锁。

注意!
为确保系统稳定与安全,请务必谨慎手动修改相关参数

deadlock_timeout


这是进行死锁检测之前在一个锁上等待的时间量(毫秒)。

  • 死锁检测相对昂贵,因此服务器不会在每次等待锁时都运行它。
  • 假设在某生产应用中死锁不常出现,并且在开始检测死锁之前只需等待一会儿。那么增加这个值就减少了其浪费在无用的死锁检测上的时间,但是也减慢了报告真正死锁错误的速度。
  • 如果指定值时没有单位,则以毫秒为单位。默认是 1000,这可能是实际中你想要的最小值。在一个高负载的服务器上,你需要增大它。这个值的理想设置应该超过你通常的事务时间,这样就可以减少在锁释放之前就开始死锁检查的机会。
  • log_lock_waits 被设置时,这个参数还可以决定发出关于锁等待的日志之前等待的时间量。如果你想调查锁延迟,你可能希望设置一个比正常的 deadlock_timeout 小的值。
数据类型 默认值 取值范围 设置分类
int 1000 1 ~ INT_MAX segment;system;restart;superuser

gp_enable_global_deadlock_detector


控制是否启用 YMatrix 数据库全局死锁检测器来管理 HEAP 表上的并发 UPDATEDELETE 等操作以提高性能。

  • 默认为 off,全局死锁检测被禁用。
  • 如果禁用全局死锁检测器(默认),YMatrix 数据库将串行地对堆表执行并发更新和删除操作。
  • 如果启用了全局死锁检测器,则允许并发更新,并且全局死锁检测器确定何时存在死锁,并通过终止与所涉及的最新事务关联的一个或多个后端进程来中断死锁。
  • 如果表中带有主键或唯一索引,则 INSERT 也可触发全局死锁。
  • CREATE / ALTER / DROP 等管理类语句也可触发死锁。
数据类型 默认值 设置分类
boolean off master;system;restart

gp_global_deadlock_detector_period


指定全局死锁探测器(GDD)后台工作进程的检测周期(以秒为单位)。

数据类型 默认值 取值范围 设置分类
int 120 5 ~ INT_MAX master;system;reload

max_locks_per_transaction


共享锁定表跟踪在 max_locks_per_transaction * (max_connections + max_prepared_transactions) 个对象(Object)上的锁。

  • 在任何一个时刻,只有不超过此参数个可区分对象能够被锁住。
  • 此参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。
  • 此参数不代表能被锁住的行数,因此此值并非是没有限制的。
  • 如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。
  • 这个参数只能在服务器启动时设置。
  • 当运行一个后备服务器时,你必须设置这个参数为大于等于主服务器上的值。否则,后备服务器上将不允许查询。
数据类型 默认值 取值范围 设置分类
int 128 10 ~ INT_MAX segments;system;restart

max_pred_locks_per_page


这个参数控制在谓词锁被提升为覆盖整个页面之前,该谓词锁能在单一页面上锁住多少行。

数据类型 默认值 取值范围 设置分类
int 2 0 ~ INT_MAX segments;system;reload

max_pred_locks_per_relation


这个参数控制在谓词锁被提升为覆盖整个关系表前,该谓词锁能够在单个关系表上锁住多少页面或元组。

  • 大于等于 0 的值表示一种绝对限制,而负值表示用 max_pred_locks_per_transaction 除以这个设置的绝对值。
数据类型 默认值 取值范围 设置分类
int -2 INT_MIN ~ INT_MAX segments;system;reload

max_pred_locks_per_transaction


共享谓词锁表跟踪在 max_pred_locks_per_transaction * (max_connections + max_prepared_transactions) 个对象(如表)上的锁。

  • 在任何一个时刻,只有不超过此参数个可区分对象能够被锁住。
  • 这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。
  • 此参数不代表能被锁住的行数,因此此值并非是没有限制的。
  • 通常来说,默认值已经在测试中被证明是足够的,但是如果你需要在一个可序列化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。
  • 这个参数只能在服务器启动时设置。
数据类型 默认值 取值范围 设置分类
int 64 10 ~ INT_MAX segments;system;restart