暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

通过 Temp UNDO 在 Oracle REDO 上节省大量成本

原创 CiciLee 2022-08-11
1124

当 Oracle 推出 RDBMS 12.1 版时,包含了一个有趣的新参数:“temp_undo_enabled”。默认情况下,“temp_undo_enabled”设置为 FALSE。此参数的目的是减少从 UNDO 生成的 REDO。长期的 Oracle DBA 将认识到这一点。这是其他所有人的简要说明。

当Oracle中的数据块发生变化时,会产生相应的UNDO和REDO。

UNDO(曾经称为回滚段)是用于反转更改并在其他会话中提供读取一致视图的向量。

如果更新了一行,然后发出了 ROLLBACK,则使用 UNDO 数据将块重建为原来的样子。

其他会话也使用 UNDO 来提供读取一致的视图,以便在其他会话中所做的更改不会更改您当前会话中的结果。

有关这方面的更多信息,请参阅管理撤消。

REDO 数据也是一个变化向量,但用途不同。 REDO 用于在实例或数据库恢复的情况下重建块。

当实例崩溃时,当前REDO LOGS中的REDO用于恢复到崩溃点。

该 REDO 也被写入存档日志,然后在从备份恢复数据库时用于完成恢复。

有关详细信息,请参阅管理重做日志。

在临时段上的 UNDO

想象一下,您正在应用程序中使用全局临时表(如果您尝试的话,这很容易)。

每个会话都有自己的 GTT 数据视图。创建全局临时表

许多 GTT 可用于瞬态数据的应用内转换。就其本质而言,GTT 通常不需要为实例恢复或数据库恢复而恢复。因此,不会为在 GTT 上执行的 DML 生成 REDO。

然而,GTT 上的每笔交易都默认生成 UNDO。

当 UNDO 生成时,这些 UNDO 块又受到 REDO 的保护,REDO 会填满 REDO LOGS,然后作为存档日志写出。

数据库恢复通常不需要所有这些 UNDO 和伴随的 REDO,因为它们是无法恢复的 TEMP 段。

Oracle 引入了 temp_undo_enabled 参数来帮助解决这个问题。

如果 temp_undo_enabled 设置为 TRUE,则 Oracle 不再为 GTT 的更改生成 UNDO。如果没有UNDO,则不会为UNDO 生成REDO。

这会有多大的不同?

需要进行实验。

减少返工

使用为此测试修改的 Sqlrun 版本,10 个会话同时运行 5 分钟。

在此期间,每个会话运行三个 SQL 语句。

insert into sqlrun_gtt select * from all_objects

update sqlrun_gtt set object_id = object_id + 1


merge into txcount tx
  using (select sys_context('userenv','sid') sid from dual ) s
  on (s.sid = tx.sid)
when matched then
  update set tx.txacts = tx.txacts + 1
when not matched then
  insert (sid, txacts)
  values(sys_context('userenv','sid'),1)

MERGE 语句用于跟踪为每个测试执行的事务数

结果

REDO生成的差异相当大
微信截图_20220811123418.png

在 temp_undo_enabled=FALSE 的情况下,生成了大约 816M 的 REDO。

在 temp_undo_enabled=TRUE 的情况下,仅生成了 2.54M 的 REDO。

如果应用程序大量使用 GTT,则只需设置这一参数即可显着减少 REDO 生成。

这种开销减少的一个副产品是,当没有生成额外的 REDO 时,能够运行另外 99 个事务。

您可能已经注意到每笔交易的 UNDO 数量增加了。 等一下,这不就是为了消除UNDO,这样就不会产生REDO了吗?

不同的是UNDO现在是Temporary UNDO,不会产生REDO。

通过加入 vundostat 和 vtempundostat 可以看到永久和临时 UNDO 使用的模式,如 allseg.sql 中所示。

SQL# @allseg

                                           PERM                    TEMP
                                           UNDO    PERM    TEMP    UNDO
