ORACLE_SGA

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ORACLE_SGA管理
一、System Global Area(SGA) 的定义
SGA是一块用于加载数据、对象并保存运行状态和数据库控制信息的一块内存区域,用来存放操作的数据/库缓存/数据字典等控制信息的内存区域/这块区域中的大多数内容都是共享存在,几乎所有的Oracle进程都会访问这块内存中的数据。

在数据库实例启动时分配,当实例关闭时释放,每个实例都有自己的SGA区。

二、SELECT System Global Area(SGA)
2.1 SQL> SHOW SGA;
2.2 SQL> select * from v$sga;
2.3 SQL> select name,bytes /1024/1024 from v$sgainfo; 详细查询sga信息
三、ALTER SYSTEM SET…设置SGA参数参数分配内存
3.0 SQL> show parameter db_*_ cache_size;
查询SGA 个别的参数
3.1 ALTER SYSTEM SET DB_*_CACHE_SIZE=200M;
3.1.1 SGA的参数
3.1.1.1 SGA_TARGET
SGA_TARGET: 用于控制SGA的自动内存管理,该参数值大于0时,则
SGA内存将会自动分配,等于0时则由DBA手动设置相关初始化参数可能告知SGA的内存分配。

3.1.1.2 STATISTICS_LEVEL
该参数设置为TYPICAL或者ALL,以便收集到足够的统计信息,否则Oracle没有相关的统计信息作参照,就无法确定如何分配SGA各部分内存。

3.1.1.3 SGA_MAX_SIZE
SGA_MAX_SIZE: 控制实例运行时SGA最大能够使用的内存空间,SGA中各个部分占用的内存加在一起不能超出SGA_MAX_SIZE的值。

3.1.1.4 其他参数
3.1.1.
4.1 Shared_pool_siz e
Shared_pool_siz e: 用于控制共享池内存
3.1.1.
4.2 java_pool_size
java_pool_size: 用于控制Java池内存
3.1.1.
4.3 large_pool_size
large_pool_size: 用于控制大池的内存
3.1.1.
4.4 streams_pool_size
streams_pool_size: 用于控制流池的内存
3.1.1.
4.5 db_*_cache_size
db_*_cache_size: 用于控制数据缓冲池的内存
3.1.1.
4.6 log_buffer
log_buffer:用于控制日志缓冲区的内存
3.2 Granule 定义Oracle数据块的大小,最小分配单位
db_cache_size最小值为一个粒度(Granule),粒度也是Oracle 9i引入的一个新概念,
是连续虚拟内存分配的单位,Granule的大小不能由DBA修改,而是由整个SGA的大小和操作系统平台的类型进行分配。

3.2. 1 Granule 为4MB的情况
大多数平台下,当SGA小于1GB时
3.2. 2 Granule 为8MB的情况
Windows 32位平台,当SGA大于1GB时
3.2. 3 Granule 为16MB的情况
大多数平台下,当SGA大于1GB时
3.2. 4 V$SGA_DYNAMIC_COMPONENTS查看当前实例的力度单位
SQL> select component, granule_size/1024/1024 from v$sga_dynamic_components;
3.3 设置SGA参数时的原理
在为SGA设置参数时,实际设置的参数的值必须是Granule的整数倍,如果指定的参数不是Granule的整数倍,Oracle会自动进行调整。

3.3.1 Granule 粒度整数倍原理
3.3.2 总和小于SGA_MAX_SIZE最大值原理
SGA_MAX_SIZE初始化参数设置SGA 的总内存最大上限值(只是上限值,并不一定就是SGA实际占用的内存),在实际运行过程中,SGA中各部分占用的内存加住在一起不能超出SGA_MAX_SIZE的参数值,否则会触发ORA-00384错误。

3.3.3 动态修改原理
从Oracle 9i开始,Oracle允许在实例运行过程中,动态修改SGA的内存分配参数,而不需要重新启动实例。

在Oracle 10g版本中,直接支持修改当前内存值的SGA参数,包括
SHATED_POOL_SIZE
LARGE_POOL_SIZE
JAV A_POOL_SIZE
STREAMS_POOL_SIZE
CACHE_SIZE
SGA_TARGET
3.4 SGA各部分内存的特点
SGA中各部分所使用的内存只能供自己使用。

