美文网首页PostgreSQL
DEBUG跟踪PG进程的两种形式

DEBUG跟踪PG进程的两种形式

作者: 长江十三寨总瓢把子 | 来源:发表于2021-02-24 15:43 被阅读0次

背景

近日有小伙伴遇到了一个生产问题,pg_rewind命令会偶发的出现这个错误消息

... // rewind 过程信息

The program "initdb" was found by "xxx/bin/pg_rewind"
but was not the same version as pg_rewind.
Check your installation.
Failure,exiting

各种环境检查、验证搞了一通之后没什么头绪,找我帮忙,我看了看代码,感觉是个bug,那就只能debug试试了。

网上逛了一圈发现,大部分教人跟踪PG源码的帖子,都是gdb attach进程的方式,并不适合这个场景,pg_rewind是个命令,一气呵成,中途不会有机会让你停下来去attach一把的。

研究了下gdb的help信息,发现--args选项可行。
问题调查完,确实是个bug,但并不是社区版PG的bug,是我们定制版PG的bug。原因不重要,但这个调查方法我觉得可以总结一下。

跟踪PG进程的两条路

场景一、跟踪SQL进程

SQL的执行是在建立连接之后,因此,可以在建立连接之后,执行SQL之前,通过gdb的方式attach进程,附加断点,然后debug跟踪,举个栗子,开2个窗口,一边执行SQL,一边debug

  • 窗口一:建连接,取pid
[guqi@localhost ~]$ psql -p 51005
psql (xxxx based on PG 11.6)
Type "help" for help.

postgres=# select pg_backend_pid();
 pg_backend_pid
----------------
          52069
(1 row)
  • 窗口二:gdb attch pid
-- 格式:gdb postgres命令的路径 pid
[root@localhost ~]# gdb /data/postgres/app/bin/postgres 52069
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-119.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
... 
0x00007fe6060bef23 in __epoll_wait_nocancel () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-317.el7.x86_64
(gdb)

场景二、跟踪PG命令

PG安装路径的bin目录内有很多封装好的二进制命令,这些不像SQL需要单独建连接执行,因此跟踪这些命令的执行,也不能像场景一那样可以事先打好断点。

strace跟踪

strace可以跟踪命令执行过程中的系统调用,并且-tt选项可以打印调用的时间点,举个栗子:

[guqi@localhost ~]$ strace -tt createdb -h 127.1 -p 51005
14:59:41.171926 execve("/data/guqi/postgres/app/bin/createdb", ["createdb", "-h", "127.1", "-p", "51005"], 0x7ffc4ad5d878 /* 31 vars */) = 0
14:59:41.172721 brk(NULL)               = 0xa55000
14:59:41.172861 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc1f4f1f000
14:59:41.172982 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
14:59:41.173238 open("/data/guqi/postgres/app/lib/tls/x86_64/libpq.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
...
14:59:41.207330 sendto(3, "X\0\0\0\4", 5, MSG_NOSIGNAL, NULL, 0) = 5
14:59:41.207446 close(3)                = 0
14:59:41.207641 exit_group(1)           = ?
14:59:41.208050 +++ exited with 1 +++
[guqi@localhost ~]$

gdb跟踪

gdb可以直接执行一个二进制命令

gdb [options] [executable-file [core-file or process-id]]

但是默认情况下,这个executable-file不能带参数,否则会报错。gdb提供了一个--args选项,可以传递参数。进入gdb交互之后,start开始运行命令,gdb会在主函数的入口处自动打个断点(挺人性的),之后就和场景一一样了。

[guqi@localhost ~]$ gdb --args /data/guqi/postgres/bin/pg_rewind -D /data/guqi/data/master --source-server="host=127.0.0.1 port=51101 user=guqi"
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-119.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
...
Reading symbols from /data/guqi/postgres/app/bin/pg_rewind...done.
(gdb) b 433
Breakpoint 1 at 0x40294e: file /data/guqi/src/build_alone/../xxx/src/bin/pg_rewind/pg_rewind.c, line 433.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040294e in main
                                                   at /data/guqi/src/build_alone/../xxx/src/bin/pg_rewind/pg_rewind.c:433
(gdb)start
Temporary breakpoint 2 at 0x4021a3: file /data/guqi/src/build_alone/../xxx/src/bin/pg_rewind/pg_rewind.c, line 125.
Starting program: /data/guqi/postgres/app/bin/pg_rewind -D /data/guqi/data/master --source-server=host=127.0.0.1\ port=51101\ user=guqi
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib64/libthread_db.so.1".

Temporary breakpoint 2, main (argc=4, argv=0x7fffffffe388)
    at /data/guqi/src/build_alone/../xxx/src/bin/pg_rewind/pg_rewind.c:125
125             set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_rewind"));
(gdb) c
Continuing.

场景二的两个方式,可以结合使用。

GDB常用的调试命令

  1. 在指定的文件,指定行,打断点
b postgres.c:line_num
  1. 查看/删除断点
info b
delete 1-5(断点序号)
  1. 执行
c:执行程序,直到断点或者结束为止
n:单步执行
s:单步执行,遇到函数调用,会进入函数内部
  1. 打印程序内的变量
-- 这个比较多变
-- 变量的形式支持类型强转,指针引用,内存地址等等,很强大
p var
  1. 主动调用函数
call func_name(pam_1,pam_2)
  1. 跳越到程序指定行去执行,类似goto语法
-- 跳跃过去之后,程序会直接开始执行,相当于从第xx行开始敲了个continue命令
jump line_num

相关文章

  • DEBUG跟踪PG进程的两种形式

    背景 近日有小伙伴遇到了一个生产问题,pg_rewind命令会偶发的出现这个错误消息 各种环境检查、验证搞了一通之...

  • Oracle SQL 学习笔记33 - 跟踪SQL运行信息

    应用跟踪概览 End-to-End 应用跟踪有两种形式:Enterprise Manager和DBMS_MONIT...

  • PostgreSQL体系架构

    PG的几个主要进程,以及PG的核心架构。进程和体系结构详见下图: 从上面的体系结构图可以看出来,PG使用经典的C/...

  • debug_backtrace

    debug_backtrace — 产生一条回溯跟踪(backtrace) debug_backtrace ([ ...

  • 第四十三章 使用^TRACE跟踪进程性能

    第四十三章 使用^TRACE跟踪进程性能 ^TRACE 实用程序提供了跟踪IRIS 进程执行的功能。被跟踪的进程将...

  • 从底层源码浅析Mybatis的SqlSessionFactory

    快速进入Debug跟踪 我们可以在此处打上断点,Debug模式启动进入断点,再按F7跟踪入其方法 源码分析准备 在...

  • PostgreSQL体系结构

    概览 PG是一个典型的c/s模型 体系结构=实例+存储结构实例=进程+内存结构 实例结构 PG是多进程的,类似or...

  • 开发调试工具

    1、跟踪工具ltrace 跟踪进程调用库函数的情况strace 跟踪进程的系统调用情况和信号产生情况 ...

  • Linux内核ftrace原理

    gcc的-pg选项 ftrace 支持动态trace,即可以跟踪内核和模块中任意的全局函数。它利用了gcc的-pg...

  • 跟踪进程

    strace -o output.txt -T -tt -e trace=all -p 1623

网友评论

    本文标题:DEBUG跟踪PG进程的两种形式

    本文链接:https://www.haomeiwen.com/subject/mdrsfltx.html