1、Data_buffer_cache
用来保存频繁访问的数据的内存缓冲区域,以便于oracle用户进程需访问的某块数据可以首先到data_buffer_cache中来寻找能命中(cache hit),从而大大减少从磁盘读取数据所需要的IO时间。
两个不同的列表:
  • 待写列表(write list):包含已被修改的,但尚未写入磁盘的脏缓存块的指示列表。
  • 最近最少使用(Least recently used/LRU list):包含空闲缓存块、命中缓存块,及还未移入待写列表的脏缓存块的指示列表。
四个不同缓冲池:
  • Default pool
  • Keep pool
  • Recycle pool
  • DB_nk_cache_size
查看data_buffer_cache:
SQL> select current_size from v$buffer_pool;           #查看当前分配大小。
SQL> show parameter db%cache_size;                    #查看最低分配限制(ASMM下)
(1)Default pool
数据库对象未特别指定时所使用的默认缓冲池。分别以不同算法处理缓冲区数据,使缓冲数据能尽长或尽短时间地占用default pool缓冲区。
工作方式:
当oracle进程访问一块缓冲区后,会将该缓冲区移动到LRU列表的MRU端(下图中的hot area),随着更多被访问的缓冲区移动到LRU列表的MRU端,较早前被访问过的缓冲区就会逐渐向LRU列表的LRU端(下图中的Cold area)移动。
 
当用户进程执行全表扫描时,数据首次将会从磁盘被读入内存缓冲区,之后将该缓冲区移动到LRU列表的LRU端,以使这些通常只是暂时需要的全表扫描数据所占用的缓冲区能被尽快地移出数据缓冲区,为其他使用频率更高的数据块腾出空间。
查看当前分配的大小:
 SQL> select component,current_size from v$sga_dynamic_components where component='DEFAULT buffer cache';
或SQL> select name,current_size from v$buffer_pool;
如何指定对象使用default pool缓冲区:默认使用default pool。
测试default pool使用效果:
SQL> shutdown immediate
SQL> startup                       #重启数据库,清空缓存。
SQL> show parameter db%cache_size     #查看data_buffer_cache大小。
SQL> conn system/oracle                 #以非sysdba用户登录。
SQL> create table t1 as select * from dba_objects;     #创建测试表。
SQL> select object_name,a.status,count(*) from v$bh a,user_objects b
  2  where a.objd=b.object_id and object_name in ('T1') group by object_name,a.status;
OBJECT_NAME                    STATUS    COUNT(*)
------------------------------ ------- ----------
T1                             xcur             1                      #查看指定对象在default pool中所占用的缓冲区块数目。
SQL> set autotrace on statistics                #开启显示统计信息功能。
SQL> select count(*) from t1;                  #全表扫描。
  COUNT(*)
----------
     49807
Statistics
----------------------------------------------------------
         28  recursive calls
          0  db block gets
        761  consistent gets
        684  physical reads                                            #有物理读。
          0  redo size
        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
SQL> select count(*) from t1;                        #再次全表扫描。
  COUNT(*)
----------
     49807
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        689  consistent gets
           0  physical reads                                #无物理读。
          0  redo size
        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
SQL> select object_name,a.status,count(*) from v$bh a,user_objects b
  2  where a.objd=b.object_id and object_name in ('T1') group by object_name,a.status;
OBJECT_NAME                    STATUS    COUNT(*)
------------------------------ ------- ----------
T1                             xcur           685                      #查看指定对象在default pool中所占用的缓冲区块数目。
(2)Keep pool
将存储在该缓存的数据一直保存在缓存中。该缓存不参与ASMM的动态管理,不能自动调整大小。默认未启用,大小为0.手工修改指定值后,default pool的空间将被相应的消减。
经常访问的热点表应该专门放入keep pool,以防止在默认情况下所有对象都使用default pool时,一个大对象临时调入default pool将其中的真正热点数据挤出default pool带来的性能损失。
工作方式:
与default pool不同,新读入的数据不断以先进先出的方式从LRU表的MRU端移动到LRU端,直到无空闲缓冲时,LRU端最久未使用的数据被调出缓冲区。
查看当前分配的大小:
SQL> select component,current_size from v$sga_dynamic_components
  2  where component='KEEP buffer cache';                      
