重新编译 oracle 包时更新的缓存是啥?

Posted

技术标签:

【中文标题】重新编译 oracle 包时更新的缓存是啥?【英文标题】:What are the caches that get updated when re-compiling an oracle package?重新编译 oracle 包时更新的缓存是什么? 【发布时间】:2018-02-27 08:58:38 【问题描述】:

我正在使用 Oracle PL-SQL 包。有一个流程在执行时似乎有问题,我试图弄清楚。我做了一些数据更正,但问题仍然存在。所以我添加了跟踪并再次执行流程,它完美地工作了!!!

由于重新编译包,问题似乎得到了解决。那可能吗?如果是这样,这是怎么发生的?

【问题讨论】:

【参考方案1】:

有几种可能性。

更有可能的是,您的包将一些数据存储在局部变量中,例如 PL/SQL 集合。这将忽略基础源表中的数据更改,除非您有适当的过程来触发重新填充。编译包会清除会话状态,因此在运行过程时会看到新数据。

对此的一种变体是将数据存储在事务级别设置的全局临时表中。同样,重新创建包会发出一个提交,这会导致 GTT 丢弃数据。

另一种可能性是您的过程在只读事务中运行。所以它只在会话开始时看到数据的状态。同样,重新编译包会破坏这一点。


如果这些解释都不适用于您的情况,您将需要提供有关您的存储过程正在做什么的更多详细信息。

【讨论】:

【参考方案2】:

包是子程序的集合。第一次调用子程序时,整个包被加载到共享池的Library Cache中。对其进行解析,然后执行代码。对于任何后续调用,已解析的代码将被重用,避免硬解析。早些时候,当第一次调用代码时,我们得到一个库缓存未命中。后续调用会命中库缓存。

如果包所依赖的任何对象通过 DDL 发生结构更改,则库缓存中的解析代码将失效,并在下一次调用时重新加载。我曾经在 Oracle 9i 的嵌套过程中遇到过这个问题。 12c 没遇到过这种情况。

如果您有兴趣了解 Oracle 内存结构,OracleDocumentation 是最好的起点。

【讨论】:

以上是关于重新编译 oracle 包时更新的缓存是啥?的主要内容,如果未能解决你的问题,请参考以下文章

oracle中 触发器 \'SCOTT.TR_EMP\' 无效且未通过重新验证是啥错误

myeclipse项目重新编译失败:清理项目缓存

Apache 正在运行线程 MPM,但您的 PHP 模块未编译为线程安全的。您需要重新编译 PHP。 AH00013:预配置失败

是啥导致了这种过多的“复合层”、“重新计算样式”和“更新层树”循环?

sbt总是重新编译CI中的完整项目,即使使用缓存?

c# visual studio 重新生成解决方案是啥意思?