我正在从PLSQL存储过程中收集运行时分析数据。在某些存储过程执行时收集数据,但需要在这些过程的多次执行中累积。
为了最大限度地减少开销,我想在数据收集时间间隔内将分析数据存储在某个可访问PLSQL的Oracle内存驻留存储器中,然后转储累积值。数据收集间隔可能是几秒或几小时;它可以不跨系统启动存储这些数据。像Web服务器中的会话状态一样。
我有什么选择存储这些数据?
我所知道的唯一方法是dbms_sessions中的上下文:
procedure set_ctx (value in varchar8) as
begin
dbms_session.set_context ( 'Test_Ctx', 'AccumulatedValue', value, NULL, 'ProfilerSessionId' );
end set_ctx;
这样可行,但每次更新需要大约50微秒(!)的累计值。
我所希望的是一种使用vanilla PLSQL语句访问/存储某些Oracle内存中的值数组的方法,访问时间通常是对包本地数组进行的数组访问。
编辑(在了解了PLSQL包变量的会话生存期之后):
是否存在PLSQL可访问的变量,其寿命比“会话”长?我猜这些变量可能需要同步才能从多个会话中启用安全更新。奇怪的是,我收集的那种性能数据不会受到这种同步故障的严重影响,因为性能数据值只是单调增长。同步错误仅仅意味着我们没有捕捉到一点价值增长,我认为这不会损害我所做的事情。
答案 0 :(得分:2)
我能想到的唯一方法就是拥有一个持续运行并维护内存数据的“监听器”进程。然后,您的其他进程将通过与侦听器通信来记录信息。 DBMS_PIPE或DBMS_AQ。在DBMS_PIPE文档中有一个Pro * C侦听器进程的示例。
但是,我怀疑这对于调用程序是否比通过自治事务将信息写入表的更简单的解决方案更有效。
答案 1 :(得分:0)
如何使用具有相当固定内存配置文件的每会话程序包,您定期(每N次更新)刷新数据库(对于“所有会话”数据),然后重置。
如果您可以执行Insert而不是更新,则锁定的风险应该非常低,然后您可以使用行上的视图或物化视图来获取累计总数。
或者,如果使用与Tony建议的DBMS_AQ方法结合使用,则可以保证不会出现锁定 - 将消息放入队列的速度很快,您可以将队列链接到在Oracle背景上执行的PLSQL包上的回调线。
答案 2 :(得分:0)
我不完全确定你在做什么,但我已经为PL / SQL写了一个详细的日志包,它允许通过PL / SQL等跟踪执行,时间到毫秒。但与自己相关,有一个选项可以记录到内存,即没有使用PL / SQL集合的I / O.换句话说,您可以登录到缓冲区并定期将缓冲区刷新到表中。它可以从https://sourceforge.net/p/plj-logger/home/或http://www.pljumpstart.com/download
获取它具有实现非常简单的附加优点。单个包装和支持表等。