一直没有集中的时间和精力去好好阅读Postgresql(后边简称postgres或者PG)的源码,由于平时大都工作在windows平台,所以,也懒得切换到linux vm下,尝试直接通过VisualStudio2008来理顺PG中的代码。由于都是用C所写,可移植性相当好,读懂了一个平台,换到另一个平台,相信不是什么难事。
可以说,PG的代码注释非常漂亮,也很完整,只可惜本人水平有限,难以在短时间内获得大收获。
一、准备工作:
你所要的,是一份完整的源码和VisualStudio2008开发境。完整的源码有两种途径:
1. 直接从PG官网上下载一份比较近的源码,如:
http://ftp.postgresql.org/pub/source/v9.2.1/postgresql-9.2.1.tar.gz (9.2.1)
2. 直接使用GIT,本地clone一份,可以得到最新的源码
有精力的话,可以参考PG的相关文档,它会告诉你如何获取最新的源码
3. 1和2的区别是什么?
1里有关sql的语法解析.l,.y已经免去了,直接有生成的代码。如果是2,则需要flex和bison (GnuWin32工具)生成对应的代码。
4. 下载一个windows版本的Perl吧。生成VC的工程需要它。假定Perl安装到c:\perl
二、编译一个Debug版本
进到代码$pg\src\tools\vc目录,创建一个config.pl文件,内容大致如下:
# Configuration arguments for vcbuild.
use strict;
use warnings;
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
ldap => 1,# --with-ldap
nls => undef,# --enable-nls=<path>
tcl => undef,# --with-tls=<path>
perl => 'c:\Perl',# --with-perl
python => undef,# --with-python=<path>
krb5 => undef,# --with-krb5=<path>
openssl => undef,# --with-ssl=<path>
uuid => undef,# --with-ossp-uuid
xml => undef,# --with-libxml=<path>
xslt => undef,# --with-libxslt=<path>
iconv => undef,# (not in configure,path to iconv)
zlib => undef # --with-zlib=<path>
};
1;
[注意:],因为只是阅读源码,一些第三方的依赖包,这里全部弄成undef,如果想自己构建完整的PG包,那则需要好好整理了。
这样,你的基本环境就具备了。 先进入VS2008的编译命令行(菜单里头进)。进到刚才的"tools"目录,命令行下,运行:
build.bat DEBUG
进入漫长的编译过程。
编译完成以后,就可以运行install.bat d:\pgsql,将其安装到d:\pgsql里头了。
三、调试
为发布目录d:\pgsql设置几个简单的环境变量:
PGHOME -> d:\pgsql
PGDATA -> %PGHOME%\data
PATH -> %PGHOME%\bin;%PGHOME%\lib;%PATH%
在这之后,进到目录:
d:\pgsql,运行以下几个简单的命令:
initdb -E UTF-8 --locale=chs
pg_ctl start
createdb iihero
psql iihero
这样,即可进到psql的运行环境。
想要调试,只要用VS2008打开pgsql\pgsql.sln方案文件,所有的工程即会打开。attach上你所要的postgres.exe进程即可。
以上是所有的从源码到调试的最基本的准备工作。
四、Win32下是如何启动的:
也就是说pg_ctl.exe是从哪个地方进去的?
入口点在:
bin->工程pg_ctl->pg_ctl.c,这个文件只有在win32平台才需要。别的平台上也没有pg_ctl这个可执行程序。它的作用只是要启动一个进程postgres.exe,然后自己退出。
通过getopt_long(argc,argv,"cD:l:m:N:o:p:P:sS:t:U:wW",long_options,&option_index),得到正确的命令行参数,
如果得到的是start命令:START_COMMAND,do_wait置为false,如果是STOP,则do_wait置为true。
紧接着会调用do_start() (针对START_COMMAND)
它会调用start_postmaster(),然后结束(不用wait)
你如果细看一下start_postmaster() 的实现,会发现它就是通过调用CreateRestrictedProcess(cmd,...),通过命令行,来创建一个进程postgres,而这个进程的实现位于: (工程)postgres->src->main->main.c
在启动过程中又会创建若干子进程。
代码浏览路径:
postgres->src->backend->main->main.c
再到bootstrap,再到: postgres->src->backend->postmaster->*.c