下面通过,一个关于“GDB调试PG数据库CheckPoint子进程”的例子,描述一下GDB调试PG数据库子进程的方法。
PG数据库启动之后,启动postmaster父进程,随后postmaster进程会fock出CheckPoint子进程,下面逐步描述我是怎么完成调试的。
本人使用的是14.0版本的源码,关于数据库部署,配置环境的相关操作,这里不做描述。
1. 源码编译前的准备
PG在源码编译之前,需要首先执行./configure命令(configure文件在源码目录第一层),在这一步时,就需要打开调试功能,然后再编译:
(1)执行命令:./configure -prefix=/usr/local/pgsql --enable-debug
(2)vi /opt/postgresql-14.0/src/Makefile.global
找到下面这行:
CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -g -O2
上面的行的"-O2"选项删除,然后加上"-g"。"-O2"是编译器的优化选项,如果打开了,代码的执行顺序会改变,使得追踪起代码来比较困难,所以要去除。gdb 调试程序的时候打印变量值出现<value optimized out>就是由于没有去掉 “-O2”。
(3)执行命令: make clean all(如果要求root权限,执行sudo make clean all)
(4)执行命令: make install(本例中,pg默认部署在/usr/local/pgsql目录下)
此时安装完成,然后自己确保环境正常安装,可以创建数据库了。
2. 创建数据库
登录你创建的用户postgres, 创建一个数据库mydb。
3. GDB调试
这里我们尝试去通过GDB查看检查点的一个控制“自动触发检查点的时间参数--CheckPointTimeout”的值。
(1)首先查看postgres的相关进程号
进程ID=30928,对应的是PG的主进程,获取到主进程号为30928。
(2) 执行GDB
如上执行gdb attach 30928,进入调试。
(3)打断点将主进程在fork 检查点子进程之前挂住
由于postmaster主进程运行时,会在下面的位置处,拉起检查点子进程,所以此处打上断点:
断点如下,然后执行r,重新运行。
(4)然后GDB结果如下:
(5)设置: set follow-fork-mode child
(6)然后在子进程的接口CreteCheckPoint上打上断点:
执行:b CreateCheckPoint(为了我在会话中执行CHECKPOINT命令,强制创建检查点时,可以将进程卡在这个位置)
(7)然后执行c,等待进程执行到断点位置。
(8)打开会话,执行CHECKPOINT;命令
(9)然后通过p CheckPointTimeout,打印出该参数的值,如上上图所示。
上面就是探讨的方法。方法很多,后续会继续补充。