ITPub博客

首页 > 数据库 > Oracle > tom 9I-10G的sga的多缓存池 多块和dual表的一点分析

tom 9I-10G的sga的多缓存池 多块和dual表的一点分析

原创 Oracle 作者:dotaddjj 时间:2012-02-14 22:58:54 0 删除 编辑

Sga共享内存区,在nomount阶段已经分配,每个oracle进程都会访问其中的某一点。在unix操作系统上,sga是一个物理实体,进程可以附加到这段独立的内存上。

[oracle@localhost ~]$ ipcs -m|grep ora

0x01b9ced8 65537 oracle 640 1612709888 771

Windows上,oracle会作为一个地址空间单个进程执行,sga将作为专用内存分配给oracle.exe进程,无法查看sga分配内存

固定sga

固定sga是sga一个组件,其大小跟平台版本有关,安装数据库时,固定sga会编译到二进制执行文件中。固定sga中保存了各sga组件的变量和参数,通常很小无法调整用于自启sga定位其他组件。(可以想象为bootstrap$启动数据库一样,用于在内存中先创建bootstrap$表然后通过物理文件插入数据到bootstrap$中初始化数据字典。)

Log_buffer

重做日志缓存区用于保存redo log的buffer,然后在事务提交,日志切换,log_buffer达到1MB或者1/3,每三秒一次时都会触发LGWR把log_buffer写入redo log。

由于LGWR频繁的写入,一般设置较大的log_buffer意义不大,不过对于大量并发事务的大型系统,较大的log_buffer更为合理,一个大型事务中会产生很多redo,此时别的session的事务也可能在运行,较大的log_buffer更能满足这种并发大事务系统。

SQL> alter system set log_buffer=1 scope=spfile;

系统已更改。

SQL> startup force;

ORACLE 例程已经启动。

Total System Global Area 373293056 bytes

Fixed Size 1249080 bytes

Variable Size 117440712 bytes

Database Buffers 251658240 bytes

Redo Buffers 2945024 bytes

数据库装载完毕。

数据库已经打开。

SQL> show parameter log_buffer;

NAME TYPE VALUE

------------------------------------ ----------- ------------------------

log_buffer integer 2899456

log_buffer的默认最小大小受os限制,即使设置1字节log_buffer,log_buffer依然根据os选择合适的log_buffer。

数据字典查询的hint rbo:

select * from dba_objects where data_object_id in

(select data_object_id from dba_objects

group by data_object_id having count(*)>1)

上述sql语句在cbo下cost 365,由于是本机测试库,相对硬件环境较差,特别是磁盘I/O性能上,sql语句长时间未反应,发现执行计划中走了obj$基表的全表扫描,这个基表相对比较大,试试hint /*+rule*/强制走rbo,rbo下会默认索引为最高级别,obj$表选择了索引,sql语句马上就有相应执行结果,由于对数据字典无法分析,oracle可能无法高效利用索引,强制hint rbo相对与无法分析统计的数据字典执行效率大幅提升!这也提醒在cbo下统计分析的重要性!

Oracle 10g的dual虚表的两个有意思的查询

SQL> select sysdate from dual;

SYSDATE

--------------

14-2月 -12

执行计划

----------------------------------------------------------

Plan hash value: 1388734953

-----------------------------------------------------------------

| Id | Operation | Name | Rows | Cost (%CPU)| Time |

-----------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |

| 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 |

-----------------------------------------------------------------

统计信息

----------------------------------------------------------

1 recursive calls

0 db block gets

0 consistent gets

0 physical reads

0 redo size

412 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 * from dual;

D

-

X

执行计划

----------------------------------------------------------

Plan hash value: 272002086

--------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 2 | 2 (0)| 00:00:01 |

| 1 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |

--------------------------------------------------------------------------

统计信息

----------------------------------------------------------

24 recursive calls

0 db block gets

6 consistent gets

3 physical reads

0 redo size

404 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

看出在oracle 10g后对dual表做了调整,当不实际查询dual表的数据时,oracle会直接做函数等查询,而没有实际访问dual表,对于大量使用dual表的系统,减少大量一致性读和物理读次数。

多缓存池技术:

除了一般的默认缓存池db cache,oracle8I又推出了db_keep_cache和db_recycle_cache多缓存技术,db_keep_cache池用于存储希望一直保存的块,db_recycle_cache用于临时的大块,而防止随机访问大块导致缓存区大量刷新输出。

多缓存技术一般是作为一种低级的精细的调优手段,而且多缓存池之间无法共享,创建段时需要设置存储的缓存池,不然会存储在默认缓存池中,这也增加了管理的难度。

同样在oracle 9I开始,除了原先的多缓存池,数据库内还可以有多个不同的数据块大小。

设置非缺省块缓存池大小

Alter system set db_4K_cache_size=10m

然后创建非缺省块的表空间

Create tablespace test_4k datafile size 50M autoextend on 10M

Blocksize 4K

注意这里需要先制定非缺省数据块大小的缓存池大小,然后再创建相应的表空间。跟多缓存池技术一样,非缺省块也为数据库的管理增加了复杂性,主要是用作可传输表空间技术,将数据文件在数据库之间传输,而一般不用做调优,倒是可以用在一些特殊情况下,例如混合系统中,既需要事务处理也需要事务分析。

共享池和large pool

存储sql pl/sql解析执行计划和数据字典的共享内存结构,共享池一般存储相对较小的内存块chunk。

大池用于大块内存分配,是一个回收型的内存空间,一般不重用,如果把大块内存存储在共享池中,会导致共享池中部分可用内存老化,而实际上大块内存也不需要缓存。

大池主要用于:共享服务器下在sga中分配uga区(共享服务器链接下uga一般很大),语句并行执行,rman备份下的磁盘I/O缓冲

[@more@]

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/25362835/viewspace-1057354/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    220
  • 访问量
    1662981