当前位置: 首页 > news >正文

Linux 环境 libpq加载异常导致psql 连接 PostgreSQL 库失败失败案例

文章目录

  • 局点现象
  • 定位结论
  • 局点环境
  • 补充知识点如下
    • 库文件加载顺序
      • 关键事实:
      • 您系统中的证据:
      • 优先级对比表:
      • 解决方案强化:
      • 最终检查:
  • 本局点解决方法

局点现象

  1. 数据库 mdm 升级失败
  2. 检查日志, 发现是由于 psql 连接数据库报错,
psql: symbol lookup error: psql: undefined sybol : PQmblenBounded

定位结论

通常表示 psql 可执行文件所依赖的 libpq 动态库版本与编译时版本不一致或不兼容,即运行时找不到它需要的某个函数(PQmblenBounded)。

web 界面升级, 使用的 shell 非普通 sh xxx.sh 中的shell 环境, 加载的环境变量没那么全, 局点环境中 psql 在运行过程中, 会加载系统自带的库文件缓存路径, 局点默认的缓存为

[root@localhost ~]# ldconfig -p |grep libpq.so.5libpq.so.5 (libc6,x86-64) => /usr/local/lib/libpq.so.5libpq.so.5 (libc6,x86-64) => /usr/lib64/libpq.so.5[root@localhost ~]# nm -D /usr/local/lib/libpq.so.5 | grep PQmblenBounded
[root@localhost ~]# nm -D /usr/lib64/libpq.so.5 | grep PQmblenBounded
000000000001b010 T PQmblenBounded@@RHPG_14[root@localhost ~]# nm -D /program/lib/libpq.so.5 | grep PQmblenBounded
000000000001a8c0 T PQmblenBounded

可以看到 /usr/local/lib下 与 /usr/lib64 下的 库文件中, 没有 PQmblenBounded 函数, 而 我们产品的库文件路径/program/lib 下的 libpq.so.5中是有的

局点环境

[root@localhost lxm]# ldd /program/bin/psql |grep libpqlibpq.so.5 => /program/lib/libpq.so.5 (0x00007f9a02984000)
[root@localhost lxm]# 
[root@localhost lxm]# echo $LD_LIBRARY_PATH 
/program/lib:/usr/local/fuse/lib:/usr/lib64:/usr/local/lib:/lib:/lib64:/driverfile/lib
[root@localhost lxm]# 
[root@localhost lxm]# ldconfig -p |grep libpqlibpqwalreceiver.so (libc6,x86-64) => /usr/local/lib/libpqwalreceiver.solibpq.so.5 (libc6,x86-64) => /usr/local/lib/libpq.so.5libpq.so.5 (libc6,x86-64) => /usr/lib64/libpq.so.5
[root@localhost lxm]# 
[root@localhost lxm]# 
[root@localhost lxm]#  /program/bin/psql -U postgres -c "\c ras; " -c "select current_database()"
You are now connected to database "ras" as user "postgres".current_database 
------------------ras
(1 row)

补充知识点如下

库文件加载顺序

  1. LD_LIBRARY_PATH 指向的路径
  2. /etc/ld.so.conf.d/xxx.conf
    按照字母排序
  3. ldconfig 缓存的标准系统路径 /lib /lib64 /usr/lib /usr/lib64 等

