# DBE_PLDEBUGGER Schema
DBE_PLDEBUGGER Schema下的系统函数用于调试存储过程，仅管理员有权限执行这些调试接口，但无修改和创建新函数的权限。目前支持的接口及其描述如下所示。
![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
- 当在函数体中创建用户时，调用attach、next、continue、info_code、step、info_breakpoint、backtrace、finish中会返回密码的明文。因此不建议用户在函数体中创建用户。
- 仅支持在CN节点上调试存储过程，并且调试端和被调试端需连接在同一CN节点。
- 调试端和被调试端需连接在同一database，否则使用函数oid获取函数信息的接口将不可用。
- 用户在当前会话使用dbe_pldebugger.turn_on函数开启存储过程调试后，当前会话的所有PL/SQL类型存储过程将不能下推至DN节点。因此，请在调试结束后，及时使用dbe_pldebugger.turn_off函数关闭当前会话的存储过程。
- 不支持直接调试触发器，不支持EXECUTE DIRECT ON将语句下发至DN节点触发调试。
- 在使用dbe_pldebugger.turn_on函数开启存储过程调试前生成的预编译语句可能无法被调试。
- dbe_pldebugger.error_\*类型函数，只能在报错断住时才能使用。
- 当存储过程调试时，如果被调试的存储过程中涉及加锁的操作，请注意在调试端勿执行可能导致死锁的操作。
- 三权分立开启时，仅允许初始用户和属主可以调试定义者权限的函数；三权分立关闭时，允许系统管理员、属主、初始用户调试定义者权限的函数。
 
对应权限角色为gs_role_pldebugger，可以由管理员用户通过如下命令将debugger权限赋权给该用户。
```
GRANT gs_role_pldebugger to user;
```
需要有两个客户端连接数据库，一个客户端负责执行调试接口作为debug端，另一个客户端执行调试函数，控制server端存储过程执行。示例如下：
- 准备调试 通过PG_PROC，查找到待调试存储过程的oid，并执行DBE_PLDEBUGGER.turn_on(oid)。本客户端会作为server端使用。
  ```
  gaussdb=# CREATE OR REPLACE PROCEDURE test_debug ( IN  x INT) 
  AS  
  BEGIN
      INSERT INTO t1 (a) VALUES (x);
      DELETE FROM t1 WHERE a = x;
  END;
  /
  CREATE PROCEDURE
  gaussdb=# SELECT OID FROM PG_PROC WHERE PRONAME='test_debug';
    oid
  -------
   16389
  (1 row)
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.turn_on(16389);
   nodename | port
  ----------+------
   datanode |    0
  (1 row)
  ```
  

- 开始调试 server端执行存储过程，会在存储过程内第一条SQL语句前hang住，等待debug端发送的调试消息。仅支持直接执行存储过程的调试，不支持通过trigger调用执行的存储过程调试。
  ```
  gaussdb=# call test_debug(1);
  ```
  再起一个客户端，作为debug端，通过turn_on返回的数据，调用DBE_PLDEBUGGER.attach关联到该存储过程上进行调试。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.attach('datanode',0);
   funcoid |  funcname  | lineno |              query
  ---------+------------+--------+----------------------------------
     16389 | test_debug |      3 |   INSERT INTO t1 (a) VALUES (x);
  (1 row)
  ```
  在执行attach的客户端调试，执行下一条statement。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.next();
   funcoid |  funcname  | lineno |        query
  ---------+------------+--------+----------------------
     16389 | test_debug |      0 | [EXECUTION FINISHED]
  (1 row)
  ```
  在执行attach的客户端调试，可以执行以下变量操作。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.info_locals(); --打印全部变量
   varname | vartype | value | package_name | isconst
  ---------+---------+-------+--------------+---------
   x       | int4    | 1     |              | f
  (1 row)
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.set_var('x', 2); --变量赋值
   set_var
  ---------
   t
  (1 row)
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.print_var('x'); --打印单个变量
   varname | vartype | value | package_name | isconst
  ---------+---------+-------+--------------+---------
   x       | int4    | 2     |              | f
  (1 row)
  ```
  直接执行完成当前正在调试的存储过程。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.continue();
   funcoid |  funcname  | lineno |        query
  ---------+------------+--------+----------------------
     16389 | test_debug |      0 | [EXECUTION FINISHED]
  (1 row)
  ```
  当存储过程报错时，会出现以下提示，此时进入报错断住逻辑。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.continue();
   funcoid |  funcname  | lineno |            query
  ---------+------------+--------+-------------------------------
     16389 | test_debug |      0 | [EXECUTION HAS ERROR OCCURRED!]
  (1 row)
  ```
  此时进入报错断住逻辑，可以调用error_info_locals,error_backtrace,error_end,print_var接口查看信息，其他接口不能再使用，需要使用error_end结束当前报错断住。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.error_end();
   funcoid |  funcname  | lineno |      query
  ---------+------------+--------+------------------
     16389 | test_debug |      0 | [END HANG ERROR!]
  (1 row)
  ```
  直接退出当前正在调试的存储过程(报错断住逻辑不可用)，不执行尚未执行的语句。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.abort();
   abort
  -------
   t
  (1 row)
  ```
  client端查看代码信息并识别可以设置断点行号。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.info_code(16389);
   lineno |                           query                           | canbreak
  --------+-----------------------------------------------------------+----------
          | CREATE OR REPLACE PROCEDURE public.test_debug( IN  x INT) | f
        1 | AS  DECLARE                                               | f
        2 | BEGIN                                                     | f
        3 |     INSERT INTO t1 (a) VALUES (x);                        | t
        4 |     DELETE FROM t1 WHERE a = x;                           | t
        5 | END;                                                      | f
        6 | /                                                         | f
  (7 rows)
  ```
  设置断点。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.add_breakpoint(16389,4);
   breakpointno 
  --------------
              0
  (1 row)
  ```
  查看断点信息。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.info_breakpoints();
   breakpointno | funcoid | lineno |              query              | enable
  --------------+---------+--------+---------------------------------+--------
              0 |   16389 |      4 |     DELETE FROM t1 WHERE a = x; | t
  (1 row)
  ```
  执行至断点。
  ```
  gaussdb=# SELECT * FROM DBE_PLDEBUGGER.continue();
   funcoid |  funcname  | lineno |              query
  ---------+------------+--------+---------------------------------
     16389 | test_debug |      4 |     DELETE FROM t1 WHERE a = x;
  (1 row)
  ```
  存储过程执行结束后，调试会自动退出，再进行调试需要重新attach关联。如果server端不需要继续调试，可执行turn_off关闭，或退出session。具体调试接口如[表1]所示。
   表1DBE_PLDEBUGGER 
  | 接口名称                                                                                                                    | 描述                                          |
  |:---|:---|
  | [DBE_PLDEBUGGER.turn_on](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1674.html)              | server端调用，标记存储过程可以调试，调用后执行该存储过程时会hang住等待调试信息。 |
  | [DBE_PLDEBUGGER.turn_off](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1675.html)              | server端调用，标记存储过程关闭调试。                        |
  | [DBE_PLDEBUGGER.local_debug_server_info](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1676.html) | server端调用，打印本session内所有已turn_on的存储过程。         |
  | [DBE_PLDEBUGGER.attach](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1677.html)                 | debug端调用，关联到正在调试存储过程。                       |
  | [DBE_PLDEBUGGER.info_locals](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1678.html)             | debug端调用，打印正在调试的存储过程中的变量当前值。                   |
  | [DBE_PLDEBUGGER.next](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1679.html)                  | debug端调用，单步执行。                                |
  | [DBE_PLDEBUGGER.continue](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1680.html)               | debug端调用，继续执行，直到断点或存储过程结束。                    |
  | [DBE_PLDEBUGGER.abort](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1681.html)                | debug端调用，停止调试，server端报错长跳转。                   |
  | [DBE_PLDEBUGGER.print_var](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1682.html)                | debug端调用，打印正在调试的存储过程中指定的变量当前值。                 |
  | [DBE_PLDEBUGGER.info_code](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1683.html)              | debug和server端都可以调用，打印指定存储过程的源语句和各行对应的行号。      |
  | [DBE_PLDEBUGGER.step](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1684.html)                  | debug端调用，单步进入执行。                              |
  | [DBE_PLDEBUGGER.add_breakpoint](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1685.html)          | debug端调用，新增断点。                              |
  | [DBE_PLDEBUGGER.delete_breakpoint](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1686.html)      | debug端调用，删除断点。                                 |
  | [DBE_PLDEBUGGER.info_breakpoints](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1687.html)         | debug端调用，查看当前的所有断点。                            |
  | [DBE_PLDEBUGGER.backtrace](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1688.html)             | debug端调用，查看当前的调用栈。                           |
  | [DBE_PLDEBUGGER.enable_breakpoint](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1689.html)       | debug端调用，激活被禁用的断点。                            |
  | [DBE_PLDEBUGGER.disable_breakpoint](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1690.html)      | debug端调用，禁用已激活的断点。                           |
  | [DBE_PLDEBUGGER.finish](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1691.html)                | debug端调用，继续调试，直到断点或返回上一层调用栈。                  |
  | [DBE_PLDEBUGGER.set_var](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1692.html)                | debug端调用，为变量进行赋值操作。                          |
     
  
 
- **[DBE_PLDEBUGGER.turn_on](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1674.html)**   
- **[DBE_PLDEBUGGER.turn_off](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1675.html)**   
- **[DBE_PLDEBUGGER.local_debug_server_info](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1676.html)**   
- **[DBE_PLDEBUGGER.attach](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1677.html)**   
- **[DBE_PLDEBUGGER.info_locals](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1678.html)**   
- **[DBE_PLDEBUGGER.next](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1679.html)**   
- **[DBE_PLDEBUGGER.continue](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1680.html)**   
- **[DBE_PLDEBUGGER.abort](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1681.html)**   
- **[DBE_PLDEBUGGER.print_var](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1682.html)**   
- **[DBE_PLDEBUGGER.info_code](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1683.html)**   
- **[DBE_PLDEBUGGER.step](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1684.html)**   
- **[DBE_PLDEBUGGER.add_breakpoint](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1685.html)**   
- **[DBE_PLDEBUGGER.delete_breakpoint](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1686.html)**   
- **[DBE_PLDEBUGGER.info_breakpoints](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1687.html)**   
- **[DBE_PLDEBUGGER.backtrace](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1688.html)**   
- **[DBE_PLDEBUGGER.enable_breakpoint](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1689.html)**   
- **[DBE_PLDEBUGGER.disable_breakpoint](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1690.html)**   
- **[DBE_PLDEBUGGER.finish](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1691.html)**   
- **[DBE_PLDEBUGGER.set_var](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1692.html)**   
- **[DBE_PLDEBUGGER.error_backtrace](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1693.html)**   
- **[DBE_PLDEBUGGER.error_end](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1694.html)**   
- **[DBE_PLDEBUGGER.error_info_locals](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-1695.html)**   