SQL> select name,current_size from v$buffer_pool;
修改当前分配大小:
SQL> alter system set db_keep_cache_size=10M scope=both;
SQL> show parameter db_keep_cache
SQL> select component,current_size from v$sga_dynamic_components
  2  where component='KEEP buffer cache';                      
SQL> select name,current_size from v$buffer_pool;            #可见default pool相应地减少了。
指定对象使用keep pool:
SQL> create table t_keep(n int) storage(buffer_pool keep);
SQL> alter table t1 storage(buffer_pool keep);
(3)Recycle pool
随时清除存储在其中不再被用户需要的数据,该缓存不参与ASMM的动态管理,不能自动调整大小。默认未启用,大小为0.手工修改指定值后,default pool的空间将被相应的消减。
不常访问的大对象应该专门放入recycle pool,以防止一个大对象临时调入default pool,而将其中真正的热点表挤出default pool带来的性能损失。
工作方式:
与default pool和keep pool都不同,对于recycle pool,先进入缓存的表被保留在recycle pool中。recycle pool满了以后,读取的数据将不被缓存。
查看当前分配的大小:
SQL> select component,current_size from v$sga_dynamic_components
  2  where component='RECYCLE buffer cache';
SQL> select name,current_size from v$buffer_pool;
修改当前分配大小:
SQL> alter system set db_recycle_cache_size=10M scope=both;
SQL> show parameter db_recycle_cache
SQL> select component,current_size from v$sga_dynamic_components
  2  where component='RECYCLE buffer cache';
SQL> select name,current_size from v$buffer_pool;
指定对象使用keep pool:
SQL> create table t_rec(n int) storage(buffer_pool recycle);
SQL> alter table t1 storage(buffer_pool keep);
2、shared pool
共享池是SGA中最关键的内存片段,特别是在性能和可伸缩性上。一个太小的共享池会降低性能,使系统停止;太大的共享池也会有同样的效果,将会消耗大量的CPU来管理这个共享池。
shared pool分为library_cache和data dictionary cache两个主要的部分及近600项其余部分。
查看shared_pool参数默认设置值,为0则表示ASMM已开启:
SQL> show parameter shared_pool_size;
查看shared_pool当前运行期间所分配大小:
SQL> select pool,sum(bytes) from v$sgastat group by pool;
查看shared_pool中所有组成部分:
SQL> select * from v$sgastat;
SQL> select pool,sum(bytes) from v$sgastat group by pool;
(1)Library Cache
用户提交一个新SQL语句时,Oracle会分析(parse)该句SQL(硬解析),这个过程将耗费相对较多的时间。分析完毕后,oracle会将该SQL的分析结果给保存在Library Cache中,当数据库再次执行该SQL时,oracle将直接取第一次分析结果而不再重新解析,从而减少运行时间。
  • Library Cache四个组成部分:
  • 共享SQL区:保存语句文本,编译后的语法分析树及执行计划。
  • 私有SQL区:保存语句中的变量值。
  • 共享PL/SQL区:保存PL/SQL语句。
  • 控制结构区:保存锁等控制信息。
查看library cache的大小:
SQL> select sum(sharable_mem) from v$db_object_cache;
测试library cache的作用:
SQL> set timing on
SQL> select count(*) from dba_objects;
  COUNT(*)
----------
     49809
Elapsed: 00:00:00.20
SQL> select count(*) from dba_objects;
  COUNT(*)
----------
     49809
Elapsed: 00:00:00.10
查看保存在library cache中保存的已分析的SQL语句:
SQL> select * from v$sqltext where sql_text like '%dba_object%';
SQL> select sql_text from v$sqlarea where sql_text like '%dba_object%';
绑定变量:
绑定变量的使用:
SQL> select object_id,object_name from dba_objects where object_id=5100;
SQL> select object_id,object_name from dba_objects where object_id=5101;
SQL> variable i number;            #定义变量。
SQL> exec :i:=5100;                 #给变量赋值。
SQL> print :i                            #打印变量值。
SQL> select object_id,object_name from dba_objects where object_id=:i;
SQL> exec :i:=5101;
SQL> select object_id,object_name from dba_objects where object_id=:i;
SQL> select sql_text,parse_calls from v$sqlarea where sql_text like '%object_id%';
SQL_TEXT
--------------------------------------------------------------------------------
PARSE_CALLS
-----------
select object_id,object_name from dba_objects where object_id=:i              #缓存的sql语句。
          2                                                                                                #被调用次数。
