【記憶體管理】Oracle如何使用ASMM自動共享記憶體管理

恩強Boy發表於2020-12-03

一、  自動共享記憶體管理介紹

自動共享記憶體管理ASMM Automatic Shared Memory Management, 以下均稱 ASMM )是 Oracle 10g 版本推出的特性,但是在 11g 12c 版本,仍然可以用 ASMM 來替代自動記憶體管理 AMM Automatic Memory Management )。

1.  ASMM 概念

oracle 9i 開始,一些 SGA 引數可以進行動態地修改,透過 alter system 命令可以放大或縮小他們的當前值。整個SGA 的大小被 sga_max_size 引數限制。每一個 SGA 引數都是以“顆粒”的形式進行分配,這些“顆粒”大小將取決於 sga_max_size 的值和硬體平臺。

9i 版本開始,下面的引數可以動態的定義:

- Shared Pool

- Default Buffer Cache

- Large Pool

10g 之前版本,當你想要放大或縮小這些動態引數,空閒的記憶體不會自動的修改,我們必須手動的進行修改。在 10g 版本,引入了 ASMM 特性,目的是減輕 DBA SGA 的某些元件進行手工修改工作。

ASMM 啟動時,讓 Oracle 自動為 SGA 的元件進行正確的分配,如:

- SHARED POOL

- LARGE POOL

- JAVA POOL

- STREAMS POOL

- DB CACHE(using the DB_BLOCK_SIZE value)

這個功能的主要目地就是,Oracle 根據當前的工作負載分配可用記憶體。根據記憶體活動增強記憶體使用,避免 ORA-4031 這樣的記憶體錯誤發生。


2.  配置ASMM

自動共享記憶體管理ASMM 透過一個引數配置: sga_target

sga_target 設定為 0 ASMM 將會被禁用。你只能用更舊的方法去調節記憶體分配,因此需要自己定義上述自動調節引數。

當設定以下條件,ASMM 將會被啟動:

- statistics_level=typical or all

- sga_target > 0

ASMM 被啟用,記憶體將在所有的元件之間擴充套件。因此, sga_target 值將定義可在自動調節引數和手動引數之間共享記憶體大小。

手動引數如下:

- db_cache_size

- db_nk_cache_size(non default block size)

- log_buffer

- fixed sga

- streams_pool_size

在這些手動引數中,有一些是可修改的,有一些是固定的(僅在啟動時固定)

可修改的:db_cache_size,streams_pool_size

固定的:db_nk_cache_size,fixed sga,log_buffer

sga_target 值被 sga_max_size 值限制, sga_max_size 引數不能動態修改。

SQL> show parameter sga_max

 

NAME             TYPE            VALUE

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

sga_max_size    big integer 300M

如果你想要修改更大的sga_target, 將會得到以下錯誤提示:

SQL> alter system set sga_target=600m;

alter system set sga_target=600m

*

ERROR at line 1:

ORA-02097: parameter cannot be modified because specified value is invalid

ORA-00823: Specified value of sga_target greater than sga_max_size

二、使用ASMM 示例

1. 手動設定 ASMM

當你剛升級資料庫從低版本到10g 版本時,可能會出現以下情況:

sga_target 沒有定義,預設為 0

SQL> show parameter sga;

NAME                        TYPE        VALUE

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

lock_sga                   boolean     FALSE

pre_page_sga              boolean     FALSE

sga_max_size              big integer 164M

sga_target                big integer 0

所有SGA 引數已經被手動設定

SQL> show parameter size

NAME                         TYPE        VALUE

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

bitmap_merge_area_size      integer   1048576

create_bitmap_area_size     integer   8388608

db_block_size     integer   8192

db_cache_size     big integer 24M

db_keep_cache_size     big integer 0

db_recovery_file_dest_size big integer 2G

db_recycle_cache_size   big integer 0

db_16k_cache_size     big integer 0

db_2k_cache_size     big integer 0

db_32k_cache_size     big integer 0

db_4k_cache_size     big integer 0

db_8k_cache_size     big integer 0

global_context_pool_size   string

hash_area_size     integer   131072

java_max_sessionspace_size integer   0

java_pool_size     big integer 48M

large_pool_size     big integer 8M

max_dump_file_size     string   UNLIMITED

