oracle 12c undo,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段之后,这个禁用操作明显没有生效。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值