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

Go程序连接MariaDB后无法访问Unix Socket的诡异问题求助

调试方向建议

核心现象回顾

  • 连接MariaDB前,os.Stat("/var/lib/mysql/mysql.sock")正常,可成功连接并查询数据
  • 连接建立后,再次执行os.Stat返回stat /var/lib/mysql/mysql.sock: no such file or directory
  • SetConnMaxLifetime到期后,连接池无法重连,所有查询失败
  • 调用db.Close()后,os.Stat又能正常找到socket文件
  • socket权限为0777,父目录均具备o+x权限,已禁用fapolicyd和SELinux

具体调试步骤

1. 排查进程命名空间隔离问题

  • 找到Go进程PID:ps aux | grep <你的Go程序名>
  • 检查进程根目录下的socket路径:ls -l /proc/<Go进程PID>/root/var/lib/mysql/mysql.sock,若不存在,说明进程可能处于独立的文件系统命名空间,路径映射发生变化
  • 对比Go进程与MariaDB进程的命名空间:
    # 查看Go进程命名空间
    lsns -p <Go进程PID>
    # 查看MariaDB进程命名空间(先拿PID)
    ps aux | grep mysqld
    lsns -p <MariaDB进程PID>
    
    重点对比mnt(挂载)命名空间是否一致

2. 跟踪进程系统调用

  • 实时跟踪Go进程的stat和connect调用:
    strace -p <Go进程PID> -e stat,connect
    
    观察连接前后stat的路径参数、返回值差异
  • 全程记录系统调用日志,事后分析:
    strace -o go_db_trace.log -f <你的Go程序启动命令>
    
    搜索日志中stat /var/lib/mysql/mysql.sock相关条目,定位错误触发的上下文

3. 监控MariaDB socket文件状态

  • 持续监控socket的存在、权限、inode变化:
    watch -n 1 ls -li /var/lib/mysql/mysql.sock
    
    若inode号发生变化,说明socket被删除重建
  • 查看MariaDB日志(默认路径/var/log/mariadb/mariadb.log),搜索socket相关条目,确认是否存在重启、异常重建socket的情况

4. 验证Go连接池行为

  • 在代码中添加日志,记录连接获取、释放时间点,以及SetConnMaxLifetime的配置值,确认连接到期回收时机与问题触发时间是否匹配
  • 限制连接池大小为1,复现问题:
    db.SetMaxOpenConns(1)
    
    排查是否为多连接导致的资源冲突

5. 检查文件描述符限制

  • 查看Go进程的文件描述符限制:
    cat /proc/<Go进程PID>/limits | grep "Max open files"
    
    对比系统限制,确认是否存在文件描述符耗尽情况
  • 查看socket的进程持有情况:
    lsof | grep mysql.sock
    
    排查是否有异常进程持续占用socket资源

内容的提问来源于stack exchange,提问作者Taco de Wolff

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:50:02