BEGIN_TIME          END_TIME               BLKS    UNDO    UNDO    BLKS
------------------- ------------------- ------- ------- ------- -------
07/05/2022 12:46:20 07/05/2022 12:56:20   98309    3618
07/05/2022 12:56:20 07/05/2022 13:06:20   67406    2476
07/05/2022 13:06:20 07/05/2022 13:16:20   57562    1899
07/05/2022 13:16:20 07/05/2022 13:26:20    1459     234
07/05/2022 13:26:20 07/05/2022 13:36:20     689     266
07/05/2022 13:36:20 07/05/2022 13:46:20   45881    1570
07/05/2022 13:46:20 07/05/2022 13:56:20   59245    2029
07/05/2022 13:56:20 07/05/2022 14:06:20       7      88
07/05/2022 14:06:20 07/05/2022 14:16:20    3607     170
07/05/2022 14:16:20 07/05/2022 14:26:20   86646    3027
07/05/2022 14:26:20 07/05/2022 14:36:20   44228    1563
07/05/2022 14:36:20 07/05/2022 14:46:20   87402    3035
07/05/2022 14:46:20 07/05/2022 14:56:20    5992     580
07/05/2022 14:56:20 07/05/2022 15:06:20      64    3410    3156  109760
07/05/2022 15:06:20 07/05/2022 15:16:20       3       9       0       0
07/05/2022 15:16:20 07/05/2022 15:26:20       6      74
07/05/2022 15:26:20 07/05/2022 15:36:20       7     517     154    5360
07/05/2022 15:36:20 07/05/2022 15:46:20       0       5       0       0
07/05/2022 15:46:20 07/05/2022 15:56:20       4     118      26     905
07/05/2022 15:56:20 07/05/2022 16:06:20     102    4959    2330   80995
07/05/2022 16:06:20 07/05/2022 16:16:20   54313    4484     333   11622
07/05/2022 16:16:20 07/05/2022 16:26:20   23349    1772       0       0
07/05/2022 16:26:20 07/05/2022 16:36:20       3     104
07/05/2022 16:36:20 07/05/2022 16:46:20       0       1

24 rows selected.

这些 V$ 视图中的数据每 10 分钟更新一次,因此各种测试之间存在一些重叠。也就是说,我们可以看到在相同的 10 分钟时隙中同时使用了永久和临时 UNDO 段。

如果我能找到一种方法来为每个包含 REDO 生成,我也会将它包含在 SQL 中。在任何情况下,临时 UNDO 块都不会生成任何 REDO。

细枝末节

如果您想查看有关如何执行这些测试的详细信息,请继续阅读。

如果没有,也许您想调查一下是否有任何数据库可以从减少 GTT TEMP 段上的 REDO 中受益。

如前所述,Sqlrun 用于同时运行多个 SQL 语句。

Sqlrun 分支中的 sqlrun.pl Perl 脚本被修改为执行以下操作。

  • 删除、创建和填充 stats_begin 表,用于在测试期间跟踪重做和撤消
  • 删除并创建用于跟踪重做和撤消的 stats_end 表

对 sqlrun.pl 所做的更改有点杂乱无章,有相当多的硬编码。如果其中任何一个进入功能列表,它将正确完成。目前,测试是最重要的事情。

测试在 19.9 PDB 中的 UNDOTEST 帐户下运行。

SQL# @showpriv undotest
"Roles/Privileges for which user or role? - "
( Wildcards OK )

           PRIV
GRANTEE    TYPE                  PRIV NAME              OWNER      TABLE_NAME                  GRANTABLE
---------- --------------------- ---------------------- ---------- --------------------------- ---------
UNDOTEST   ROLE                  CONNECT                                                       NO
                                 RESOURCE                                                      NO
           SYSPRIV               ALTER SESSION                                                 NO
           TABPRIV               SELECT                 SYS        V_$INSTANCE                 NO

4 rows selected.

作为 UNDOTEST 用户,最初运行 create/create.sql 脚本:

$  cat create/create.sql


drop table sqlrun_gtt purge;

create global temporary table sqlrun_gtt
on commit delete rows
as
select * from all_objects
where 1=0;



drop table txcount purge;

create table txcount ( sid number, txacts number);

文件 SQL/Oracle/sqlfile.conf 具有三个活动的 SQL 脚本:

$  grep -vE '^\s*$|^\s*#'  SQL/Oracle/sqlfile.conf | grep sql
1,temp-insert.sql,
1,temp-update.sql,
1,txcount-update.sql,

这些是每个 Oracle 会话重复执行的 SQL 文件。

txcount-update.sql 脚本在测试期间更新事务数。 它实际上负责当 temp_undo_enabled = TRUE/ 时生成的相当一部分 UNDO。

运行测试

一切就绪后,运行测试就相当简单了

sqlrun.sh 的内容

./sqlrun.pl \
   --exe-mode sequential \
   --connect-mode flood \
   --tx-behavior commit \
   --max-sessions 10 \
   --exe-delay 0.25 \
   --db p2 \
   --username undotest \
   --password XXXX \
   --runtime  300 \
   --sqldir $(pwd)/SQL

在运行 sqlrun.sh 之前,将 job_queue_processes 参数设置为 0,以便在测试期间不会运行任何系统作业。

temp_undo_enabled 参数根据需要设置为 TRUE|FALSE,并在每个测试会话之前进行检查。

SQL# @set-temp-undo-off

System altered.


V$PARAMETER for temp_undo_enabled report for
Instance: cdb1
Date/Time:  07/05/2022 18:42:25

                                                                                                            DEF  SESS SYS