SGA的内存对外部是共享的,但是的对内部是各自独立非共享的。

3.4 自动SGA内存管理
3.4.1 SGA_TARGET参数设置
该参数值值大于0时,则SGA内存将会自动分配,等于0时则由DBA收到设置相关初始化参数控制SGA的内存分配.
3.4.2 STATISTICS_LEVEL参数设置
设置为TYPICAL或者ALL,以便使收集到足够的统计信息。

否则Oracle没有有相关的统计信息作参照,就无法确定如何分配SGA各部分的内存。

该参数值值大于0时,则SGA内存将会自动分配,等于0时则由DBA收到设置相关初始化参数控制SGA的内存分配.
3.5 优化database buffer cache
3.5.1 首先查看database buffer cache 的大小
3.5.2 第二步,查看缓冲区命中率是否需要调优
3.5.3 第三步,获取Oracle的推荐值
四、The Struct of System Global Area(SGA)
4.1 Database Buffer Cache 缓冲区缓存
Buffer Cache用于存储最近使用的数据块,这些数据块可能是被修改过的,也可能是未经修改的,我们知道,在Oracle对数据的处理过程中,代价最的是物理I/O(Physical I/O)操作了。

在Oracle9i之前,Buffer Cache的设置主要由两个参数决定:db_block_buffers和db_block_size。

db_block_buffers设置分配给Buffer Cache的缓冲区数量,这个数值乘以db_block_size 得出的才是Buffer Cache的大小。

从Oracle 9i开始,Oracle引入了一个新的初始化参数db_cache_size,该参数用来定义主Block_Size(db_block_size定义的块大小)的Default缓冲池的大小。

4.1.2 LRU 算法管理Buffer Cache
Oracle管理Buffer Cache使用的LRU算法。

但是很多的批处理操作(如全表扫描)可能会导致Buffer Cache的刷新,将经常需要使用的数据“挤出”Buffer Cache。

你可将LRU理解成一个队列,哪些曾经访问过,但是最近没有被访问的数据放在LRU 尾部,而那些经常访问的数据则放在LRU 头部,头部也被称为MRU(Most Recently Used).随着频繁被访问的数据不断移动到MRU端,相应那些不经常访被访问到的数据则逐渐向LRU尾部移动。

4.1.2.1 Write List (写入列表)
写入列表中维护的是Dirty Block(脏缓存块),指那些发生了修改,但尚未保存到数据文件的数据。

4.1.2.2 List Recently Used ,LRU(最近最少使用列表)
最近最少使用列表LRU包括Free Buffers(空闲缓存),Pined Buffers(命中缓存),以及那些还没有来得及移到写入列表的Dirty Block脏缓存块。

4.1.2.3 Cache Hit (缓存命中)
当用户访问数据时,Oracle先从Buffer Cache中查询,如果能够找到相应的数据,Oracle 就会直接将数据从内存中读取并返回给用户。

4.1.2.4 Cache Miss(缓存失败)
当用户访问数据时,Oracle先从Buffer Cache中查询,如果没有查询到,Oralce就必须访问数据文件,找到所需要的数据块,然后复制到Buffer Cache中,最后再从Buffer Cache 中返回给用户。

4.1.2.4.1 Cache Miss(缓存失败)后Oracle原理
4.1.3 Buffer Cache 多缓冲池技术
4.1.3.1 SELECT Buffer Cache
Keep Pool池:存放经常使用的数据
Recycle Pool池:存放一次性读取使用的数据
Default Pool池:存放未指定存储池的数据,按照LRU算法管理。

SQL> select id,name,block_size,current_size,target_size 查询各个缓冲池的设置
2 from v$buffer_pool;
4.1.3.1.2 看Buffer Cache 各个数据块的大小
SQL> show parameter cache_size;查看缓冲池数据块大小的设置NAME TYPE V ALUE ------------------------------------ ----------- --------
client_result_cache_size big integer 0
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 0
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
SQL>
4.1.3.2 各个缓冲池对应的设置参数
DB_CACHE_SIZE 对应Default Pool
BUFFER_P00L_KEEP 对应Keep Pool
BUFFER_POOL_RECYCLE 对应Recycle Pool
三个池之间相互独立
默认情况下,所有表都使用DEFAULT池,它的大小就是Buffer Cache的大小,由初始化参数db_cache_size(8i 中是db_block_size*db_block_buffers)决定。

