2

我正在研究一组 PL/Python 存储过程。我正在使用 PostgreSQL 9.3(从 apt.postgresql.org 安装)和 Python 2.7 解释器;在 Ubuntu 13.04 上运行。

该错误发生在大型操作的中间(创建一个物化视图,该视图使用来自具有 > 300,000 行的源表的数据并使用 PL/Python 存储过程计算一些字段)。

我得到的错误输出是:

ERROR:  could not convert SPI error to Python exception
CONTEXT:  PL/Python function "get_first_level_parent"
********** Error **********

ERROR: could not convert SPI error to Python exception
SQL state: XX000
Context: PL/Python function "get_first_level_parent"

(“get_first_level_parent”是其中一个存储过程的名称)。

PostgreSQL 服务器日志不提供任何进一步的说明(我不熟悉 PostgreSQL 和 PL/Python 内部结构)。使用详细错误日志记录运行时,我得到以下信息:

2013-10-18 12:56:43 EAT ERROR:  XX000: could not convert SPI error to Python exception
2013-10-18 12:56:43 EAT CONTEXT:  PL/Python function "get_first_level_parent"
2013-10-18 12:56:43 EAT LOCATION:  PLy_spi_exception_set, plpy_spi.c:576

PostgreSQL 错误代码文档告诉我这XX000internal_error. 如果我隔离对存储过程的调用并在它自己的语句中运行它,例如SELECT get_first_level_parent(373673007),它不会引发错误。

我的问题是 - 我可以使用哪些工具/技术来调试此类错误?对于我当前的问题,我很可能通过重写存储过程来“解决”问题(慢慢地,一次测试一小部分)。这是唯一的出路吗?

4

2 回答 2

2

我会在src/pl/plpython/plpy_spi.c:PLy_spi_exception_set(). 这可能是 PL/Python 在处理某些边缘条件时的错误。

于 2013-10-18T14:28:21.853 回答
1

在存储过程中大量使用plpy.notice(...语句后,我最终隔离了一个能够可靠地重现错误的 SQL 存储过程调用。

这里的罪魁祸首是我编写的一个 PL/Python 程序中的一个边缘案例。我在其中一个存储过程中有一个递归算法。递归的使用是由问题域决定的。在所有正常操作条件下,递归不会超过 10-12 深度(输入数据是众所周知的并且相对静态)。我的实现中存在一个错误,在某些情况下会导致无限递归。

PL/Python 似乎没有设置为处理RuntimeError超过最大递归深度时发生的情况。这可能是一个非常罕见的边缘情况。

于 2013-10-19T07:58:00.093 回答