NAME                                                INST VALUE                                              VAL? MOD? MOD?
-------------------------------------------------- ----- -------------------------------------------------- ---- ---- ----
temp_undo_enabled                                      1 FALSE                                              Y    Y    I
temp_undo_enabled                                      2 FALSE                                              Y    Y    I

虽然这是一个 RAC 数据库,但所有测试都是在实例 1 上执行的。

现在运行 sqlrun.sh

$  ./sqlrun.sh
driver config file:.../sqlrun/SQL/Oracle/driver-config.json
sqlFile: /home/jkstill/oracle/dba/undo_size/temp-undo/sqlrun/SQL/Oracle/sqlfile.conf


SQL PARSER:

DEBUG: 0
sqlParmFileFQN:  .../sqlrun/SQL/Oracle/sqlfile.conf
exeMode: sequential

$sqlParms: $VAR1 = {
          'txcount-update.sql' => '1',
          'temp-insert.sql' => '1',
          'temp-update.sql' => '1'
        };
Connect Mode: flood
Truncating undotest.txcount
PID: 15152
Waiting on child 15152...
PID: 0
PID: 15154
Waiting on child 15154...
PID: 0
PID: 15156
Waiting on child 15156...
PID: 0
PID: 15158
Waiting on child 15158...
PID: 0
PID: 15160
Waiting on child 15160...
PID: 0
PID: 15162
Waiting on child 15162...
PID: 0
PID: 15164
Waiting on child 15164...
PID: 0
PID: 15166
Waiting on child 15166...
PID: 0
PID: 15168
Waiting on child 15168...
Timer Check: 300
PID: 0
Timer Check: 300
Timer Check: 300
Timer Check: 300
PID: 15170
Waiting on child 15170...
PID: 0
Timer Check: 300
Timer Check: 300
Timer Check: 300
Timer Check: 300
deleting stats_begin
Timer Check: 300
Timer Check: 300
Results of dropping stats_begin: 0E0
Results of creating stats_begin: 20


~/sqlrun $
$  ps
  PID TTY          TIME CMD
15153 pts/4    00:00:00 perl
15155 pts/4    00:00:00 perl
15157 pts/4    00:00:00 perl
15159 pts/4    00:00:00 perl
15161 pts/4    00:00:00 perl
15163 pts/4    00:00:00 perl
15165 pts/4    00:00:00 perl
15167 pts/4    00:00:00 perl
15169 pts/4    00:00:00 perl
15171 pts/4    00:00:00 perl
15281 pts/4    00:00:00 ps
18634 pts/4    00:00:00 bash

当测试在一个 SSH 会话中运行时,另一个正忙于循环运行此监控脚本:

#!/usr/bin/env bash

USERNAME=somedba
PASSWORD=XXX
DB=p2

while :
do

   sqlplus -S -L $USERNAME/$PASSWORD@$DB  <<-EOF
      set pause off verify off feed on term on
      @@stats-end
      @@stats-report
      exit
   EOF

   sleep 5

done

此监视器允许您在测试运行时查看 UNDO 和 REDO 统计数据的变化。 它还显示了测试完成的事务数。

当事务数不再增加时,sqlrun.sh 的当前迭代已经完成。

注意:此测试不一定是文章正文中的值所基于的相同测试运行。

NAME                                                VALUE    TXCOUNT
---------------------------------------- ---------------- ----------
redo size                                     984,328,224       2407
undo change vector size                       588,628,380       2407

2 rows selected.


20 rows updated.


Commit complete.


NAME                                                VALUE    TXCOUNT
---------------------------------------- ---------------- ----------
redo size                                   1,002,735,604       2452
undo change vector size                       599,633,832       2452

2 rows selected.


20 rows updated.


Commit complete.


NAME                                                VALUE    TXCOUNT
---------------------------------------- ---------------- ----------
redo size                                   1,021,414,600       2500
undo change vector size                       610,805,356       2500

2 rows selected.


2 rows updated.


Commit complete.


NAME                                                VALUE    TXCOUNT
---------------------------------------- ---------------- ----------
redo size                                     919,021,668       2514
undo change vector size                       549,578,792       2514

2 rows selected.


2 rows updated.


Commit complete.


NAME                                                VALUE    TXCOUNT
---------------------------------------- ---------------- ----------
redo size                                     919,021,668       2514
undo change vector size                       549,578,792       2514

投入使用

这只是启用 temp_undo_enabled 参数的好处之一,尽管它是一个引人注目的好处。

如果您正在寻找减少 Oracle 12c+ 数据库中 REDO 生成的机会,请务必测试此参数的使用。

我希望你觉得这篇文章有帮助。 随意提出任何问题或在评论中分享您的想法,并确保注册以获取更新。

原文标题:Big Savings on Oracle REDO Via Temp UNDO
原文作者:Jared Still
原文地址:https://blog.pythian.com/big-savings-on-oracle-redo-via-temp-undo/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论