如何使用gdb调试一次vacuum的过程

xiaobu 8天前 23

阅读源码和单步调试,可以帮助我们更加深刻地理解技术背后的秘密。下面我给gdb初学者介绍如何单步调试vacuum操作。

 

1. 编译PG源码,采用configure/make/make install三步进行编译源码。假设编译的源码目录是

/home/postgres/postgresql-17.5

你在执行configure时,采用./configure --prefix=/home/postgres/pg175 --enable-debug --enable-cassert CFLAGS="-O0",这样的代码是没有经过优化的,调试起来更加方便。

2. PG软件安装好后,initdb创建一个数据库集群,并准备一张表,譬如叫做state,你可以在里面胡乱加一些数据。

3. 使用psql登录,然后用ps -ef | grep postgres来查看这个客户端对应的后台进程的pid,或者执行如下命令也可以获得本次链接对应的后台进程的进程号:

postgres=# select pg_backend_pid();
 pg_backend_pid 
----------------
        1323921
(1 row)

拿到这个进程号以后,你打开另外一个窗口登录服务器,准备执行gdb。建议你使用root用户执行gdb,这样就不会有权限问题,执行如下命名,其中-p 1323921是把gdb贴到那个后台进程:

root@/home/postgres# gdb --tui --directory=postgresql-17.5 -p 1323921

进入到gdb后,执行如下命令:

b ExecVacuum
c

上述命令就是在ExecVacuum函数的开始下断点,c表示继续执行,quit可以退出gdb。然后在psql窗口执行vacuum命令:

oracle=# vacuum state;

你在gdb窗口就会发现后台程序停留在ExecVacuum函数的开始部分,然后你就用n和s进行单步执行,就会一步步看到vacuum的具体执行过程。再结合源码的阅读,你就会对vacuum的理解更加深刻。

后面我会分享我调试vacuum的心得体会。

最新回复 (1)
  • xiaobu 8天前
    引用 2

    vacuum真正干活的函数是lazy_scan_heap(),这个函数在src/backend/access/heap/vacuumlazy.c中,你可以在这个函数下断点,然后使用bt命令显示它的调用堆栈或者次序。

    lazy_scan_heap
    heap_vacuum_rel
    table_relation_vacuum
    vacuum_rel
    vacuum
    ExecVacuum
    standard_ProcessUtility
    ProcessUtility
    ProcessRunUtilty
    PortalRunMulti
    PortalRun
    exec_simple_query
    PostgresMain
    BackendMain
    postmaster_child_launch
    BackendStartup
    ServerLoop
    PostmasterMain
    main
    
返回
发新帖