关键事实:

  1. 默认标准路径

    • 在大多数 Linux 发行版中,/etc/ld.so.conf 文件默认包含以下路径:
      include /etc/ld.so.conf.d/*.conf
      /usr/local/lib    # 这是标准本地软件安装路径
      /usr/lib
      /lib
      
    • 这意味着 /usr/local/lib 总是会被 ldconfig 扫描并加入缓存
  2. 验证方法

    # 1. 检查默认配置
    cat /etc/ld.so.conf# 典型输出(RHEL/CentOS):
    include ld.so.conf.d/*.conf
    /usr/local/lib    # 明确列出的标准路径
    /usr/lib
    /lib# 2. 查看缓存中的路径
    ldconfig -v | grep -A1 "search dir"
    
  3. 优先级特性

    • 由于在 /etc/ld.so.conf 中直接定义(而非通过 .d 目录)
    • 它的加载顺序早于 /etc/ld.so.conf.d/ 中的配置文件
    • 因此有较高优先级

您系统中的证据:

[root@localhost ~]# ldconfig -p |grep libpqlibpq.so.5 (libc6,x86-64) => /usr/local/lib/libpq.so.5   # 来自标准路径libpq.so.5 (libc6,x86-64) => /usr/lib64/libpq.so.5       # 来自标准路径

优先级对比表:

路径类型示例优先级来源典型优先级
主配置文件路径/usr/local/lib/etc/ld.so.conf最高
.d目录早期文件/etc/ld.so.conf.d/00-*.conf文件名排序
.d目录后期文件/etc/ld.so.conf.d/99-*.conf文件名排序
LD_LIBRARY_PATH任何自定义路径环境变量最高(但受限制)

解决方案强化:

# 创建超高级别配置文件(00前缀)
sudo tee /etc/ld.so.conf.d/00-pg.conf <<< "/program/lib"# 重建缓存(确保新路径最先加载)
sudo ldconfig# 验证缓存顺序(/program/lib 应该在最前面)
ldconfig -p | grep libpq.so.5

最终检查:

# 查看实际加载的库
LD_DEBUG=libs psql -c "SELECT 1" 2>&1 | grep libpq.so# 预期输出:
#   find library=libpq.so.5 [0]; searching
#     trying file=/program/lib/libpq.so.5   # 应该先尝试这个
#     trying file=/usr/local/lib/libpq.so.5 # 后尝试这个

结论
/usr/local/lib 确实是标准路径且优先级较高,但通过创建 00-pg.conf 文件,您可以强制系统优先使用 /program/lib 中的新版库,完美解决符号缺失问题。

本局点解决方法

echo '/program/lib'  > /etc/ld.so.conf.d/00-pg.conf && ldconfig[root@localhost ~]# cat /etc/ld.so.conf.d/00-pg.conf 
/program/lib
[root@localhost ~]# ldconfig
[root@localhost ~]# ldconfig -p |grep libpqlibpqwalreceiver.so (libc6,x86-64) => /program/lib/libpqwalreceiver.solibpqwalreceiver.so (libc6,x86-64) => /usr/local/lib/libpqwalreceiver.solibpq.so.5 (libc6,x86-64) => /program/lib/libpq.so.5libpq.so.5 (libc6,x86-64) => /usr/local/lib/libpq.so.5libpq.so.5 (libc6,x86-64) => /usr/lib64/libpq.so.5libpq.so (libc6,x86-64) => /program/lib/libpq.so
[root@localhost ~]# 
[root@localhost ~]# ldd /program/bin/psql |grep libpqlibpq.so.5 => /program/lib/libpq.so.5 (0x00007f5b60bfc000)

可以看到, 现在 /program/lib/libpq.so.5 位于最高优先级了

http://www.lryc.cn/news/609574.html

相关文章:

  • uniapp开发微信小程序textarea在ios下有默认内边距的问题(textarea兼容问题)
  • 如何给Word和WPS文档添加密码或取消密码
  • Ethereum:拥抱开源,OpenZeppelin 未来的两大基石 Relayers 与 Monitor
  • Jwts用于创建和验证 ​​JSON Web Token(JWT)​​ 的开源库详解
  • OpenLayers 入门指南【五】:Map 容器
  • R 语言科研绘图第 67 期 --- 箱线图-显著性
  • Nestjs框架: Node.js 多环境配置策略与 dotenv 与 config 库详解
  • 政府财政行业云原生转型之路
  • Druid学习笔记 01、快速了解Druid中SqlParser实现
  • 排序算法入门:直接插入排序详解
  • 室内分布系统
  • ICCV 2025|单视频生成动态4D场景!中科大微软突破4D生成瓶颈,动画效果炸裂来袭!
  • Flutter开发 了解Scaffold
  • 深入理解Java的SPI机制,使用auto-service库优化SPI
  • 区块链基础之Merkle B+树
  • Azure DevOps - 使用 Ansible 轻松配置 Azure DevOps 代理 - 第6部分
  • 打造个人数字图书馆:LeaNote+cpolar如何成为你的私有化知识中枢?
  • 多级表头的导出
  • 软件打包前进行文件去重
  • Unix 命令行shell基础--学习系列003
  • Web 开发 12
  • 嵌入式硬件中三极管原理分析与控制详解
  • 嵌入式硬件篇---OpenMV存储
  • 单片机51 day46
  • 基于单片机智能鱼缸/水族箱/水产养殖系统设计
  • 第二篇:深入解析 FastAPI + LangChain 实现流式对话接口:`chat` 函数详解
  • 嵌入式硬件中三极管推挽电路控制与实现
  • 单片机裸机程序设计架构
  • Ubuntu 下 MySQL 运维自动化部署教程(在线简易版)
  • MLIR Introduction