Oracle中library cache和dictionary cache概述

library cache最主要的功能就是存放用户提交的SQL语句、SQL语句相关的解析树(解析树也就是对SQL语句中所涉及的所有对象的展现 )、 执行计划、用户提交的PL/SQL程序块(包括匿名程序块、存储过程、包、函数等)以及它们转换后能够被Oracle执行的代码等。为了 对这些 内存结构进行管理,library cache中还存放了很多控制结构,包括lock、pin、dependency table等。

library cache也存放了很多的数据库对象的信息,包括表、索引等。有关这些数据库对象的信息都是从dictionary cache中获得的。 如果 用户对library cache中的对象信息进行了修改,比如为表添加了一个列等,则这些修改会返回到dictionary cache中。

在library cache中存放的所有信息单元都叫做对象(object),这些对象可以分成两类:一类叫存储对象,也就是上面所说的数据库 对象 。它们是通过显式的SQL语句或PL/SQL程序创建出来的,如果要删除它们,也必须通过显式的SQL命令进行删除。这类对象包括表、视 图、索 引、包、函数等;另一类叫做过渡对象,也就是上面所说的用户提交的SQL语句或者提交的PL/SQL匿名程序块等。这些过渡对象是在 执行SQL 语句或PL/SQL程序的过程中产生的,并缓存在内存里。如果实例关闭则删除,或者由于内存不足而被交换出去,从而被删除。

当用户提交SQL语句或PL/SQL程序块到shared pool以后,会在library cache中生成一个可执行的对象,这个对象就叫做游标(cursor )。 不要把这里的游标与标准SQL(ANSI SQL)的游标混淆起来了,标准SQL里的游标是指返回多条记录的SQL形式,需要定义、打开、关闭 。下 面所说到的游标如无特别说明,都是指library cache中的可执行的对象。游标是可以被所有进程共享的,也就是说如果100个进程都 执行相 同的SQL语句,那么这100个进程都可以共用该SQL语句所产生的游标,从而节省了内存。

每个游标都是由library cache中的两个或多个对象所体现的,至少两个对象。一个对象叫做父游标(parent cursor),包含游标的名 称以 及其他独立于提交用户的信息。从v$sqlarea视图里看到的都是有关父游标的信息;另外一个或多个对象叫做子游标(child cursor) ,如 果SQL文本相同,但是可能提交SQL语句的用户不同,或者用户提交的SQL语句所涉及的对象为同名词等,都有可能生成不同的子游标。 因为 这些SQL语句的文本虽然完全一样,但是上下文环境却不一样,因此这样的SQL语句不是一个可执行的对象,必须细化为多个子游标后 才能够 执行。子游标含有执行计划或者PL/SQL对象的程序代码块等。

在介绍library cache的内部管理机制前,先简单介绍一下所谓的hash算法。

Oracle内部在实现管理的过程中大量用到了hash算法。hash算法是为了能够进行快速查找定位所使用一种技术。所谓hash算法,就是根 据要 查找的值,对该值运用一定的hash函数后得出该值所在的索引号。进入索引号所对应的一列数值列表(可以理解为一个二维数组)里 ,然后 再对其中所含有的值进行逐个比较,从而找到该值。这样就避免了对整个数值列表进行扫描才能找到该值,这种全扫描的方式显然 要比hash 查找方式低效很多。其中,每个索引号对应的数值列在Oracle里都叫做一个hash bucket。

我们来列举一个最简单的hash算法。假设我们的数值列表最多可以有10个元素,也就是有10个hash bucket,每个bucket最多可以包含 10个 数值。则对应的二维数组就是t[10][10]。我们可以定义hash算法为n MOD 10。通过这种算法,可以将所有进入的数据均匀放在10个 hash  bucket里面,hash bucket编号从0到9。比如,我们把1到100都通过这个hash函数均匀放到这10个hash bucket里,当查找32在哪里时 ,只要 将32 MOD 10等于2,这样就知道32必定位于2号hash bucket里,于是到t[2][10]里去找,2号hash bucket里有10个数值,逐个比较2 号hash  bucket里是否存在32就可以了。这里可以看出,为了找到32这个值,我们总共需要比较11次(1+10)。如果不使用hash算法,而采 用遍历扫 描的方式,则需要比较100次。

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/database/Oracle/

library cache就是使用多个hash bucket来管理的,其hash算法当然比我们前面列举的要复杂多了。每个hash bucket后面都串连着多 个句 柄(该句柄叫做library cache object handle),这些句柄描述了library cache里的对象的一些属性,包括名称、标记、指向对象 所处的 内存地址的指针等。实际上,hash bucket就是通过串连起来的对象句柄才体现出来的,它本身是一个逻辑上的概念,是一个逻辑组 ,而不 像对象是一个具体的实体。Oracle根据shared_pool_size所指定的shared pool尺寸自动计算hash buckets的个数,shared pool越 大,则可 以挂载的对象句柄就越多。

