ORA-00382與DB_nK_CACHE_SIZE引數設定

Hoegh發表於2015-07-28
    最近在嘗試最佳化一個包含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引數。


操作環境

我在Oracle10g+Windows Server 2008 Standard R2環境下進行以下操作。

點選(此處)摺疊或開啟

  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.  
  10. 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,還是找不出規律,這個問題放到以後再研究一下。

hoegh
15.07.28
-- The End --
 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30162081/viewspace-1754656/,如需轉載,請註明出處,否則將追究法律責任。

相關文章