暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL之"process 56406 still waiting for ShareLock on ..."

3009

你可能在你的日志中看到如下所示的日志信息:

"""

LOG: 00000: process 65045 still waiting for ShareLock on transaction 46815253 after 1000.072 ms

"""

含义:进程650451000.072毫秒之后仍在等待事务46815253上的ShareLock。

这条信息说明数据库表上存在行锁,进程56673正在等待事务46390004上的锁释放,以获得ShareLock。日志消息的详细信息会告诉我们哪个进程持有这个锁,以及这个锁的完整等待队列,列表中的第一个进程将在下一个被授予锁。

日志文件中可能含有如下信息,即上面提到的日志消息的详细信息

DETAIL: Process holding the lock: 65050. Wait queue: 65045,65131.

它指示:进程65050正持有这个锁,锁的完整等待队列为 65045,65131。列表中的第一个进程也即65045将在下一个被授予锁。

当我们在日志中看到很多这样的消息,我们就有必要去检查下库中是否长时间存在大量的exclusive锁,同时需要确认为什么这样的exclusive锁会一直存在。这一点跟上一篇的解法相同。

或者我们可以启用 log_statement  log_min_duration_statement,来记录花费时间超过所设参数值的所有查询,记录服务器上存在的所有慢查询信息,再进一步定位到具体语句。

查看服务器上的锁信息:

    SELECT locker.pid,  
    pc.relname,
    locker.mode,
    locker_act.application_name,
    least(query_start,xact_start) start_time,
    locker_act.state,
    CASE
    WHEN granted='f' THEN
    'wait_lock'
    WHEN granted='t' THEN
    'get_lock'
    END lock_satus,current_timestamp - least(query_start,xact_start) AS runtime,
    locker_act.query
    FROM pg_locks locker,pg_stat_activity locker_act, pg_class pc
    WHERE locker.pid=locker_act.pid
    AND NOT locker.pid=pg_backend_pid()
    AND application_name<>'pg_statsinfod'
    AND locker.relation = pc.oid
    AND pc.reltype<>0 --and pc.relname='t'
    ORDER BY runtime desc;

    问:

    1、所有的锁等待信息都会被记录吗?

    不会,只有在配置了log_lock_waits=on,并且在超过了deadlock_time,进程仍在等待锁时,才会记录这样的日志信息。log_lock_waits含义可参考我上一篇文章。

    2、通常什么情况会出现这种现象呢?

    对表中特定行的锁争用一般会出现这种现象,特别是当存在需要长时间才提交的复杂事务时。

    当日志中频繁出现这种日志,就需要考虑可能的诱因。

    比如:

    • 是不是应用中逻辑设计不合理,存在没有及时提交的事务;

    • 是不是数据库负载过高,导致update的执行效率降低;

    • 被更新表上索引太多,导致update的执行效率低;

    • 应用设计不合理,同一时间段重复更新同一条(批)记录;

    参考:

    https://pganalyze.com/docs/log-insights/locks/L71

    https://postgres.fun/20111104143745.html

    文章转载自PostgreSQL运维技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论