ORA-00382与DB_nK_CACHE_SIZE参数设置

最近在尝试优化一个包含blob字段表的查询,考虑使用非标准块缓存。但是,在尝试设置DB_32K_CACHE_SIZE参数时,遭遇报错(报错内容:ORA-00382: 32768 不是有效的块大小, 有效范围为 [..])。于是,到官方文档查了一下,才明白这个参数的设置由于和底层数据块相关,与操作系统是紧密相连的。在Windows操作系统下,DB_32K_CACHE_SIZE参数时不可用的,但是,它支持DB_16K_CACHE_SIZE。

这里给出参数的官方文档说明以及具体的操作过程,仅供参考。

官方文档说明DB_nK_CACHE_SIZE

属性

描述

参数类型

整型数

语法

DB_[2 | 4 | 8 | 16 | 32]K_CACHE_SIZE =integer[K | M | G]

默认值

0 (默认情况下,不设置非标准块大小缓存)

修改

ALTER SYSTEM

取值范围

最小值: 0 (如果值大于0,会自动修改为内存颗粒大小*处理器个数,或者4MB*CPU个数,取二者较大值)

最大值: 取决于操作系统

基本参数

DB_nK_CACHE_SIZE (其中 n = 2, 4, 8, 16, 32) 指定了nK缓存区的大小。你可以设置除DB_BLOCK_SIZE之外的其他数值。例如,如果DB_BLOCK_SIZE4096,那么你设置DB_4K_CACHE_SIZE就是非法的(因为4K的缓存区大小已经被DB_CACHE_SIZE参数设置过了)

如果数据库中存在nK块大小的在线表空间,那么不能设置该参数为0

操作系统会限制特定的块大小。例如,如果操作系统最大块尺寸小于32KB,那么你不能设置DB_32K_CACHE_SIZE参数。同样,如果最小块尺寸大于2KB,那么你也不能设置DB_2K_CACHE_SIZE参数。

操作环境

  1. SQL> select * from v$version;
  2.  
  3. BANNER
  4. ----------------------------------------------------------------
  5. Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
  6. PL/SQL Release 10.2.0.4.0 - Production
  7. CORE 10.2.0.4.0 Production
  8. TNS for 64-bit Windows: Version 10.2.0.4.0 - Production
  9. NLSRTL Version 10.2.0.4.0 - Production
  10.  
  11. SQL>

查看DB_BLOCK_SIZE

首先,我们查看一下数据库的标准块大小,这个是由 DB_BLOCK_SIZE参数决定的。
  1. SQL>
  2. SQL> show parameter db_block_size
  3.  
  4. NAME TYPE VALUE
  5. ------------------------------------ ----------- ------------------------------
  6. db_block_size integer 8192
  7. SQL>

根据官方文档的解释,这就意味着我们是无法设置DB_8K_CACHE_SIZE参数的,否则会报错,如下所示:

  1. SQL>
  2. SQL> alter system set db_8k_cache_size=200M;
  3. alter system set db_8k_cache_size=200M
  4. *
  5. 第 1 行出现错误:
  6. ORA-32017: 更新 SPFILE 时失败
  7. ORA-00380: 无法指定 db_8k_cache_size, 因为 8K 是标准块大小
  8.  
  9. SQL>

查看所有与cache size相关的参数

根据官方文档的说明,默认情况下DB_nK_CACHE_SIZE参数的值都是0,我们可以查看一下所有与cache size相关的参数。

  1. SQL> show parameter cache_size
  2.  
  3. NAME TYPE VALUE
  4. ------------------------------------ ----------- ------------------------
  5. db_16k_cache_size big integer 0
  6. db_2k_cache_size big integer 0
  7. db_32k_cache_size big integer 0
  8. db_4k_cache_size big integer 0
  9. db_8k_cache_size big integer 0
  10. db_cache_size big integer 0
  11. db_keep_cache_size big integer 0
  12. db_recycle_cache_size big integer 0
  13. SQL>

设置DB_32K_CACHE_SIZE报错

我尝试把DB_32K_CACHE_SIZE参数修改为200M,遭遇报错。

  1. SQL> alter system set db_32k_cache_size=200M;
  2. alter system set db_32k_cache_size=200M
  3. *
  4. 第 1 行出现错误:
  5. ORA-32017: 更新 SPFILE 时失败
  6. ORA-00382: 32768 不是有效的块大小, 有效范围为 [..]

现在明白了,这个参数的设置和操作系统紧密相关。既然无法设置DB_32K_CACHE_SIZE,也就是说,Windows Server 2008 Standard R2操作系统的最大块尺寸是小于32K的。

设置DB_16K_CACHE_SIZE

那么,接下来我们尝试设置DB_16K_CACHE_SIZE参数。

  1. SQL>
  2. SQL> alter system set db_16k_cache_size=200M;
  3.  
  4. 系统已更改。
  5.  
  6. SQL> show parameter db_16k
  7.  
  8. NAME TYPE VALUE
  9. ------------------------------------ ----------- -----------------------
  10. db_16k_cache_size big integer 208M
  11. SQL>

从结果来看我们是设置成功了,但是我们明明设置的是200M,为什么查出来的是208M呢?这个我们也可以从官方文档的说明中找到答案——“如果值大于0,会自动修改为内存颗粒大小*处理器个数,或者4MB*CPU个数,取二者较大值”。我看了一下系统的硬件配置,双核*12CPU,也就是有24CPU。那么,内存颗粒大小即granule又是什么呢?

原来,SGA中的各个组件分配都是以granule作为一个单位来分配的,而并不是一次分配1M1K这样的单位。granule大小是以SGA大小由系统设定的,当SGA小于1G时,granule大小为4M,SGA大于1G的时候granule大小为16M。接下来,我们查看一下sga以及granule大小。

  1. SQL> show sga
  2.  
  3. Total System Global Area 1258291200 bytes
  4. Fixed Size 2163712 bytes
  5. Variable Size 360446976 bytes
  6. Database Buffers 889192448 bytes
  7. Redo Buffers 6488064 bytes
  8. SQL>
  9. SQL> select component,granule_size from v$sga_dynamic_components;
  10.  
  11. COMPONENT GRANULE_SIZE
  12. ---------------------------------------------------------------- ------------
  13. shared pool 16777216
  14. large pool 16777216
  15. java pool 16777216
  16. streams pool 16777216
  17. DEFAULT buffer cache 16777216
  18. KEEP buffer cache 16777216
  19. RECYCLE buffer cache 16777216
  20. DEFAULT 2K buffer cache 16777216
  21. DEFAULT 4K buffer cache 16777216
  22. DEFAULT 8K buffer cache 16777216
  23. DEFAULT 16K buffer cache 16777216
  24. DEFAULT 32K buffer cache 16777216
  25. ASM Buffer Cache 16777216
  26.  
  27. 已选择13行。
  28.  
  29. SQL>

由此,我们知道granule大小为16M。但是208granule大小*处理器个数,或者4MB*CPU个数,这几个数字始终联系不到一起。
于是,我又尝试把
db_16k_cache_size设为100M,看看是什么效果。

点击(此处)折叠或打开

  1. SQL>
  2. SQL> alter system set db_16k_cache_size=100M;
  3.  
  4. 系统已更改。
  5.  
  6. SQL> show parameter db_16k
  7.  
  8. NAME TYPE VALUE
  9. ------------------------------------ ----------- ------------------------
  10. db_16k_cache_size big integer 112M
  11. SQL> 

我们设置的110M,查询结果是112M,还是找不出规律,这个问题放到以后再研究一下。

猜你喜欢

转载自www.linuxidc.com/Linux/2015-08/121126.htm