• postgresql的死锁检测机制


    死锁检测,是pg的一种自动检测机制,可以发现两个或者多个session之间对互斥资源的申请造成的死锁,并且可以随机将其中一个事务回滚掉,以解除死锁。

    PG的死锁时间由deadlock_timeout参数控制,默认是1s,当发生死锁超时,会随机将一个事务回滚掉,同时记录到数据库日志中。


    deadlock_timeout

    死锁检测之前在一个锁上等待的总时间。

    This is the amount of time to wait on a lock before checking to see if there is a deadlock condition.

    deadlock_timeout设置为1s,也即意味着,锁出现的一秒后,系统才会触发死锁检测机制,如果检测到死锁。会随机将其中任一事务回滚掉。

    这个值越大,锁触发死锁检测等待的时间越长。这个值一般要超过大多数事务执行的时间。

    特殊情况下,如果我们想定位死锁问题,我们可以先调大这个值,让因死锁而“挂起“的会话,维持“挂起”状态的时间更长点,以便我们定位具体SQL。


    当死锁发生后,你可能在服务器日志或者会话报错中看到如下形式的日志信息:

    1. ERROR:  deadlock detected
    2. DETAIL:  Process 18446 waits for ShareLock on transaction 976; blocked by process 18478.
    3. Process 18478 waits for ShareLock on transaction 975; blocked by process 18446.
    4. HINT:  See server log for query details.
    5. CONTEXT:  while updating tuple (0,2in relation "t_data"

    从上图中的日志信息中可以看到服务器是产生了循环依赖的,Process 18446 waits for process 18478, Process 18478 waits for 18446,process 18446和process 18478都被挂起,无法向前推进。

    当死锁发生后,我们可以从pg_stat_activity表中,获取当前挂起的会话中找到对应的client_addr、client_port,以及具体query等信息。

    1. SELECT client_addr, client_port, query
    2. FROM pg_stat_activity
    3. WHERE state = 'active'
    4.   AND wait_event_type = 'Lock'
    5. ORDER BY state_change

    一般我们希望能找到最初挂起的会话,因此我们按state_change排序pg_stat_activity,因为其他会话稍后可能卡在最初导致死锁的会话后面。

    扩展

    pg_stat_activity视图中wait_event_type,这字段表示等待事件的类型。 wait_event_type的取值可为:LWLockNamed、LWLockTranche、Lock、BufferPin。其中Lock表示backend后台进程等待重量级的锁,通常是指 relation、tuple、page、transactionid 等子类型锁。

    我们知道死锁会带来很多问题:产生死锁的会话无法继续推进,同时它占用的资源无法释放,时间长了之后可能会导致系统中出现更多的锁,进而导致服务雪崩。所以一般来说,我们是不希望在生产环境中发生死锁的。死锁的检测和解除,如上文所示可以通过设置合理的deadlock_timeout来解决。除此之外,我们使用一些预防策略,来防治死锁的产生。

    死锁的预防

    1. 死锁只有在锁存在的情况下才会发生,所以缓解死锁的一个策略就是减少锁的使用,比如说避免大事务,尽量减少显式锁的使用,减小锁的粒度等。

    2. 一般我们要确保使用数据的所有应用程序,以一致的顺序获取多个对象上的锁,防止出现互相等待的情况。

    另外,业务侧也需要实现重试机制,通过重试来恢复因死锁而中止的事务操作。

    参考:

    https://www.cybertec-postgresql.com/en/postgresql-understanding-deadlocks/ https://www.cybertec-postgresql.com/en/debugging-deadlocks-in-postgresql/

    该篇已首发到公众号PostgreSQL运维技术,欢迎来踩~

    悄悄放一张:

    PostgreSQL运维技术 

     

     

  • 相关阅读:
    AD21常用规则设置
    ENVI_常用扩展工具名
    docker-compose概述与简单编排部署
    DeepSpeed4Science:利用先进的AI系统优化技术实现科学发现
    arXiv2022-12 | FLIP:Scaling Language-Image Pre-training via Masking
    ASEMI二极管1N4148(T4)的用途和使用建议
    Socket类关于TCP字符流编程的理解学习
    2023全网最全requests库和requests模块使用详解(建议收藏)
    Java 基础数据类型占用内存空间和字符串编码简介(二)
    【Java设计模式 常用编程设计原则】KISS、YAGNI和DRY原则
  • 原文地址:https://blog.csdn.net/qq_35462323/article/details/126054539