4.1.3.3 创建表时指定缓冲存储池
如果在创建数据表或者修改数据表时,指定STORAGE(BUFFER_POOL KEEP)或者STROAGE(BUFFER_POOL_RECYCLE)语句,就设置了这张表使用KEEP或者RECYCLE 缓冲区。

这两个缓冲区的大小分别由初始化参数db_keep_cache_size和db_recycle_cache_size来决定。

SQL〉CREATE TBALE table_name STORAGE(BUFFER_POOL,KEEY)
SQL〉ALTER TBALE table_name STORAGE(BUFFER_POOL,DEFAULT)
在Oracel 8i中,只能修改参数文件,然后重新启动数据库,才能使对这两个参数的修改生效。

在Oracle 9i中,可以动态修改。

4.1.3.4 创建非标准块的表空间的步骤
4.1.3.4.1 首先必须为该非标准块分配内存区
SQL> ALTER SYSTEM SET DB_16K_CACHE_SIZE=100M;
4.1.3.4.2 创建表空间并制定数据块的大小
SQL>CREATE TABLESPACE TBS16K DATAFILE
2 ‘f:\oracle\oradatatbs1601.dbf’ size 100M BLOCKSIZE 16K;
我们可以看到Oracle 9i允许在同一个数据库中存在多种Block_size的表空间,分别为2k、4k、8k、16k、32k的Block_size,其中由db_block_size定义的块大小被称为主block_size. 如果在数据库中创建不同block_size的表空间,则需要分别设定db_nk_cache_size参数。

各个缓冲池的设置,可以通过查询v$buffer_pool得到:
4.2 Shared Pool (共享池)
从一个逻辑层面来看,shared pool由以下两部分构成:
Library cache 和dictionary cache
4.2.1 library cache
Library cache存放了最近执行的SQL语句、存储过程、函数、解析数以及执行计划等。

Library Cache是shared pool中最重要的部分,也是在shared pool中进进出出最活跃的部分,需要我们仔细研究,所以,我们在说到shared pool实际上可以认为是在指library cache .
library cache 最主要的功能就是存放用户提交的SQL语句、SQL语句相关的解析树(解析树也就是SQL语句中所涉及到的所有对象的展现)、执行计划、用户提交的PL/SQL程序块(包括匿名程序块、存储过程、包、函数等)以及他们转换后能够被oracle执行的代码等。

为了对这些内容进行管理,还存放了很多控制结构,包括lock、pin、dependencytable等。

Library cache 还存放了很多的数据库对象的信息,包括表、索引等等。

有关这些数据库对象信息的都是从dictionary cache中获得的。

如果用户对library cache 中的对象信息进行了修改,则这些修改回返回到dictionary cache 中。

4.2. 1.1 object
在library cache中存放的所有信息单元都叫做object,这些对象可以分成两类:
4.2. 1.1.1 存储对象
也就是上面所说的数据库对象。

他们是通过显示的SQL语句或者PL/SQL语句程序创建出来的,如果要删除他们,也必须通过显示的SQL命令进行删除。

这类对象包括表、视图、索引、包、函数等等;
4.2. 1.1.2 过渡对象
也就是上面所说的用户提交的SQL语句或者提交的PL/SQL程序块等。

这些过渡对象是在执行SQL语句或PL/SQL 的过程中产生的,并缓存在内存里。

如果实例关闭则删除,或者由于内存不足而被交换出去,从而被删除。

4.2. 1.2 cursor
当用户提交SQL语句或者PL/SQL程序块到oracle的shared pool以后,在library cache 中生成的一个可执行对象,这个对象就叫做cursor(游标)。

不要把这里的cursor与表中的SQL的游标混淆起来了,标准的SQL游标如无特别说明,都是指library cache中的可执行对象。

4.2. 1.2.1 cursor的特点
Cursor是可以被所有进程共享的,也就是说如果100个进程都执行相同的SQL语句,呢么100个进程都以同时使用该SQL语句所产生的游标,从而节省了内存。

