共享内存shared pool (3):Library cache
Shared pool物理层面上由许多内存块(chunck)组成。从逻辑功能划分,Shared pool主要由三部分组成:Library cache,Dictionary cache和Control Structure。本文主要讲述 Library cache.
Library cache
library cache最主要的功能就是存放用户提交的SQL语句,SQL语句相关的解析树(解析树也就是对SQL语句中所涉及到的所有对象的展现)--->共享SQL区(shared SQL areas),私有SQL区(private SQLareas,如果配置了共享服务器),执行计划,用户提交的PL/SQL程序块(包括匿名程序块,存储过程,包,函数等)以及它们转换后能够被Oracle执行的代码等,为了对这些内存结构进行管理,library cache中还存放了很多控制结构,包括lock,pin,dependency table,11G中的mutex等
Library cache要解决三个问题
- 快速定位:Library cache中对象众多,Oracle如何管理这些对象,以便服务进程可以迅速找到他们需要的信息。比如,某个服务进程需要迅速定位某个SQL是否存在于Library cache中。
- 关系依赖:Library cache中的对象存在复杂的依赖关系,当某个objec失效时,可以迅速将依赖其的对象也置为失效状态。比如,某个表发生了结构变化,依赖其的SQL语句需要重新解析。
- 并发控制:Library cache中必须有一个并发控制的机构,比如:锁机制,来管理大量共享对象的并发访问和修改的问题
Library cache问题的解决方法
- 快速定位:Oracle利用Hash Bucket结构来解决library cache中快速定位的问题
- 关系依赖:Oracle利用LCO(library cache object)中dependency table解决对象依赖关系
- 并发控制:Oracle利用LATCH/LOCK/PIN解决并发控制
Hash Bucket
- Hash Bucket是通过串连起来的对象句柄体现出来的,Hash Bucket本身是一个逻辑的概念,而不像对象是一个具体的实体。
- Oracle根据shared_pool_size尺寸自动计算hash buckets的个数,shared pool越大,则可以挂载的对象句柄就越多。
- 此处的Hash Bucket同 共享内存 share pool (2)中的Bucket原理相似,但不是同一个。
library cache handle
每个hash bucket后面都串连着多个句柄,这些句柄描述了library cache里的对象的一些属性,包括名称、标记、指向对象所处的内存地址的指针等
library cache object
Library Cache Object是由一些独立的heap所组成。前面说Library cache handle指向对象(Library cache Object),其实就是指向第一个heap 0,而Heap 0记录了指向其他heap的指针信息
- Dependency table --当前LCO依赖的其它LCO信息,如SQL语句依赖的表、视图等. (LCO :library cache object)
- Chile table----保存当前LCO的子LCO信息。
- Data blocks ---保存SQL语句、执行计划、执行文本等信息
SQL语句在Library cache执行的第一次检查过程
- 通过语法语义权限等检查的SQL语句进入Library cache
- 将SQL文本转化为ASCII值(大小写ASCII不同)并进行hash函数的运算
- 得到一个HASH值对应到hash bucket的号码
- 进入该hash bucket对应的链表进行扫描并比较
parent cursor/ child cursors
当用户提交SQL语句或PL/SQL程序块到oracle的shared pool以后,在library cache中生成的一个可执行的对象,这个对象就叫做游标(cursor)。不要把这里的游标与标准SQL(ANSI SQL)的游标混淆起来了,标准SQL的游标是指返回多条记录的SQL形式,需要定义、打开、关闭。下面所说到的游标如无特别说明,都是指library cache中的可执行的对象。游标是可以被所有进程共享的,也就是说如果100个进程都执行相同的SQL语句,那么这100个进程都可以同时使用该SQL语句所产生的游标,从而节省了内存。
每个游标都是由library cache中的两个或多个对象所体现的,至少两个对象。一个对象叫做父游标(parent cursor),包含游标的名称以及其他独立于提交用户的信息(v$sqlarea视图里看到的都是有关父游标的信息);另外一个或多个对象叫做子游标(child cursors)。例如:SQL文本相同,但提交SQL语句的用户不同,有可能生成不同的子游标。
参考blog:
http://blog.csdn.net/haibusuanyun/article/details/17844211
http://czmmiao.iteye.com/blog/1273261