下面通过,一个关于“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,打印出该参数的值,如上上图所示。

        上面就是探讨的方法。方法很多,后续会继续补充。