内置stack工具

    特性简介

    stack工具是获取数据库中各线程的调用栈的工具,用于辅助数据库运维人员定位死锁、hang等问题。

    提供函数级别的调用栈信息,提升数据库内核运维人员分析、定位死锁、hang等问题的效率。

    特性描述

    可以通过函数gs_stack()或者工具gs_ctl stack两种方式获取数据库中线程的调用栈。

    1. gs_stack()函数方式

      • select * from gs_stack(pid)获取指定线程调用栈。

        1. -[ RECORD 1 ]-------------------------------------------------------------------------------------------------------
        2. tid | 139670364324352
        3. lwtid | 308
        4. stack | __poll + 0x2d
        5. | CommWaitPollParam::caller(int (*)(pollfd*, unsigned long, int), unsigned long) + 0x34
        6. | int comm_socket_call<CommWaitPollParam, int (*)(pollfd*, unsigned long, int)>(CommWaitPollParam*, int (*)(pollfd*, unsigned long
        7. , int)) + 0x28
        8. | comm_poll(pollfd*, unsigned long, int) + 0xb1
        9. | ServerLoop() + 0x72b
        10. | PostmasterMain(int, char**) + 0x314e
        11. | main + 0x617
        12. | __libc_start_main + 0xf5
        13. | 0x55d38f8db3a7
        14. [ RECORD 2 ]-------------------------------------------------------------------------------------------------------
        15. tid | 139664851859200
        16. lwtid | 520
        17. stack | __poll + 0x2d
        18. | WaitLatchOrSocket(Latch volatile*, int, int, long) + 0x29f
        19. | SysLoggerMain(int) + 0xc86
        20. | InternalThreadFunc(void*) + 0x2d
        21. | start_thread + 0xc5
        22. | clone + 0x6d
    2. gs_ctl stack方式获取调用栈

      • 执行以下命令获取指定线程的调用栈。

        1. gs_ctl stack -D data_dir -I lwtid

        上述命令中-D data_dir用于指定需要获取调用栈的gaussdb进程的数据目录,-I lwtid用于指定目标线程的lwtid,lwpid可以ls /proc/pid/task/获取。具体步骤如下所示。

        1. 获取gaussdb进程号和数据目录。

        2. 通过进程号获取lwtid,task目录下的目录名就是lwtid。

          1. ls /proc/308/task/
          2. 1096 505 522 525 529 532 536 539 542 546 549 552 555 558 561 565 569 575 584 833 923 926 929 932 935 938
          1. gs_ctl stack -D /xxx/openGauss/cluster/data1/dn1 -I 1096
          2. [2022-05-21 10:52:51.354][24520][][gs_ctl]: gs_stack start:
          3. tid<140409677575616> lwtid<1096>
          4. __poll + 0x2d
          5. CommWaitPollParam::caller(int (*)(pollfd*, unsigned long, int), unsigned long) + 0x34
          6. int comm_socket_call<CommWaitPollParam, int (*)(pollfd*, unsigned long, int)>(CommWaitPollParam*, int (*)(pollfd*, unsigned long, int)) + 0x28
          7. comm_poll(pollfd*, unsigned long, int) + 0xb1
          8. ServerLoop() + 0x72b
          9. PostmasterMain(int, char**) + 0x329a
          10. main + 0x617
          11. __libc_start_main + 0xf5
          12. 0x55cf616e7647
          13. [2022-05-21 10:52:51.354][24520][][gs_ctl]: gs_stack finished!
      • 执行以下命令获取所有线程的调用栈。

        上述命令中,-D data_dir用于指定需要获取调用栈的gaussdb进程的数据目录。具体步骤如下所示。

        1. 获取gaussdb进程号和数据目录。

          1. ps -ux | more
          2. USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
          3. perfadm 308 9.3 10.1 8719348 1649108 ? Sl May20 58:58 /xxx/bin/gaussdb -u 92617 -D /xxx/openGauss/cluster/data1/dn1 -M pending

    特性约束

    1. 仅用于gaussdb进程,其他进程,如cms、gtm等不支持。
    2. 如果使用SQL的方式执行,则需要CN、DN进程处于正常状态,可连接和执行SQL。
    3. 如果使用gs_ctl的方式执行,则需要CN、DN进程处于可响应信号的状态。
    4. 不支持并发,在获取全线程栈的场景,各个线程的调用栈不处于同一时间点。
    5. 最多支持128层调用栈,如果实际情况超过128层,则仅保留栈顶的128层。
    6. 符号表没有被trip(当前release版本,使用的是strip –d,仅去掉了debug信息,符号表没有被trip,如果改为strip –s,则仅能显示指针,无法显示出符号名)。
    7. SQL执行方式仅支持monadmin、sysadmin用户。
    8. 注册了SIGURG信号的线程,才能获取调用栈。

    无。