object_cache_max_size_percent integer   10

object_cache_optimal_size   integer   102400

olap_page_pool_size   big integer 0

parallel_execution_message_size integer 2148

sga_max_size       big integer 164M

shared_pool_reserved_size   big integer 4M

shared_pool_size     big integer 80M

sort_area_retained_size   integer   0

sort_area_size     integer   65536

streams_pool_size     big integer 0

workarea_size_policy   string   AUTO

所以,自動調節的引數有

db_cache_size=24M

shared_pool_size=80M

large_pool_size=8M

java_pool_size=48M

手動設定ASMM 模式

SQL> alter system set sga_target= 100 M;

SQL> show parameter sga;

NAME                               TYPE        VALUE

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

lock_sga                        boolean     FALSE

pre_page_sga                   boolean     FALSE

sga_max_size                   big integer 164 M

sga_target                      big integer 164 M

sga_target 作為 sga 的最小值,並且 sga_target 已經自動做了調整,以支援 V$SGA_DYNAMIC_COMPONENTS 檢視中列出的自動調節引數的初始值。

SQL> select component, current_size, min_size, user_specified_size from v$sga_dynamic_components;

COMPONENT     CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE

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

shared pool     80     80   80

large pool         8      8   8

java pool       48     48   48

streams pool       0       0   0

DEFAULT buffer cache   24     24   24

KEEP buffer cache       0       0   0

RECYCLE buffer cache     0       0   0

DEFAULT 2K buffer cache     0       0   0

DEFAULT 4K buffer cache     0       0   0

DEFAULT 8K buffer cache     0       0   0

DEFAULT 16K buffer cache     0       0   0

DEFAULT 32K buffer cache     0      0   0

OSM Buffer Cache       0       0   24

在這種情況下,oracle 沒有更多空餘的記憶體可以用來進行動態調節。

SQL>  select * from v$sga_dynamic_free_memory;

CURRENT_SIZE

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

            0

假設設定sga_max_size 超過 SGA 的計算大小,我們設定為 700M

SQL> alter system set sga_max_size= 300 M scope=spfile;

SQL> shutdown immediate;

SQL> startup

SQL> alter system set sga_target=164M;

SQL> show parameter sga;

NAME                                  TYPE          VALUE

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

lock_sga                             boolean       FALSE

pre_page_sga                         boolean      FALSE

sga_max_size                         big integer 300M

sga_target                           big integer   164M

SQL> select current_size/1024/1024 "CURRENT_SIZE" from v$sga_dynamic_free_memory;

CURRENT_SIZE

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

         1 36

此時我們發現有140M 的空餘記憶體可供 SGA 使用

2. 增加、減少 sga_target

修改sga_target 大小

SQL> alter system set sga_target=200M;

SQL> show parameter sga

NAME                                 TYPE            VALUE

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

lock_sga                             boolean        FALSE

pre_page_sga                         boolean        FALSE

sga_max_size                         big integer 300 M

sga_target                           big integer 200 M

 

SQL> select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE", user_specified_size/1024/1024 "USER_SPECIFIED_SIZE" from v$sga_dynamic_components;

COMPONENT     CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE

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

shared pool     80     80   80

large pool     8     8   8

java pool     48     48   48

streams pool     0     0   0

DEFAULT buffer cache   60     24   24

KEEP buffer cache   0     0   0

RECYCLE buffer cache   0     0   0

DEFAULT 2K buffer cache 0     0   0

DEFAULT 4K buffer cache 0     0   0

DEFAULT 8K buffer cache 0     0   0

DEFAULT 16K buffer cache 0     0   0

DEFAULT 32K buffer cache 0     0   0

OSM Buffer Cache   0     0   24

透過上面的對比我們可以看到,db_buffer_cache 大小由 24 自動調節到 60 SGA SIZE=80M+8M+48M+60M=196M ,預留 4M 作為手動引數。 Oracle 將根據記憶體管理器查出的結果,根據每個自動調節元件的需求來決定在哪裡分配更多的空間。

再次進行如下設定

SQL> alter system set sga_target=300M;

SQL>   select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE",

user_specified_size/1024/1024 "USER_SPECIFIED_SIZE" from v$sga_dynamic_components;

COMPONENT     CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE

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

shared pool     80     80   80

