Oracle数据库如何防止临时表操作产生归档日志?

问题描述 投票:0回答:1

在我的应用程序中,我们动态创建表来存储特定于会话的信息。这些表是在活动会话开始时创建的,并在会话关闭后删除。最近,用户群呈指数级增长,现在每天大约有 50 万个会话,这导致每天创建和删除 50 万个临时表。

以前,Oracle 每天生成约 10-12 GB 的归档日志,但现在,由于会话数量和临时表创建的增加,归档日志大小已飙升至每天 450 GB。这些临时表遵循特定的命名模式,以 PUser_ 开头。

问题是临时表操作被记录在存档日志中,即使它们对于恢复目的不是必需的。

有什么办法可以让这些临时表操作不被写入Oracle的归档日志中吗?

如果有任何见解或解决方案可以减少这些临时表引起的存档日志大小,我将不胜感激。

oracle-database oracle12c
1个回答
0
投票

这听起来对于 PL/SQL 集合来说是一个合适的情况,当在包头级别定义时,它们在会话的生命周期内是持久的。第一次接触包时会运行实例化代码(在包主体中的

BEGIN
之后),该代码会加载关联数组,从那时起,不再重复。

样本表:

CREATE TABLE my_roles (username varchar2(128), role_name varchar2(128));

INSERT INTO my_roles VALUES ('XYZ','ROLE1');
INSERT INTO my_roles VALUES ('XYZ','ROLE2');
COMMIT;

包装码:

CREATE OR REPLACE PACKAGE pkg_plsql_auth
AS
  TYPE role_tabtype IS TABLE OF Boolean INDEX BY varchar2(128);
  tab_roles role_tabtype;
END pkg_plsql_auth;
/
CREATE OR REPLACE PACKAGE BODY pkg_plsql_auth
AS
BEGIN
  FOR rec_role IN (SELECT *
                     FROM my_roles
                    WHERE username = 'XYZ')
  LOOP
    tab_roles(rec_role.role_name) := TRUE;
  END LOOP;
END pkg_plsql_auth;
/

现在测试一下:

BEGIN
  IF pkg_plsql_auth.tab_roles.EXISTS('ROLE1') 
  THEN
    dbms_output.put_line('I have role1');
  ELSE
    dbms_output.put_line('I do not have role1');
  END IF;

输出:

I have role1
I do not have role3
  

这将使其 100% 保留在 PGA 内存中。这实际上比全局临时表 (GTT) 更好,因为 GTT 在临时表空间中创建临时段。虽然它们确实避免了重做日志记录,但它们仍然涉及 I/O。另一方面,PL/SQL 集合是来自可用内存的简单 malloc,关联数组类型 (

INDEX BY ...
) 针对超快速元素访问进行了优化,如果您每次都知道自己对哪个角色感兴趣,那么这将是合适的.

© www.soinside.com 2019 - 2024. All rights reserved.