每个游标都是由library cache中的两个或多个对象所体现的,至少两个对象。

4.2. 1.2.2 parent cursor
一个对象叫做父游标(parent cursor),包含游标的名称以及其他独立于提交的用户信息。

从v$sqlarea视图里看到的都是有关父的信息;
4.2. 1.2.3 child cursor
另外一个或多个对象叫做子游标(child cursors),如果SQL文本相同,但是可能提交的SQL语句的用户不同,或者用户提交的SQL语句所涉及到的对象名为同名字等,都有可能生成不同的子游标。

因为这些SQL语句的文本虽然完全一样,但是上下文环境却不一样,因此这样的SQL语句不是一个可执行的对象,必须细化为多个child cursor后才能够执行。

子游标含有执行计划或者PL/SQL对象程序代码块等。

4.2. 1.3 hash bucket
在oracle的内部管理的过程中大量用到了hash算法。

所谓hash算法,就是根据要查找的值,对该值进行一定的hash算法后得出该值所在的索引号,然后进入到该值应该存在的一列数值列表(可以理解为一个二维的数组)里,通过该索引号去找到它应该数据哪一个列表。

然后再进入所确定的列表里,对其中所含有的值,进行一个一个的比较,从而找到该值。

这样就避免了对整个数值列表进行扫面才能找到该值,这种全表扫面方式想显然要比hash 查找方式抵低效的多,其中,每个索引号对应的数值列在oracle里都叫做一个hash bucket.
4.2. 1.3. 1 library object handle
Library cache 就是使用多个hash bucket 来管理,每个hash bucket后面都串联着多个library object handle(句柄),这些句柄描述了library cache 里的对象的一些属性,包括名称、标记、指向对象所处的内容地址的指针等。

下图可以描述library cache的整体结构:
Object handle存放了对象的name、namespace、有关对象的一些标记(比如对象是否为只读,为本地对象还是远程对象、是否被pin在内存中等等)以及有关对象的一些统计信息等。

而且,object handle中还存放了当前正在lock住和pin住该对象的用户列表、以及当前正在等待lock 和pin 该对象的用户列表。

4.2. 1.3. 1. 1 ASCII 数值
当有一条SQL语句进入library caceh的时候,先将SQL文本转化为对应的ASCII数值,然后对这些ASCII数值进行hash函数运算:传入函数的是SQL语句的name和namespace。

4.2. 1.3. 1. 2 name
Name,对于SQL语句来说name就是SQL语句的文本
4.2. 1.3. 1. 3 namespace
Namespace,对于SQL来说是“SQL Area”,表示共享游标。

4.2. 1.3. 1. 3.1 v$librarycache
V$librarycache查询所有的namespace
4.2. 1.3. 1. 4 hash bucket
运算hash函数后得到一个值,该值就是hash bucket的号码,从而该SQL语句被分配到该号的hash bucket里去。

实际上,hash bucket就是通过串联起来的对象句柄才体现出来的,它本身是一个逻辑上的概念,是一个逻辑组,而不像是一个具体的实体。

Oracle根据share_pool_size所指定的shared pool尺寸自动计算hash buckets的个数,shared pool 越大,则可以挂载的对象句柄就越多。

4.2. 1.3. 1. 4.1 reload
当某个进程需要处理某个对象时,比如处理一条新进入的SQL语句时,它会对SQL语句应用hash算法,以决定其所在的hash bucket的编号,然后进入该hash bucket进行扫描比较。

有可能会发生该object handle(对象句柄)存在,但是object handle所指向的对象已经被交换出内存的情况出现。

这时对应的对象必须被再次装载(reload)。

也可能改对象的句柄都不存在,这时进程必须重新构建一个object handle到hasf bucket 上,然后再重新装载的对象。

4.2. 1.3. 1. 5 SQL 语句的相关对象
SQL语句相关的对象有很多(最直观的就是SQL语句的文本),这些对象存放在library cache里,他们都通过object handle来访问,可以把library cache理解为一本书,而SQL语句的对象就是书中的页,而object handle就是目录,通过目录可以快读定位到指定内存的页。

