我一直无法让plperl在Windows上与Postgres 9.1一起工作。
这里描述了同样的问题,但到目前为止还没有解决方案:http://postgresql.1045698.n5.nabble.com/bug - 6204 -使用- plperl函数生成-崩溃td4802111.html
再生产
安装Perl 5.14 32-bit for Windowshttp://downloads.activestate.com/activeperl/releases/5.14.2.1402/activeperl - 5.14.2.1402 mswin32 - x86 - 295342. - msi
将Perl添加到系统路径变量从Enterprise DB安装Postgres 9.1.2 32位windows www.enterprisedb.com/products/pgdownload.do
现在创建一个测试数据库,添加perl,并尝试创建一个函数:
postgres=# create database plperl_test;
CREATE DATABASE
postgres=# c plperl_test
WARNING: Console code page (437) differs from Windows code page (1252)
8-bit characters might not work correctly. See psql reference
page "Notes for Windows users" for details.
You are now connected to database "plperl_test" as user "postgres".
plperl_test=# create language plperl;
CREATE LANGUAGE
plperl_test=# create function perl_test() returns void as
plperl_test-# $$
plperl_test$# $$
plperl_test-# language plperl;
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
注意,这会导致Postgres服务器进程关闭。呵!
当我查看我的Postgres日志文件时,我发现这个…
2011-12-29 15:51:08 PST STATEMENT: create function perl_test() returns void as
$$
$$
language plperl;
2011-12-29 15:51:26 PST LOG: server process (PID 10364) was terminated by exception 0xC0000005
2011-12-29 15:51:26 PST HINT: See C include file "ntstatus.h" for a description of the hexadecimal value.
2011-12-29 15:51:26 PST LOG: terminating any other active server processes
2011-12-29 15:51:26 PST WARNING: terminating connection because of crash of another server process
2011-12-29 15:51:26 PST DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
2011-12-29 15:51:26 PST HINT: In a moment you should be able to reconnect to the database and repeat your command.
2011-12-29 15:51:26 PST LOG: all server processes terminated; reinitializing
2011-12-29 15:51:36 PST FATAL: pre-existing shared memory block is still in use
2011-12-29 15:51:36 PST HINT: Check if there are any old server processes still running, and terminate them.
我很惊讶地发现谷歌在这个问题上没有好的答案。似乎Activstate对一些人有效,但对另一些人无效。有人怀疑不同版本的windows系统库之间存在冲突,但没有确定的结果。然而,我终于能够构建一个plperl.dll工作,使用草莓perl.
下面是让plperl使用strawberry perl的循序渐进的步骤说明。诀窍是重新编译postgresql和plperl,但是在现有的postgresql安装上安装plperl。
首先,您需要以下内容:
- mingw (http://www.mingw.org)
- 草莓perl。http://www.strawberryperl.org
- Postgresql来源。
这个mingw网站让人摸不着头脑。没有单独的软件包可以下载。你必须下载一个安装程序来下载其他的东西。这里有一个快速链接。
http://sourceforge.net/projects/mingw/files/Installer/在安装程序中,选择C和c++,以及要安装的MSYS环境。Mingw不会污染你的环境,所以把它安装在任何旧的位置。
至于perl,我不认为activestate提供了必要的文件(共享库),我发现strawberry的CPAN支持更优越(与activestate的私有ppm站点相比),而activestate的傻逼举动是把旧版本放在付费墙后面(并迫使其他站点删除其托管副本)。F.U. ActiveState .
Postgresql 9.1最初是基于perl 5.14构建的,所以最好还是使用那个版本。
解压并安装所有这些东西。Mingw会给你一个shell(在启动菜单中查找快捷方式)来编译。启动一个shell,不要关闭它。
运行以下命令安装/删除包:
mingw-get install libminizip
mingw-get remove mingw-perl
您需要删除mingw的perl,以便构建过程使用草莓perl代替。您可以使用path变量来代替,但这种方法更简单
现在,您需要进入您解压缩postgresql源代码的目录。在mingw shell中,使用根路径/c来引用c:驱动器。
现在只需配置并生成
./configure --with-perl
make
请注意,postgres文档说使用gmake,但在mingw上,它是make。
在构建实际的plperl.dll文件时可能会失败。这是因为构建环境没有生成正确的命令来构建dll。如果出现如下错误:
dllwrap -o plperl.dll --dllname plperl.dll --def libplperldll.def plperl.o SPI.o Util.o -L../../../src/port -Wl,--allow-multiple-definition -Wl,--as-needed -LC:/strawberry/perl/lib/CORE -l -L../../../src/backend -lpostgres
c:/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../../mingw32/bin/ld.exe: cannot find -l-L../../../src/backend
c:/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../../mingw32/bin/ld.exe: cannot find -lpostgres
cd到src/pl/plperl目录,执行如下命令:
dllwrap -o plperl.dll --dllname plperl.dll --def libplperldll.def plperl.o SPI.o Util.o -L../../../src/port -Wl,--allow-multiple-definition -Wl,--as-needed -L/c/strawberry/perl/lib/CORE -L../../../src/backend -lpostgres -lperl514
(注意perl安装在c:strawberry目录下,mingw安装在c:mingw目录下)
至此,您已经完成了。在该目录中有一个plperl.dll,它可以取代postgresql附带的plperl.dll。
这里说,(ActiveState) Perl 5.14需要让它工作。我不确定这个品牌,因为我必须为postgres 9.0使用旧版本的strawberry perl,它工作得很好。重要的是为Postgres 9.1使用正确的Perl 5.14版本。尝试使用与您的postgres安装相匹配的二进制格式(32位或64位)
在使用新安装的PostgreSQL 9.1.11 (x64)后,我发现ActivePerl 5.14.1 (x64)可以工作。关键是要确保PostgreSQL能够在其环境PATH
中找到所需的perl DLL。
在postgres lib目录下的plperl.dll
上运行Dependency Walker。在PostgreSQL 9.1.11的情况下,它有一个依赖于perl514.dll
-所以改变你的环境路径,包括它所在的目录(即c:perlbin)。通过重新运行Dependency Walker重新检查DLL是否被正确检测到,然后完全停止/启动PostgreSQL服务,你应该就可以了。
如果你发现plperl.dll
有一个依赖于不同的perl DLL,那么你需要使用一个版本的ActivePerl匹配(即perl58.dll将匹配ActivePerl 5.8, perl510.dll将匹配ActivePerl 5.10 -确保perl和PostgreSQL的二进制格式总是匹配(32/64位))。