oracle全对象编译(Oracle 19c)
编译全部失效对象
在Oracle 19c中,UTL_RECOMP.RECOMP_PARALLEL
是一个用于并行重新编译数据库中无效对象的PL/SQL过程。该过程的参数主要包括以下几个:
参数列表
-
threads (IN PLS_INTEGER DEFAULT NULL)
- 描述:指定用于并行重新编译的线程数。如果此参数为NULL,则使用
job_queue_processes
参数的值。通常,将线程数设置为与可用CPU数量相匹配是一个好的起点。 - 注意:并行重新编译会利用多个CPU来加速重新编译过程,但也可能对系统资源(如磁盘I/O)造成较大压力,特别是在磁盘系统速度较慢的情况下。
- 描述:指定用于并行重新编译的线程数。如果此参数为NULL,则使用
-
schema (IN VARCHAR2 DEFAULT NULL)
- 描述:指定要重新编译无效对象的模式(schema)。如果此参数为NULL,则重新编译数据库中的所有无效对象。
- 示例:如果只想重新编译
SCOTT
模式下的无效对象,可以将此参数设置为'SCOTT'
。
-
flags (IN PLS_INTEGER DEFAULT 0)
- 描述:此参数通常用于内部诊断和测试,普通用户在使用时通常不需要设置此参数。
使用示例
-
使用默认线程数重新编译SCOTT模式下的所有无效对象:
EXEC UTL_RECOMP.RECOMP_PARALLEL(NULL, 'SCOTT');
这里,
threads
参数为NULL,因此将使用job_queue_processes
的值;schema
参数为'SCOTT'
,指定了要重新编译的模式。 -
使用4个线程重新编译数据库中的所有无效对象:
EXEC UTL_RECOMP.RECOMP_PARALLEL(4);
这里,
threads
参数被明确设置为4,而schema
参数为NULL,表示要重新编译数据库中的所有无效对象。
注意事项
- 执行权限:通常,这个包需要以SYSDBA身份通过SQL*Plus或其他数据库管理工具执行。
- 系统资源:并行重新编译可能会消耗大量系统资源,特别是当有大量无效对象需要编译时。在执行此操作之前,请确保系统有足够的资源来处理额外的负载。
- 依赖关系:
UTL_RECOMP
包依赖于其他几个包(如STANDARD
、DBMS_STANDARD
、DBMS_JOB
和DBMS_RANDOM
)处于有效状态。如果这些包中的任何一个无效,则可能需要先重新编译它们。 - 避免DDL冲突:在执行
UTL_RECOMP.RECOMP_PARALLEL
期间,应避免在数据库中执行其他DDL操作,因为这可能会导致死锁。
综上所述,UTL_RECOMP.RECOMP_PARALLEL
的参数包括threads
、schema
和flags
,其中threads
和schema
是用户在使用时可能需要特别关注的参数。另外,UTL_RECOMP.RECOMP_PARALLEL不提供任何返回结果,若需要确认编译结果是否都成功,可以查询dba_objects的status(VALID 有效,INVALID 无效)。
小惊喜
有pl/sql develop的同学可以使用pl/sql develop提供的工具:Compile Invalid Objects(就摆在工具栏里),可视化查看、编译失效对象,轻松确认编译结果(对象是否有效)。
编译全部对象
在Oracle 19c中,通常不需要编译所有对象,因为大多数对象(如表、视图等)在创建时就已经被编译了。然而,有时你可能需要重新编译存储过程、函数、包、类型等PL/SQL对象,尤其是当它们变为无效状态时。对于想要编译所有Oracle对象的情况,这里需要澄清一点:通常这不是推荐的做法,因为大多数对象(如表和索引)在创建时就已经编译完成,并且不需要再次编译。不过,如果确实需要针对所有PL/SQL对象进行编译,可以通过编写PL/SQL脚本来实现。
编译所有PL/SQL对象的步骤
-
编写PL/SQL脚本:
编写一个PL/SQL脚本,该脚本遍历DBA_OBJECTS
或ALL_OBJECTS
(取决于你的权限和需要)视图,查找所有PL/SQL对象(如存储过程、函数、包等),并对每个对象执行编译命令。示例脚本(仅编译存储过程和函数):
DECLARE CURSOR obj_cursor IS SELECT owner, object_name, object_type FROM dba_objects WHERE object_type IN ('PROCEDURE', 'FUNCTION') -- 如果你只想重新编译无效的对象,可以取消注释下一行 -- AND status = 'INVALID' ORDER BY owner, object_name; v_owner VARCHAR2(128); v_name VARCHAR2(128); v_type VARCHAR2(20); BEGIN FOR rec IN obj_cursor LOOP v_owner := rec.owner; v_name := rec.object_name; v_type := rec.object_type; CASE v_type WHEN 'PROCEDURE' THEN EXECUTE IMMEDIATE 'ALTER PROCEDURE ' || v_owner || '.' || v_name || ' COMPILE'; WHEN 'FUNCTION' THEN EXECUTE IMMEDIATE 'ALTER FUNCTION ' || v_owner || '.' || v_name || ' COMPILE'; -- 其他类型可以类似处理 -- ... END CASE; -- 可以在这里添加错误处理逻辑 EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error compiling ' || v_type || ' ' || v_owner || '.' || v_name || ': ' || SQLERRM); END LOOP; COMMIT; -- 如果在编译过程中有修改,请确保提交 END; /
注意:这个脚本默认会编译所有存储过程和函数,包括已经有效的对象。如果你只想重新编译无效的对象,可以取消注释
AND status = 'INVALID'
这一行。 -
执行脚本:
在SQL*Plus、SQLcl、SQL Developer或其他支持PL/SQL的客户端中执行上述脚本。 -
监控和日志:
确保监控脚本的执行过程,并记录任何可能的错误或警告。这些日志对于后续的问题排查和性能优化非常有用。
注意事项
- 权限:确保你有足够的权限来编译目标对象。通常,你需要拥有对象的ALTER权限或DBA权限。
- 性能影响:编译大量对象可能会对数据库性能产生短暂影响,特别是在生产环境中。建议在低峰时段执行此类操作。
- 依赖关系:在编译对象时,Oracle会检查对象的依赖关系。如果依赖的对象无效,则当前对象也可能无法编译成功。因此,在处理依赖关系时,请确保按照正确的顺序编译对象。
- 错误处理:在脚本中添加适当的错误处理逻辑,以便在编译过程中捕获并记录任何错误或警告。
总之,虽然可以编写PL/SQL脚本来编译所有Oracle对象,但通常只需要针对特定类型的对象(如PL/SQL对象)进行编译。对于其他类型的对象(如表、视图等),它们通常在创建时就已经编译完成,并且不需要再次编译。