有一阵子因工作需要,根据前人的文字和网上资源摸索着搭建了一个PostgreSQL的调试环境,与大家分享一下。
准备工作:
1.PostgreSQL(以下称pg)源码。
可以到官方网站上下载,最新的是9.0,此前的是8.4.1、8.4.2和8.4.3。注意8.4.*版本和9.0版本在配置时稍有不同,我会着重说明。这里使用8.4.1版本的源码,解压到d:/ code/postgresql8.4.1。
2.编译所需的工具包。
主要有openssl、Perl、Python、Tcl、iconv、krb5、xml、xslt、zlib、bison、flex。这些工具都可以从相应官网上下载。为了简化起见,可以安装pg对应版本的windows可执行安装文件,安装完成后就会自动添加这些工具。默认的路径如下:openssl、Perl、Python、Tcl的路径为c:/;iconv、krb5、xml、xslt、zlib的路径在c:/prog/pgsql/depend;bison、flex的路径在c:/prog/pgsql/GnuWin32/bison/bin。有些人愿意把这些工具放在一个统一的目录下面以便管理,这是个人习惯问题,读者可以根据自己的习惯配置。
3.准备编译环境
我使用的编译平台是vs2005。由于pg是在linux上开发,所以windows下的源码并没有对应的工程文件,好在pg提供了自动配置的perl文件,可以手动生成。
4.设置环境变量
由于需要执行perl文件调用bison、flex,所以必须在环境变量中添加相应的路径;另外必须添加的是编译器的路径,注意:8.4.*版本是Msbuild.exe一般在C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727目录下,9.0版本是vcbuild.exe在C:/或D:/Program Files/Microsoft Visual Studio 8/VC/vcpackages下。这些改动以及下文提到的config.pl细微差别可以对比两个版本的Solution.pm。因操作系统的不同,进行环境变量设置后并不能马上生效,需要重启,这里提供一种方法,避免重启。在命令行下执行SET $PATH=C:回车,退出cmd,再次进入cmd,执行set进行查看环境变量是否重启。
5.配置pg的编译环境
转到源码目录D:/code/postgresql-8.4.1,再进入src/tools/msvc下,可以看见一个名为config.pl的文件,在9.0版本中文件名为config_default.pl。这是一个文本文件,可以用UltraEdit打开,内容如下:
our $config = {
asserts=>0, # --enable-cassert
# integer_datetimes=>1, # --enable-integer-datetimes - on is now default
# float4byval=>1, # --disable-float4-byval, on by default
# float8byval=>0, # --disable-float8-byval, off by default
# blocksize => 8, # --with-blocksize, 8kB by default
# wal_blocksize => 8, # --with-wal-blocksize, 8kb by default
# wal_segsize => 16, # --with-wal-segsize, 16MB by default
nls=>undef, # --enable-nls=<path>
tcl=>'c:/tcl', # --with-tls=<path>
perl=>'c:/perl', # --with-perl
python=>'c:/python24', # --with-python=<path>
krb5=>'c:/prog/pgsql/depend/krb5', # --with-krb5=<path>
ldap=>1, # --with-ldap
openssl=>'c:/openssl', # --with-ssl=<path>
uuid=>'c:/prog/pgsql/depend/ossp-uuid', #--with-ossp-uuid
xml=>'c:/prog/pgsql/depend/libxml2',
xslt=>'c:/prog/pgsql/depend/libxslt',
iconv=>'c:/prog/pgsql/depend/iconv',
zlib=>'c:/prog/pgsql/depend/zlib'# --with-zlib=<path>
};
这里需要把uuid选项注掉,另外把对应工具包的路径修改成自己的路径,如果是采用pg windows下可执行文件生成的工具包,以上配置均为默认路径不需要修改了。
这里简单介绍一下配置文件中的几个选项。tcl、perl、python是脚本语言;Krb5是一个提供网络认证服务的系统;LDAP(Lightweight Directory Access Protocol)是一个用来发布目录信息到许多不同资源的协议;openssl,其中SSL是Secure Socket Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输;UUID (Universally Unique Identifier),提供分布式系统中的所有元素都能唯一标识,这样在数据库中就不需考虑数据库名称重复问题,在widows中有自己的标准GUID,这也是该选项被注掉的原因;Xml(Extensible Markup Language)是对html的扩展,XSLT(Extensible Stylesheet Language Transformations)这是一种对XML文档进行转化的语言;Iconv是libiconv库的接口,libiconv是一个基于GNU协议的开源库,主要解决多语言编码处理转换等应用问题;zlib提供压缩函数库。
读者可根据自己兴趣查阅相关文档。
6.修改源码中的错误
在8.4.*版本中postgresql-8.4.1/contrib/fuzzystrmatch/dmetaphone.c中存在几处错误,导致编译失败,问题如下:
dmetaphone.c(464): error C2001: 常量中有换行符
dmetaphone.c(465): error C2146: 语法错误 : 缺少":"(在标识符"MetaphAdd”的前面)
dmetaphone.c(1040): error C2001: 常量中有换行符
dmetaphone.c(1041): error C2146: 语法错误 : 缺少":"(在标识符"current”的前面)
查看源码很明显这是464、1040行 case 缺少单引号所致。
dmetaphone.c(1041): error C2196: case 值"16186”已使用
这里将464和1040行的case注掉一个。
在/postgresql-8.4.1/src/backend/main中的main.c中,注释掉第157行,即检查root的那行。 pg出于安全性的考虑禁止以root用户登陆,如果这行不注掉,编译后的postgre.exe将启动失败。
7.生成工程文件
进入CMD,CD到D:/code/postgresql-8.4.1/src/tools/msvc目录下,执行perl build.pl DEBUG,DEBUG必须添加否则无法生成调试信息。编译十分钟后,生成成功,忽略中间的黄色警告。如果perl编译失败的话,查看一下flex、bison、perl的环境设置是否正确;如果是代码没有更改所致,则很容易定位。
8.创建自己的数据库
在D:/code/postgresql-8.4.1下新建一个bin目录,转到D:/code/postgresql-8.4.1/src/tools/msvc,运行perl install.pl ../postgresql-8.4.1/bin,这一步的目的是将各地编译的成果拷贝到新建的那个bin目录下。
在D:/code/postgresql-8.4.1/bin/bin目录下,运行initdb.exe --no-locale billywangqi,billywangqi是数据库名,命令执行完后,在D:/code/postgresql-8.4.1/bin/bin会生成一个billywangqi的文件夹。
9.设置pgsql.sln的工程属性
打开postgresql目录下的pgsql.sln文件,在主工程中设置配置属性->调试->命令参数为:
-D billywangqi (正常模式)
在工作目录中设置为:D:/code/postgresql-8.4.1/bin/bin
10.编译
设置完工程文件后,就可以对pg源码进行编译了。8.4版本可能报无法生成工程文件的错误,一般是由于flex和bison环境变量没有正确设置所致。这里需要对9.0版本进行特殊设置,把src/backend/parser/scan.l属性->配置属性->自定义生成步骤->常规里的所有选项清空。这是由于按照src/tools/msvc/pgflex.bat中的命令无法将词法文件编译通过。对比8.4版本及其它模块词法文件,发现多了如下几个选项
%option reentrant
%option bison-bridge
%option bison-locations
%option noyyalloc
%option noyyrealloc
%option noyyfree
而正是这几个选项,导致词法编译不过去。令人奇怪的是,不管是在windows还是在linux,单独用flex编译scan.l时都会报错,但是在linux上整体编译时却能通过。在网上发贴提问,寥寥几句回复,按其法验证仍旧如是,若有高人路过请予指点。
编译后启动时可能报dll文件不存在无法启动的问题,这时候需要把文章一开始提到的安装包里对应的dll文件copy到D:/code/postgresql-8.4.1/bin/bin下,我记得主要是krb5文件下的dll文件。
11.调试
首次创建时pg只有模板库,需要在命令行用 psql template1 命令进入 psql 然后创建新的数据库。在调试pg代码时,需要把postgres.exe 附加到进程(点击调试->附加到进程),这时候你会发现有很多postgres.exe,不要大惊小怪这是因为postgres是多进程的。一般会把最后一个添加进去,也可以全部附加到进程。
有时会出现断点无效的情况,这时尝试设置主工程文件(postgres)属性->配置属性->链接器->常规->输出文件为:
D:/code/postgresql-8.4.1/bin/bin/postgre.exe
如果需要调试plpgsql,则尝试设置plpgsql工程文件属性->配置属性->链接器->常规->输出文件为:
D:/code/postgresql-8.4.1/bin/lib/plpgsql.dll
要确保这些dll文件都存在。
至此,postgreSQL的windows平台调试环境搭建完成。