oracle ORA-28579: 从外部过程代理回调期间出现网络错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/429777/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 17:39:47  来源:igfitidea点击:

ORA-28579: network error during callback from external procedure agent

oracleoracle10gexternal-process

提问by Ryan Ahearn

Has anyone seen this error when trying to call an external C function from an Oracle query? I'm using Oracle 10g and get this error every time I try to call one of the two functions in the library. A call to the other function returns fine every time, though the function that works is all self-contained, no calls to any OCI* functions.

有没有人在尝试从 Oracle 查询中调用外部 C 函数时看到此错误?我正在使用 Oracle 10g,每次尝试调用库中的两个函数之一时都会收到此错误。对另一个函数的调用每次都能正常返回,尽管运行的函数都是自包含的,没有调用任何 OCI* 函数。

Here's the stored procedure that is used to call the failing C code:

这是用于调用失败的 C 代码的存储过程:

CREATE OR REPLACE PROCEDURE index_procedure(text in clob, tokens in out nocopy clob, location_needed in boolean)
as language c
name "c_index_proc"
library lexer_lib
with context
parameters
(
  context,
  text,
  tokens,
  location_needed
);

Any help would be appreciated. Everything I've found on this error message says that the action to take is: Contact Oracle customer support.

任何帮助,将不胜感激。我在此错误消息中发现的所有内容都表明要采取的措施是:联系 Oracle 客户支持。

Edit: I've narrowed it down to the point that I know that there is a segfault deep in libclntsh after I call OCILobTrim (to truncate it down to 0 length) on the tokens clob. Here is the code I've been using to call this procedure.

编辑:我已经将范围缩小到我知道在我在令牌 clob 上调用 OCILobTrim(将其截断为 0 长度)后,libclntsh 中存在深度段错误的程度。这是我用来调用这个过程的代码。

declare text CLOB; tokens CLOB;
begin
dbms_lob.createtemporary(tokens, TRUE);
dbms_lob.append(tokens, 'token');
dbms_lob.createtemporary(text, TRUE);
dbms_lob.append(text, '<BODY>Test Document</BODY>');
index_procedure(text, tokens, FALSE);
dbms_output.put_line(tokens);
end;
/

Is there something wrong with this setup that might be causing OCILobTrim problems?

此设置是否有问题可能导致 OCILobTrim 问题?

回答by Dave Costa

It looks like this is one of those errors that essentially means any number of things could have gone wrong with the external procedure.

看起来这是那些错误之一,基本上意味着外部过程可能出现任何数量的问题。

There is a known bug in 10.2.0.3, no idea if it's relevant:

10.2.0.3 中有一个已知错误,不知道是否相关:

ORA-28579 occurs when trying to select data from a pipelined table function implemented in "C" using the ODCITable/ANYDATASET interface. ODCITableDescribe works fine but ODCITableFetch generates an ORA-28579 error.

ORA-28579 在尝试从使用 ODCITable/ANYDATASET 接口以“C”实现的流水线表函数中选择数据时发生。ODCITableDescribe 工作正常,但 ODCITableFetch 生成 ORA-28579 错误。

I would suggest:

我会建议:

  1. Look in the database server trace directories, and the directory where the external proc is located, for any log or trace files generated when the error occurs.
  2. Instrument your external proc in some way so that you can try to trace its execution yourself.
  3. Contact Oracle support
  1. 在数据库服务器跟踪目录和外部 proc 所在的目录中查找发生错误时生成的任何日志或跟踪文件。
  2. 以某种方式检测您的外部 proc,以便您可以尝试自己跟踪其执行情况。
  3. 联系 Oracle 支持

回答by Ryan Ahearn

Well, an upgrade to 10.2.0.4 (was using 10.2.0.1) at least gave me an understandable error instead of a fairly useless core file and the ORA-28579.

好吧,升级到 10.2.0.4(使用 10.2.0.1)至少给了我一个可以理解的错误,而不是一个相当无用的核心文件和 ORA-28579。

It turns out that the code I was debugging was assuming that calling OCILobRead would return all of the data in one pass. This is the case for any client using a fixed width character set.

事实证明,我正在调试的代码假设调用 OCILobRead 将一次性返回所有数据。任何使用固定宽度字符集的客户端都是这种情况。

For clients using a variable width character set, this isn't the case, OCILobRead was actually reading part of the data and returning OCI_NEED_DATA and future calls to OCILobTrim and OCILobWrite were failing because of the still pending call to OCILobRead. The solution was to loop OCILobRead calls until OCI_NEED_DATA was no longer returned and we had all of the needed data in our buffer.

对于使用可变宽度字符集的客户端,情况并非如此,OCILobRead 实际上正在读取部分数据并返回 OCI_NEED_DATA 并且未来对 OCILobTrim 和 OCILobWrite 的调用失败,因为对 OCILobRead 的调用仍然未决。解决方案是循环 OCILobRead 调用,直到不再返回 OCI_NEED_DATA 并且我们在缓冲区中拥有所有需要的数据。

A call to OCIBreak also would have allowed the OCILobTrim and OCILobWrite functions to continue, though we wouldn't have had all of the needed input data.

对 OCIBreak 的调用也将允许 OCILobTrim 和 OCILobWrite 函数继续,尽管我们不会拥有所有需要的输入数据。