oracle中的IMU和 PVRS

1、概述

10g中,redolog
buffer的改进,的确是个不小的创新,我最近研究了下10g版本在redolog buffer上的改进,和大家共享下。
说之前,我先提下,redo信息产生的过程:

1)先在PGA区域中生成redo entries,也就是redo条目,并计算大小记录之;
2)服务器进程oracle<sid>去rodolog
buffer中申请 redo copy latch(redo 复制闩),失败了,会发生等待事件,成功了则:
3)再去申请redo allocation latch(在rodolog buffer中申请空间的闩),一旦redo中有足够的空间,就可以申请成功,这时
4)释放这个redo allocation latch
5)服务器进程再去申请redo writting latch(redo 写入内存的闩),成功后则:
6)服务器进程把PGA中准备好得redo entries 写入到redolog buffer中,
7)按顺序释放redo writting latch 和redo copy latch。
分析以上7步,完成redo信息的产生,接下来就是lgwr进程的写入在线日志文件的工作了,我不去介绍。

        大家观测这个过程不难发现,redo copy latch在开始就被申请,而最后才被释放,势必会引起争用,或者等待事件的发生,降低了效率,到了9i这个版本,oracle引入了PBRS(public
redo strands)机制
,就是借鉴了share pool 分出多个子池(subpool)的思想,也分出了多个log buffer,每个buffer有独立的latch保护,以提高并发性,提高效率。
        到了10g版本,又有了改革的新思想,就是PVRS(private redo strands)机制。原理是,在share pool中申请多个小的私有内存空间,每个在64-128KB之间,被独立的redo allocation latch保护。这样的好处是显而易见的,单个redo信息很小,但个数很多的时候(oracle多年测试得出结论就是大多数事务所产生的redo都是很小的,但次数比较多),不会在PGA中产生redo
entries,而是直接放在 share pool中申请多个小的私有内存空间中,redo copy latch也不再需要,因为oracle认为redo copy latchF这个闩是是引发竞争的根源。当redo写出到文件时,LGWR将PBRS和PVRS中的内容写出到日志文件中。产生日志时首选pvrs,如果redo条目太大,或者share pool没有空间,再用redo log buffer(也就是9i时发明的PBRS中)。

2、Oracle 10g InMemory Undo新特性

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

从Oracle10g开始,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
------------------------------ -------------
usercommits                           2877
IMUcommits                            1549

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

sys@TQGZS> select name,gets,misses,immediate_gets,sleeps
    from v$latch_children where name like '%undo latch';
NAME                                         GETS     MISSES IMMEDIATE_GETS    SLEEPS
------------------------------           ---------- ----------     --------------                   ----------
In memory undolatch                   0         0              0                                    0
In memory undolatch                   0         0              0                                    0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   0         0              0                                   0
In memory undo latch                   0         0             0                                   0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   0         0              0                                   0
In memory undolatch                   4         0              2                                   0
In memory undolatch                 214       0             25                                 0
In memory undolatch                6118       0           3064                             0
In memory undolatch                4230       0           1084                             0
In memory undolatch               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 -

时间: 2024-11-06 03:28:50

oracle中的IMU和 PVRS的相关文章

关于java判断oracle中的表是否存在,不存在则创建一个表的问题

问题描述 关于java判断oracle中的表是否存在,不存在则创建一个表的问题 代码如下try{ Class.forName(""oracle.jdbc.driver.OracleDriver""); String url = ""jdbc:oracle:thin:@""+localhost+"":""+port+"":""+dbname; con

用sqoop将oracle中的表导入hadoop出现如图问题 求解决方案!

问题描述 用sqoop将oracle中的表导入hadoop出现如图问题 求解决方案! 解决方案 http://www.linuxidc.com/Linux/2014-02/96678.htm 照这个链接再搞一下 解决方案二: 我当初就是照他的方案弄得 不知道为什么连接不上去

在Oracle中计算时间差的方法

如何在Oracle中计算时间差呢?计算时间差是Oracle DATA数据类型的一个常见问题.Oracle支持日期计算,你可以创建诸如"日期1-日期2"这样的表达式来计算这两个日期之间的时间差. 一旦你发现了时间差异,你可以使用简单的技巧来以天.小时.分钟或者秒为单位来计算时间差.为了得到数据差,你必须选择合适的时间度量单位,这样就可以进行数据格式隐藏. 使用完善复杂的转换函数来转换日期是一个诱惑,但是你会发现这不是最好的解决方法. round(to_number(end-date-st

在ORACLE中移动数据库文件

在ORACLE中移动数据库文件 ---- ORACLE数据库由数据文件,控制文件和联机日志文件三种文件组成.由于磁盘空间的变化,或者基于数据库磁盘I/O性能的调整等,数据库管理员可能会考虑移动数据库文件.下面以UNIX平台为例,分别讨论三种数据库文件的移动方法. ---- 一.移动数据文件: ---- 可以用ALTER DATABASE,ALTER TABLESPACE两种方法移动数据文件. ---- 1. ALTER DATABASE方法: ---- 用此方法,可以移动任何表空间的数据文件.

ORACLE中序列-sequence的应用

oracle oracle中没有象Acces中自动编号的字段类型,所以在oracle中要想用一个字段自动增值,还比较麻烦,在此提供给大家一个方法,利用序列,来完成字段的自动增加,下边介绍一下怎么创建序列,使用序列,和删除序列. 1.创建序列--------------create sequence  create sequence  Seq_AutoID   //所起序列名叫 Seq_AutoID ,需要记住此序列名,以后方可调用 minvalue   1   //最小值从1开始 可以根据自己的

ORACLE中字符串比较

oracle|比较|字符串  在ORACLE中,将空字符串视为NULL,任何值与NULL比较结果都为NULL.如此一来,在比较两个字符串的时候就会出现意外.请看以下的例子:DECLARE     i VARCHAR2(10) := NULL;    v VARCHAR2(10) := 'ABC';BEGIN    IF(i = v) THEN        DBMS_OUTPUT.PUT_LINE('相等');    ELSE        DBMS_OUTPUT.PUT_LINE('不等');

Oracle Faq(如何在ORACLE中更改表的列名和顺序 )

oracle 如需转载,请注明出处!用过ORACLE的人都知道,要想在ORACLE中更改表的列名和顺序可是一件很烦琐的事,下面给大家提供一种简单的方法. SQL> select object_id from all_objects where owner='SCOTT' and object_name='T1'; OBJECT_ID----------6067SQL> select obj#,col#,name from sys.col$ where obj#=6067; OBJ# COL#-

用ASP.NET 2.0在Oracle中存取图片(文件)的操作

asp.net|oracle 有时由于某种需要(如安全性)须将图片或文件存放在数据库中,当然一般情况下特别是文件比较大的时候很多人不提倡将文件以二进制的形式存放在数据库中的,现将Oracle中文件的存取整理如下(思路和在SQL Server2000中存取一样,存储时在数据中存放图片或文件的二进制字节流,读出时将数据库中对应字段读取到字节数据,然后输出):       1.在TOAD或SQLPlus中创建一下数据库表. 1CREATE TABLE TEST_TABLE2(3  ID     VAR

Oracle中如何快速删除数据字典管理的表空间

oracle|数据 我的测试环境:Hp rp7410主机,Hp-unix11.11 OS,Oracle8.1.7.4的数据库,一个有90张表大约100G的测试表空间TBS_TEST. 问题的提出:Oracle中在使用drop tablespace <tablespace_name> including contents;删除数据字典管理的表空间时存在着很大的效率问题. 测试开始: 1.使用drop tablespace <tablespace_name> including con