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

案例分享一则:PostgreSQL 连接无法中止?结合线程分析来解决!

113
问题现象

经现场同事反馈:某业务系统中一条针对特定条件单行数据的 UPDATE 语句持续执行失败,始终处于等待状态。初步判断存在行级锁阻塞—— 目标数据被其他会话持有锁,导致更新操作无法获取锁资源。
进一步排查发现,锁的源头会话状态为active,当前执行的命令为“commit”,该状态已持续长达 3 小时。为解除阻塞,尝试通过 PostgreSQL 内置函数 pg_cancel_backend 和 pg_terminate_backend 中止该会话,函数返回 “执行成功”,但实际会话仍未终止,锁阻塞问题依旧。

解决过程


对服务器的资源使用情况进行分析:服务器CPU资源使用率正常,IO无等待。

使用ps -aux命令查看进程,状态为Ssl,不属于僵死进程。其中进程状态为Ssl,具体含义为:

  • S (Interruptible Sleep - 可中断睡眠)

  • s (Session Leader - 会话首进程)

  • l (Multi-threaded - 多线程) 该进程当前正处于可中断睡眠状态,可能是在等待一个I/O操作的返回。


结合状态含义推断,该进程正处于可中断睡眠,大概率在等待某个 I/O 操作的返回结果。

先尝试查看该进程的堆栈信息:

    $ strace -p 10590
    strace: Process 10590 attached
    futex(0x7f0466ed69d0, FUTEX_WAIT, 32005, NULL^Cstrace: Process 10590 detached
    <detached ...>
    $ strace -p 32005
    strace: Process 32005 attached
    recvfrom(991, 

    输出内容(recvfrom(991, )表明,进程10590的线程32005正在从一个网络套接字(socket)上读取数据,并且当前处于阻塞状态,正在等待数据的到达。

    随后,使用pstack命令输出线程32005的详细堆栈信息:

      $ pstack 32005
      Thread 1 (process 32005):
      #0 0x00007f06877a4aeb in recv () from lib64/libpthread.so.0
      #1 0x00007f04691a1db7 in _$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Read$GT$::read_buf::h3eeec915066f63ff () from u01/pgsql-14/lib/zombodb.so
      #2 0x00007f04691cb32d in _$LT$ureq..stream..DeadlineStream$u20$as$u20$std..io..BufRead$GT$::fill_buf::h565ca4f6dd0b9687 () from /u01/pgsql-14/lib/zombodb.so
      #3 0x00007f04691b7d89 in std::io::read_until::hd3435b9b8a0c10f7 () from /u01/pgsql-14/lib/zombodb.so
      #4 0x00007f04691c983c in ureq::response::read_next_line::ha98fc8ffa5c263aa () from /u01/pgsql-14/lib/zombodb.so
      #5 0x00007f04691c7a71 in ureq::response::Response::do_from_stream::h0de926971bb48f09 () from /u01/pgsql-14/lib/zombodb.so
      #6 0x00007f04691c385c in ureq::unit::connect_inner::h44e1f90178349343 () from /u01/pgsql-14/lib/zombodb.so
      #7 0x00007f04691c1b1a in ureq::unit::connect::h86e6e17e828e786d () from /u01/pgsql-14/lib/zombodb.so
      #8 0x00007f04691d689a in ureq::request::Request::do_call::_$u7b$$u7b$closure$u7d$$u7d$::h72c10a8208ac877b () from /u01/pgsql-14/lib/zombodb.so
      #9 0x00007f04691d63fa in ureq::request::Request::do_call::h01ec124203ce1635 () from /u01/pgsql-14/lib/zombodb.so
      #10 0x00007f046976b60f in zombodb::elasticsearch::Elasticsearch::execute_request::h14967194aa7a9f06 () from /u01/pgsql-14/lib/zombodb.so
      #11 0x00007f0469475571 in std::panicking::try::h7307813c61e33389 () from /u01/pgsql-14/lib/zombodb.so
      #12 0x00007f046962248b in std::sys_common::backtrace::__rust_begin_short_backtrace::hd88bb24605bcea7a () from /u01/pgsql-14/lib/zombodb.so
      #13 0x00007f0469625f88 in core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h232e4d11b993f2be () from /u01/pgsql-14/lib/zombodb.so
      #14 0x00007f04691a8046 in std::sys::pal::unix::thread::Thread::new::thread_start::h3631815ad38387d6 () from /u01/pgsql-14/lib/zombodb.so
      #15 0x00007f068779dea5 in start_thread () from /lib64/libpthread.so.0
      #16 0x00007f06861ba96d in clone () from /lib64/libc.so.6

      堆栈信息清晰指向关键结论:PostgreSQL 通过 zombodb.so 插件(ZomboDB 插件)发起了对 Elasticsearch(ES)的请求(Elasticsearch::execute_request),但始终未收到 ES 的响应数据,导致线程在 recv 网络调用处持续阻塞。

      经确认,被更新的表已创建 ZomboDB 索引,更新操作触发后会自动通过 ZomboDB 插件向 ES 发起数据回写请求。

      结合现场环境排查,推断此次异常的直接原因是:PostgreSQL 与 ES 之间的网络中断,且 ZomboDB 插件未配置请求超时时间,导致插件线程持续等待 ES 响应,进而造成会话 commit 无法完成、进程无法终止。

      最后,采用 gdb 工具直接强制中止阻塞线程。 使用gdb 命令连接到线程后,输入kill杀掉线程,再输入quit退出即可。

        $ gdb -p 32005
        ......

        gdb命令退出后,发现10590会话已经不存在,相关的锁等待也没有了。

        最后,欢迎感兴趣的朋友加入DB演武场交流群,在这里可以交流PostgreSQL、Linux、Kingbase、openGauss等各类技术知识。关注公众号“张家辉的DB演武场”后,后台发送“加群“,即可获取最新加群二维码。

        文章转载自张家辉的DB演武场,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论