作者:dbtan |【转载时请以超链接形式标明文章出处作者信息】


Oracle 10g In Memory Undo新特性:

通过以前的介绍,可知道Undo的管理方式和常规的数据管理方式是相同的,当进行数据修改时,会在Buffer中创建前镜像,同时会记录相应的Redo,然后这些Undo数据同样会写出到UNDO SEGMENT上,当进行一致性读或回滚时,可能会产生大量的consistent gets和physical reads。注意到这里,Undo会产生Redo信息,又会写UNDO SEGMENT,进而又可能产生大量读取I/O,这些都是资源密集型操作。如果能够缩减Undo在这些环节的Redo与Undo写出,那么显然就可以极大地提升数据库性能,减少资源的消耗和使用。

从Oracle 10g开始,Oracle在数据库中引入了In Memory Undo(可以被缩写为IMU)的新技术,使用这一技术,数据库会在共享内存中(Shared Pool)开辟独立的内存区域用于存储Undo信息,这样就可以避免Undo信息以前在Buffer Cache中的读写操作,从而可以进一步的减少Redo生成,同时可以大大减少以前的UNDO SEGMENT的操作。IMU中数据通过暂存、整理与收缩之后也可以写出到回滚段,这样的写出提供了有序、批量写的性能提升。

IMU机制与前面日志提到的PVRS紧密相关,由于每个IMU Buffer的大小在64~128KB左右,所以仅有特定的小事务可以使用,每个事务会被绑定到一个独立的空闲的IMU Buffer,同时相关的Redo信息会写入PVRS中,同样每个IMU Buffer会由一个独立的In Memory Undo Latch保护,当IMU Buffer或PVRS写满之后,数据库需要写出IMU中的信息。

一个新引入的隐含参数可以控制该特性是否启用,这个参数是_in_memory_undo,在Oracle 10g中这个参数的缺省值是TRUE(不同版本和平台参数的初始设置可能不同):

sys@TQGZS> @GetHidPar.sql
Enter value for par: _in_memory_undo
old   4: AND x.ksppinm LIKE '%&par%'
new   4: AND x.ksppinm LIKE '%_in_memory_undo%'
NAME                           VALUE                DESCRIB
------------------------------ -------------------- ------------------------------------------------------------
_in_memory_undo                TRUE                 Make in memory undo for top level transactions

IMU的内存在Shared Pool中分配,回想一下Redo Log Buffer的内存使用与功能,实际上IMU技术在某种程度上也是参考了Log Buffer的机制,通过以下查询可以获得系统当前分配的IMU内存:

sys@TQGZS> select * from v$sgastat where name ='KTI-UNDO';
POOL         NAME                                BYTES
------------ ------------------------------ ----------
shared pool  KTI-UNDO                          1235304

In Memory Undo池缺省的会分配3个,用以提供更好的并发:

sys@TQGZS> @GetHidPar.sql
Enter value for par: _imu_pool
old   4: AND x.ksppinm LIKE '%&par%'
new   4: AND x.ksppinm LIKE '%_imu_pool%'
NAME                           VALUE                DESCRIB
------------------------------ -------------------- ------------------------------------------------------------
_imu_pools                     3                    in memory undo pools

IMU的使用信息,如提交次数可以通过V$SYSSTAT视图查询:

sys@TQGZS> select name,value from v$sysstat where name like '%commits';
NAME                                   VALUE
------------------------------ -------------
user commits                            2877
IMU commits                             1549

新的内存Buffer通过In Memory Undo Latch来进行保护:

sys@TQGZS> select name,gets,misses,immediate_gets,sleeps
  2  from v$latch_children where name like '%undo latch';
NAME                                 GETS     MISSES IMMEDIATE_GETS     SLEEPS
------------------------------ ---------- ---------- -------------- ----------
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    0          0              0          0
In memory undo latch                    4          0              2          0
In memory undo latch                  214          0             25          0
In memory undo latch                 6118          0           3064          0
In memory undo latch                 4230          0           1084          0
In memory undo latch                39583          0           2842          0
18 rows selected.

除了前面提到的,还有几个隐含参数与IMU有关:
·_recursive_imu_transactions控制递归事务是否使用IMU,该参数缺省值为False

sys@TQGZS> @GetHidPar.sql
Enter value for par: _recursive_imu_transactions
old   4: AND x.ksppinm LIKE '%&par%'
new   4: AND x.ksppinm LIKE '%_recursive_imu_transactions%'
NAME                           VALUE                DESCRIB
------------------------------ -------------------- ------------------------------------------------------------
_recursive_imu_transactions    FALSE                recursive transactions may be IMU

·_db_writer_flush_imu控制是否允许DBWR将IMU事务的降级为常规事务,并执行UNDO SEGMENT的写出操作,缺省值为TRUE

sys@TQGZS> @GetHidPar.sql
Enter value for par: _db_writer_flush_imu
old   4: AND x.ksppinm LIKE '%&par%'
new   4: AND x.ksppinm LIKE '%_db_writer_flush_imu%'
NAME                           VALUE                DESCRIB
------------------------------ -------------------- ------------------------------------------------------------
_db_writer_flush_imu           TRUE                 If FALSE, DBWR will not downgrade IMU txns for AGING

此外,在RAC环境中,IMU不被支持。

经过不同版本Oracle技术的不断演进,Oracle的内存管理已经和以前大为不同,现在Buffer Cache、Shared Pool、Log Buffer的内容正在不断交换渗透,Redo、Undo数据都可以部分地存储在共享池中,Oracle 11g的Result Cache也被记录在Shared Pool当中。

- The End -