1

我有一个在 Solaris 环境中运行可执行 shell 脚本的 Oracle 调度程序作业。作业在每个月的第二个星期日运行,它在调度程序作业日志中以失败状态运行,错误代码为: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 Scheduler Job 进行测试时。首先它运行良好,我通过 TOAD-> 会话浏览器查看它的会话,它运行良好,查询重建索引正在运行,但在最后一个索引完成后,作业以错误 ORA-27369 结束:EXECUTABLE 类型的作业失败并退出代码: 不是楼主。

我检查了所有的脚本。ALTER_INDEX_REBUILD.sql 和 LOG_ALTER_INDEX_REBUILD.txt 都没有更新,如果存在 Spool 命令,默认创建和替换,它们的最后修改日期是 2013 年 4 月 13 日。它应该更改为 2013 年 5 月 9 日。

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

所有权和许可

我浏览过有关 ORA-27369 的信息,但到目前为止还没有给我任何提示。

真挚地

4

2 回答 2

2

有几个大问题要问:

  • 为什么要作为外部作业运行一个 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博客上的许多条目。
于 2013-05-13T10:58:43.423 回答
1

据我所知,由 DBMS_SCHEDULER 启动的外部程序作为低权限用户帐户运行(通常没有人,请参阅Oracle 论坛)。

要调试此问题,您可以:

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

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

于 2013-05-13T10:41:26.387 回答