Oracle效能最佳化 之 共享池

不一樣的天空w發表於2017-04-21
Oracle效能最佳化 之 共享池
http://blog.chinaunix.net/uid-26762723-id-3247692.html

一、共享池簡介:

共享池的位置、各個部分及作用;

二、設定、檢視共享池大小:

     在9i中我們用引數Shared_pool_size設定共享池的大小,10g中的設定我們下面再講。另需注意,無論在9i還是10g中,Shared_pool_size引數的值都不一定代表共享池的真正大小,實際共享池大小會和此引數的值有一些出入。如果要檢視共享池的大小,可以使用如下兩種方式:

1)、使用Show sga

下面是Show sga的執行結果:

SQL> show sga

Total System Global Area  448790528 bytes

Fixed Size                  1249488 bytes

Variable Size              79695664 bytes

Database Buffers          360710144 bytes

Redo Buffers                7135232 bytes

     此命令顯示了SGA各部分的大小。這其中Fixed size是固定區域,這塊區域用於存貯一些管理他記憶體結構的管理性資訊。DBA是不需要調節這塊記憶體的。Database buffers是Buffer cache的大小。Redo buffers是重做快取的大小。Variable Size是可變區域,共享池佔了它約百分之八、九十的大小,它其中還包括Java池、大池等SGA除固定區、Buffer cache和重做快取之外的所有其他池。另外,也有一些管理性資訊在此可變區域中。比如我們經常使用的V$系統動態效能檢視,就源自此可變區域中的管理性資訊(V$的資訊來自於X$,而X$中的資料來自於可變區域中的一些結構)。因為共享池佔了可變區域的大部分,因此我們一般可以透過它來大概念的瞭解共享的大小。

     除Show Sga外,我們還可以用V$sgastat檢視顯示SGA各記憶體結構的大小,在此檢視中,我們可以精確的看到共享池的大小,下面是這個檢視的顯示資訊的樣式:

SQL> select * from v$sgastat where rownum<=10;

POOL         NAME                            BYTES

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

             fixed_sga                     1249488

             buffer_cache                360710144

             log_buffer                    7135232

shared pool  dpslut_kfdsg                      256

shared pool  hot latch diagnostics              80

shared pool  ENQUEUE STATS                    8360

shared pool  transaction                    264528

shared pool  KCB buffer wait statistic        3352

shared pool  invalid low rba queue             320

shared pool  KQF optimizer stats table        2396

…………………………………………………………………………………………………………………………………………


     在10G中,這個檢視顯示600多行,所有POOL列不為空的行,就是可變區域的各個部分。POOL為空的行,從NAME列可以看到,分別是固定區域、Buffer cache和重做快取。這三行的大小和Show sga中顯示的大小是一樣的。下面我們按POOL分組,看看可變區域中各記憶體池的大小:

SQL> select pool,sum(bytes)/1024/1024||' MB' from v$sgastat where pool is not null group by pool;

POOL         SUM(BYTES)/1024/1024||'MB'

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

java pool    4 MB

shared pool  64.00447845458984375 MB

large pool   4 MB

     可以看到可變區域中,有Java pool和Large pool,大小都是4MB,還有共享池大小為64MB多一點。將這三個池加起來,仍不到Show sga中顯示的可變區域大小。那是因為除這三個池外,可變區域還有著如X$結構這樣的管理性資訊。

     這個檢視可以用在9i和10g中,不過在10g中另有一個檢視可以詳細更準確的共享池大小方面的資訊。下面我們來了解一下在10g中,對記憶體管理做了什麼改進。

三、10g中設定共享池的大小:

     在10g中,共享池的簡單設定更加方便,我們只需要定義SGA_TARGET引數的值,也就是目標SGA大小,Oracle就會根據此目標值自動設定共享池的大小。而且,如果發現共享池記憶體不夠了,如果系統還有空閒的記憶體,Oracle將可以自動擴充套件共享池的大小。注意,我們剛才說了,這是共享池的簡單設定,這種簡單設定其實是根本不用設定。你只要告訴它SGA有多大,它可以自動設定SGA中的所有記憶體元件。這是10g相比9i的一大新特色,它使DBA的工作更加簡單化了。Oracle本身越來越智慧,再往下發展下去,很多人擔心DBA會不會失業。因為軟體越來越智慧、越來越簡單,總有一天將會淘汰掉DBA。持這種觀點的人,大多數是對計算機瞭解的不夠深入,當深入的學習下去之後,就會發現我們現在的人工智慧水平是多麼的幼稚可笑,這個話題我們就不在這裡討論了。有興趣的同學可以去看看各種人工智慧演算法方面的書,如神經網路、遺傳演算法等等,自然就會明白我們當前的人工智慧發展水平。回到我們本身的話題,不可否認,軟體是向著智慧化、自動化的方面發展,但是智慧化程度越高,其本身也越複雜。就像人腦,複雜的多少科學家多少代的努力都無法完全瞭解其運作原理。這麼複雜的系統一旦出現問題,需要程度更高的人,才可解決。比如汽車,由你自己駕駛,汽車出了毛病,很多地方都可以修。而我們的神舟火箭呢,它的執行軌道早就設定好的,它不需要飛行員親自駕駛,自動化程度比汽車高了一大截。但是,神舟火箭要是出了問題呢,誰能修?我們資料庫將來也是這樣發展,隨著智慧化程度的提高,必將淘汰掉大批的初級DBA,但對高階DBA的需求,只會比以前更大。而且高階DBA的薪資水平,也會比以前更高。因為剛才我們已經說了,智慧化水平越高,軟體本身越複雜。越來越複雜的軟體,對DBA的要求也一定會越來越高。就像我們正要講的共享池,它的簡單設定簡單到不必再設定。但是,在確定了SGA_TARGET大小後,如果Oracle自動定義的共享池大小不合適怎麼辦,有很多時候我們不能完全依賴軟體的智慧,顯然Oracle公司也清楚的明白這一點,因此,它還是保留了一些讓DBA手動調整共享池等SGA記憶體元件的權利,10G下的調整比9i理解起來稍微複雜一點,下面我們說一下10g下共享池的調整注意事項。