当一条SQL语句进入library cache的时候,先将SQL文本转化为对应ASCII数值,然后对这些ASCII数值进行hash函数的运算,传入函数 的参 数包括SQL语句的名称(name,对于SQL语句来说其name就是SQL语句的文本)以及命名空间(namespace,对于SQL语句来说是“SQL  AREA” ,表示共享游标。可以从视图v$librarycache里找到所有的namespace)。运用hash函数后得到一个值,该值就是hash bucket的号 码,从而 该SQL语句被分配到该号的hash bucket里去。

当某个进程需要处理某个对象时,比如处理一条新进入的SQL语句时,它会对该SQL语句应用hash函数算法,以决定其所在的hash  bucket的 编号,然后进入该hash bucket进行扫描以确定是否存在相同的SQL语句。有可能会发生该对象的句柄存在,但是句柄所指向的对 象已经被交 换出内存的情况出现。这时对应的对象必须被再次装载(reload)。也可能该对象的句柄都不存在,也就是说该条SQL语句是第 一次被执行 ,这时进程必须重新构建一个对象句柄挂到hash bucket上,然后再重新装载对象。SQL语句相关的对象有很多(最直观的就是 SQL语句的文 本),这些对象都存放在library cache里,它们都通过句柄来访问。可以把library cache理解为一本书,而SQL语句的对象 就是书中的页 ,而句柄就是目录,通过目录可以快速定位到指定内容的页。

对象句柄存放了对象的名称(name)、对象所属的命名空间(namespace)、有关对象的一些标记(比如对象是否为只读、为本地对象 还是 远程对象、是否被pin在内存中等)以及有关对象的一些统计信息等。其中存放的最重要的内容应该就是指向Heap 0对象的指针了。 Heap 0 用来存放与对象有直接关系的一些信息,比如对象类型、对象相关的表、实际的执行计划、执行PL/SQL的机器码等。Heap是由一个 或多个 chunk组成的,这些chunk可以是分散的分布在library cache中的,不需要连续分布。

我们可以通过查询视图v$db_object_cache来显示library cache中有哪些对象被缓存,以及这些对象的大小尺寸。比如,我们可以用下 面的 SQL语句来显示每个namespace中,大小尺寸排在前3名的对象:

select *

from (select row_number() over(partition by namespace

order by sharable_mem desc) size_rank,

namespace,

sharable_mem,

substr(name, 1, 50) name

from v$db_object_cache

order by sharable_mem desc)

where size_rank <= 3

order by namespace, size_rank;

而dictionary cache则是专门用来存放SYS schema所拥有的对象的内存区域。使用dictionary cache时以行为单位,而不像其他比如 buffer  cache以数据块为单位,因此dictionary cache也叫做row cache。构造dictionary cache的目的是为了加快解析SQL语句的速度, 因为 dictionary cache里存放了所有表的定义、Storage信息、用户权限信息、约束定义、回滚段信息、表的统计信息等。基本上我们不需 要过 多地关注它。

Oracle里是没有初始化参数来控制library cache和dictionary cache应该占多大的内存的,我们只能控制shared pool的大小。因为前 面说 过,shared pool里的一个可用chunk,如果存放了数据字典的信息,那么它就属于dictionary cache。否则,如果存放了SQL文本或执 行计 划等信息,则它就属于library cache。有时某chunk原先可能放的是SQL文本,后来由于内存不足被数据字典信息所覆盖,则该chunk 就从 library cache变成了dictionary cache。所以我们不能单独控制library cache和dictionary cache各是多大。

时间: 2024-12-02 04:07:23

Oracle中library cache和dictionary cache概述的相关文章

Oracle中library cache pin与PROCEDURE的重建

前面提到,Oracle10g重建Procedure的处理有所增强,最初看到这个增强的时候,我想这个增强是否可以减少困扰已久的Library Cache的竞争呢? 我们看一下以下测试,首先在第一个session执行操作: SQL> create or replace PROCEDURE pining 2 IS 3 BEGIN 4 NULL; 5 END; 6 / Procedure created. SQL> SQL> alter session set nls_date_format='

Oracle结果集缓存(Result Cache)--服务器、客户端、函数缓存

