首页 > 数据库 > Oracle > Oracle体系结构II
Oracle的内存由系统全局区(System Global Area,简称SGA)和程序全局区(Program Global Area,简称PGA)组成。
系统全局区(system global area,SGA)是一组包含了 Oracle 数据库数据及实例控制信息的共享的内存结构。当多个用户并发地连接到同一个实例后,这些用户将共享此实例 SGA 中的数据。因此 SGA 也被称为共享全局区(shared global area)。
SGA越大系统的性能越好,但SGA过大也会起到反作用。一般情况下,SGA不应超过系统实际内存的1/2。但从Oracle 9i开始支持动态SGA特性,即无需关闭实例就可以改变数据高速缓冲区、共享池和大池的大小。数据高速缓冲区、共享池的大小也可以根据工作负载自动调整,但SGA的总大小不能超过初始化参数SGA_MAX_SIZE的设置。。
如图2-1所示,SGA包括三个子缓冲区:保留缓冲区、循环缓冲区和非标准大小块缓冲区。SGA包括以下结构:
<!--[if !supportLists]-->● <!--[endif]-->数据高速缓冲区(Data Buffer Cache)
<!--[if !supportLists]-->● <!--[endif]-->重做日志缓冲区(Redo Log Buffer)
<!--[if !supportLists]-->● <!--[endif]-->共享池(Shared Pool)
<!--[if !supportLists]-->● <!--[endif]-->Java池(Java Pool)
<!--[if !supportLists]-->● <!--[endif]-->大池(Large Pool)
<!--[if !supportLists]-->● <!--[endif]-->流池(Stream Pool)
图 2-1 SGA结构示意图
|
|
在Oracle中无论是读取还是修改数据,都是由服务器进程在数据库高速缓冲区中完成的。数据库高速缓冲区的作用就是用来缓存最近从数据库中读出的数据块,并可供其他客户进程共享。用户进程查看数据时,首先检查需要的信息是否在缓冲区内,如果在缓冲区中,就可以直接访问,否则访问物理文件并读取数据块到数据库缓冲区。我们知道内存的读写速度要比物理设备的读写速度快很多,这样就可以大大提高Oracle数据库的性能。
<!--[if !supportLists]-->1) <!--[endif]-->数据库高速缓冲区的子缓冲区
根据缓冲数据块的状态,Oracle将数据高速缓冲区可划分成:
<!--[if !supportLists]-->● <!--[endif]-->脏缓冲区(Dirty Buffer):
当数据库发生DML(Insert、Update、Delete)操作时,会对缓冲区内容进行修改,这样缓冲区的内容就会和相对应的数据文件不一致,这时,缓冲区标识为“脏缓冲区”。
<!--[if !supportLists]-->● <!--[endif]-->自由缓冲区(Free Buffer):
当“脏缓冲区”的内容被写入数据文件后,因为该缓冲区与相应数据文件部分内容一致,所以将这些缓冲区称为“自由缓冲区”。
当执行SELECT语句时,会将对应数据文件部分数据读取到数据高速缓存的相应缓冲区,因为缓冲区与数据块内容完全一致,所以这些缓冲区也被称为“自由缓冲区”。
<!--[if !supportLists]-->● <!--[endif]-->忙缓冲区(Pinned Buffer):
“忙缓冲区”是指服务器进程正在访问的缓冲区。
每个数据库的数据库高速缓冲区大小有限,所以一般不会把磁盘上的所有数据都可以存放在缓冲区中。
为了防止数据库高速缓冲区空间不够用,Oracle会将脏缓冲区中的数据写入对应的数据文件中,以腾出空间给新的数据。
如果缓冲区不脏,即为“自由缓冲区”,它可以直接被读入新的数据块。)随后访问被写入磁盘导致额外的高速缓存未命中的数据。
“脏列表”的作用就是记录脏缓冲区的情况。如果某些缓冲区中的数据块被修改,就会加入该列表,只有脏列表中的缓冲区数据块需要写回数据库文件,一旦写回数据库文件,缓冲区就会从脏列表中清除。
<!--[if !supportLists]-->2) <!--[endif]-->非标准块大小支持
数据库块是Oracle数据库I/O的最小单位。
每个数据库都可以通过参数DB_BLOCK_SIZE指定标准块大小(2k、4k、8k、16k、32k),默认为8k。但是Oracle数据库同时支持多种块大小,我们称这些标准块以外的块为“非标准大小块”。
非标准大小块的高速缓冲区大小指定以下参数(DB_nK_CACHE_SIZE):
DB_2K_CACHE_SIZE
DB_4K_CACHE_SIZE
DB_8K_CACHE_SIZE
DB_16K_CACHE_SIZE
DB_32K_CACHE_SIZE
DB_nK_CACHE_SIZE参数不能用于设定标准大小块的高速缓存,标准大小块的缓存尺寸由参数DB_CACHE_SIZE的值决定。
<!--[if !supportLists]-->3) <!--[endif]-->使用多个缓冲区
数据库管理员(DBA )可以通过创建多个缓冲池来提高数据库缓冲区高速缓存的性能。
用户可以指定方案对象(schema object)(表,簇,索引,及分区)使用相应的缓冲池,以便控制数据被移出缓存区的时机。
<!--[if !supportLists]-->● <!--[endif]-->保留缓冲区(Keep Buffer Cache):用来保留在内存中最有可能重用的对象。
保留这些对象将减少I/O操作,指定DB_KEEP_CACHE_SIZE参数的值配置。
<!--[if !supportLists]-->● <!--[endif]-->循环缓冲区(Recycle Buffer Cache):用来保留被重用机会不大的内存块。
指定DB_RECYCLE_CACHE_SIZE参数的值配置该缓冲区的大小。
<!--[if !supportLists]-->● <!--[endif]-->默认缓冲区(Default Buffer Cache):此池始终存在。它相当于一个实例的数据库高速缓冲区中保留和循环区以外的部分。指定参数DB_CACHE_SIZE。
注:保留缓冲区和循环缓冲区并非默认缓冲区的子集。
可以使用BUFFER_POOL子句对对象定义默认的缓冲区。
EXAMPLE:
CREATE INDEX cust_idx …
STORAGE (BUFFER_POOL KEEP);
ALTER TABLE oe.customers
STORAGE (BUFFER_POOL RECYCLE);
<!--[if !supportLists]-->4) <!--[endif]-->数据库高速缓冲区空间管理
Oracle用LRU(Least Recently Used)算法来管理数据高速缓冲区。该算法将最近使用的数据块按照使用时间的早晚排成队列,当缓冲区占满后,调入新的数据块时,必须清除已有的数据块,来获得空闲数据块空间,那么,最合理的选择就是清除最早没有使用数据块,因为使用该块的概率相对比较小。通过规划SGA时合理地设置数据高速缓存的尺寸,尽量的避免缓冲区占满的情况发生,否则就会降低系统的效率。
Oracle将队列分成两端,分别为热端和冷端。
HOT COLD
|
A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
假设新数据块K将要被读入,又没有空闲位置,则Oracle会对冷端头J块进行判断: 假设J被访问次数为1,Oracle将会认为J不是一个经常被访问的块(冷),则会将J块踢出队列,将K插入至F的位置,F和其他块右移:
HOT COLD
|
A |
B |
C |
D |
E |
K |
F |
G |
H |
I |
假设新数据块L将要被读入,又没有空闲位置,则Oracle会对冷端头I块进行判断:
假设I被访问次数为5,Oracle将会认为I是一个经常被访问的块(热),则会将I块放入热端头,A和其他快右移如下图所示:
HOT COLD
|
I |
A |
B |
C |
D |
E |
K |
F |
G |
H |
这时,将对下一个冷端头块H进行判断:
假设H被访问次数为1,Oracle将会认为H不是一个经常被访问的块(冷),则会将H块踢出队列,将L插入至E的位置,E和其他块右移:
HOT COLD
|
I |
A |
B |
C |
D |
L |
E |
K |
F |
G |
但是这时,我们会发现。I块被放入热端头,经过漫长的时间,I块最终会被放到冷端头进行判断;如果这段时间中,即使I没有再被访问过,I的访问次数也仍然是5,这样I将再次回到热端头,这样就造成了死循环,I永远无法被踢出列表。
因此,当I被放到热端头的时候,访问次数将会被清零。如果这段时间I被访问多次,则有机会回到热端头,否则,可能被踢出列表。
<!--[if !supportLists]-->5) <!--[endif]-->数据库高速缓冲区的大小管理
1> 连接数据库
[oracle@oracle ~ ]$ sqlplus / as sysdba
2> 显示数据库高速缓冲区的大小
SQL> show parameter db_cache_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_cache_size big integer 0
3> 显示保留缓冲区的大小
SQL> show parameter db_keep_cache_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_keep_cache_size big integer 0
4> 显示循环缓冲区的大小
SQL> show parameter db_recycle_cache_size
5> 修改数据库高速缓冲区的大小
SQL> ALTER SYSTEM SET db_cache_size=500m;
6> 清空数据库高速缓冲区
SQL> ALTER SYSTEM FLUSH buffer_cache;
图 2-2 数据库高速缓冲区示意图
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29781254/viewspace-1744937/ ,如需转载,请注明出处,否则将追究法律责任。