DBE_PLDEBUGGER Schema

DBE_PLDEBUGGER下系统函数用于单机下调试存储过程,目前支持的接口及其描述如下所示。仅管理员有权限执行这些调试接口,且无权限修改和创建新函数。

DBE_PLDEBUGGER Schema - 图1 须知:

当在函数体中创建用户时,调用attach、next、continue、 info_code、step、info_breakpoint、backtrace、 finish中会返回密码的明文。因此不建议用户在函数体中创建用户。

对应权限角色为gs_role_pldebugger,可以由管理员用户通过如下命令将debugger权限赋权给该用户。

1. GRANT gs_role_pldebugger to user;

需要有两个客户端连接数据库,一个客户端负责执行调试接口作为debug端,另一个客户端执行调试函数,控制server端存储过程执行。示例如下。

  • 准备调试

通过PG_PROC,查找到待调试存储过程的oid,并执行DBE_PLDEBUGGER.turn_on(oid)。本客户端就会作为server端使用。

1. openGauss=# CREATE OR REPLACE PROCEDURE test_debug ( IN x INT) 2. AS 3. BEGIN 4. INSERT INTO t1 (a) VALUES (x); 5. DELETE FROM t1 WHERE a = x; 6. END; 7. / 8. CREATE PROCEDURE 9. openGauss=# SELECT OID FROM PG_PROC WHERE PRONAME='test_debug'; 10. oid 11. ------- 12. 16389 13. (1 row) 14. openGauss=# SELECT * FROM DBE_PLDEBUGGER.turn_on(16389); 15. nodename | port 16. ----------+------ 17. datanode | 0 18. (1 row) - 开始调试

server端执行存储过程,会在存储过程内第一条SQL语句前hang住,等待debug端发送的调试消息。仅支持直接执行存储过程的调试,不支持通过trigger调用执行的存储过程调试。

1. openGauss=# call test_debug(1);

再起一个客户端,作为debug端,通过turn_on返回的数据,调用DBE_PLDEBUGGER.attach关联到该存储过程上进行调试。

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.attach('datanode',0); 2. funcoid | funcname | lineno | query 3. ---------+------------+--------+---------------------------------- 4. 16389 | test_debug | 3 | INSERT INTO t1 (a) VALUES (x); 5. (1 row)

在执行attach的客户端调试,执行下一条statement。

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.next(); 2. funcoid | funcname | lineno | query 3. ---------+------------+--------+---------------------- 4. 16389 | test_debug | 0 | [EXECUTION FINISHED] 5. (1 row)

在执行attach的客户端调试,可以执行以下变量操作

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.info_locals(); --打印全部变量 2. varname | vartype | value | package_name | isconst 3. ---------+---------+-------+--------------+--------- 4. x | int4 | 1 | | f 5. (1 row) 6. openGauss=# SELECT * FROM DBE_PLDEBUGGER.set_var('x', 2); --变量赋值 7. set_var 8. --------- 9. t 10. (1 row) 11. openGauss=# SELECT * FROM DBE_PLDEBUGGER.print_var('x'); --打印单个变量 12. varname | vartype | value | package_name | isconst 13. ---------+---------+-------+--------------+--------- 14. x | int4 | 2 | | f 15. (1 row)

直接执行完成当前正在调试的存储过程。

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.continue(); 2. funcoid | funcname | lineno | query 3. ---------+------------+--------+---------------------- 4. 16389 | test_debug | 0 | [EXECUTION FINISHED] 5. (1 row)

直接退出当前正在调试的存储过程,不执行尚未执行的语句。

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.abort(); 2. abort 3. ------- 4. t 5. (1 row)

client端查看代码信息并识别可以设置断点行号。

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.info_code(16389); 2. lineno | query | canbreak 3. --------+-----------------------------------------------------------+---------- 4. | CREATE OR REPLACE PROCEDURE public.test_debug( IN x INT) | f 5. 1 | AS DECLARE | f 6. 2 | BEGIN | f 7. 3 | INSERT INTO t1 (a) VALUES (x); | t 8. 4 | DELETE FROM t1 WHERE a = x; | t 9. 5 | END; | f 10. 6 | / | f 11. (7 rows)