在10g中還是要用Shared_pool_size引數調整共享池,但它已經不再是共享池大小的決定因素。在10g中它只決定了共享池最小有多大,也就是它是共享大小的下限。如果你將它設定為1G,那麼Oracle絕不會分配低於1G記憶體的共享池。它可能正好按你的要求分配1G,也可能分配多於1G記憶體的共享池。通常,如果你使用此引數將共享池設定的比以前更大,那麼這個設定將會馬上生效。而如果你發現共享池有些大了,應該設定的更小些才合適,你用此引數將共享池設定的小了一些,那麼這個設定將不會馬上生效。為什麼呢?因為此引數只是共享池大小的下限。你的共享池本來有1.5G,你將此引數設為了1G,Oracle會認為你只是想讓共享池最小不要低於1G,那麼當前共享池的大小1.5G滿足你的要求,因此,Oracle不會調低共享池大小。什時候它自己也認為1.5G太大了,應該小一些,這時它才會將共享池調小。也就是說在10G中,Oracle加強了自身對共享池的掌控權,只保留給DBA設定下限的權力。

我們可以透過一個檢視V$SGA_DYNAMIC_COMPONENTS來了解SGA中各記憶體元件的大小:

     步驟1:我先手動將shared_pool_size引數值設為50M:

SQL> alter system set shared_pool_size=50m;

系統已更改。

     步驟2:顯示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                        92274688   92274688            54525952

large pool                          8388608    8388608             8388608

java pool                           4194304    4194304                   0

streams pool                              0          0                   0

DEFAULT buffer cache              247463936  243269632           209715200

KEEP buffer cache                         0          0                   0

RECYCLE buffer cache                      0          0                   0

DEFAULT 2K buffer cache                   0          0                   0

DEFAULT 4K buffer cache             8388608    8388608             8388608

DEFAULT 8K buffer cache                   0          0                   0

DEFAULT 16K buffer cache                  0          0                   0

COMPONENT                      CURRENT_SIZE   MIN_SIZE USER_SPECIFIED_SIZE

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

DEFAULT 32K buffer cache                  0          0                   0

ASM Buffer Cache                          0          0           209715200

已選擇13行。

這些列的意義我們簡單介紹如下:

COMPONENT:SGA中記憶體元件的名稱

CURRENT_SIZE:當前所佔用記憶體大小

MIN_SIZE:透過分析資料,Oracle認為的該記憶體元件的最小大小

USER_SPECIFIED_SIZE:使用者指定的大小。也就是DBA透過設定Shared_pool_size這些引數設定的大小。

上面是我在將shared_pool_size定為50M後的顯示結果,從上面的結果可以看出來,USER_SPECIFIED_SIZE為52MB,因為記憶體是按塊分配的,在10g中是4MB一個塊,52M正好是13個記憶體塊,Oracle沒辦法分配50M,因為50不能被4整除。從MIN_SIZE列可以看出,Oracle認為88M的共享池應該最小的共享池大小,因此CURRENT_SIZE列中記錄的當前大小就是88MB。

     步驟3:繼續實驗,如果我調高共享池記憶體會怎樣呢:

SQL> alter system set shared_pool_size=100m;

系統已更改。

將共享池記憶體設為100MB

     步驟4:顯示結果

SQL> SELECT COMPONENT,CURRENT_SIZE,MIN_SIZE,USER_SPECIFIED_SIZE from V$SGA_DYNAMIC_COMPONENTS where COMPONENT='shared pool';

COMPONENT                      CURRENT_SIZE   MIN_SIZE USER_SPECIFIED_SIZE

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

shared pool                       104857600   92274688           104857600

     這一次我只顯示共享池,可以看到使用者指定大小(USER_SPECIFIED_SIZE)已經是100MB了,當前大小也是100MB。Oracle認為的最小大小MIN_SIZE並沒有變,還是88M,這是因為我們並沒有進行太多的操作,Oracle認為資料庫的負載並不重,最小大小因此沒有增加。

     現在的共享池大小是100M,如果你將共享池大設定為88M,當前大小也不會馬上變為88MB。因為shared_pool_size只是用來告訴Oracle使用者希望共享池的最小大小是多少,但Oracle不會立即減小共享池。Oracle會在它認為合適的時候,減少共享池的大小。

四、共享池的調優:

共享池Miss比其他池大,應該調優庫快取

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

相關文章