You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash读取postgres输出fd3时阻塞死锁的问题排查及解决方案

问题解答

1. 管道缓冲区大小调整方法

你之前调整的net.unix.max_dgram_qlen是Unix域数据报套接字的队列参数,和你用到的进程替换生成的管道无关,所以不生效。Linux系统下管道缓冲区的调整方法如下:

  • 先调整系统级管道最大缓冲区限制:
    临时生效执行:
    sysctl -w fs.pipe-max-size=10485760 # 单位为字节,这里设置为10M
    
    永久生效将fs.pipe-max-size=10485760写入/etc/sysctl.conf,执行sysctl -p加载配置。
  • 针对你脚本中打开的fd3单独调整缓冲区大小:
    在exec 3< <(...)语句执行后,新增以下代码调整缓冲区到1M:
    python3 -c "import fcntl; fcntl.fcntl(3, fcntl.F_SETPIPE_SZ, 1048576)"
    
    也可以用C写轻量工具调用fcntl接口实现相同效果,适合没有python环境的场景。

2. 方案优化建议

调整缓冲区大小只能降低死锁概率,只要存在暂停读取管道的逻辑,缓冲区总有被打满的可能,你自己提供的执行SQL前清空缓冲区的方案稳定性更高,可优化以下细节:

  • 移除重复行判断逻辑:原有逻辑中如果出现连续两行相同的合法日志,会被误判为缓冲区已空,导致还有积压数据未读取。优化后的清空逻辑如下:
    echo "Empty postgres output buffer before executing sql command"
    # 连续2次读取超时则认为缓冲区已空
    local timeout_count=0
    while [ $timeout_count -lt 2 ]
    do
            read -u 3 -t 0.5 line 
            if [ $? -ne 0 ]
            then
                    ((timeout_count++))
                    continue
            fi
            timeout_count=0
            echo "Postgres: $line"
    done
    echo "Buffer is empty"
    
    调整超时时间为0.5秒、连续2次超时判空的逻辑,兼顾清空效率和准确性。

内容的提问来源于stack exchange,提问作者Torge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 05:36:05