存储过程最佳实践:Fenced 还是 Unfenced?

Chr*_*ich 7 db2 best-practices stored-procedures

我相信我了解受防护和不受防护的存储过程背后的原因。

在数据库(在我们的例子中是 DB2)的“外部”运行,以防止在出现指针等问题时数据库引擎可能损坏。

Unfenced 在数据库“内部”运行,这意味着性能更好。

根据我的研究,SQL PL 总是基本上不受限制,因为它是 SQL,因此不能像编程语言那样访问内存。

C/C++ 和 Java 过程可以在受保护或不受保护的情况下运行。但是由于它们可能会访问内存,因此应该考虑将它们围起来运行,除非可以确定代码的质量不会崩溃并且需要性能。

首先,我对上述内容的理解是否正确?

其次,从所有存储过程(甚至定义为 SQL PL 的存储过程)开始,通常是最佳实践吗?

存储过程的任何其他最佳实践,尤其是与防护和/或安全相关的?

编辑:进一步的研究表明 SQL PL 过程不能运行栅栏。由于它们不包含任何可能损害数据库引擎的代码,例如指针或文件 I/O,DB2 知道它们是安全的并在引擎内部运行它们(即,不受保护)。话虽如此,我仍在寻找有关所有其他存储过程的最佳实践。

mus*_*cio 5

更准确地说,NOT FENCED例程在与数据库管理器本身相同的进程空间中运行。该引擎是用 C 语言编写的,因此调用未受防护的例程就像从main(). 这就是所有内存损坏和性能方面的来源:未受保护的例程可以访问所有相同的资源——内存、文件等——作为数据库管理器进程本身。

对于FENCED例程,数据库管理器启动一个单独的进程 ( db2fmp),它依次执行例程代码。因此,操作系统保护可防止受防护的例程访问属于数据库管理器的任何内存区域或资源。

严格来说,SQL 例程不能被隔离,因为它们不“运行”,但它们比不隔离要好——它们是 DB2 运行时引擎本身执行的字节码,因此没有单独的线程或进程。

C 和 C++ 例程可以被隔离,在这种情况下它们在单独的进程中执行,或者不被隔离,在这种情况下它们被加载到数据库管理器进程空间并作为函数调用。

Java 例程只能通过它们需要一个单独的进程(Java 虚拟机)来执行这一事实而受到保护。如果您将它们声明为 NOT FENCED,则该选项将被悄悄忽略。

说了这么多,您在受保护和不受保护之间的唯一选择是使用 C/C++ 例程。通常,为了安全起见,您会运行受防护的模式,仅当您非常确定它们不会损害数据库管理器并且它们需要更高的性能1时才更改为非防护模式。


1 - 受防护和非受防护例程之间的性能差异来自与分配受防护进程以及数据库管理器和非受防护例程之间的进程间通信相关的开销。即使这样,每次调用受保护的例程时也不会创建受保护的进程;将创建一个池并将其重用于此类调用。所有这一切意味着您可能会看到仅当该例程被非常频繁地调用(例如,每秒数十次或更多次)时才将其声明为受保护的好处。