4.2. 1.3. 1. 6 Heap 0 对象的指针
Object handle 中最重要的内容就是Heap 0对象的指针了,
Heap 0 用来存放与对象有直接关系的一些信息,比如对象类型、对象相关的表(比如依赖表、子表等)、指向对象的其他数据块指针(这些数据块执行了实际存放SQL文本、PL/SQL代码、错误信息等的大内存块,这些大内存块一次叫做heap 1、2、3等)等信息。

4.2. 1.3. 1. 7 Heap
Heap 是由一个或多个chunk组成的,这些chunk可是是分散的分布在library cache中的,不需要连续分布。

Heap 是通过调用服务器进程进行分配的,任何对象都具有heap 0,至于还应该分配哪些其他的heap则是由对象的类型决定的,比如SQL游标具有heap 1和heap 6,而PL/SQL 程序包则具有heap1、2、3和4按照heap的使用情况,Oracle 会在SGA、PGA或者UGA 中分配heap,但是heap 0始终都在library cache中进行分配的。

如果所请求的heap已经在SGA中分配了,则不会再PGA中再次分配heap。

4.2. 1.3. 1. 8 对上图的详细解释
如上图中所看到的heap 0实际上是指heap 0的句柄,其中包含的对象包括:
4.2. 1.3. 1. 8. 1 object type
Library cache 中的对象类型包括:表、视图、索引、同名词等等,每个对象只能有一个object type.根据object type将对象归类到不同的namespace里。

一个objcet type对应一个namespace,但是一个namespace可能对应对各object type.以下是比较常见的那么生怕测:4.2. 1.3. 1. 8. 1. 1 SQL AREA
SQL AREA:也可以叫做CRSR,表示shared cursor,存放共享的SQL语句。

4.2. 1.3. 1. 8. 1. 2 TABLE/PROCEDURE
TABLE/PROCEDURE:存放object type包括:table、view、sequence、synonym、procedure 的定义、function的定义以及package的定义。

4.2. 1.3. 1. 8. 1. 3 BODY
BODY:存放procedure的实际代码、function的实际代码以及pagkage的实际代码
4.2. 1.3. 1. 8. 1. 4 TRIGGER
TRIGGER:存放的object type 为trigger
4.2. 1.3. 1. 8. 1. 5 index
index:存放的object type 为index
4.2. 1.3. 1. 8. 2 object name
Object name:对象名称由三部分组成
4.2. 1.3. 1. 8. 2. 1 Schema
Schema的名称,对于共享游标(SQL语句或PL/SQL程序块)来说为空。

4.2. 1.3. 1. 8. 2. 2 对象名称
对象名称分为两种情况:对于共享游标(SQL语句或PL/SQL程序块)来说,其对象名称就是SQL语句的语句本身;而对于其他对象(比如表、视图、索引)就是其在数据字典中的名称。

4.2. 1.3. 1. 8. 2. 3 Database link
Database link的名称,这是可选的,如果是本地对象,则为空。

这样,对象的名称的格式为:@DBLINK.比如,可以为hr.employees@,也可以为hr.employees等。

4.2. 1.3. 1. 8. 3 flags
Flags: flags 主要用来描述对象是否已经被锁定。

对象具有三种类型的flag:
4.2. 1.3. 1. 8. 3. 1 public flag
Public flag: 表示对象上没有锁定(pin)或者latch
4.2. 1.3. 1. 8. 3. 2 status flag
Status flag: 表示对象上存在锁定(pin),说明对象正在被创建或者删除或者修改等
4.2. 1.3. 1. 8. 3. 3 specitial flag
Specitial flag: 表示对象上存在library cache latch
4.2. 1.3. 1. 8. 4 tabl es
Tables: 对每个对象,都会维护以下一串tables中的若干个
4.2. 1.3. 1. 8. 4. 1 dependency table
Dependency table: 含有当前对象所依赖的其他对象。

比如一个视图可能会依赖其组成的多个表、一个存储过程可能依赖其中所调用的其他存储过程、一个游标可能依赖其中所涉及到的多个表的。

Dependency table中的每个条目都指向一块物理内存,该物理内存中含有当前对象所依赖的对象句柄。

4.2. 1.3. 1. 8. 4. 2 child table
Child table: 含有当前对象的的字对象,只有游标具有child table. Child table中的每个条目都指向一个可执行的SQL 命令所对应的句柄。

