`
dingjun1
  • 浏览: 207854 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ORACLE 内存结构 事件相关 statspack

阅读更多
基本的内存结构包括:System Global Area SGA(服务和后台进行共享)和Program Global Area PGA(每个服务和后台进行

私有)
SGA:
Database buffer cache
Redo log buffer
Shared pool
Java pool
Large pool
Streams pool
Data dictionary cache
Other miscellaneous information

SGA有一部分保存实例状态的概况信息,用于后台进行访问,叫做fixed SGA,SGA中还会有进程间的通信信息,比如锁等。
如果使用共享服务模式,请求和应答队列和一些PGA的内容会存放在SGA中。

shared pool:用于SQL和PL/SQL运行内存信息,java pool:java对象和java运行内存信息,buffer cache 用于缓存磁盘上的数

据块。

实例启动时使用最小的内存,通过扩充内存分配允许实例使用更多的内存,直到SGA_MAX_SIZE初始化参数的大小。如果该参数

的值小于小于SGA中各组成部分分配的内存之和(这些参数是显示的设定的值),那么会忽略这个值。所以这个值只对扩充时

有用。

为了优化系统性能,整个SGA的容量应与实际的内存相符,避免使用虚拟内存产生页交换。
SGA大小由多个初始化参数值决定。
DB_CACHE_SIZE  标准容量数据块(standard block)使用的缓存区的容量。
LOG_BUFFER  重做日志缓冲区(redo log buffer)的容量,以字节(byte)为单位。
SHARED_POOL_SIZE  存储共享 SQL 及 PL/SQL 的内存容量,以字节(byte)为单位。
LARGE_POOL_SIZE  大型池(large pool)的容量。默认值为 0。
JAVA_POOL_SIZE  Java 池(Java pool)的容量。

从ORACLE10G开始,DBA只需使用SGA_TARGET参数指定实例可用的SGA问题即可。ORACLE能够自动地将内存分配给SGA的各个子组

件。

BUFFER CACHE由两上列表组成:write list 和最近最少使用列表(least recently used)。write list记录脏缓冲区,即数据

被改变但是还没有被写到磁盘。LRU list包括空闲区,保持区和还没有移到write list中的脏数据块。
空闲区是可能被动使用,不包含有用数据的区,pinned buffers是最近被访问的区。
当进程访问一块缓冲区时,会移动它到LRU LIST的MRU(most recently used)端。dirty buffers会慢慢移向LRU端。

当ORACLE用户进程请求特定的数据块时,它会在database buffer cache中查找数据,如果进程在缓存中找到(cache hit),

它会直接从内存中获取,如果进程没有找到数据,在访问数据前,会先从数据文件中拷贝数据块到缓冲中,并移动到MRU端。
要从数据文件中读取块到缓冲区,必须先找到空闲的缓冲区,进程会查询LRU LIST,从lru端进行查找。
如果用户进程在查询LRU LIST中找到dirty buffer,会移到这个buffer到write list中。然后继续查找。
当进程从LRU端。如果用户进程没有找到空闲的buffr,进程会停止查找同时对DBWn后台进程发出信号,把脏缓冲区写入到磁盘

中。

当用户进程进行全表扫描时,它会从表中读取数据块到缓冲区中,并将这些缓冲区移动到LRU端(与MRU端不同)这是因为全表

扫描的数据通常只是暂时需要的。
也可以控制默认的表扫描涉及的数据块行为,指定在全表扫描时表的数据块放到MRU端,在创建,修改或簇时使用cache语句,

可以为小的检索表或是大的静态的历史表指定这一行为,以后面对表的访问可以避免I/O。

另外我们可以设置其它两个值,KEEP和RECYCLE。通过设定DB_KEEP_CACHE_SIZE和DB_RECYCLE_CACHE_SIZE。它们之间是相互独立的。

KEEP buffer pool 是在内存中一直保存方案对象的数据,比如常使用的小表或者是有较大数据的静态表(不变的数据,keep buffer pool是有一定大小的),为了避免I/O可以让其一直保持在内存中。
RECYCLE buffer pool是随时清除存储不再被使用,比如不希望某个表保持在内存中,操作完后马上释放空间。
DEFAULT buffer pool是存储没有分配任何buffer pool的方案对象,与显示的分配为DEFAULT POOL一样。
当用户进程进行全表扫描时,它会从表中读取数据块到缓冲区中,并将这些缓冲区移动到LRU端(与MRU端不同)这是因为全表扫描的数据通常只是暂时需要的。
也可以控制默认的表扫描涉及的数据块行为,指定在全表扫描时表的数据块放到MRU端,在创建,修改或簇时使用cache语句。

上述的池只对标准数据块大小才可用。非标准的有自己的默认池。创建非标准数据块的表空间需要有对应的池。
DB_2K_CACHE_SIZE=256M

alter table table_name storage(buffer_pool keep|recycle|default);
alter table table_name nocache|cache;

Redo Log Buffer:
重做日志缓冲区(redo log buffer)是SGA内一块被循正使用的缓冲区,记录数据库变化信息,信息以重做条目的形式存储。
Oracle 利用重做条目内的信息就可以重做由 INSERT,UPDATE,DELETE,CREATE,ALTER,及 DROP 等操作对数据库进行的修

改。重做条目可以被用于进行数据库恢复(database recovery)

ORACLE 数据库进程将重做条目从用户的内存空间复制到SGA的重做日志缓冲区,重做条目在重做日志缓冲区占用连续的空间。

后台LGWR负责写到归档重做日志文件中。一般参数值越大则重做日志文件的I/O性能越高,特别在长事务或是事务数量较大的

系统中尤为明显。此参数默认值为512KB与128*CPU_COUNT中的较大者。


Shared Pool
   library cache(shared sql area,(may be private sql area),pl/sql ) ,dictionary cache etc.

1、library cache
   包括:shared SQL AREA和private sql area(共享服务器模式下时),PL/SQL procedures和packages,以及锁和library

cache handle.shared SQL areas可以被所有用户访问。
ORACLE会为所执行的每个SQL提供一个共享SQL区和一个私有的SQL区,当两个用户执行相同的SQL语句时,ORACLE能发现这种情

况,并令用户重用共享SQL区,但是每个用户同时还拥有 SQL 语句的私有 SQL 区。
共享SQL AREA包含有解析树和执行计划。一个语句被多次执行时使用同一个共享SQL区,节省了内存。

Oracle 处理各种 PL/SQL 程序结构( program unit)(过程,函数,包,匿名块,及数据库触发器)的方式与处理单独的

SQL 语句类似。Oracle 为每个程序结构分配一块公共内存区以保存其解析及编译的结果。同时 Oracle 还要为程序结构创建

私有内存区,以保存程序结构在其运行的会话中所独有的信息,包括本地变量(local variable),全局变量(global

variable),包变量(package variable)(也被称为包实例(package instantiation)),及 SQL 执行缓冲区(buffers

for executing SQL)。


2、dictionary cache

3、buffers for parallel execution messages

4、control structures

清空共享池命令:
ALTER SYSTEM FLUSH SHARED_POOL;

2、理解consistent reads,physical  reads,buffer gets

如果有很多小事务和一个执行很时间查询语句作用于同一个表,当改变发生后,查询需要查看到已改变的内容回滚后的信息,

以便维持读一致的表镜像。
consistent changes:数据库阻塞回滚条目,实现一个块上的一致读。
consistent gets:统计一致读模式下的逻辑读数。

consistent gets from cache:块从buffer cache中要求读一致的次数。
db block gets from cache:当前块从BUFFER CACHE中请求的次数
physical reads cache:把数据块从磁盘读到buffer cache中的数目。

1 - (('physical reads cache') / ('consistent gets from cache' + 'db block gets from cache')




statspack收集数据机制:
通过对当前数据库的状态创建快照。
execute dbms_job.run(x); --where x is the job number of the statspack job
execute statspack.snap;

快照执行后,statspack会从RAM SGA的内存结构中提取样品,
转换成对应的值存放到STATSPACK相应的表中。这些值会用于
与其它快照进行对比。
在很多情况下SGA中的v$视图中有statspack中对应的表。
V$视图与STATSPACK捕获的信息区别:
V$视图收集的是从实例启动开始一直增加值直到实例关闭。而statspack是一个积累值。
获取一段时间的报告是通过比较两个快照。

如果在两个快照之间重启了服务,值将不可用,会出现后面的快照值小于前面的快照值,
积累值为负数。

v$sysstat        stats$sysstat
v$sgastat        stats$sgastat
v$parameter      stats$parameter
v$librarycache   stats$librarycache

十,Statspack 报告分析

  Statspack 报告分为如下部分

  1.  数据库总体信息

  含实例、版本、是否RAC、CPU、物理内存、oracle内存设置等等

  2.  每秒每事务的资源消耗情况

  3.  实例的各组件的命中率

  4.  共享池总体情况(Shared Pool Statistics)

  5.  等待时间最长的前5个等待事件(Top 5 Timed Events)

  含前5等待事件,两次采样间cpu占用,内存分配等信息。Oracle各版本等待事件并不完全相同,数量依版本升高而增加,关于各项等待事情的说明,三思之前的"学习动态性能表"系列文章中有过介绍,有心的朋友可以去搜搜看。

  6. DB 所有等待事件(Wait Events)--Total wait time>=0.001 的事件。

  7.  后台等待事件(Background Wait Events)--Total wait time>=0.001 的事件。

  8.  柱状显示的等待事件(Wait Event Histogram)--显示各等待事件不同响应时间的比例

  9.  根据CPU开销进行排序的SQL(SQL ordered by CPU)

  10.  根据执行时间进行排序的SQL(SQL ordered by Elapsed)

  11.  根据BufferGets进行排序的SQL(SQL ordered by Gets)

  12.  根据物理读进行排序的SQL(SQL ordered by Reads)

  13.  根据执行次数排序的SQL(SQL ordered by Executions)

  14.  根据解析调用次数排序的SQL(SQL ordered by Parse Calls)

  15.  实例记录的各项活动的统计数据(Instance Activity Stats)

  16.  表空间的IO统计(Tablespace IO Stats)

  17.  数据文件的IO统计(File IO Stats)

  18.  数据文件读柱状图形式统计(File Read Histogram Stats)

  19. Buffer 池统计数据(Buffer Pool Statistics)--含实例恢复的统计数据,buffer池大小设置建议等等。

  20. PGA 统计数据(PGA Aggr Target Stats)--含PGA缓存命中率,柱状图形式的统计以及PGA设置建议等等。

  21.  进程的内存占用情况(Process Memory Summary Stats)--含占用内存较多的进程等。

  22. undo 段摘要

  23. undo 段统计

  24.  锁存器的当前情况

  25.  锁存器睡眠等待统计

  26.  锁存器失败情况

  27.  数据字典cache性能统计(Dictionary Cache Stats)

  28.  库缓存的活动情况(Library Cache Activity)

  29. Rule 集(Rule Sets)

  30.  共享池设置建议(Shared Pool Advisory)

  31. SGA 摘要(SGA Memory Summary)

  32. SGA 统计信息(SQL Memory Statistics)

  33.  系统参数(init.ora Parameters)



一些参考信息:
Buffer nowaits, redo nowaits latch, sorts   90---100%
library cache                               50%--100%
parse, buffer hit                           0%---100%
以上的比率与等待事件相关
shared pool usage 应该稳定在80%--90%,如果大于90%应该检查(绑定和重新加载)?
一般来说Buffer Busy Wait不应大于1%

如果主要时间不是花费在空闲等待上,ORACLE提供的最重要的诊断信息是流逝时间
与主要I/O相关的等待:
Db file sequential read  - Index reads or scans
Db file scattered read   - Full table scans
Direct path read/write   - temp I/O hash_join sort
Log related waits-IO,switches, buffer

Db file * read ->SQL引起的 buffer gets 和 disk reads,  File IO stats
CPU Time ->解析比率,排序,SQL执行,SQL buffer gets/disk reads,SMP processes(bugs)
Direct path reads/writes->排序,哈希连接  hash_area_size  sort_area_size, File IO stats
Buffer busy waits->Buffer pool,Buffer waits,File IO stats Segment statistics.

其它重要的等待事比如:latches enqueues
按:buffer gets,disk reads,executions,parse counts排序的SQL。

free buffer waits 或者 write buffer waits 隐含 db writer 跟不上buffer pool的吞吐量。
Busy buffer waits 显示多上进程访问同一个块的内容,需要检查数据的Class,减少内容(比如反转关键字索引,一个块
中包含更少的块,freelists,initrans,more rollbacks 等。)
高比率的并发插入会引起busy buffer waits.

library cache:
reloads显示过期的代码和重新解析情况,如果使用变量绑定,增加shared_pool大小,keep objects


1、DB File Scattered Read:
这个事件主要提示与全表扫描相关的等待。当整个表被装入内存时,不能装载到连续的缓冲区,只会分散到缓冲区。
提示表缺少必要的索引。这时需要检查全表扫描是否有必要。可以试着把一些小表缓存起来,避免多次读取该表。
2、DB File Sequential Read:
这个事件大概提示单块读(比如索引等),大量的等待表示不好的表连接顺序或者没有选择性的建索引。这个事件也可以
出现在多事务,调优很多的系统。这时应该和效率低的SQL一起检查,确定索引扫描是必要的。检查多个表的连接顺序。
DB_CACHE_SIZE将是一个决定性的因素。有问题的hash-area连接,这个会引起顺序读等待高,也会揭示direct path read/write等待事件。
3、Free Buffer
提示系统在等待内存中的缓冲区,当前没有可用的缓冲区。可能表示需要增加DB_BUFFER_CACHE.如果已经调整表示SQL的
选择率低,引起索引块充满了缓冲区。也有可能是大理的DML操作使数据库的写进程不能满足当前的需要。可以考虑增加
checkpointing或是使用更多的写进程。或是增加物理磁盘。
4、Buffer Busy
该等待事件表示正在等待一个以 unshareable方式使用的缓冲区,或者表示当前正在被读入buffer cache。一般来说Buffer Busy Wait不应大于1%。检查缓冲等待统计部分(或V$WAITSTAT),看一下等待是否位于段头(Segment Header)。如果是,可以考虑增加自由列表(freelist,对于Oracle8i DMT)或者增加freelist groups(在很多时候这个调整是立竿见影的,在8.1.6之前,这个freelists参数不能动态修改;在8.1.6及以后版本,动态修改 feelists需要设置COMPATIBLE至少为8.1.6).

如果这一等待位于undo header,可以通过增加回滚段(rollback segment)来解决缓冲区的问题。如果等待位于undo block上,我们可能需要检查相关应用,适当减少大规模的一致性读取,或者降低一致性读取(consistent read)的表中的数据密度或者增大DB_CACHE_SIZE。

如果等待处于data block,可以考虑将频繁并发访问的表或数据移到另一数据块或者进行更大范围的分布(可以增加pctfree值,扩大数据分布,减少竞争),以避开这个"热点"数据块,或者可以考虑增加表中的自由列表或使用本地化管理的表空间(Locally Managed Tablespaces)。

如果等待处于索引块,应该考虑重建索引、分割索引或使用反向键索引。为了防止与数据块相关的缓冲忙等待,也可以使用较小的块:在这种情况下,单个块中的记录就较少,所以这个块就不是那么"繁忙";或者可以设置更大的pctfree,使数据扩大物理分布,减少记录间的热点竞争。

在执行DML (insert/update/ delete)时,Oracle向数据块中写入信息,对于多事务并发访问的数据表,关于ITL的竞争和等待可能出现,为了减少这个等待,可以增加 initrans,使用多个ITL槽。在Oracle9i 中,引入了一个新概念:ASSM(Segment Space Management Auto)。通过这个新特性Oracle 使用位图来管理空间使用。

ASSM 结合LMT 彻底改变了Oracle 的存储机制,位图freelist 能够减轻缓冲区忙等待(buffer busy wait),这个问题在Oracle9i 以前的版本里曾是一个严重的问题。

Oracle 宣称ASSM 显著地提高了DML 并发操作的性能,因为(同一个)位图的不同部分可以被同时使用,这样就消除了寻找剩余空间的串行化。根据Oracle 的测试结果,使用位图freelist 会消除所有分段头部(对资源)的争夺,还能获得超快的并发插入操作。在Oracle9i 之中,Buffer Busy wait 不再常见!

5. latch free-latch 释放

latch是一种低级排队机制,用于保护SGA中共享内存结构。latch就像是一种快速地被获取和释放的内存锁。用于防止共享内存结构被多个用户同时访问。如果latch不可用,就会记录latch释放失败(latch free miss )。有两种与闩有关的类型:

■ 立刻。

■ 可以等待。

假如一个进程试图在立刻模式下获得闩,而该闩已经被另外一个进程所持有,如果该闩不能立可用的话,那么该进程就不会为获得该闩而等待。它将继续执行另一个操作。

大多数latch问题都与以下操作相关:

没有很好的是用绑定变量 (library cache latch)、重作生成问题(redo allocation latch)、缓冲存储竞争问题(cache buffers LRU chain),以及buffer cache中的存在"热点"块(cache buffers chain)。

通常我们说,如果想设计一个失败的系统,不考虑绑定变量,这一个条件就够了,对于异构性强的系统,不使用绑定变量的后果是极其严重的。

另外也有一些latch等待与bug有关,应当关注Metalink相关bug的公布及补丁的发布。当latch miss ratios大于0.5%时,就应当研究这一问题。

Oracle的latch机制是竞争,其处理类似于网络里的CSMA/CD,所有用户进程争夺latch,对于愿意等待类型(willing-to-wait)的latch,如果一个进程在第一次尝试中没有获得latch,那么它会等待并且再尝试一次,如果经过_spin_count次争夺不能获得latch, 然后该进程转入睡眠状态,持续一段指定长度的时间,然后再次醒来,按顺序重复以前的步骤.在8i/9i中默认值是_spin_count=2000。

如果SQL语句不能调整,在 8.1.6版本以上,Oracle提供了一个新的初始化参数: CURSOR_SHARING可以通过设置CURSOR_SHARING = force 在服务器端强制绑定变量。设置该参数可能会带来一定的副作用,对于Java的程序,有相关的bug,具体应用应该关注Metalink的bug公告。

6. Log Buffer Space-日志缓冲空间

当你将日志缓冲(log buffer)产生重做日志的速度比LGWR 的写出速度快,或者是当日志切换(log switch)太慢时,就会发生这种等待。这个等待出现时,通常表明redo log buffer 过小,为解决这个问题,可以考虑增大日志文件的大小,或者增加日志缓冲器的大小。

另外一个可能的原因是磁盘 I/O 存在瓶颈,可以考虑使用写入速度更快的磁盘。在允许的条件下设置可以考虑使用裸设备来存放日志文件,提高写入效率。在一般的系统中,最低的标准是,不要把日志文件和数据文件存放在一起,因为通常日志文件只写不读,分离存放可以获得性能提升。

7. Log File Switch-日志文件切换

当这个等待出现时,表示所有的提交(commit)的请求都需要等待"日志文件切换"的完成。

Log file Switch 主要包含两个子事件:

log file switch (archiving needed)

log file switch (checkpoint incomplete)

log file switch (archiving needed)

这个等待事件出现时通常是因为日志组循环写满以后,第一个日志归档尚未完成,出现该等待。出现该等待,可能表示io 存在问题。解决办法:

可以考虑增大日志文件和增加日志组

移动归档文件到快速磁盘

调整log_archive_max_processes .

log file switch (checkpoint incomplete)-日志切换(检查点未完成)

当你的日志组都写完以后,LGWR 试图写第一个log file,如果这时数据库没有完成写出记录在第一个log file 中的dirty 块时(例如第一个检查点未完成),该等待事件出现。

该等待事件通常表示你的DBWR 写出速度太慢或者IO 存在问题。

为解决该问题,你可能需要考虑增加额外的DBWR 或者增加你的日志组或日志文件大小。

8. log file sync-日志文件同步

当一个用户提交或回滚数据时,LGWR 将会话期的重做由日志缓冲器写入到重做日志中。日志文件同步过程必须等待这一过程成功完成。为了减少这种等待事件,可以尝试一次提交更多的记录(频繁的提交会带来更多的系统开销)。将重做日志置于较快的磁盘上,或者交替使用不同物理磁盘上的重做日志,以降低归档对LGWR的影响。

对于软RAID,一般来说不要使用RAID 5,RAID5 对于频繁写入得系统会带来较大的性能损失,可以考虑使用文件系统直接输入/输出,或者使用裸设备(raw device),这样可以获得写入的性能提高。

9. log file single write该事件仅与写日志文件头块相关,通常发生在增加新的组成员和增进序列号时。

头块写单个进行,因为头块的部分信息是文件号,每个文件不同。更新日志文件头这个操作在后台完成,一般很少出现等待,无需太多关注。

10. log file parallel write

从log buffer 写redo 记录到redo log 文件,主要指常规写操作(相对于log file sync)。如果你的Log group 存在多个组成员,当flush log buffer 时,写操作是并行的,这时候此等待事件可能出现。

尽管这个写操作并行处理,直到所有I/O 操作完成该写操作才会完成(如果你的磁盘支持异步IO或者使用IO SLAVE,那么即使只有一个redo log file member,也有可能出现此等待)。

这个参数和log file sync 时间相比较可以用来衡量log file 的写入成本。通常称为同步成本率。

11. control file parallel write-控制文件并行写

当server 进程更新所有控制文件时,这个事件可能出现。如果等待很短,可以不用考虑。如果等待时间较长,检查存放控制文件的物理磁盘I/O 是否存在瓶颈。

多个控制文件是完全相同的拷贝,用于镜像以提高安全性。对于业务系统,多个控制文件应该存放在不同的磁盘上,一般来说三个是足够的,如果只有两个物理硬盘,那么两个控制文件也是可以接受的。在同一个磁盘上保存多个控制文件是不具备实际意义的。减少这个等待,可以考虑如下方法:

IXDBA.NET技术社区

减少控制文件的个数(在确保安全的前提下)

如果系统支持,使用异步IO

转移控制文件到IO 负担轻的物理磁盘

12. control file sequential read/ control file single write 控制文件连续读/控制文件单个写对单个控制文件I/O 存在问题时,这两个事件会出现。如果等待比较明显,检查单个控制文件,看存放位置是否存在I/O 瓶颈。

13. direct path write-直接路径写该等待发生在,系统等待确认所有未完成的异步I/O 都已写入磁盘。对于这一写入等待,我们应该找到I/O 操作最为频繁的数据文件(如果有过多的排序操作,很有可能就是临时文件),分散负载,加快其写入操作。

如果系统存在过多的磁盘排序,会导致临时表空间操作频繁,对于这种情况,可以考虑使用Local管理表空间,分成多个小文件,写入不同磁盘或者裸设备。

14. Idle Event-空闲事件

最后我们来看几个空闲等待事件。一般来说,空闲等待是指系统因为无事可做的等待,或者等待用户的请求或响应等,通常我们可以忽略这些等待事件。空闲事件可以通过stats$idle_event 表查询得到。

我们看一下系统的主要空闲等待事件,对这些事件大家应该有个大致的印象,如果你的Top 5 等待事件中,主要都是这些事件,那么一般来说你的系统是比价清闲的。


                    
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics