ORA-06520/ORA-06522加载失败主因是extproc进程与.so格式不匹配:需确认库为ELF64、依赖完整(ldd无not found)、监听器正确配置PLSExtProc及ENVS=“EXTPROC_DLLS=ANY”,且SELinux或noexec挂载未拦截。
ORA-06520 / ORA-06522 加载失败:检查 extproc 进程与库格式是否匹配
oracle 调用 c 动态库失败,90% 是因为 extproc 进程无法加载你的 .so 文件。根本原因不是路径写错,而是 elf 格式不兼容或依赖缺失。
- 必须确认你的
.so是ELF64格式(file extproc.so输出含ELF64),32 位库在 64 位 Oracle 下直接报ORA-06522: only ET_DYN and ET_EXEC can be loaded -
extproc进程由监听器启动,它不继承数据库用户的LD_LIBRARY_PATH,所以库内所有依赖(如libstdc++.so.6)必须能被系统动态链接器直接定位 - 用
ldd extproc.so检查是否有not found条目;若有,要么把对应库软链到$ORACLE_HOME/lib,要么用patchelf --set-rpath重写运行时路径
监听器未启用 PLSExtProc:检查 listener.ora 和 tnsnames.ora 配置项
Oracle 不是直接加载 .so,而是通过 IPC 连接一个独立的 extproc 外部过程代理进程。如果监听器没配好这个 SID,调用会卡在连接阶段,报错可能静默或表现为超时。
-
listener.ora中必须存在SID_DESC块,且SID_NAME = PLSExtProc,PROGRAM = extproc,ENVS = "EXTPROC_DLLS=ANY"(生产环境慎用 ANY,可指定绝对路径) -
tnsnames.ora必须定义EXTPROC_CONNECTION_DATA条目,并确保KEY与listener.ora中IPC地址的KEY完全一致(比如都是EXTPROC1521) - 改完配置后必须执行
lsnrctl reload或lsnrctl stop && lsnrctl start,仅reload有时不生效
PL/SQL 函数声明参数类型不匹配:注意 C 原生类型与 Oracle 类型映射
函数创建成功不代表能正确传参。Oracle 的 parameters 子句若写错,会导致栈错位、返回垃圾值,甚至 core dump —— 错误不会立刻报出,而是在首次调用时崩溃。
- C 函数签名是
int sysrun(int *command),那么 PL/SQL 声明中syscomm in double precision就是错的:double precision对应 C 的double *,不是int * - 正确写法应为:
create or replace function sysrun(syscomm in binary_integer) return binary_integer ... parameters(syscomm int, return int) - 避免用
double precision或number传地址;指针参数一律用binary_integer+int映射,字符串用varchar2+string
权限与 SELinux 干扰:Oracle 用户能否真正读取和执行你的 .so?
即使 ls -l 看起来权限没问题,SELinux 或文件系统挂载选项(如 noexec)仍会拦截 extproc 的加载行为,错误日志里往往只显示模糊的 ORA-06520。
- 确认
.so所在目录挂载时没有noexec选项(mount | grep noexec) - 检查 SELinux 状态:
getenforce;若为Enforcing,临时设为Permissive测试:setenforce 0 -
.so文件本身需对oracle用户可读可执行(chmod 755),但不能放在/tmp或用户家目录——extproc默认禁止从这些路径加载
ldd 输出里的 not found 和 SELinux 的拒绝日志,它们不会出现在 Oracle alert.log 里,得去 audit.log 或 strace -p $(pgrep extproc) 才能看到真实原因。


