4.2. 1.3. 1. 8. 4. 3 translation table
Translation table : 包含当前对象所引的的名称是如何解释为Oracle 底层对象的名称,只有游标具有translation table。

4.2. 1.3. 1. 8. 4. 4 authorization table:
Authorization table: 包含该对象上所对应的权限,一个条目对应一个权县。

4.2. 1.3. 1. 8. 4. 4 access table:
Access table :对于dependency table 中的每一个条目,都会在access table中存在对应的一个或多个条目。

比如,假设对象A依赖对象B,那么A的dependency table 和access table 中都会存在一个条目指向B。

位于access table中的指向B的条目说明了对B具有什么样的访问类型,从而也说明了用户要执行A则必须具有对B的权限。

4.2. 1.3. 1. 8. 4. 5 read-only dependency table:
Read-only dependency table:类似于dependency table,但是存放的是只读对象。

4.2. 1.3. 1. 8. 4. 6 schema name table:
Schema name table 包含authorization table的条目所属的schema
4.2. 1.3. 1. 8. 5 data bl ocks:
Data blocks:对象的其他信息会存放在不同的heap中,为了找到这些heap,会在heap 0中存放多个(最多16个,但是这16个data block不会都用到)data blocks结构,每个data block 含有指向这些实际heap内存块的指针。

除了heap 0 以外,还有11个heap ,根据对象的不同进行分配,并存放了不同的内容。

4.2. 1.3. 1. 8.
5. 1 heap 1
Heap 1:存放PL/SQL对象的源代码。

Heap 2:存放PL/SQL对象的解析树,这有个好听的名字,DIANA,
Heap 3:存放PL/SQL对象的伪代码。

Heap 4:存放PL/SQL对象基于硬件的伪代码
Heap 5:存放了编译时的错误信息
Heap 6:存放了共享游标对象的SQL文本。

Heap 7:可用空间
Heap 8-11:根据对象的不同而使用的子heap
4.2.2 dictionary cache
Dictionary cache则存放了在执行SQL语句过程中,所参照的数据字典信息,包括SQL 语句所涉及的表明、表的列、权限信息等。

Dictionary cache也叫做row cache,因为这里面的信息都是以数据行的形式存放的,而不是以数据块的形式存放的。

对于dictionary cache 来说,Oracle倾向于将它们一直缓存在shared pool里,而不会将他们交换出内存。

4.2.3 shared pool 组件之间的关系图
从图中得出,当SQL语句(select object_id,object_name from sharedpool_test)进入library cache时,Oracle会到dictionary cache中去找与sharedpool_test表有关的数据。

字典信息,比如表名、表的列等,以及用户权限等信息,如果发现dictionary cache 中没有这些信息,则将会将system表空间里德数据字典信息调
入buffer cache 内存,读取内存数据块里的数据字典内容,然后将这些读取出来的外部数据字典信息的内容按照行的形式放入dictionary cache 里,从而构造出dc_tables之类的对象。

然后再从dictionary cache中的行数据中取出有关信息放入library cache 中。

4.2.4 shared pool运行原理
4.2.4.1 解析SQL语句
Oracle 数据库作为一个管理数据的产品,必须能够认出用户所提交的管理命令(也就是SQL语句),从而进行响应。

认出的过程叫做解析SQL语句的过程。

解析的过程是一个相当复杂的过程,它要考虑各种可能的异常情况,比如SQL语句涉及到的对象不存在、提交的用户没有权限等。

而且还要考虑如何执行SQL语句,采用什么样的方式去获取数据等。

解析的最终结果是要产生Oracle自己内部的执行计划,从而指导SQL的执行过程。

可以看到,解析的过程是一个非常消耗资源的过程。

因此,Oracle对SQL语句进行了概括和抽象:
4. 2.4.1.1 SQL 静态部分
SQL 语句的静态部分,也就是SQL语句本身的关键词、所涉及的表名称以及表的列等。

4.2.4.1.2 SQL 动态部分
SQL 语句的静态部分,也就是SQL语句本身的关键词、所涉及的表名称以及表的列等。

对SQL动态部分的解析的影响相比静态部分解析的影响来说是微乎其微的。

