文章目錄
- 局點現象
- 定位結論
- 局點環境
- 補充知識點如下
- 庫文件加載順序
- 關鍵事實:
- 您系統中的證據:
- 優先級對比表:
- 解決方案強化:
- 最終檢查:
- 本局點解決方法
局點現象
- 數據庫 mdm 升級失敗
- 檢查日志, 發現是由于 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)
補充知識點如下
庫文件加載順序
- LD_LIBRARY_PATH 指向的路徑
- /etc/ld.so.conf.d/xxx.conf
按照字母排序 - ldconfig 緩存的標準系統路徑 /lib /lib64 /usr/lib /usr/lib64 等
關鍵事實:
-
默認標準路徑:
- 在大多數 Linux 發行版中,
/etc/ld.so.conf
文件默認包含以下路徑:include /etc/ld.so.conf.d/*.conf /usr/local/lib # 這是標準本地軟件安裝路徑 /usr/lib /lib
- 這意味著
/usr/local/lib
總是會被ldconfig
掃描并加入緩存
- 在大多數 Linux 發行版中,
-
驗證方法:
# 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"
-
優先級特性:
- 由于在
/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 位于最高優先級了