Oracle结果集缓存(Result Cache)--服务器.客户端.函数缓存 在11g中,Oracle提供了结果集缓存特性.该缓存是在共享内存中存储全部的结果集,如果一个查询SQL被执行,且它对应的结果集在缓存中,那么,该SQL的几乎全部开销都可以避免.这些开销包括,解析时间.逻辑读.物理读和任意的通常可能会遭遇的争用.但是,在实际的情况中,结果集缓存仅在少数的情况下是有效的,原因有如下几点: (1)有数据重叠的多个SQL会在缓存中保存冗余的数据. (2)对依赖对象的任何改变(包括对查询中引用

在ASP中模拟.NET下的cache技术

cache 为了提高网站首页的性能,首页凡是需要调用数据库显示数据的地方都会先试图从缓存中调用数据,如果缓存中没有可用数据再打开数据库取出记录集,为了让页面显示数据和数据库在一定时间内同步,我们把缓存的过期时间设置成30秒. 声明:缓存管理类出自于动网论坛7.0 注意:最好不要在缓存里直接缓存带状态的对象和MTA模式的对象,比如说直接缓存记录集或者数据库链接对象等. <%Sub ShowRsArr(rsArr) '用表格显示记录集getrows生成的数组的表结构 ' Response.Write

.net中何有效的使用Cache

cache Cache 即高速缓存 ,我想很多人对他的第一印象一定像我一样,感觉他一定能提高系统得性能和运行速度.的确.Net推出cache的初衷确实是这样的.那么cache是如何提高系统性能与运行速度呢?是不是在任何情况下用cache都能提高性能?是不是cache用的越多就越好呢?我在近期开发的项目中有所体会,写下来当作总结也希望能跟大家一起探讨探讨,有错误的地方希望大家批评指正. 1.       Cache 是如何工作的.l         Cache 是分配在服务器上的一个公共的内存片.

Java Cache系列之Cache概述和Simple Cache

前记:最近公司在做的项目完全基于Cache(Gemfire)构建了一个类数据库的系统,自己做的一个小项目里用过Guava的Cache,以前做过的项目中使用过EHCache,既然和Cache那么有缘,那就趁这个机会好好研究一下Java中的Cache库.在Java社区中已经提供了很多Cache库实现,具体可以参考http://www.open-open.com/13.htm,这里只关注自己用到的几个Cache库而且这几个库都比较具有代表性:Guava中提供的Cache是基于单JVM的简单实现:EHC

Oracle中的Shared Pool详解

Oracle数据库作为一个管理数据的产品,必须能够认出用户所提交的管理命令(通常叫做SQL语句),从而进行响应.认出的过程叫做解析SQL语句的过程,响应的过程叫做执行SQL语句的过程.解析是一个相当复杂的过程,它要考虑各种可能的异常情况,比如SQL语句涉及的对象不存在.提交的用户没有权限等.而且,还需要考虑如何执行SQL语句,采用什么方式去获取数据等.解析的最终结果是要产生 Oracle自 己内部的执行计划,从而指导SQL的执行过程.可以看到,解析是一个非常消耗资源的过程.因此,Oracle在解

Oracle中解析SQL语句的过程

为了将用户写的SQL文本转化为Oracle认识的且可执行的语句,这个过程就叫做解析过程.解析分为硬解析和软解析.一条SQL语句在第一次被执行时必须进行硬解析. 当客户端发出一条SQL语句(也可以是一个存储过程或者一个匿名PL/SQL块)进入shared pool时(注意,我们从前面已经知道,Oracle对这些SQL不叫做SQL语句,而是称为游标.因为Oracle在处理SQL时,需要很多相关的辅助信息,这些辅助信息与SQL语句一起组成了游标), Oracle首先将SQL文本转化为ASCII值,然后

oracle中Shared pool深入分析及性能调整

摘要:本文首先详细介绍了oracle中shared pool的概念以及所包含的内存结构.然后深入介绍了oracle对于shared pool的管理机制.最后全面介绍了有关buffer cache监控以及调优的实用方法. 1. shared pool的概念 oracle数据库作为一个管理数据的产品,必须能够认出用户所提交的管理命令(通常叫做SQL语句),从而进行响应.认出的过程叫做解析SQL语句的过程,响应的过程叫做执行SQL语句的过程.解析的过程是一个相当复杂的过程,它要考虑各种可能的异常情况,

oracle中的闩锁(latch)简介

1.闩锁.锁定和并发性 数据库系统本身是一个多用户并发处理系统,在同一个时间点上,可能会有多个用户同时操作数据库.这里就涉及两个很重要的问题. 这些用户之间的操作不会互相破坏.比如两个用户同时在相同的物理位置上写数据时,不能发生互相覆盖的情况.这叫串行化,也就是说,即便两个用户同 时写,也必须有先后,一个用户写完,另一个用户继续写.串行化会降低系统的并发性,但这对于保护数据结构不被破坏来说则是必需的. 在满足串行化的前提下,如何将并发性提升到最大. 在Oracle数据库中,通过闩锁(latch)