本帖最后由 群发软件 于 2017-9-5 22:28 编辑
与 Oracle 实例关联的基本内存结构包括:
万能群发软件 万能营销软件
系统全局区 (SGA):由所有服务器和后台进程共享。SGA 中存储的数据示例包括高速缓存的数据块和共享 SQL 区域。
程序全局区 (PGA):各个服务器进程和后台进程专用,每个进程都有一个 PGA。
SGA 是共享内存区,包含实例的数据和控制信息,由以下各项组成:
数据库缓冲区高速缓存:用于缓存从磁盘检索到的数据块
重做日志缓冲区:用于缓存重做信息,直到其可以写入磁盘为止
共享池:用于缓存可在用户间共享的各种结构
大型池:用于缓冲大型 I/O 请求的可选区域,以便支持并行查询、共享服务器、Oracle XA 以及某些类型的备份操作
Java 池:用于存放 Java 虚拟机 (JVM) 中特定于会话的 Java 代码和数据
流池:由 Oracle Streams 使用
保留缓冲区高速缓存:用于存放会尽可能长地保留在缓冲区高速缓存中的数据
循环缓冲区高速缓存:用于存放缓冲区高速缓存中很快过期的数据
nK 块大小缓冲区高速缓存:用于缓存大小与默认数据库块大小不同的数据块,用来支持可传输的表空间
数据库缓冲区高速缓存、共享池、大型池、流池和 Java 池的大小可以按照当前需求自动调整。而且,这些内存缓冲区以及保留缓冲区高速缓存、循环缓冲区高速缓存和 nK 块大小缓冲区高速缓存可以在不关闭实例的情况下进行更改。
Oracle 数据库会提供预警和指导,以标识内存大小问题,从而帮助确定相应的内存参数值。
程序全局区 (PGA) 是一个内存区,其中包含每个服务器进程的数据及控制信息。服务器进程是处理客户机请求的进程。每个服务器进程都有在服务器进程启动时创建的自己专用的 PGA。只有该服务器进程才能访问。
所用 PGA 内存量和 PGA 的内容取决于实例是否是在共享服务器模式下配置的。通常,PGA 包含下列内容:
专用 SQL 区:包含绑定信息和运行时内存结构等数据。发出 SQL 语句的每个会话都有一个专用 SQL 区。
会话内存:此处分配的内存用于存放会话变量以及与该会话相关的其它信息。
1.缓冲区高速缓存 data buffer cache
通过指定 DB_CACHE_SIZE 参数的值,可以配置缓冲区高速缓存。缓冲区高速缓存可存放数据文件中块大小为 DB_BLOCK_SIZE 的数据块的副本。缓冲区高速缓存是 SGA 的一部分;因此所有用户都可以共享这些块。服务器进程将数据文件中的数据读入缓冲区高速缓存。为了提高性能,服务器进程有时在一个读操作中会读取多个块。然后由 DBWn 进程将数据从缓冲区高速缓存写入数据文件。为提高性能,DBWn 在一个写操作中会写入多个块。
在任何给定时间,缓冲区高速缓存都可能会存放一个数据库块的多个副本。虽然该块只存在一个当前副本,但为了满足查询需要,服务器进程可能需要根据过去的映像信息构造读一致性副本。这称为读一致性 (CR) 块。
网站发帖软件 博客发帖软件最近最少使用 (LRU) 列表可反映缓冲区的使用情况。缓冲区将依据其被引用时间的远近和引用频率进行排序。因此,最经常使用且最近使用过的缓冲区将列在最近最常使用一端。传入的块先被复制到最近最少使用一端的缓冲区中,然后该缓冲区将被指定到列表中央,作为起点。从这个起点开始,缓冲区根据使用情况在列表中上下移动。
缓冲区高速缓存中的缓冲区可以处于以下四种状态之一:
已连接:当前正将该块读入高速缓存或正在写入该块。其它会话正等待访问该块。
干净的:该缓冲区目前未连接,如果其当前内容(数据块)将不再被引用,则可以立即执行过期处理。这些内容与磁盘保持同步,或者缓冲区包含块的读一致性快照。
空闲/未使用:缓冲区因实例刚启动而处于空白状态。此状态与“干净的”状态非常相似,不同之处在于缓冲区未曾使用过。
灰:缓冲区不再处于连接状态,但内容(数据块)已更改,因此必须先通过 DBWn 将内容刷新到磁盘,然后才能执行过期处理。
服务器进程使用缓冲区高速缓存中的缓冲区;而 DBWn 进程通过将更改的缓冲区写回数据文件,使高速缓存中的缓冲区变为可用状态。检查点队列中列出将要写出到磁盘的缓冲区。
Oracle 数据库支持同一数据库中有多种块大小。标准块大小用于 SYSTEM 表空间。标准块大小可以通过设置初始化参数 DB_BLOCK_SIZE 来指定。其有效值介于 2 KB 到 32 KB 之间,默认值为 8 KB。非标准块大小的缓冲区的高速缓存大小通过以下参数指定:
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_BLOCK_SIZE 的值为 nK,则设置 DB_nK_CACHE_SIZE 是非法的。标准块大小的高速缓存的大小始终由 DB_CACHE_SIZE 的值确定。
由于每个缓冲区高速缓存的大小都有限制,因此,通常并非磁盘上的所有数据都能放在高速缓存中。当高速缓存写满时,后续高速缓存未命中会导致 Oracle 数据库将高速缓存中已有的灰数据写入磁盘,以便为新数据腾出空间。(如果缓冲区中没有灰数据,则不需要写入磁盘即可将新块读入该缓冲区。)以后若对已写入磁盘的任何数据进行访问,则会导致再次出现高速缓存未命中现象。
数据请求导致高速缓存命中的几率会受到高速缓存大小的影响。高速缓存越大,包含所请求数据的几率也就越大。因此,增加高速缓存大小会提高引起高速缓存命中的数据请求的百分比。
数据库管理员 (DBA) 可以创建多个缓冲区池来提高数据库缓冲区高速缓存的性能。您可以根据对象的访问情况将其分配给某个缓冲区池。缓冲区池有三种:
保留:此池用于保留内存中可能要重用的对象。将这些对象保留在内存中可减少 I/O 操作。通过使池的大小大于分配给该池的各个段的总大小,可以将缓冲区保留在此池中。这意味着缓冲区不必执行过期处理。保留池可通过指定 DB_KEEP_CACHE_SIZE 参数的值来配置。
循环:此池用于内存中重用几率很小的块。循环池的大小要小于分配给该池的各个段的总大小。这意味着读入该池的块经常需要在缓冲区内执行过期处理。循环池可通过指定 DB_RECYCLE_CACHE_SIZE 参数的值来配置。
默认:此池始终存在。它相当于没有保留池和循环池的实例的缓冲区高速缓存,可通过 DB_CACHE_SIZE 参数进行配置。
注:保留池或循环池中的内存不是默认缓冲区池的子集。
CREATE INDEX cust_idx …
STORAGE (BUFFER_POOL KEEP …);
ALTER TABLE oe.customers
STORAGE (BUFFER_POOL RECYCLE);
ALTER INDEX oe.cust_lname_ix
STORAGE (BUFFER_POOL KEEP);
手工刷新内存:
alter system flush buffer cache;
BUFFER_POOL 子句用于定义对象的默认缓冲区池。它是 STORAGE 子句的一部分,对 CREATE 和 ALTER 表、簇和索引语句有效。未明确设置缓冲区池的对象中的块将进入默认缓冲区池。
营销软件 网络营销推广软件
语法为:BUFFER_POOL [KEEP | RECYCLE | DEFAULT]。
使用 ALTER 语句更改对象的默认缓冲区池时,已缓存的块会一直保留在其当前缓冲区中,直到正常缓冲区管理活动将它们清除为止。从磁盘读取的块将被放置在为该段新指定的缓冲区池中。
由于多个缓冲区池被分配给某一个段,所以有多个段的对象可以将块放置在多个缓冲区池中。例如,按索引组织的表在索引段和溢出段上可以有多个不同的池。
2.共享池 shared pool
大小通过 SHARED_POOL_SIZE 指定。
库高速缓存包含语句文本、已进行语法分析的代码和执行计划。
数据字典高速缓存包含数据字典表中各表、列和权限的定义。
用户全局区 (UGA) 包含会话信息(如果使用 Oracle 共享服务器)。
库高速缓存:库高速缓存包含共享 SQL 区和 PL/SQL 区 - 经过完全语法分析或编译的 PL/SQL 块和 SQL 语句的表示法。PL/SQL 块包括:
过程和函数
程序包
触发器
匿名
PL/SQL 块
数据字典高速缓存:数据字典高速缓存将字典对象的定义存放在内存中。
结果高速缓存:结果高速缓存包含 SQL 查询结果高速缓存和 PL/SQL 函数结果高速缓存。此高速缓存用于存储 SQL 查询或 PL/SQL 函数的结果,以加快其将来的执行速度。
用户全局区:UGA 包含 Oracle 共享服务器的会话信息。使用共享服务器会话时,如果尚未配置大型池,则 UGA 位于共享池中。
3.大型池large pool
可配置为 SGA 中一个单独的内存区
大小由 LARGE_POOL_SIZE 参数指定
用于在内存中为以下各项存储数据:
--UGA
--备份和还原操作
--并行查询消息传送
大型池必须显式配置。大型池的内存不是来自共享池,而是直接来自 SGA,这就增大了 Oracle 服务器在实例启动时需要的共享内存量。
大型池用于为以下各项分配大量会话内存:
--I/O 服务器进程
--备份和还原操作
--Oracle 共享服务器进程和 Oracle XA 接口(事务处理与多个数据库交互时使用)
由于从大型池为 Oracle 共享服务器分配会话内存,因此共享池中由于频繁分配和取消分配大对象而产生的碎片也就很少。将大对象从共享池中分离出来,可增加共享池内存的使用效率,这意味着,它可以将更多内存用于处理新的请求,以及在需要时用于保留现有数据。
4.Java pool
可配置为 SGA 中一个单独的内存区
大小由 JAVA_POOL_SIZE 参数指定
用于将 JVM 中特定于会话的所有 Java 代码和数据存储在内存中
5.重做日志缓冲区 redo buffer cache
Oracle 服务器进程将重做条目从用户的内存空间复制到每个 DML 或 DDL 语句的重做日志缓冲区。重做条目包含重建或重做 DML 和 DDL 操作对数据库的更改所必需的信息。它们用于数据库恢复,需要占用缓冲区中的连续空间。
重做日志缓冲区是一个循环缓冲区;服务器进程可以用新条目覆盖重做日志缓冲区中已写入磁盘的条目。LGWR 进程的写速度通常都很快,足以确保缓冲区中始终有存储新条目的空间。LGWR 进程将重做日志缓冲区写入磁盘上的活动联机重做日志文件(或活动组成员)中。LGWR 进程将 LGWR 上次写入磁盘以来进入缓冲区的所有重做条目复制到磁盘。
什么导致 LGWR 执行写操作?
用户进程提交事务处理时
每隔三秒,或每当重做日志缓冲区占满三分之一时
DBWn 进程将修改的缓冲区写入磁盘时(如果相应的重做日志数据尚未写入磁盘)
SGA,PGA,UGA都是Oracle管理的内存区。
SGA(System Global Area),即系统全局区,Oracle中最重要的内存区。
PGA(Process Global Area),即程序全局区,一个进程的专用的内存区。
UGA(User Global Area),即用户全局区,与特定的会话相关联。
专用服务器连接模式,UGA在PGA中分配。
共享服务器连接模式,UGA在SGA中的Large Pool中分配。
如果采用专用服务器连接模式,PGA中包含UGA,其他区域用来排序,散列和位图合并。
简单来讲,PGA=UGA+排序区+散列区+位图合并区。
二、PGA的管理模式。
PGA分两种管理模式:
1) 手动PGA内存管理,用户指定排序区和散列区所使用的内存,每个连接使用相同的内存。
2) 自动PGA内存管理,告诉Oracle可以使用的PGA的总量,由Oraclce根据系统负载决定具体分配。
9iR1时默认为手动PGA内存管理,9iR2以后默认为自动PGA内存管理。
PGA内存可以动态扩大和回收。
PGA内存管理模式由WORKAREA_SIZE_POLICY控制。
1) 设为MANUAL,启用手动内存管理。
2) 设为AUTO,并且PGA_AGGREGATE_TARGET不为0时,启用自动内存管理。
三、手动PGA内存管理
有三个参数对PGA影响最大。
SORT_AREA_SIZE:对信息排序所用的内存总量
SORT_AREA_RETAINED_SIZE:排序后在内存中保存排序信息的内存总量。
HASH_AREA_SIZE:存储散列列表所用的内存量。
下面对这三个参数进行说明:
1) SORT_AREA_SIZE:
如果SORT_AREA_SIZE设为512KB,SORT_AREA_RETAINED_SIZE也为512KB,则Oracle使用512KB的内存进行排序,排序后所有数据都留在内存中。
2) SORT_AREA_RETAINED_SIZE:
如果SORT_AREA_SIZE设为512KB,SORT_AREA_RETAINED_SIZE设为384KB,则Oracle使用512KB的内存进行排序,然后保留384KB的已排序数据,另外512KB-384KB=128KB的已排序数据会写到临时表空间中。
如果SORT_AREA_RETAINED_SIZE没有设置,则它的值为0,但是实际保留的排序数据和SORT_AREA_SIZE相同。
3) HASH_AREA_SIZE:
一个大集合和另个集合进行连接时,会用到HASH_AREA_SIZE参数。较小的 表会放到这部分内存中作为驱动表,然后大表进行探索(PROBE)操作进行连接。如果HASH_AREA_SIZE过小会影响两个集合(表)连接时的性能。
注意点:
1) 如果需要排序的数据量大于SORT_AREA_SIZE,Oracle会分批进行排序。把当前已排序的数据保存到临时表空间中,然后对剩余的数据进行排序。最后,还会对这些保存在临时表空间中的已排序数据再进行排序,因为每次保存到临时表空间中的已排序数据只是部分数据的排序,对整体需排序的数据来说只是部分局部有序。
2) *_AREA_SIZE只是对某个操作的限制,一个查询可能有多个操作,每个操作都有自己的内存区。如果SORT_AREA_SIZE设为5MB,一个查询可能会有10个排序操作,这样一个查询会占用50MB的排序内存。
3) 3,*_AREA_SIZE内存的分配是按需分配。如果一个查询需要5MB内存进行排序,就算分配1G的SORT_AREA_SIZE也不会全部使用,只会使用需要的5MB的内存量。
四、自动PGA内存管理
要启用自动PGA内存管理,设置下列参数:
1,WORKAREA_SIZE_POLICY=AUTO
2,PGA_AGGREGATE_TARGET=非零
有关PGA_AGGREGATE_TARGET:
1) PGA_AGGREGATE_TARGET是一个目标值。连接数少的时候实际分配PGA内存会比它要小。连接数多的时候实际分配的PGA内存会比它要大,但是Oracle会努力保持总PGA保持在PGA_AGGREGATE_TARGET值内。
例如,PGA_AGGREGATE_TARGET 设为300MB。5个用户连接时,每个用户可能分配10MB的PGA内存,共分配50MB的PGA内存。300个用户连接时每个用户可能分配1.3MB的PGA内存,共分配390MB的PGA内存。当用户连接多时,Oracle会降低每个用户的PGA内存使用量。
2) 一个串行查询(非并行查询)可能包括多个排序/散列操作,每个排序/散列操作最多使用5%的PGA内存。
3) 一个并行查询最多可用到30%的PGA内存,无论有多少并行进程。
五、手动PGA内存管理与自动PGA内存管理
自动PGA内存管理相对于手动PGA内存管理有很多优点
1, 当用户连接少时
a) 手动PGA内存管理不管有多少可用内存都按照预设值进行分配。比如当前空闲内存为300MB,连接需要10MB的内存进行排序,而我们设定的排序区大小为5MB,导致虽然有足够的空闲内存却无法分配给当前连接,造成执行效率低下。
b) 自动PGA内存管理会根据当前空闲内存来进行分配。当空闲内存为300MB,当前用户需要10MB内存进行排序,Oracle就会分配10MB内存给当前用户。
2, 当用户连接多时
a) 手动PGA内存管理会完全按照预设值分配内存。如果物理内存总量为1G,排序区设为5MB,当有300个用户连接时,Oracle会分配1.5G的内存,这已经超过了我们的实际物理内存!
b) 自动PGA内存管理会根据当前连接情况进行分配。如果物理内存总量为1G,PGA_AGGREGATE_TARGET为300MB,当用户数从10升到300时,每个用户连接的内存会从满足需要的10MB慢慢减少到1.3MB,虽然最后总量也会超过PGA_AGGREGATE_TARGET,但比起手动PGA内存管理要好很多了。
什么时候使用自动PGA内存管理?什么时候使用手动PGA内存管理?
白天系统正常运行时适合使用自动PGA内存管理,让Oracle根据当前负载自动管理、分配PGA内存。
夜里用户数少、进行维护的时候可以设定当前会话使用手动PGA内存管理,让当前的维护操作获得尽可能多的内存,加快执行速度。
如:服务器平时运行在自动PGA内存管理模式下,夜里有个任务要大表进行排序连接后更新,就可以在该操作session中临时更改为手动PGA内存管理,然后分配大的SORT_AREA_SIZE和HASH_AREA_SIZE(50%甚至80%内存,要确保无其他用户使用),这样能大大加快系统运行速度,又不影响白天高峰期对系统造成的影响。
六、操作命令
系统级更改:
ALTER SYSTEM SET WORKAREA_SIZE_POLICY = {AUTO | MANAUL};
ALTER SYSTEM SET PGA_AGGREGATE_TARGET=100000000;
ALTER SYSTEM SET SORT_AREA_SIZE = 65536 SCOPE = SPFILE;
ALTER SYSTEM SET HASH_AREA_SIZE = 65536 SCOPE = SPFILE;
会话级更改
ALTER SESSION SET WORKAREA_SIZE_POLICY = {AUTO | MANAUL};
ALTER SESSION SET SORT_AREA_SIZE = 65536;
ALTER SESSION SET HASH_AREA_SIZE = 65536;
七、学以致用
1,排序区:
pga_aggregate_target为100MB,单个查询能用到5%也就是5MB时排序所需时间
SQL> create table sorttable as select * from all_objects;
表已创建。
SQL> insert into sorttable (select * from sorttable);
已创建49735行。
SQL> insert into sorttable (select * from sorttable);
已创建99470行。
SQL> set timing on;
SQL> set autotrace traceonly;
SQL> select * from sorttable order by object_id;
已选择198940行。
已用时间: 00: 00: 50.49
Session级修改排序区为30mb所需时间
SQL> ALTER SESSION SET WORKAREA_SIZE_POLICY = MANUAL;
会话已更改。
已用时间: 00: 00: 00.02
SQL> ALTER SESSION SET SORT_AREA_SIZE = 30000000;
会话已更改。
已用时间: 00: 00: 00.01
SQL> select * from sorttable order by object_id;
已选择198940行。
已用时间: 00: 00: 10.76
可以看到所需时间从50.49秒减少到10.31秒,速度提升很明显。
2,散列区:
pga_aggregate_target为100MB,单个查询能用到5%也就是5MB时表连接所需时间
SQL> select /*+ use_hash(tb1 tb2)*/ * from sorttable tb1,sorttable tb2 where tb1.object_id=tb2.object_id;
已选择49735行。
已用时间: 00: 00: 40.50
Session级修改散列区为30mb所需时间
SQL> ALTER SESSION SET WORKAREA_SIZE_POLICY = MANUAL;
会话已更改。
已用时间: 00: 00: 00.01
SQL> ALTER SESSION SET HASH_AREA_SIZE = 30000000;
会话已更改。
已用时间: 00: 00: 00.01
SQL> select /*+ use_hash(tb1 tb2)*/ * from sorttable tb1,sorttable tb2 where tb1.object_id=tb2.object_id;
已选择49735行。
已用时间: 00: 00: 04.47
所需时间由40.50秒提升到4.47秒,效果同样很明显。
备注:以上实验皆执行全表扫描保证相关表读入缓冲区中,避免因数据没读入缓存造成误差。
结论:在9iR2版以后,PGA不再像以前那样困扰DBA了,Oracle会帮我们做好PGA的分配。但这并不意味着DBA不需要深入了解PGA了,掌握PGA并根据适当应用会让工作如虎添翼。