4.2.4.1.3 SQL 共享池(shared pool)
如果Oracle在缓存中没有找到用户提交来的语句的相同语句(执行计划),则必须重新从头到尾进行完整的解析过程这部分存放SQL语句的内存叫做shared pool(共享池)
4.2.4.1.4 shared_pool_size
该参数决定shared pool大小,10g以后可以不用设定该参数。

4.2.5 Shared Pool内存块
4.2.
5.1 Chunk
从一个物理层面来看,shared pool 是有许多内存块组成,这些内存块通常称为为chunk。

Chunk是shared pool中内存分配的最小单位,一个chunk中的所有内存都是连续的。

这些chunk刻意分为四类,这四类可以从x$ksmsp(该视图中的每个行都表示share pool里德一个chunk)的ksmchcls字段看到:(sys登录)
4.2.
5.1.1 Free
这中类型的chunk不包含有效的对象,可以不受限制的被分配
4.2.
5.1.2 Recr
意味着recreatable,这种类型的chunk里包含的对象可以在需要的时候被临时移走,并且在需要的时候被重新创建。

比如对于很多有关共享SQL语句的chunk就是recreatable的。

4.2.
5.1.3 Freeabl:
这中类型的chunk 包含的对象都是曾经被session使用的,并且随后被完全或部分释放的。

这种类型的chunks不能临时从内存移走,因为它们是在处理过程中间产生,如果移走的话就无法被重建。

4.2.
5.1.4 Perm
意味着permanent,这种类型的chunks包含永久的对象,大型的permanent类型的chunks 也可能含有有用的空间,这部分可用空间可以在需要的时候释放回shared pool里。

4.2.
5.1.5 chunk 类型存放位置
当chunk属于free类型的时候,它就不属于library cache,也不属于dictionary cache。

如果该chunks被用于存放SQL游标时,则chunk进入library cache; 同样,如果该chunk 被用于存放数据字典的信息时,则该chunk进入dictionary cache 。

4.2.
5.1.6 shared_pool_reserved_size
对于非常大的对象,Oracle会为他们单独从保留区域里分配空间,而不是从这个可用的chunk链表中来分配空间。

这部分空间的大小尺寸就是由初始化参数shared_pool_reserved_size决定的。

缺省为shared_pool_reserved_size的5%,这块保留区域与正常的chunk的管理是完全分开的,小的chunk不会进入这块保留区域,而这块保留区域的可用chunk也不会挂在bucket上。

4.2.
5.1.
6.1 v$shared_pool_reserved
V$shared_pool_reserved 视图用来查看shared_pool_reserved_size的使用情况,通常来说该视图的request_misses字段显示了需要从保留区域的可用链表上获得的大的chunk而不能获得的次数,该字段应该尽量为0.
4.2.
5.2 buckets
在share pool里,可用的chunk(free)类型会被串起来成为可用的链表(free lists)或者可以叫做buckets(一个可用的free list就是一个bucket)。

我们可以使用下面的命令将shared pool的内存转储出来看这些bucket
Alter session set events ‘immediate trace name heapdump level 2’
我们可以看到,可用的chunk链表(bucket)被分成了254个,每个bucket上挂的chunk 的尺寸是不一样的,有一个递增的趋势,每个bucket上都有一个size字段,这个size就说明了该bucket上能链接的可用的chunk的大小尺寸。

4.2.
5.2.1 进程访问bucket原理
当一个进程需要shared pool里的一个chunk时,假设当前需要21个单位空间,则该进
程首先到符合所需空间大小的bucket(这里是bucket2)上去扫描,以找到一个尺寸最合适的chunk,扫描持续到bucket的最末端,直到找到完全符合尺寸的chunk位置。

如果找到的chunk的尺寸比需要的尺寸要大,则该chunk就会被拆分成两个chunk,一个chunk被用来存放数据,而另外一个则成为free类型的chunk,并被挂到当前该bucket 上,也就是bucket2上。

然而,如果该bucket不含有任何需要尺寸的chunk,那么就从下一个非空的bucket上(这里就是bucket3)获得一个最小的chunk,
如果在剩下的所有bucket上都找不到可用的chunk,则需要扫描已经使用的recreatable 类型的chunk链表,从该链表上释放一部分的chunk出来,因为只有recreatable类型的chunk 才是可以被临时移出内存的。