large pool     8     8   8

java pool     48     48   48

streams pool     0     0   0

DEFAULT buffer cache   160       24   24

KEEP buffer cache   0     0   0

RECYCLE buffer cache   0     0   0

DEFAULT 2K buffer cache 0     0   0

DEFAULT 4K buffer cache 0     0   0

DEFAULT 8K buffer cache 0     0   0

DEFAULT 16K buffer cache 0     0   0

DEFAULT 32K buffer cache 0     0   0

OSM Buffer Cache   0     0   24

如上圖所示,db_cache_size 已經提升到了 160 。此時所有新增的 SGA 記憶體都已經新增給 buffer cache

正如上面所言,sga_target 引數包括自動調節和手動引數。當你去提高一個手動引數時,它將會影響自動調節部分。

SQL>   alter system set streams_pool_size=10M;

SQL> select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE",

user_specified_size/1024/1024 "USER_SPECIFIED_SIZE", last_oper_type "TYPE" from

v$sga_dynamic_components;

COMPONENT        CURRENT_SIZE MIN_SIZE    SER_SPECIFIED_SIZE   TYPE

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

shared pool     80   80   80     STATIC

large pool     8   8   8     STATIC

java pool     48   48   48     STATIC

streams pool     12   0   12     GROW

DEFAULT buffer cache   148   24   24     SHRINK

KEEP buffer cache   0   0   0     STATIC

RECYCLE buffer cache   0   0   0     STATIC

DEFAULT 2K buffer cache 0   0   0     STATIC

DEFAULT 4K buffer cache 0   0   0     STATIC

DEFAULT 8K buffer cache 0   0   0     STATIC

DEFAULT 16K buffer cache 0   0   0     STATIC

DEFAULT 32K buffer cache 0   0   0     STATIC

OSM Buffer Cache   0   0   24     STATIC

如上圖所示,我們手動修改了streams pool 引數,該引數型別變為 GROW,db_buffer_cache 引數型別變為 SHRINK

注意到這裡streams pool 12M 而不是我們修改的 10M ,是因為 streams pool 基於 GRANULE_SIZE 四捨五入到 12M 了。查詢 GRANULE_SIZE 基本單位如下:

SQL> select component, granule_size/1024/1024 "GRANULE_SIZE(Mb)" from v$sga_dynamic_components;

COMPONENT       GRANULE_SIZE(Mb)

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

shared pool     4

large pool       4

java pool       4

streams pool     4

DEFAULT buffer cache   4

KEEP buffer cache     4

RECYCLE buffer cache   4

DEFAULT 2K buffer cache   4

DEFAULT 4K buffer cache   4

DEFAULT 8K buffer cache   4

DEFAULT 16K buffer cache   4

DEFAULT 32K buffer cache   4

OSM Buffer Cache     4

也可以透過v$sga_resize_ops 檢視, sga 中元件的歷史變化

SQL> select component, oper_type, oper_mode,initial_size/1024/1024 "INITIAL",

TARGET_SIZE/1024/1024 "TARGET", FINAL_SIZE/1024/1024   "FINAL", status from v$sga_resize_ops;

COMPONENT         OPER_TYPE   OPER_MODE INITIAL TARGET FINAL STATUS

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

DEFAULT buffer cache   SHRINK    MANUAL 160 148 148    COMPLETE

streams pool       GROW      MANUAL 0   12   12     COMPLETE

如果你打算減少sga_target, 自動最佳化的引數將會受影響,但是手動引數不會受影響。

SQL> alter system set sga_target=200M;

SQL>    select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE",   user_specified_size/1024/1024 "USER_SPECIFIED_SIZE", last_oper_type "TYPE" from v$sga_dynamic_components;

COMPONENT        CURRENT_SIZE MIN_SIZE    SER_SPECIFIED_SIZE   TYPE

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

shared pool     80   80   80     STATIC

large pool     8   8   8     STATIC

java pool     48   48   48     STATIC

streams pool     12   0   12     GROW

DEFAULT buffer cache   48   24   24     SHRINK

KEEP buffer cache   0   0   0     STATIC

RECYCLE buffer cache   0   0   0     STATIC

DEFAULT 2K buffer cache 0   0   0     STATIC

DEFAULT 4K buffer cache 0   0   0     STATIC