设置断点。

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.add_breakpoint(16389,4); 2. lineno | query | canbreak 3. --------+-----------------------------------------------------------+---------- 4. | CREATE OR REPLACE PROCEDURE public.test_debug( IN x INT) | f 5. 1 | AS DECLARE | f 6. 2 | BEGIN | f 7. 3 | INSERT INTO t1 (a) VALUES (x); | t 8. 4 | DELETE FROM t1 WHERE a = x; | t 9. 5 | END; | f 10. 6 | / | f 11. (7 rows)

查看断点信息。

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.info_breakpoints(); 2. breakpointno | funcoid | lineno | query | enable 3. --------------+---------+--------+---------------------------------+-------- 4. 0 | 16389 | 4 | DELETE FROM t1 WHERE a = x; | t 5. (1 row)

执行至断点。

1. openGauss=# SELECT * FROM DBE_PLDEBUGGER.continue(); 2. funcoid | funcname | lineno | query 3. ---------+------------+--------+--------------------------------- 4. 16389 | test_debug | 4 | DELETE FROM t1 WHERE a = x; 5. (1 row)

存储过程执行结束后,调试会自动退出,再进行调试需要重新attach关联。如果server端不需要继续调试,可执行turn_off关闭,或退出session。具体调试接口请见下面列表。

表 1 DBE_PLDEBUGGER

接口名称 描述
DBE_PLDEBUGGER.turn_on server端调用,标记存储过程可以调试,调用后执行该存储过程时会hang住等待调试信息。
DBE_PLDEBUGGER.turn_off server端调用,标记存储过程关闭调试。
DBE_PLDEBUGGER.local_debug_server_info server端调用,打印本session内所有已turn_on的存储过程。
DBE_PLDEBUGGER.attach debug端调用,关联到正在调试存储过程。
DBE_PLDEBUGGER.info_locals debug端调用,打印正在调试的存储过程中的变量当前值。
DBE_PLDEBUGGER.next debug端调用,单步执行。
DBE_PLDEBUGGER.continue debug端调用,继续执行,直到断点或存储过程结束。
DBE_PLDEBUGGER.abort debug端调用,停止调试,server端报错长跳转。
DBE_PLDEBUGGER.print_var debug端调用,打印正在调试的存储过程中指定的变量当前值。
DBE_PLDEBUGGER.info_code debug和server端都可以调用,打印指定存储过程的源语句和各行对应的行号。
DBE_PLDEBUGGER.step debug端调用,单步进入执行。
DBE_PLDEBUGGER.add_breakpoint debug端调用,新增断点。
DBE_PLDEBUGGER.delete_breakpoint debug端调用,删除断点。
DBE_PLDEBUGGER.info_breakpoints debug端调用,查看当前的所有断点。
DBE_PLDEBUGGER.backtrace debug端调用,查看当前的调用栈。
DBE_PLDEBUGGER.enable_breakpoint debug端调用,激活被禁用的断点。
DBE_PLDEBUGGER.disable_breakpoint debug端调用,禁用已激活的断点。
DBE_PLDEBUGGER.finish debug端调用,继续调试,直到断点或返回上一层调用栈。
DBE_PLDEBUGGER.set_var debug端调用,为变量进行赋值操作。
- DBE_PLDEBUGGER.turn_on
- DBE_PLDEBUGGER.turn_off
- DBE_PLDEBUGGER.local_debug_server_info
- DBE_PLDEBUGGER.attach
- DBE_PLDEBUGGER.info_locals
- DBE_PLDEBUGGER.next
- DBE_PLDEBUGGER.continue
- DBE_PLDEBUGGER.abort
- DBE_PLDEBUGGER.print_var
- DBE_PLDEBUGGER.info_code
- DBE_PLDEBUGGER.step
- DBE_PLDEBUGGER.add_breakpoint
- DBE_PLDEBUGGER.delete_breakpoint
- DBE_PLDEBUGGER.info_breakpoints
- DBE_PLDEBUGGER.backtrace
- DBE_PLDEBUGGER.enable_breakpoint
- DBE_PLDEBUGGER.disable_breakpoint
- DBE_PLDEBUGGER.finish
- DBE_PLDEBUGGER.set_var