张文升
http://ode.cnblogs.com
Email:wensheng.zhang#foxmail.com
本文使用Xming、Putty和VMWare几款工具,在Windows桌面环境调用Ubuntu虚拟机上的图形界面进行PostgreSQL源码的调试。文中的所有步骤适合真机Ubuntu系统,只是所有图形界面的调用是在Windows桌面环境下。这样做,和直接在Ubuntu虚拟机中进行调试,并没有什么区别,只是我个人比较喜欢Windows下的一些工具的界面,如VISIO2013,Office2013,比起Libreoffice还是要方便美观很多。如果是linux用户,可以跳过配置xshell部分即可。
一、配置Eclipse和JAVA环境变量
1、下载jdk并解压,之后配置系统环境变量
export JAVA_HOME=/opt/jdk1.7.0_60
export JRE_HOME=$JAVA_HOME/jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
2、下载Eclipse并解压
在尝试运行eclipse时,当遇到“No Java virtual machine”的错误时,首先确定JAVA环境变量是否正确配置并使之生效了,如果问题依旧,可以通过在Eclipse目录中建立一个jre的软连接到jdk的jre目录即可。
ln -s /opt/jdk1.7.0_60/jre /opt/eclipse/jre
在Putty中配置X11,配置完成后尝试运行Eclipse,当遇到“connot open display”类似的错误时,回到虚拟机的图形界面,执行sudo xhost +,问题应该就可以解决了。在Windows中看到Eclipse界面,但是Eclipse的所有字体都非常小,可以通过在xming快捷方式的启动参数里加上一个参数:-dpi 108。windows默认的dpi是96像素,建议设置为96的125%或150%。
如:
"C:\Program Files (x86)\Xming\Xming.exe" :0 -clipboard -multiwindow -dpi 108
二、配置PostgreSQL源码
1、安装PostgreSQL源码调试所需要的包
sudo apt-get install make gcc g++ gdb tar libreadline6-dev zlib1g-dev bison flex
sudo apt-get install openssl libssl-dev libpam-dev libxml2 libxml2-dev libxslt-dev tcl tcl-dev libperl-dev python python-dev systemtap systemtap-sdt-dev
如果要调试PostgreSQL源码,需要安装gdb:sudo apt-get install gdb。
2、添加PostgreSQL的系统用户
sudo adduser postgres
3、在PostgreSQL源码目录中执行configure
如果只打开--enable-debug选项,在gdb里进行调试时,会有一些变量的值无法打印出来,这是因为gcc在进行编译代码时,会进行一定程度的优化。为了能够在调试跟踪时看到所有变量的值的变化情况,我们有必要降低甚至取消优化选项:CFLAGS=-o0 --enable-depend --enable-cassert --enable-debug
./configure CFLAGS=-O0 --prefix=/opt/PostgreSQL/9.3.4/ --with-perl --with-python --with-tcl --with-openssl --with-pam --without-ldap --with-libxml --with-libxslt --enable-thread-safety --enable-dtrace --enable-depend --enable-cassert --enable-debug
三、在Eclipse中建立PostgreSQL源码工程
1、新建一个Project并导入PostgreSQL源码
Language:选择C,必须去掉"C++"复选框
Toolchain for Indexer Settings:选择Linux GCC
单击"Finash"按钮。
2、设置Eclipse的Make Target
在调试PostgreSQL之前,首先需要将其安装到某个目录中,在Eclipse中是通过建立一个Make Target实现的。
在工程单击右键,选择Make Targets-Create,在弹出的"Create Make Target"对话框中,Target name文本控件的值输入:install,实际上它要做的就是我们通过源码编译安装时执行make install命令,单击OK按钮完成。
3、编译安装PostgreSQL源码到目标目录
在PostgreSQL源码工程上单击右键,选择Make Targets-Build,选择install,单击Build。
直到console窗口出现"PostgreSQL installation complete.",表示安装完成。
此时,在prefix参数指定的安装目录下,会生成bin、include、lib和share目录。
观察console窗口:
观察Progress窗口:
看到install完成
查看安装目录:
vincent@devpc:~$ ls -l /opt/PostgreSQL/9.3.4/
drwxr-xr-x 2 root root 4096 Jul 10 20:57 bin
drwxr-xr-x 4 root root 4096 Jul 10 20:57 include
drwxr-xr-x 4 root root 4096 Jul 10 20:57 lib
drwxr-xr-x 3 root root 4096 Jul 10 20:56 share
4、创建PostgreSQL的data目录并初始化实例
vincent@devpc:~$ sudo mkdir /opt/PostgreSQL/9.3.4/data
vincent@devpc:~$ sudo chown -R postgres.postgres /opt/PostgreSQL/9.3.4/data/
vincent@devpc:~$ su - postgres
postgres@devpc:~$ /opt/PostgreSQL/9.3.4/bin/initdb -D /opt/PostgreSQL/9.3.4/data/
四、运行PostgreSQL源码工程
初始化成功后,回到Eclipse,在PostgreSQL源码项目上单击右键菜单Run Configurations
双击C/C++ Application,会创建一个名为postgresql-source-9.3.4 Default的配置界面,在C/C++Application文本控件中输入src/backend/postgres
或者点击Search Project...按钮,选择postgres
两种方法都可以。完成后,切换到上图中红色箭头所指的Arguments选项卡,在Program arguments文本控件中输入启动实例参数-D和数据库的数据目录所在:-D /opt/PostgreSQL/9.3.4/data,如下图所示:
单击Apply,然后单击Run,上图中因为已经点击过Apply按钮,所以Apply按钮是禁用状态。如果这一步遇到Run按钮是禁用状态,那可能你使用的不是postgres用户运行Eclipse,可以切换到postgres用户试试看。
LOG: database system was shut down at 2014-07-11 02:44:35 CST
LOG: database system is ready to accept connections
LOG: autovacuum launcher started
看到这些信息,表示数据库已成功启动。
查看postgres进程和相关后台进程:ps -ef | grep postgres
至此,数据库已经安装,启动成功,可以通过psql连接到数据库进行测试。
postgres@devpc:~$ /opt/PostgreSQL/9.3.4/bin/psql -U postgres postgres
点击Console面板右侧的红色Terminate图标,看到以下输出即可停止数据库服务了。
LOG: received smart shutdown request
LOG: autovacuum launcher shutting down
五、调试PostgreSQL代码
1、调试主进程
数据库运行成功后,一定要关闭已经开启的Postmaster进程才能进行调试,否则会提示"Postmaster已经存在"的错误。
单击工程右键,Debug As-Local C/C++ Application,选择"postgres"作为调试程序,单击OK,即可进入调试模式。
此时程序自动会在main函数处停下,所以要继续点击工具栏上的"Resume"按钮(Eclipse默认的快捷键F8)让主进程运行完,否则无法连接数据库。Debug运行完后会有和运行成功时一样的提示信息。
这时的console窗口会有以下输出:
LOG: database system was interrupted; last known up at 2014-07-12 14:37:56 CST
LOG: database system was not properly shut down; automatic recovery in progress
LOG: record with zero length at 0/178A4A0
LOG: redo is not required
LOG: autovacuum launcher started
LOG: database system is ready to accept connections
2、服务进程(postgres子进程)的调试
使用psql连接数据库,查看当前的进程号:select pg_backend_pid();
注意:记住这个进程号,如15878。
打开另一个终端,输入ps -ef | grep sql
发现此时,多了一个进程:
lq 20579 20558 0 22:13 ? 00:00:00 postgres: lq DemoDB [local] idle
回到Eclipse调试界面,单击菜单Run->Debug Configure,在弹出的Debug Configurations界面,双击C/C++ Attach to Application:
配置界面:
Name:postgres
Main选项卡:
C/C++ Application:src/backend/postgres
Project:pgsql
Build configuration:取消"Select configuration...",选择"Use Active"
单击Debug,然后会出现一个进程选择窗口,输入"post"在程序的进程列表中,选择进程号(21706)对应的postgres进程。
单击OK。
在调试子进程的过程中遇到以下错误:
Could not attach to process. If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf
解决方法:
1.可以通过下面的命令对这个限制进行临时修改,但是重启后限制依旧存在。
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
2.可以通过修改配置文件来解除限制(我选择了这种方式)
sudo vim /etc/sysctl.d/10-ptrace.conf
修改前:
kernel.yama.ptrace_scope = 1
修改后:
kernel.yama.ptrace_scope = 0
重启之后可以生效。
修改之后重复上述的步骤既可看到已经将调试工具挂上了这个postgres进程。
六、PostgreSQL WIKI推荐的5本好书
1、An Introduction to Database Systems, by C.J. Date, Addison, Wesley
2、A Guide to the SQL Standard, by C.J. Date, et. al, Addison, Wesley
3、Fundamentals of Database Systems, by Elmasri and Navathe
4、Transaction Processing, by Jim Gray and Andreas Reuter, Morgan Kaufmann
5、Transactional Information Systems, by Gerhard Weikum and Gottfried Vossen, Morgan Kaufmann