select sql_text,parse_calls from v$sqlarea where sql_text like '%object_id%'
          1
select object_id,object_name from dba_objects where object_id=5100
          1
select object_id,object_name from dba_objects where object_id=5101
          1
#可见使用绑定变量可以增加sql语句缓存的命中率,减少硬解析所带来的性能损失。

Data Dictionary Cache

专供数据字典使用的缓冲区,SQL语句分析过程中需要大量访问系统数据字典(从磁盘数据文件中访问数据字典成为recursive calls),即可使用该缓存区专门存放数据字典,从而避免过多的recursive calls所带来的性能损失。

数据字典是关于数据库的参考信息、数据库的结构信息、数据库的用户信息等各类信息描述的一组表和视图的集合。

数据字典用于描述所有数据库对象的数据库对象的集合。

SQL> select * from v$fixed_table;   #查看系统中所有的动态表。

SQL> select * from dict;          #查看数据字典。

SQL> select object_name,object_type,created from dba_objects where object_name in ('TEST','T1');                      #从数据字典的dba_objects表中查询指定数据库对象的相关描述。

SQL> select * from dba_users;         #从数据字典dba_users表中查询数据库用户的相关描述。

SQL> select * from dba_data_files;  #从数据字典dba_data_files表中查询所有数据库文件的相关描述。

数据字典中表的分类:

静态表:对各类数据库对象的各类属性的描述,常见的有下面三类字母开头:

  1. dba_*:存储当前数据库中所有数据库对象的描述
  2. all_*:存储当前用户能够访问的数据对象的描述
  3. user_*:存储当前用户所拥有的数据库对象的描述

动态表:不断动态更新以反映数据库当前运行状况,常见以“v$”开头。

 

查看data dictionary cache的大小:

SQL> select sum(sharable_mem) from v$sqlarea;

测试的data dictionary cache作用:

SQL> set autot on stat                                #打开统计信息显示。
SQL> select count(*) from dba_source;             #查询一张表。

  COUNT(*)
----------
    292167

Statistics
----------------------------------------------------------
        312  recursive calls                                   #recursive calls 次数。
          0  db block gets
       1998  consistent gets
        698  physical reads
          0  redo size
        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> select count(*) from dba_source;             #再次查同一张表。

  COUNT(*)
----------
    292167

Statistics
----------------------------------------------------------
          0  recursive calls                                  #可见recursive calls 次数明显减少。
          0  db block gets
       1927  consistent gets
          0  physical reads
          0  redo size
        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

3、Large pool

large_pool用来分配大内存块,来处理比shared pool更大的内存,实际常用做备用池,用以缓解oracle对共享池和PGA区内存的使用压力。使用large pool的对象主要有:

多线程服务器MTS:在SGA的large_pool中分配UGA;

语句的并行查询Parallel Exection:用作进程间的消息缓冲器;

恢复管理器RMAN:备份时用作磁盘I/O缓冲区。

SQL> show parameter large_pool             #查看large_pool参数默认值,为0则应表示ASMM已开启。

SQL> select pool,sum(bytes) from v$sgastat group by pool;   # 查看large_pool当前运行期间ASMM实际分配大小。

4、Java pool

oracle在内核中加入了对java的支持。该缓冲区转为java开发和应用所设,若不用java程序则没必要改变该缓冲区的默认大小。

SQL> show parameter java_pool             #查看java_pool参数默认值,为0则应表示ASMM已开启。

SQL> select pool,sum(bytes) from v$sgastat group by pool;   # 查看java_pool当前运行期间ASMM实际分配大小。

5、redo_log_buffer

对数据库的任何修改都按顺序被记录在该缓冲区,然后由LGWR进程根据条件将更改信息批量写入磁盘上的redo log文件,以节省磁盘IO。该缓存不参与ASMM的动态管理,不能自动调整大小。

SQL> select name,bytes from v$sgastat where name='log_buffer';   #查看log_buffer实际大小。

SQL> show parameter log_buffer              #查看log_buffer预设大小。

SQL> alter system set log_buffer=2000000 scope=spfile;     #手工修改log_buffer大小,需重启。

6、streams_buffer

用于对流复制进行缓冲。

SQL> show parameter streams_pool     #查看streams_pool参数默认值。