Oracle 如何让DBA暂停并恢复正在更新大表中每一行的存储过程?

Oracle 如何让DBA暂停并恢复正在更新大表中每一行的存储过程?,oracle,Oracle,我有一个大约一百万行的表,我需要用一个冗长的计算结果更新表中的每一行(每一行的计算结果可能不同)。因为这很耗时,DBA必须能够控制执行。此特定计算需要每年运行一次(它会进行年终总结)。我想使用DBMS_调度程序创建一个作业。创建一个作业,从表中获取100行,更新它们,然后停止;然后,作业的下一次执行将从上一次执行停止的位置开始 我的第一个想法是在存储过程的末尾包含以下代码: -- update 100 rows, storing the primary key of the last -- up

我有一个大约一百万行的表,我需要用一个冗长的计算结果更新表中的每一行(每一行的计算结果可能不同)。因为这很耗时,DBA必须能够控制执行。此特定计算需要每年运行一次(它会进行年终总结)。我想使用DBMS_调度程序创建一个作业。创建一个作业,从表中获取100行,更新它们,然后停止;然后,作业的下一次执行将从上一次执行停止的位置开始

我的第一个想法是在存储过程的末尾包含以下代码:

-- update 100 rows, storing the primary key of the last
-- updated row in last_id
-- make a new job that will run in about a minute and will
-- start from the primary key value just after last_id
dbms_scheduler.create_job
( job_name=>'yearly_summary'
, job_type=>'STORED_PROCEDURE'
, job_action=>'yearly_summary_proc(' || last_id || ')'
, start_date=>CURRENT_TIMESTAMP + 1/24/60
, enabled=>TRUE
);
但当存储过程运行时,我会出现以下错误:

ORA-27486: insufficient privileges
ORA-06512: at "SYS.DBMS_ISCHED", line 99
ORA-06512: at "SYS.DBMS_SCHEDULER", line 262
ORA-06512: at "JBUI.YEARLY_SUMMARY_PROC", line 37
ORA-06512: at line 1

欢迎提出其他方法的建议。我更喜欢使用DBMS_调度器,我更喜欢不必创建任何表;这就是我将最后一个id传递给存储过程的原因。

我倾向于对使用这样的作业来控制执行持谨慎态度。连续作业之间的延迟往往太短,DBA无法确定要终止/暂停的作业等。或者延迟足够长,运行时间的很大一部分将花费在连续作业之间的延迟上

在不创建任何新对象的情况下,您可以使用该包允许DBA发送暂停作业的警报。您的代码可以每隔一百行调用
DBMS\u ALERT.WAITONE
方法,以检查DBA是否发出了特定警报(即
PAUSE\u YEAREND\u作业
ALERT)。如果未收到警报,代码可能会继续。如果收到警报,您可以暂停代码,直到收到另一个警报(即,
RESUME\u YEAREND\u JOB
)或一段固定的时间,或者基于DBA随
pause\u YEAREND\u JOB
警报发送的消息(即消息可以是暂停的秒数或暂停的日期等)


当然,您也可以通过创建一个新表,让DBA向表中写入一行以暂停作业,并每隔N行从表中读取数据来完成同样的工作。

另一个探索途径是dbms调度器对执行窗口和资源计划的支持工具

而且:

有了windows和资源计划,DBA可以简单地配置系统来执行您的过程,以遵守某些规则—包括作业窗口和仅使用特定数量的资源(即CPU使用量)执行

这样,程序可以每年运行一次,并且可以控制CPU的使用

但这可能无法提供DBA想要的手动控制


另一个想法是编写过程来处理所有记录,但每1000左右提交一次。DBA可以使用dbms job.cancel()命令来取消作业(如果他们希望作业停止),然后他们可以在准备就绪时恢复作业(通过重新安排或重新运行)。诀窍在于,该过程需要能够跟踪已处理的行,例如,使用“已处理的日期”列,或者使用一个单独的表列出主键和已处理的日期。

除了关于
DBMS\u ALERT
的答案外,DBA还希望能够看到存储过程的最新位置。您应该使用Oracle中的功能来执行此操作。

感谢您提供有关windows和资源计划的信息。我会看看这些。