oracle内存结构
oracle内存结构由SGA与PGA组成,实例启动的时候,SGA与后台进程启动,
SGA:
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的请求队列中,当有空闲的共享服务器进程时,调度器就会把此客户请求排列过去给它处理。
show sga时
Fixed Size:
oracle 的不同平台和不同版本下可能不一样,但对于确定环境是一个固定的值,里面存储了SGA 各部分组件的信息,可以看作引导建立SGA的区域。
Variable Size:
包含了shared_pool_size、java_pool_size、large_pool_size 等内存设置
shared pool:
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
大池:
大池专门用于以下情况
1、共享服务器连接,用于在SGA中分配UGA
2、语句并行执行,允许分配进程间的消息缓冲区
3、备份,在某些情况下用于RMAN的磁盘I/O缓冲区
以上这些内存分配都不应该在LRU缓冲区池中(数据缓冲区),因为LRU缓冲区的目标是管理小块的内存,另外像共享服务器的连接内存,一旦会话注销,这个内存就不会再重用,所以应该立即释放,不应该放入LRU缓冲区管理!
database buffer cache