

# 执行 Oracle 数据库实例的常见计划任务
<a name="Appendix.Oracle.CommonDBATasks.Scheduler"></a>

某些 `SYS` 拥有的计划程序作业可能会影响正常的数据库操作。在这种情况下，Oracle 支持人员建议您修改计划。如果您需要启用或禁用 `SYS` 作业，请先在测试环境中测试对计划作业的操作，然后再在生产环境中实施它。要执行 `SYS` 拥有的 Oracle 计划程序作业的任务，请使用 Amazon RDS 包 `rdsadmin.rdsadmin_dbms_scheduler`。

下表所示的 Amazon RDS for Oracle 数据库引擎版本支持 `rdsadmin.rdsadmin_dbms_scheduler` 过程。使用此软件包时，您可以指定表中列出的 `SYS` 作业。


| 数据库版本 | 默认启用的作业 | 默认禁用的作业 | 
| --- | --- | --- | 
| Oracle Database 19c |  <pre>BSLN_MAINTAIN_STATS_JOB<br />CLEANUP_NON_EXIST_OBJ<br />CLEANUP_ONLINE_IND_BUILD<br />CLEANUP_ONLINE_PMO<br />CLEANUP_TAB_IOT_PMO<br />CLEANUP_TRANSIENT_PKG<br />CLEANUP_TRANSIENT_TYPE<br />DRA_REEVALUATE_OPEN_FAILURES<br />FILE_SIZE_UPD<br />ORA$AUTOTASK_CLEAN<br />PMO_DEFERRED_GIDX_MAINT_JOB<br />PURGE_LOG<br />RSE$CLEAN_RECOVERABLE_SCRIPT<br />SM$CLEAN_AUTO_SPLIT_MERGE</pre>  |  <pre>FGR$AUTOPURGE_JOB<br />FILE_WATCHER<br />HM_CREATE_OFFLINE_DICTIONARY<br />LOAD_OPATCH_INVENTORY<br />ORA$PREPLUGIN_BACKUP_JOB<br />XMLDB_NFS_CLEANUP_JOB</pre>  | 
| Oracle Database 21c |  <pre>BSLN_MAINTAIN_STATS_JOB<br />CLEANUP_NON_EXIST_OBJ<br />CLEANUP_ONLINE_IND_BUILD<br />CLEANUP_ONLINE_PMO<br />CLEANUP_TAB_IOT_PMO<br />CLEANUP_TRANSIENT_PKG<br />CLEANUP_TRANSIENT_TYPE<br />DRA_REEVALUATE_OPEN_FAILURES<br />FILE_SIZE_UPD<br />ORA$AUTOTASK_CLEAN<br />PMO_DEFERRED_GIDX_MAINT_JOB<br />PURGE_LOG</pre>  |  <pre>FGR$AUTOPURGE_JOB<br />FILE_WATCHER<br />HM_CREATE_OFFLINE_DICTIONARY<br />LOAD_OPATCH_INVENTORY<br />ORA$PREPLUGIN_BACKUP_JOB<br />ORA$_ATSK_AUTOSTS<br />XMLDB_NFS_CLEANUP_JOB</pre>  | 

## Oracle 计划程序过程的常见参数
<a name="Appendix.Oracle.CommonDBATasks.Scheduler.CommonParameters"></a>

要使用 Oracle 计划程序执行任务，请使用 Amazon RDS 包 `rdsadmin.rdsadmin_dbms_scheduler` 中的过程。有几个参数是包中的过程通用的。该包具有以下常见参数。


****  