DEFAULT 8K buffer cache 0   0   0     STATIC

DEFAULT 16K buffer cache 0   0   0     STATIC

DEFAULT 32K buffer cache 0   0   0     STATIC

OSM Buffer Cache   0   0   24     STATIC

sga_target 在設定的時候,是有一個最小值限制。它的最小值計算方式為:

SUM(MIN_SIZE)= 所有自動調節引數 + streams_pool 的當前值 + 4M = 176M

如果你的設定值小於這個最小值,那麼將會報ORA-00827 的錯誤。

1)  升高、降低自動調節引數

你可以選擇去改變一些自動調節引數,如下:

SQL> alter system set shared_pool_size=100M;

SQL>select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "

user_specified_size/1024/1024 "USER_SPECIFIED_SIZE", last_oper_type "TYPE" from

v$sga_dynamic_components;

COMPONENT     CURRENT_SIZE MIN_SIZE    USER_SPECIFIED_SIZE TYPE

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

shared pool     100     80 100     GROW

large pool     8     8 8     STATIC

java pool     48     48 48     STATIC

streams pool     12     0 12     GROW

DEFAULT buffer cache   28     24 24     SHRINK

KEEP buffer cache   0     0 0     STATIC

RECYCLE buffer cache   0     0 0     STATIC

DEFAULT 2K buffer cache   0     0 0     STATIC

DEFAULT 4K buffer cache 0     0 0     STATIC

DEFAULT 8K buffer cache 0     0 0     STATIC

DEFAULT 16K buffer cache 0     0 0     STATIC

DEFAULT 32K buffer cache 0     0 0     STATIC

OSM Buffer Cache       0     0 24     STATIC

上面的查詢輸出顯示shared_pool_size 已經設定為 100M,CURRENT_SIZE USER_SPECIFIED_SIZE 列已經被重置。其中 20M 是從 db_buffer_cache 中提取的,該列的值從 48M 減少到 28M

如果你想繼續嘗試

SQL> alter system set shared_pool_size=180M;

alter system set shared_pool_size=180M

*

ERROR at line 1:

ORA-02097: param

eter cannot be modified because specified value is invalid

ORA-04033: Insufficient memory to grow pool

3.ASMM 設定為手動

你可以禁用ASMM 設定為手動模式,只要設定 sga_target=0 即可。

SQL> alter system set sga_target=0;

在重啟例項之後,所有的MIN_SIZE 將會等於 CURRENT_SIZE

SQL> select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE",

user_specified_size/1024/1024 "USER_SPECIFIED_SIZE", last_oper_type "TYPE" from

v$sga_dynamic_components;

COMPONENT         CURRENT_SIZE MIN_SIZE     USER_SPECIFIED_SIZE TYPE

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

shared pool     104   104     104     STATIC

large pool     8   8   8     STATIC

java pool     48   48   48     STATIC

streams pool     12   12   12     STATIC

DEFAULT buffer cache   24   24   24     STATIC

KEEP buffer cache   0   0   0     STATIC

RECYCLE buffer cache   0   0   0     STATIC

DEFAULT 2K buffer cache 0   0   0     STATIC

DEFAULT 4K buffer cache 0   0   0     STATIC

DEFAULT 8K buffer cache 0   0   0     STATIC

DEFAULT 16K buffer cache 0   0   0     STATIC

DEFAULT 32K buffer cache 0   0   0     STATIC

OSM Buffer Cache   0   0   24     STATIC

這裡需要注意,儘管memory_target sga_target 引數設定為 0 ,自動記憶體管理( AMM/ASMM )已經禁用,但是升級到 11.2 版本之後, SGA 的大小可能會重新調整,這通常表現在 share_pool_size 增加,而剩餘的 db_cache_size 值減少。 db_cache_size 可能會縮小到引數檔案中指定的 db_cache_size 值以下。

三、總結

10g 以前的版本,可以透過為 SGA 的各個元件找到最佳的值,來達到例項調優。使用 ASMM ,我們不必調整一些 SGA 元件引數的大小, oracle 會根據例項概要來自動選擇正確的值。 Oracle 建議為這些自動調優的引數提供一個最小顯式設定,來幫助 Oracle 對於記憶體分配做出最佳選擇。

 

---- end ----

 


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

相關文章