如何在同一系统中使用DBD::Pg连接不同版本的PostgreSQL数据库
首先得明确一个核心点:lib_version对应的是DBD::Pg编译时所链接的libpq库的版本,而不是你当前连接的PostgreSQL服务器版本,也不是DBD::Pg自身的版本。生产环境里两者数值一致,是因为你的DBD::Pg是基于PostgreSQL 9.3的libpq编译的,同时连接的也是9.3的服务器,所以数值完全匹配。
在测试环境的PostgreSQL 10.3上,如果你的lib_version显示异常(比如还是90310或者其他和10.3不符的数值),大概率是因为你的DBD::Pg是在装有PostgreSQL 9.3的环境下编译的,或者测试环境中同时存在多个版本的libpq,DBD::Pg优先链接了旧版本的库。
下面是具体的排查和解决步骤:
1. 先确认当前DBD::Pg关联的libpq版本
在测试环境的命令行里执行以下命令,直接查看libpq的版本数值和字符串:
perl -MDBD::Pg -e 'print "DBD::Pg版本: $DBD::Pg::VERSION\n"; print "libpq数值版本: ", DBD::Pg::pg_libversion(), "\n"; print "libpq字符串版本: ", DBD::Pg::pg_libversion_string(), "\n"'
如果输出的libpq版本不是10.3.x,那就说明确实是链接了旧库。
2. 重新编译DBD::Pg以匹配PostgreSQL 10.3的libpq
情况一:PostgreSQL 10.3是系统默认安装
直接重新安装DBD::Pg即可,用cpanm或者手动编译:
# 用cpanm安装(推荐) cpanm DBD::Pg # 或者手动编译安装 wget https://cpan.metacpan.org/authors/id/T/TU/TURNSTEP/DBD-Pg-3.16.0.tar.gz # 可替换为最新版本 tar zxf DBD-Pg-3.16.0.tar.gz cd DBD-Pg-3.16.0 perl Makefile.PL make make test make install
情况二:PostgreSQL 10.3安装在自定义路径
需要在编译时指定PG的安装目录,确保DBD::Pg找到10.3的头文件和库:
perl Makefile.PL PGDIR=/usr/local/pgsql-10.3 # 替换为你的PG10.3实际路径 make make test make install
3. 临时解决办法(不推荐长期使用)
如果暂时不想重新编译,可以通过设置环境变量让系统优先加载PG10.3的libpq库:
- Linux系统:
export LD_LIBRARY_PATH=/usr/local/pgsql-10.3/lib:$LD_LIBRARY_PATH # 然后再运行你的Perl脚本 - macOS系统:
export DYLD_LIBRARY_PATH=/usr/local/pgsql-10.3/lib:$DYLD_LIBRARY_PATH # 然后再运行你的Perl脚本
这种方法只是临时生效,重启终端后就会失效,长期来看还是重新编译DBD::Pg更稳妥。
补充:完善你的版本日志代码
可以在脚本里同时打印更多版本信息,方便后续排查问题:
use strict; use warnings; use DBI; # 连接数据库 my $dbh = DBI->connect( "dbi:Pg:dbname=your_db;host=your_host", "your_user", "your_pass", { RaiseError => 1, AutoCommit => 1 } ) or die "连接失败: " . DBI->errstr; # 获取各类版本信息 my $dbd_pg_ver = $DBD::Pg::VERSION; my $libpq_num = DBD::Pg::pg_libversion(); my $libpq_str = DBD::Pg::pg_libversion_string(); my $server_num = $dbh->{pg_server_version}; my $server_str = $dbh->{pg_server_version_string}; # 打印日志 print "DBD::Pg版本: $dbd_pg_ver\n"; print "libpq版本: $libpq_num ($libpq_str)\n"; print "PostgreSQL服务器版本: $server_num ($server_str)\n"; $dbh->disconnect;
这里需要说明下版本数值的编码规则:PostgreSQL的版本数值是主版本*10000 + 次版本*100 + 修订版本,比如10.3.0对应的数值就是100300,9.3.10对应的是90310。
内容的提问来源于stack exchange,提问作者Adina