| 参数名称 | 数据类型 | 有效值 | 默认值 | 必需 | 描述 | 
| --- | --- | --- | --- | --- | --- | 
|  `name`  |  varchar2  |  [执行 Oracle 数据库实例的常见计划任务](#Appendix.Oracle.CommonDBATasks.Scheduler) 的表中列出的步骤   |  —  |  是  |  要修改的作业的名称。  | 
|  `attribute`  |  varchar2  |  `'REPEAT_INTERVAL'`,`'SCHEDULE_NAME'`  |  –  |  是  |  要修改的属性。 要修改作业的重复间隔，请指定 `'REPEAT_INTERVAL'`。 要修改作业的计划名称，请指定 `'SCHEDULE_NAME'`。  | 
|  `value`  |  varchar2  |  有效的计划间隔或计划名称，具体取决于使用的属性。  |  –  |  是  |  新的属性值。  | 

## 修改 DBMS\$1SCHEDULER 作业
<a name="Appendix.Oracle.CommonDBATasks.ModifyScheduler"></a>

要修改 Oracle Scheduler 的某些组件，使用 Oracle 过程 `dbms_scheduler.set_attribute`。有关更多信息，请参阅 Oracle 文档中的 [DBMS\$1SCHEDULER](https://docs.oracle.com/database/121/ARPLS/d_sched.htm#ARPLS72235) 和 [SET\$1ATTRIBUTE 过程](https://docs.oracle.com/database/121/ARPLS/d_sched.htm#ARPLS72399)。

在使用 Amazon RDS 数据库实例时，在对象名称前面加上架构名称 `SYS`。以下示例设置星期一窗口对象的资源计划属性。

```
BEGIN
    DBMS_SCHEDULER.SET_ATTRIBUTE(
        name      => 'SYS.MONDAY_WINDOW',
        attribute => 'RESOURCE_PLAN',
        value     => 'resource_plan_1');
END;
/
```

## 修改自动任务维护时段
<a name="Appendix.Oracle.CommonDBATasks.Scheduler.maintenance-windows"></a>

Amazon RDS for Oracle 实例使用维护时段的默认设置创建。自动维护任务（如优化程序统计信息收集）在这些窗口中运行。默认情况下，维护时段会打开 Oracle 数据库资源管理器。

要修改时段，请使用 `DBMS_SCHEDULER` 程序包。出于以下原因，您可能需要修改维护时段设置：
+ 您希望维护作业在不同的时间运行，具有不同的设置，或根本不运行。例如，可能需要修改时段持续时间，或更改重复时间和间隔。
+ 您希望避免在维护期间启用资源管理器造成性能影响。例如，如果指定了默认维护计划，并且在数据库处于加载状态时打开维护时段，则可能会看到等待事件，例如 `resmgr:cpu quantum`。此等待事件与数据库资源管理器相关。您有以下选项：
  + 确保您的数据库实例的非高峰时段处于活动状态。
  + 禁用默认维护计划，方法是将 `resource_plan` 属性设置为空字符串。
  + 在参数组中将 `resource_manager_plan` 参数设置为 `FORCE:`。如果您的实例使用企业版，则此设置将阻止激活数据库资源管理器计划。

**修改维护时段设置**

1. 使用 Oracle SQL 客户端 Connect 到数据库。

1. 查询调度程序时段的当前配置。

   以下示例查询 `MONDAY_WINDOW` 的配置。

   ```
   SELECT ENABLED, RESOURCE_PLAN, DURATION, REPEAT_INTERVAL
   FROM   DBA_SCHEDULER_WINDOWS 
   WHERE  WINDOW_NAME='MONDAY_WINDOW';
   ```

   以下输出显示该时段正在使用默认值。

   ```
   ENABLED         RESOURCE_PLAN                  DURATION         REPEAT_INTERVAL
   --------------- ------------------------------ ---------------- ------------------------------
   TRUE            DEFAULT_MAINTENANCE_PLAN       +000 04:00:00    freq=daily;byday=MON;byhour=22
                                                                   ;byminute=0; bysecond=0
   ```

1. 使用 `DBMS_SCHEDULER` 程序包修改时段。

   以下示例将资源计划设置为 null，以便资源管理器不会在维护时段期间运行。

   ```
   BEGIN
     -- disable the window to make changes
     DBMS_SCHEDULER.DISABLE(name=>'"SYS"."MONDAY_WINDOW"',force=>TRUE);
   
     -- specify the empty string to use no plan
     DBMS_SCHEDULER.SET_ATTRIBUTE(name=>'"SYS"."MONDAY_WINDOW"', attribute=>'RESOURCE_PLAN', value=>'');
   
     -- re-enable the window
     DBMS_SCHEDULER.ENABLE(name=>'"SYS"."MONDAY_WINDOW"');
   END;
   /
   ```

   以下示例将时段的最大持续时段设置为 2 小时。

   ```
   BEGIN
     DBMS_SCHEDULER.DISABLE(name=>'"SYS"."MONDAY_WINDOW"',force=>TRUE);
     DBMS_SCHEDULER.SET_ATTRIBUTE(name=>'"SYS"."MONDAY_WINDOW"', attribute=>'DURATION', value=>'0 2:00:00');
     DBMS_SCHEDULER.ENABLE(name=>'"SYS"."MONDAY_WINDOW"');
   END;
   /
   ```

   以下示例将重复间隔设置为每个星期一上午 10 点。

   ```
   BEGIN
     DBMS_SCHEDULER.DISABLE(name=>'"SYS"."MONDAY_WINDOW"',force=>TRUE);
     DBMS_SCHEDULER.SET_ATTRIBUTE(name=>'"SYS"."MONDAY_WINDOW"', attribute=>'REPEAT_INTERVAL', value=>'freq=daily;byday=MON;byhour=10;byminute=0;bysecond=0');
     DBMS_SCHEDULER.ENABLE(name=>'"SYS"."MONDAY_WINDOW"');
   END;
   /
   ```

## 设置 Oracle Scheduler 作业的时区
<a name="Appendix.Oracle.CommonDBATasks.Scheduler.TimeZone"></a>

要修改 Oracle Scheduler 的时区，您可以使用 Oracle 过程 `dbms_scheduler.set_scheduler_attribute`。有关 `dbms_scheduler` 程序包的更多信息，请参阅 Oracle 文档中的 [DBMS\$1SCHEDULER](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_SCHEDULER.html) 和 [SET\$1SCHEDULER\$1ATTRIBUTE](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_SCHEDULER.html#GUID-2AB97BF7-7154-4E6C-933F-B2659B18A907)。

**修改当前时区设置**

1. 使用客户端（例如 SQL Developer）连接到数据库。有关更多信息，请参阅“[使用 Oracle SQL Developer 连接到数据库实例](USER_ConnectToOracleInstance.SQLDeveloper.md)”。

1. 按如下所示设置默认时区，并将时区替换为 `time_zone_name`。

   ```
   BEGIN
     DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE(
       attribute => 'default_timezone',
       value => 'time_zone_name'
     );
   END;
   /
   ```

在以下示例中，您将时区更改为亚洲/上海。

首先查询当前时区，如下所示。

```
SELECT VALUE FROM DBA_SCHEDULER_GLOBAL_ATTRIBUTE WHERE ATTRIBUTE_NAME='DEFAULT_TIMEZONE';
```

输出显示当前时区为 ETC/UTC。

```
VALUE
-------
Etc/UTC
```

然后，将时区设置为亚洲/上海。

```
BEGIN
  DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE(
    attribute => 'default_timezone',
    value => 'Asia/Shanghai'
  );
END;
/
```

有关更改系统时区的更多信息，请参阅 [Oracle 时区](Appendix.Oracle.Options.Timezone.md)。

## 关闭 SYS 拥有的 Oracle 计划程序任务
<a name="Appendix.Oracle.CommonDBATasks.Scheduler.Disabling"></a>

要禁用 SYS 用户拥有的 Oracle 计划程序任务，请使用 `rdsadmin.rdsadmin_dbms_scheduler.disable` 过程。

该过程在 Oracle 计划程序任务中使用 `name` 常见参数。有关更多信息，请参阅“[Oracle 计划程序过程的常见参数](#Appendix.Oracle.CommonDBATasks.Scheduler.CommonParameters)”。

以下示例禁用 `SYS.CLEANUP_ONLINE_IND_BUILD` Oracle 计划程序作业。

```
BEGIN
   rdsadmin.rdsadmin_dbms_scheduler.disable('SYS.CLEANUP_ONLINE_IND_BUILD');
END;
/
```

## 开启 SYS 拥有的 Oracle 计划程序任务
<a name="Appendix.Oracle.CommonDBATasks.Scheduler.Enabling"></a>

要开启 SYS 拥有的 Oracle 计划程序任务，请使用 `rdsadmin.rdsadmin_dbms_scheduler.enable` 过程。

该过程在 Oracle 计划程序任务中使用 `name` 常见参数。有关更多信息，请参阅“[Oracle 计划程序过程的常见参数](#Appendix.Oracle.CommonDBATasks.Scheduler.CommonParameters)”。

以下示例启用 `SYS.CLEANUP_ONLINE_IND_BUILD` Oracle 计划程序作业。

```
BEGIN
   rdsadmin.rdsadmin_dbms_scheduler.enable('SYS.CLEANUP_ONLINE_IND_BUILD');
END;
/
```

## 修改 CALENDAR 类型的任务的 Oracle 计划程序重复间隔
<a name="Appendix.Oracle.CommonDBATasks.Scheduler.Modifying_Calendar"></a>

要修改重复间隔以修改 SYS 拥有的 `CALENDAR` 类型的 Oracle 计划程序作业，请使用 `rdsadmin.rdsadmin_dbms_scheduler.disable` 过程。

该过程在 Oracle 计划程序任务中使用以下常见参数：
+ `name`
+ `attribute`
+ `value`

有关更多信息，请参阅“[Oracle 计划程序过程的常见参数](#Appendix.Oracle.CommonDBATasks.Scheduler.CommonParameters)”。

以下示例修改 `SYS.CLEANUP_ONLINE_IND_BUILD` Oracle 计划程序作业的重复间隔。

```
BEGIN
     rdsadmin.rdsadmin_dbms_scheduler.set_attribute(
          name      => 'SYS.CLEANUP_ONLINE_IND_BUILD', 
          attribute => 'repeat_interval', 
          value     => 'freq=daily;byday=FRI,SAT;byhour=20;byminute=0;bysecond=0');
END;
/
```

## 修改 NAMED 类型的任务的 Oracle 计划程序重复间隔
<a name="Appendix.Oracle.CommonDBATasks.Scheduler.Modifying_Named"></a>

某些 Oracle 计划程序作业使用计划名称而不是间隔。对于此类型的作业，您必须在主用户架构中创建新的命名计划。请使用标准 Oracle `sys.dbms_scheduler.create_schedule` 过程执行该操作。此外，还要使用 `rdsadmin.rdsadmin_dbms_scheduler.set_attribute procedure` 将新的命名计划分配给作业。

该过程在 Oracle 计划程序任务中使用以下常见参数：
+ `name`
+ `attribute`
+ `value`

有关更多信息，请参阅“[Oracle 计划程序过程的常见参数](#Appendix.Oracle.CommonDBATasks.Scheduler.CommonParameters)”。

以下示例修改 `SYS.BSLN_MAINTAIN_STATS_JOB` Oracle 计划程序作业的重复间隔。

```
BEGIN
     DBMS_SCHEDULER.CREATE_SCHEDULE (
          schedule_name   => 'rds_master_user.new_schedule',
          start_date      => SYSTIMESTAMP,
          repeat_interval => 'freq=daily;byday=MON,TUE,WED,THU,FRI;byhour=0;byminute=0;bysecond=0',
          end_date        => NULL,
          comments        => 'Repeats daily forever');
END;
/
 
BEGIN
     rdsadmin.rdsadmin_dbms_scheduler.set_attribute (
          name      => 'SYS.BSLN_MAINTAIN_STATS_JOB', 
          attribute => 'schedule_name',
          value     => 'rds_master_user.new_schedule');
END;
/
```

## 在创建 Oracle 计划程序任务时关闭自动提交
<a name="Appendix.Oracle.CommonDBATasks.Scheduler.autocommit"></a>

当 `DBMS_SCHEDULER.CREATE_JOB` 创建 Oracle 计划程序任务时，它会立即创建任务并提交更改。要执行以下操作，可能需要将 Oracle 计划程序任务的创建合并到用户事务中：
+ 回滚用户事务时，回滚 Oracle 计划程序任务。
+ 提交主用户事务时，创建 Oracle 计划程序任务。

可以使用过程 `rdsadmin.rdsadmin_dbms_scheduler.set_no_commit_flag` 开启此行为。此过程不需要任何参数。您可以在以下 RDS for Oracle 版本中使用此过程：
+ 21.0.0.0.ru-2022-07.rur-2022-07.r1 及更高版本
+ 19.0.0.0.ru-2022-07.rur-2022-07.r1 及更高版本

以下示例关闭 Oracle 计划程序的自动提交，创建 Oracle 计划程序任务，然后回滚事务。由于自动提交已关闭，因此数据库还会回滚 Oracle 计划程序任务的创建。

```
BEGIN
  rdsadmin.rdsadmin_dbms_scheduler.set_no_commit_flag;
  DBMS_SCHEDULER.CREATE_JOB(job_name   => 'EMPTY_JOB', 
                            job_type   => 'PLSQL_BLOCK', 
                            job_action => 'begin null; end;',
                            auto_drop  => false);
  ROLLBACK;
END;
/

PL/SQL procedure successfully completed.

SELECT * FROM DBA_SCHEDULER_JOBS WHERE JOB_NAME='EMPTY_JOB';

no rows selected
```