oracle内存结构


oracle内存结构_oracle

oracle内存结构由SGA与PGA组成,实例启动的时候,SGA与后台进程启动,

SGA:


oracle内存结构_内存结构_02


oracle内存结构_oracle_03





PGA:是oracle给server进程分配的一个内存空间,在专用服务器配置模式下,UGA几乎是PGA的代名词,UGA就包括在PGA当中,当一个server进程启动时PGA/UGA就随之分配,server进程关闭,PGA/UGA也随之释放。PGA不属于实例范畴。但在共享服务器模式下,UGA的信息可能存放在SGA中,此时UGA与PGA应该是分开的!所以PGA包括进程内存,还可能包含UGA。


pga 是一个进程的地址空间,
uga是一个session的使用到的部分内存空间..
如果是decicated server模式, uga是在pga中的, 如果是shared server模式下, uga是在sga中的(这是了large_pool的话, 就在Large-_pool中,否则在shared pool中.)


当workarea_size_policy设置为AUTO,pga_aggregate_target有一个非0值时,表示启动自动PGA管理。在Oracle 11g r1后,可以设置memory_target参数,它会确定分别为SGA PGA分配多少内存!

不管手动或自动管理PGA时都进一步分到以下的具体参数中:

sort_area_size

sort_area_retained_size

hash_area_size



当服务器配置为专用服务器配置:每个会话都会生成一个专用服务器进程(server process),每个会话与专用的服务器进程为一对一的关系。

共享服务器配置:在共享服务器配置中,oracle使用一个”共享进程池“为大量用户会话提供服务,是一种连接池机制,

专用服务器配置与专用服务器配置最大的区别:共享服务器配置中与数据库连接的客户进程不会与共享服务器进程(server process)直接通信,而专用服务器配置中客户进程是直接与专用服务器进程通信,原因在于这个共享服务器进程是共享的。为此在客户进程与共享服务器进程中引入了一个调度器(dispatcher),这个调度程序首先会把客户进程放入SGA的请求队列中,当有空闲的共享服务器进程时,调度器就会把此客户请求排列过去给它处理。



oracle内存结构_内存结构_04


oracle内存结构_内存结构_05

show sga时

Fixed Size:

oracle 的不同平台和不同版本下可能不一样,但对于确定环境是一个固定的值,里面存储了SGA 各部分组件的信息,可以看作引导建立SGA的区域。

Variable Size:
包含了shared_pool_size、java_pool_size、large_pool_size 等内存设置



shared pool:


oracle内存结构_内存结构_06

shared pool:用于存放最近执行过的SQL语句和最近访问过的数据对象声明,包含二类文件:库缓存文件和数据字典缓存文件

如果是SGA自动内存管理,show parameter shared  shared_pool_size=0


可以通过查询v$sgastat视图获取

select sum(bytes)/1024/1024 mbytes from v$sgastat where pool='shared pool';

select name,value from v$sysstat where name  like 'parse%';查看软硬解析情况


select count(*) from x$ksmsp;  查询当前shared pool中一共有多少正在用的chunk!!

当又执行一些硬解析后,又会从free chunk中拿出一些chunk来用,此值又会增加!

shared pool内存组成结构:(内存怎么组织管理的)

1、free

2、libnary cache

3、data dictionary cache

shared pool中的内存都是以chunk的形式组织的,

Libary cache里边也有chain,但chain下的chunk不是以大小组织的,而是以SQL语句经过ASCIL码运算后产生的数字码来排列,当解析的时候,用SQL语句经过ASCIL码运算经过哈希运算后得到的数值在libnary cache里找对应的chain,然后在这条chain遍历之后发现里面有相同值的哈希的chunk的时候,这时候就不需要确解析了,


shared pool free 空间里有许多chain(链),chain上挂着许多空闲的chunk(块),不同chain上的chunk大小不同,当我们需要(SQL解析的时候)空闲的chunk的时候,就根据我们需要的大小去相应的chain上去找,找到后就写入相关信息,此时可能就会产生没用完的小 free chunk,也就是碎片,我们就把他再挂到其它小一点的 free chain链上去!

只有硬解析的时候才需要我们从free 空间里去找chunk,


alter system flush shared_pool;清空shared_pool中的所有chunk,把所有的libnary cache chunk都清空到free空间里去了,此后所有的解析都需做硬解析了,也可以用解决ora-4031,(治标不治本)




执行一条SQL语句4步过程:

1.parse  (曾经执行过的SQL语句可通过v$sqlarea视图查询)(硬解析/软解析)

    a.oracle搜索共享池的library cache,查看该语句是否曾经执行过,如果是第一次执行,则进入第二步,

    b.检查语法、对象、权限等等(利用数据字典缓冲区的数据字典,如果没找到相关数据字典,再从system表空间中的数据文件读取)

    c.解析过程中,oracle要锁表(保护表的结构)

    d.oracle优化器根据表的存储结构(表的类型:普通表、分区表、cluster、iot),索        引、统计信息等,再根据cbo(基于代价的优化器模式)优化器模式,选择一条最佳路径        ,产生执行计划,编译并存储执行代码,以便共享。

2.bind

绑定变量,优化sql


3.execute

先从数据缓冲区查找数据,如果没有,再从数据文件中读取数据到数据缓冲区,保存,以便共享,

4.fetch

把结果返回给用户

IO操作:

物理I/O:从数据缓冲区搜索不到所要的数据,就要从硬盘中读取,叫物理I/O

逻辑I/O:从数据缓冲区搜索到了所要的数据,叫逻辑I/O,调优时逻辑I/O至少要达到90%,数据库才算运行良好!

逻辑I/O大概比物理I/O快1000倍!

LRU:最近最少使用!

show parameter cursor

查找没有共享的SQL语句,在v$sql里查找执行次数小的SQL语句,观察这些SQL语句是否经常执行

select sql_fulltext,sql_id from v$sqlarea where EXECUTIONS = 1;


查看SQL执行计划:select * from table(dbms_xplan.display_cursor('798k85z2cgz64'));


REDO LOG BUFFER

oracle内存结构_内存结构_07



大池:

大池专门用于以下情况

1、共享服务器连接,用于在SGA中分配UGA

2、语句并行执行,允许分配进程间的消息缓冲区

3、备份,在某些情况下用于RMAN的磁盘I/O缓冲区

以上这些内存分配都不应该在LRU缓冲区池中(数据缓冲区),因为LRU缓冲区的目标是管理小块的内存,另外像共享服务器的连接内存,一旦会话注销,这个内存就不会再重用,所以应该立即释放,不应该放入LRU缓冲区管理!



database buffer cache