postgresql源码学习--gdb调试

1,开源pg编译安装

首先下载postgres源码,然后切换成最新的pg15稳定分支,后续源码分析基于pg15。

git clone git@github.com:postgres/postgres.git
git checkout REL_15_STABLE

编译配置,安装可debug版本的pg,安装到/home/pg15/inst目录。

cd postgres
./configure  --enable-debug  --enable-cassert --prefix=/home/pg15/inst CFLAGS=-O0
make -j all
make install

2,初始化数据目录

配置pg的bin执行文件的环境变量。

vim .bash_profile

PATH=/home/pg15/inst/bin:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/pg15/inst/lib
export PATH

source .bash_profile

开始初始化数据目录,data目录安装在/home/pg15/data

initdb -D /home/pg15/data

3,调试数据库

启动数据库后,ps查看相关进程。pg是多进程结构,主进程负责监听新到来的连接,为其创建backend服务进程,每个backend进程对应一个连接。checkpointer进程负责执行checkpoint,具体过程为刷脏页,刷wal日志,然后创建检查点,以供回收xlog日志文件。walwriter进程负责后台异步的刷wal日志。autovacuum launcher进程负责启动autovacuum进程,logical replication launcher进程负责启动逻辑复制进程。

pg15     12420  0.0  0.0 277884 13424 ?        Ss   19:54   0:00 /home/pg15/inst/bin/postgres -D data
pg15     12421  0.0  0.0 278032  1084 ?        Ss   19:54   0:00  \_ postgres: checkpointer 
pg15     12422  0.0  0.0 278016  1084 ?        Ss   19:54   0:00  \_ postgres: background writer 
pg15     12424  0.0  0.0 278016  1080 ?        Ss   19:54   0:00  \_ postgres: walwriter 
pg15     12425  0.0  0.0 279500  2108 ?        Ss   19:54   0:00  \_ postgres: autovacuum launcher 
pg15     12426  0.0  0.0 279484  1856 ?        Ss   19:54   0:00  \_ postgres: logical replication launcher

下面调试一下psql连接数据库的时候主进程fork出backend进程的流程(多进程调试)。

1.gdb住主进程

gdb挂住12420,然后让放行相关的信号,不调试信号处理函数

gdb -p 12420

handle SIGUSR1 nostop
handle SIGUSR2 nostop
handle SIGTRAP nostop
handle SIGUSR1 noprint
handle SIGUSR2 noprint
handle SIGTRAP noprint

2.另起一个backend连接数据库

psql postgres连接数据库

3.gdb主进程

首先,主进程执行select函数会返回一个1,表示有一个连接到来,然后会执行到fork_process,开始fork一个子进程出来。

#0  fork_process () at fork_process.c:45
#1  0x00000000008c5563 in BackendStartup (port=0x19b20a0) at postmaster.c:4215
#2  0x00000000008c1bae in ServerLoop () at postmaster.c:1806
#3  0x00000000008c1485 in PostmasterMain (argc=3, argv=0x198ad00) at postmaster.c:1478
#4  0x00000000007c69ae in main (argc=3, argv=0x198ad00) at main.c:202

然后要调试子进程,需要执行set follow-fork-mode child,表示跟着子进程调试,默认是父进程。当pid返回0的时候,就表示当前是子进程,为有效的话,就是父进程。

 至此,backend进程就等待psql客户端发起sql再处理。

(gdb) bt
#0  ReadCommand (inBuf=0x7ffc231ca310) at postgres.c:473
#1  0x0000000000987f9d in PostgresMain (dbname=0x13f47d8 "postgres", username=0x13f47b8 "pg15") at postgres.c:4525
#2  0x00000000008c5c04 in BackendRun (port=0x13ec0a0) at postmaster.c:4511
#3  0x00000000008c55a4 in BackendStartup (port=0x13ec0a0) at postmaster.c:4239
#4  0x00000000008c1bae in ServerLoop () at postmaster.c:1806
#5  0x00000000008c1485 in PostmasterMain (argc=3, argv=0x13c4d00) at postmaster.c:1478
#6  0x00000000007c69ae in main (argc=3, argv=0x13c4d00) at main.c:202

4.gdb用法总结

n:下一行

c:继续执行,直到下一个断点

b:打断点,可函数,行,条件断点(b breakpoint if XX==XX)

watch:值发生变化,就断点

info b:查看断点

d 1:删除第一个断点

set/p:设置值,p有返回再打印,set无打印

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值