Shell Oracle外部作业错误ORA-27369:可执行文件类型的作业失败,退出代码:Not owner

Shell Oracle外部作业错误ORA-27369:可执行文件类型的作业失败,退出代码:Not owner,shell,oracle10g,Shell,Oracle10g,我有一个Oracle调度程序作业,它在Solaris环境中运行可执行的shell脚本。作业在每个月的第二个星期日运行,在调度程序作业日志中以失败状态运行,错误代码为:ORA-27369 以下是我的shell脚本: #!/bin/bash ORACLE_HOME=/app/oracle/10g; export ORACLE_HOME; ORACLE_SID=IBSDB; export ORACLE_SID; edate=`date "+%Y%m%d"`; export edate; $OR

我有一个Oracle调度程序作业,它在Solaris环境中运行可执行的shell脚本。作业在每个月的第二个星期日运行,在调度程序作业日志中以失败状态运行,错误代码为:ORA-27369

以下是我的shell脚本:

#!/bin/bash
ORACLE_HOME=/app/oracle/10g; 
export ORACLE_HOME;
ORACLE_SID=IBSDB; 
export ORACLE_SID;

edate=`date "+%Y%m%d"`; export edate;

$ORACLE_HOME/bin/sqlplus "/ as sysdba" @/app/oracle/script/alter_all_index.sql
这个shell脚本运行sqlplus并执行alter_all_index.sql。alter_all_index.sql通过spool命令创建2个文件。首先是ALTER_INDEX_REBUILD.sql,该文件包含重建所有索引的查询。第二个文件是LOG_ALTER_INDEX_REBUILD.txt,用于存储执行ALTER_INDEX_REBUILD.sql时发生的任何错误这里是ALTER_all_INDEX.sql的代码

set wrap off
set linesize 1000
set feedback off
set pagesize 0
set verify off

set termout off

spool ALTER_INDEX_REBUILD.sql;
prompt set linesize 1000
prompt set pagesize 0
prompt spool LOG_ALTER_INDEX_REBUILD.txt

PROMPT ------------------ START FROM HERE ---------------

--prompt varID nvarchar2(40):=sys_guid();;
--prompt insert into PCB_AGCM.QUERY_HK_MONITOR (ID,  TASK_NAME, START_TIME, END_TIME, STATUS) values(varID, 'REBUILD INDEX', to_char(sysdate, 'Dy DD-Mon-YYYY HH24:MI:SS'), null, 'STARTING');;
--prompt commit;;

prompt ------------------ execute GCM_AGCM --------------

select 'ALTER INDEX '||owner||'.'||INDEX_NAME||' REBUILD ONLINE;'  
from all_indexes where owner like 'PCB_AGCM%';

PROMPT ------------------ END OF SCRIPT ----------------------

--prompt update PCB_AGCM.QUERY_HK_MONITOR set end_time=to_char(sysdate, 'Dy DD-Mon-YYYY HH24:MI:SS'), status='COMPLETED' where ID = varID;;
prompt commit;;

prompt exec PCB_AGCM.GATHER_SCHEMA_STATS();;
PROMPT /

PROMPT ------------------- END OF SCRIPT ----------------------

prompt spool off

SPOOL OFF;

@@ALTER_INDEX_REBUILD.sql
在作业运行之前,ALTER_INDEX_REBUILD.sql和LOG_ALTER_INDEX_REBUILD.txt都是从上一次手动运行生成的。 当我通过Oracle调度程序作业进行测试时。首先,它运行良好,我通过TOAD->session browser查看它的会话,它运行良好,查询重建索引正在运行,但在上一个索引完成后,作业以错误ORA-27369结束:可执行类型的作业失败,退出代码:Not owner

我检查了所有的脚本。ALTER_INDEX_REBUILD.sql和LOG_ALTER_INDEX_REBUILD.txt均未更新,Spool命令将创建并替换(如果默认存在),其最后修改日期为2013年4月13日。本应改为2013年5月9日

我得出的结论是,spool命令存在问题,但我不知道如何解决这个问题,我认为这可能与他们的所有权和权限有关,但这两个文件都归oracle所有。有人知道为什么以及如何解决这个问题吗

我已经浏览了ORA-27369,但到目前为止没有人给我任何提示


诚恳地

据我所知,DBMS_调度程序启动的外部程序以低权限用户帐户运行(通常无人,请参阅)

要调试此问题,请执行以下操作:

  • 运行一个输出UID的简单脚本
  • 检查是否允许此用户在/app/oracle/script中创建/覆盖文件/

此外,我建议您为SPOOL文件指定绝对路径,而不仅仅是文件名,或者在SQL/Plus调用之前使用
cd
,以确保在正确的目录中创建SPOOL文件。

关于这一点,有几个大问题需要问:

  • 为什么要将一个sql*plus脚本作为外部作业运行,而您可以将其作为pl/sql过程运行?一般来说,如果您不需要让操作系统参与任务,那么就不要这样做。保存在文件系统中的代码不会与数据库一起备份,更容易因连接问题或某个该死的傻瓜删除它而出错
像索引重建这样的代码应该是一个包含以下代码的过程:

for indexes in (select   owner,
                         index_name
                from     all_indexes
                where    owner like 'PCB_AGCM%'
                order by owner,
                         table_name)
loop
  sql := 'alter index '||indexes.owner||'.'||indexes.index_name||' rebuild online';

  execute immediate sql;
end loop
  • 为什么要定期重建所有索引?如果你能立即从中获得可测量的好处,那是因为你已经压缩了你的索引,但是通过索引恢复到它的自然大小,你会招致更多的开销。有关更多信息,请参阅Richard Foote的许多条目

显然,有一个名为externaljob.ora的文件,您可以在其中指定用户帐户-请参阅我回答中的Oracle论坛链接。啊,是的--我还记得这是一个真正的痛苦--我必须设置一个cron作业来定期更改文件的所有权,以便DBMS_调度程序可以访问它们。@david aldridge真棒!我是DBA领域的新手David,有很多东西需要学习。有趣的故事——有一次,当一个系统监控团队将以前未宣布的公司标准应用于unix主机时,我失去了一个完整的目录层次结构,包括代码和日期,而没有备份。“我认为你的团队可能选择了错误的方法让技术界参与他们的讨论,”我们笑着说。@Hermanplanning你在正确的地方,我的朋友。查看Richard的blogroll上的所有人。@david aldridge实际上,在重建索引之前还有另一个过程要运行。这是一个内务处理过程,删除所有超过3个月的事务数据。但我会尽量提出你的建议。脚本多久运行一次?