当某个chunk正在被使用时(可能是用户正在使用,也可能是使用了dbms_shared_pool 包将对象钉在shared pool里),该chunk是不能被移出内存的。

比如某个SQL语句所引用的表、索引等对象所占用的chunk也是不能够被移出内存的。

当shared pool中无法找到足够大小的所需内存是,包ORA-4031错误。

4.2.
5.2.2 shared pool latch
对bucket的扫描、管理、分配chunk等这些操作都是在shared pool latch的保护下进行的。

如果shared pool含有数量巨大的非常小的free类型的chunk的话,则扫描bucket时,shared pool latch会被锁定很长时间,如果增加shared pool的尺寸,仅仅是延缓shared pool latch的争用。

到了9i以后,由于大大增加了可用的chunk链表(也就是bucket的数量),同时,每个bucket所管理的可用的chunk的size递增幅度非常小,于是可以有效的将可用的chunk都均匀分布在所有的bucket上。

这样做的好处是每个bucket所挂的free类型的春困都不多,所以在查找可用的chunk 而持有shared pool latch的时间也可以缩短很多。

4.2.4 Library Cache 的结构
4.2.5 Dictionary Cache
Dictionary cache 中存放了在执行SQL语句过程中,所参照的数据字典信息,包括SQL 语句所涉及的表明、表的列、权限等信息。

Dictionary cache也叫做row cache,因为这里面的信息都是以数据行的形式存放的,而不是以数据块的形式存放的。

对于dictionary cache来说,oracle 倾向于将他们一直缓存在shared pool里,不会将他们交换出内存,因此我们不用对他们进行过多关注。

Shwared Pool 是SGA区中最重要的组成部分,由Library Cache、Dictionary Cache、Buffers for Parallel Execution Messages、Control Structures几个部分构成
4.3 Redo Log Buffer(日志缓冲池)
Redo Log Buffer存储redo entries(重做日志条目),日志记录数据库变更,最终将被写出到重做日志文件中,在数据库崩溃或故障时用于恢复;Redo Log Buffer的大小由log_buffer 决定。

4.4 Large Pool(大池)
Large Pool是SGA的一个可选组件,通常用于共享服务器模式(MTS)/并行计算或RMAN的备份恢复等操作。

4.5 Java Pool(Java池)
主要用于JVM等Java选件
4.6 Streams Pool(流池)
Streans Pool是Oracle 10g引入的概念,为Oracle的Streams功能所使用,如果不定义该参数,这部分内存将从Shared Pool中分配。

3.1.8 SQL> select * from v$sgastat; 查询SGA分配和使用的具体信息
SQL> show sga;
3.1.9 SQL> show parameter sga_max_size 查询SGA最大的参数设置
SQL> show parameter sga_max_size
NAME TYPE V ALUE
------------------------------------ ----------- --------
sga_max_size big integer 512M
SQL>
这里的SGA总和受参数SGA_MAX_SIZE设置的影响
Fixed Siize部分是SGA中的固定部分,包含数据库和实例状态等通用信息,后台进程需要访问这部分信息,不存储用户数据,通常只需要很小部分内存。

3.2 SGA 管理变迁
在Oracle 8i之中,当需要修改SGa参数时(如share_pool_size),必须修改参数文件,重新启动数据库之后,修改才能生效。

从Oracle 9i开始,Oracle推出了动态SGA调整,也就是说,允许不重新启动数据库而使得SGA的修改生效。

在Oracle 9i中,可以设置SGA_MAD_SIZE,该参数用以控制各缓冲池使用的内存总和,本质上是在进程中预先分配一段虚拟地址备用而不分配物理内存,目的是防止和进程私有地址段冲突。

设置了该参数之后,可以通过在线方式修改Oracle SGA各内存组件的内存分配,经常可能用到类似如下命令
只要总的SGA内存设置不超过SGA_MAX_SIZE的设置,更改都可以立即生效。

但是需要注意的是,在Oracel 9i中,动态减小内存设置可能会触发一些Bug,在繁忙的生产系统中,缩减各组件的内存应该是相当慎重的。

如果内存不足,则Oracle会给出错误,提示内存缺乏。

3.2 动态修改SGA参数的规则。

相关文档
最新文档