第一章ORACLE体系结构(三)本节我们将重点来学习SGA、PGA的内部组件首先学习共享池的内部组件LIBRARYCACHE、ROWCACHELibraryCache=======我们前面的例子中了解到,A售货员为小丽选一本最新上架的“CBO基础”前要先对这件事做分析。分析要选取出这本书采用不同方法会花去多少时间成本和路程成本,通常她会评估出选取该书成本最少的方法来。这里的时间成本在ORACLE中称为CPU成本,路程成本就是IO成本。通常在ORACLE中默认是按IO成本来计算,要想更精确则需要加入CPU成本。注意这些成本都是通过一些信息来评估的,所谓评估就存在不精确的问题。比如你要买的书需要采购员到上海图书馆去进货,原来用的是1.8T的货车改为了2.0T的货车。但是你评估的信息可能没有及时更新,这样评估出到上海图书馆所需要的时间比实际2.0T要慢。这在ORACLE中好比服务器CPU增加成为双核,你评估的信息没有及时知道CPU的变化,可能得到一个不准确的值。IO也是这样。当评估出成本最少的执行计划后将执行计划和解析树存入到一块内存,给其它进程共享,这块内存就是LIBRARYCACHE。LIBRARYCACHE就是前面例子中的检索室,每个售货员可以在检索室里分享别的售货员如何买书的经验,这个经验存放在检索室。所以我们反复强调了这个检索室的重要性,同样LIBRARYCACHE也就显得非常重要。我们来看下LIBRARYCACHE结构图图例1我们给LIBRARYCACHE做一个定义:LIBRARYCACHE是存储最近频繁执行的SQL或PLSQL语句信息。LIBRARYCACHE组成============⊙共享SQLAREA:LIBRARYCACHE的核心部分是SQLAREA,它存放了执行计划和解析树,必须文本匹配才可以共享,它包括:⊕SQL语句文本⊕分析树语句的已编译版本⊕执行计划执行时要采取的步骤⊙共享PL/SQLAREA:存放编译代码,调试代码,解析树等信息⊙另外会存在控制部分,如LRU列表。LRU来控制最近最频繁使用语句的执行计划和解析树尽量不容易被挤出LIBRARYCACHE我们写的SQL语句,会进入SQLAREA,写的PLSQL申明块会在PL/SQLAREA,那LIBRARYCACHE大小由谁决定呢?ORACLE的共享池为动态管理的,LIBRARYCACHE的大小由sharedpoolsize决定,由ORACLE自动管理,不允许手工设置大小。LIBRARYCACHE是很重要的一个组件,它的架构涉及到很多性能优化的概念。由于是共享系统,所以也是最容易产生并发冲突的地方。我们在性能优化课程里会详细介绍。接下来我们学习共享池第二大重要内存组件DataDictionaryCache============在ORACLE处理客户请求后,对用户发送的SQL在处理分析执行计划和解析树前,还需要做两件事⊙一个是语法分析⊙一个是语意分析我们来看一个例子在outln用户下有一个表名data_dict_cache⊙我们看到上图第1步都是在语法分析,通过语法分析器判断,SELECT写错了,写成SELET。⊙第2-5步是语意分析阶段,查询语句通过判断数据字典DC_USERS,DC_PRIVS,DC_COLUMNS看是否有相应的对象和查看权限。由于数据字典表并不见得整个表的记录都会放入DATADICTIONARYCACHE,可能是部分字典行记录被存入,所以我们又称该内存区域为ROWCACHE(行缓存区)⊙第6步是分析阶段,生成执行计划和解析树,并存入LIBRARYCACHE。DATADICTIONARYCACHE组成===================⊙DC_USERS用户列表⊙DC_PRIVS权限列表⊙DC_TABLES表的列表⊙DC_COLUMNS某表的字段列表语意分析时首先在DATADICTIONARYCACHE查找我的语句中的用户名、表名、权限、字段名、SEQUENCE名等等是否在数据字典行缓存里,如果该字典不在数据字典行缓存里,去系统表空间数据字典调入DATADICTIONARYCACHE,然后搜索SQL中涉及的对象是否有对应的字典,如果没有就会报错。我们来查看下字典缓冲里的内容在数据库中可以通过数据字典v$rowcache来查询数据字典缓存有哪些。dc是字典单词缩写,后面跟对象类别。详细的介绍将在中级课程中涉及。我们先来看数据字典CACHE的结构图图例2数据字典缓存的内容如下:⊙数据字典CACHE保存了最近最常使用的数据对象定义,如用户、权限、列、表、索引等全部可以放到数据字典共享。⊙在SQL解析阶段,服务器进程会锁住这个字典,以避免对象定义的变化。另外会关联会话的对象锁,并设置锁模式为N⊙数据字典在磁盘有一份,ORACLE通过把数据字典保存到数据字典CACHE里,加快访问速度。⊙DATADICTIONARYCACHE大小由sharedpoolsize决定接下来我们学习SGA的第二大组件DatabaseBufferCache============在前面的例子中,小丽去静安书店买“CBO基础”这本书,但是店里的仓库没有这本书的库存,那只能去上海图书馆采购这本书。上海图书馆就是我们的DB库文件,但是如果我在静安店库房有“CBO基础”书的库存,那就直接可以从静安店库存卖给小丽,而不需要去上海图书馆拿。大家说要完成这笔交易哪个快?当然是静安店快,静安店的库存相当于ORACLE的内存,而上海图书馆相当于磁盘。如果直接在静安店仓库拿,就相当于直接从内存拿。我们知道内存比磁盘快上千百倍,而静安的库房就是我们下面要讲的一个重要内存组件“DATABASEBUFFERCACHE”翻译成中文称数据库高速缓存,它存放了最近最常使用的磁盘数据块的副本(默认池),我们的业务数据就存放在此。数据库高速缓存的内容如下:⊙通过将硬盘数据预取到数据库高速缓存,我们能够更快的获取、更新、删除数据,因为计算机正在执行是在内存中执行的。内存速度快,而且必须要调用到内存才能执行。⊙它也有一个控制结构,要管理BUFFER块的入队和出队,我们称LRU,最近最少使用的链。如果是涉及到数据变更的BUFFER块头,会链接到LRUW。⊙它的大小有DB_BLOCK_SIZE决定,这是9I的参数。在10G可以通过设置SGA_TARGET让ORACLE自动管理SGA内存大小。那为了更好的管理这个仓库,我们将仓库所涉及的货物类型不同,我们分成不同的小仓库。我们可以对仓库货物的使用特性设置3类仓库,系统中有一个是默认仓库,它在ORACLE中的大小由DB_CACHE_SIZE决定。还有些频繁查阅或者买卖的书(当前最流行的书),且书占用面积不大的一批货可以单独给它开辟一个仓库,让学生们总有机会在静安分店就能看到当前最流行的书。要看最流行的书永远钉在仓库中,就不需要跑到上海图书馆去进货了。这个被钉住的书存放的仓库在ORACLE中称为KEEP池。DB_KEEP_CACHE_SIZE就是这样一个仓库。这样的话,这些经常访问的货不会轻易被其它入库的货挤出。还有一类书籍,一年或者几年才会订购一次,而且量特别大,占用面积也很大(比如大百课全书),那如果不为它单独开个仓库,那估计默认仓库里没有机会给其它书存放了,甚至会被挤掉,送回上海图书馆。那ORACLE可以为这种频繁很低,量特别的大的货存放到一个专门指定的仓库,我们称其为RECYCLE库。中文称回收库,也就是用完了这批书马上就回收掉,不去占有这么大的内容,因为下次重用的机会也不大。所以回收池没有LRU的控制逻辑。当符合回收池的条件,我就给你分配回收池,不评估你的优先级。我们可以通过DB_CACHE_ADVICE的统计开关,ORACLE会获取不同CACHE大小下的使用效率。在10G和11G在自动统计和建议方面更人性化接下来我们学习9ISGA中最后一个必备的内存组件开始备课(2010.08.15)大家的小学毕业考试成绩已经出来了,今天晚点校长来给大家公布成绩,我们班有个同学这次考试考得非常好,选择题居然只错了一道,其他题也做的很棒,总成绩比第二名多出了10多分,这位同学看来也可以去当小学老师了,呵呵。言归正传,我们上节课学习了体系结构里的SGA的几个重要内部组件。这个也是我们第一章的重中之重,我们还是来回顾下。第一个问题:我们知道SGA是由多个功能不同的共享内存组件构成。那SGA有哪些内存组件构成?上个图看懂了,这个问题就OK了。主要largepool和javapool是可选的内存组件,而图的上面四个是必选的组件。10G还增加了Streamspool,在上图没有体现(上图是基与9I的),流池我们不过多介绍。下面是我自己的一个对SGA的总结:SGA其实就是一块巨大的共享内存区域,包含了ORACLE的数据缓冲及众多的控制结构。这里的数据可以被ORACLE的各个进程使用,如果有互斥的操作,如锁定一个内存对象,则需要通过Latch与Enqueue来控制。每个ORACLE实例(instance)只能启动一个SGA,除非通过RAC等一些特殊的全局管理方式,否则不同的实例只能访问自己的SGA区域。通过如下的方式就可以查看SGA大小:Showsga第二个问题:SGA的内存分配是按什么单位来进行分配的?内存分配需要按照颗粒大小来分配。selectcomponent,current_size,granule_size/1024/1024asGRANULE_SIZE(MB)fromv$sga_dynamic_components;GRANULE就是内存颗粒。内存分配就是按GRANULE的大小来的。第三个问题:我们知道共享池(Sharedpool)可以分为SQL语句缓冲区(LibraryCache)、数据字典缓冲区(DataDictionaryCache)那LibraryCache的主要功能是什么?主要的组成部分有哪些?还要注意的是,共享池采用了LRU算法来控制最近最频繁使用语句的执行计划和解析树尽量不容易被挤出LIBRARYCACHE我再把知识给大家串下,连接我们小学学过的一些内容:对与间歇性访问的比较大的对象,如自定义的过程与包,如果不想在运行过程中被系统自动交换出去,可以调用DBMS_SHARED_POOL.KEEP存储过程将该过程或包PIN在共享池,以减少重新载入的巨大代价。大家还记得手工清除共享池内容的命令吗?Altersystemflushshared_pool;不过注意,该命令不建议在高可用的生产环境上运行,测试实验的时候随便用。与共享池相关的视图很多,我这里给出几个在高可用生产环境中经常要遇到的视图。v$sqlareav$sqltext_with_newlinesv$sql_planv$shared_pool_advice这几个视图怎么来看,留给大家做课后作业。了解下每个视图查的都是些什么内容就行,不要深究,因为这几个视图是DBA在工作中经常使用的。第四个问题:LibraryCache和DataDictionaryCache可以手工指定吗?ORACLE的共享池为动态管理的,LIBRARYCACHE与DATADICTIONARYCACHE大小由sharedpoolsize决定,由ORACLE自动管理,不允许手工设置大小。另外,我们要注意,DATADICTIONARYCACHE是用户无法直接控制的,都是有ORACLE自己完成,真正与用户有关的其实是LibraryCache.可以通过数据字典v$rowcache来查询数据字典缓存有哪些。ROWCACHE(DataDictionaryCache)我不多复习了,大家自己下来复习下。搞清楚语义分析和语法分析。第五个问题:DatabaseBufferCache(数据缓冲区)又可以细分为哪三个部分?Defaultpool、Keeppool、Recyclepool,在9I以前,他们对应的是db_block_buffers、buffer_pool_keep、buffer_pool_recycle三个参数,分别表示每个缓冲区块的个数