当前位置: 首页 > Oracle, Oracle 12c > 正文

Oracle 12C新特性-临时UNDO段(Temporary Undo Segments)

在12C版本,为了减少UNDO表空间的使用率及减少REDO和归档日志的产生量,ORACLE推出了临时UNDO段(Temporary Undo Segments)新特性。这个新特性把临时表产生的UNDO信息从UNDO表空间挪到了临时表空间,这样就减少了UNDO表空间的使用。临时表的DML操作不会产生REDO日志,但是UNDO表空间的数据会写入REDO日志中,这样将临时表产生的UNDO数据从UNDO表空间挪到临时表空间,就不会把临时表产生的UNDO信息写入REDO日志中,这样就减少了REDO日志的产生量,也就减少了归档日志的生成量。

ORACLE通过temp_undo_enabled参数来控制临时UNDO段新特性的启用,默认是FALSE关闭状态。

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ----------
temp_undo_enabled                    boolean     FALSE
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

下面测试一下在启用和禁用临时UNDO段特性时,产生的REDO信息对比,先创建测试表。

SQL> create global temporary table t_test_temp as select * from T_TEST where 1=2;

Table created.

重新打开一个会话,查询当前产生的REDO信息。

SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                              4
redo size                                                              1324

在默认情况下也就是禁用临时UNDO段特性的情况下,向一张临时表插入数据。

SQL> insert into t_test_temp select * from t_test;

6136934 rows created.

再次查看这个会话的REDO产生量。

SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                          60964
redo size                                                          21357176

可见,在禁用临时UNDO段特性的情况下,向临时表中插入数据会产生很多的REDO数据,这是因为临时表产生的UNDO数据当前保存在UNDO表空间中,而UNDO表空间的数据也会写入到REDO日志。

下面在开一个新会话,并且启用临时UNDO段特性。

SQL>  alter session set temp_undo_enabled=true;

Session altered.

查看这个会话的当前REDO产生量。

SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                              2
redo size                                                               744

然后向临时表中插入同样的数据。

SQL> insert into t_test_temp select * from t_test;

6136934 rows created.

再次查看这个会话的REDO产生量。

SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                              3
redo size                                                              1024

可见,在启用临时UNDO段的情况下,对临时表进行插入操作,REDO的产生非常少,这些应该都是数据字典变更产生的REDO。

大家应该知道,COMMIT和ROLLBACK操作是一个事务的终止,COMMIT操作只是打个标记,并不会修改数据,而ROLLBACK操作,是要根据UNDO数据去还原数据的,也就是ROLLBACK操作会修改数据,那么就意味着ROLLBACK操作是会产生REDO和UNDO的,如果是临时表的ROLLBACK操作,因为临时表本身不产生REDO,但是会产生UNDO。

下面分别对上面测试的两个会话进行ROLLBACK操作,再看一下REDO的产生量。

禁用临时UNDO段的情况下回滚后REDO产生量:

SQL> rollback;

Rollback complete.

SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                         121794
redo size                                                          27432588

回滚禁用临时UNDO段的情况下的INSERT操作产生的REDO,基本上等于插入时的REDO产生量。

在看一下启用临时UNDO段的情况下回滚后REDO产生量:

SQL> rollback;

Rollback complete.

SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                              4
redo size                                                              1156

回滚启用临时UNDO段的情况下的INSERT操作产生的REDO,基本上不产生REDO。这是因为临时表的DML操作本身就不生成REDO,而临时表的UNDO数据被保存到的临时表空间,临时表空间的数据也不会写入REDO文件。

本实验只是模拟了INSERT操作,有较真的朋友可以测试下DELETE和UPDATE操作。

最后再吐一下槽,貌似这个功能启用之后,在这个会话中并不能关闭,我的测试数据库版本是12.2.0.1.0版本,下面是测试过程。

[oracle@hm-oradb-01 ~]$ sqlplus dbdream/dbdream@localhost/pdb1

SQL*Plus: Release 12.2.0.1.0 Production on Thu Aug 30 12:27:34 2018

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Last Successful login time: Thu Aug 30 2018 10:46:41 +08:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL>  alter session set temp_undo_enabled=true;

Session altered.
SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                              2
redo size                                                               744
SQL> insert into t_test_temp select * from t_test;

6136934 rows created.
SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                              3
redo size                                                              1024
SQL> insert into t_test_temp select * from t_test;

6136934 rows created.

SQL> select name, value from v$mystat natural join v$statname where name in ('redo entries','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo entries                                                              5
redo size                                                              1436

在启用临时UNDO段的会话中,禁用临时UNDO段之后,这个禁用操作明显没有生效。

本文固定链接: https://www.dbdream.com.cn/2018/09/oracle-12c%e6%96%b0%e7%89%b9%e6%80%a7-%e4%b8%b4%e6%97%b6undo%e6%ae%b5temporary-undo-segments/ | 信春哥,系统稳,闭眼上线不回滚!

该日志由 dbdream 于2018年09月03日发表在 Oracle, Oracle 12c 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Oracle 12C新特性-临时UNDO段(Temporary Undo Segments) | 信春哥,系统稳,闭眼上线不回滚!
关键字:

Oracle 12C新特性-临时UNDO段(Temporary Undo Segments):等您坐沙发呢!

发表评论

快捷键:Ctrl+Enter