1. 程式人生 > >ORA-04031 無法分配 12519000 位元組的共享記憶體 large pool , unknown obje

ORA-04031 無法分配 12519000 位元組的共享記憶體 large pool , unknown obje

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

author:skate
time: 2009/04/14



ORA-04031: 無法分配 12519000 位元組的共享記憶體 ("large pool","unknown object","hash-join subh","kllcqc:kllcqslt")

 

解決方法:

SQL> show parameter dispa

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
dispatchers                          string      (PROTOCOL=TCP)
max_dispatchers                      integer     5
mts_dispatchers                      string      (PROTOCOL=TCP)
mts_max_dispatchers                  integer     5

sql> alter system set dispatchers='(PROTOCOL=TCP)(SERVICE=orclXDB)';


SQL> show parameter dispa

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
dispatchers                          string      (PROTOCOL=TCP)(SERVICE=orclXDB
                                                 )
max_dispatchers                      integer     5
mts_dispatchers                      string      (PROTOCOL=TCP)(SERVICE=orclXDB
                                                 )
mts_max_dispatchers                  integer     5

 

問題解決,再用select × from v$session 檢視 ,都是dedicated連線了

 

後者指定了服務名,而前者沒有。沒有指定伺服器,大概就造成了oracle例項向listener註冊時,
以任何服務名來建立的連線都是使用shared server方式。這是個人理解。

 

參考文件:http://blog.chinaunix.net/u/25477/showart_251764.html

 

相關知識總結:

 

Oracle Shared Server比較適合一些小而快的事務連線,這些事務的特點就是事務比較短,
操作和返回的資料量比較少。而對於一些資料倉庫而言,顯然是不適合建成 Shared Server
模式。下面說一下Shared Server和Dedicated Server的一些區別:

 

在Dedicated Server環境中,每一個連線都將啟動一個專用服務程序,這個專用服務程序始終
服務於這個連線直到連線斷開。每一個專用服務程序都有一個屬於自己的記憶體區域,叫做
PGA(Program GlobalArea),裡面存放了會話的資訊,包括繫結變數、遊標、排序等等。

而在Shared Server環境中,這些資訊被存放到SGA中的UGA(User Global Area)區域中,
這個區域一般都位於大型池中(Large pool)

 

 shared_server structure


在Shared Server環境中,一個排程器服務多個連線的請求,並將請求放到請求佇列(request queue)
中,所有排程器共用一個請求佇列,接著由共享服務程序(Shared Server processes)來處理這些請
求,並將處理後的結果返回到響應佇列(response queue),與請求佇列不同,每個排程器都有自己
的一個響應佇列,然後由排程器把響應佇列中的結果返回給客戶端。其中請求佇列和響應佇列都是SGA中的一部分。
在一個共享服務環境中,一個客戶端請求的步驟是這樣的:

1、 客戶端傳送一個請求到排程器
2、 排程器將請求放入到請求佇列中
3、 共享服務程序從請求佇列中取出請求進行處理
4、 共享服務程序將處理後的結果放到排程器的響應佇列中
5、 排程器從響應佇列中取出結果返回給客戶端

 

同時,在Shared server環境中,也可以使用連線池的方法來存放多個連線請求,資料庫定
時斷開空閒的連線來服務其它新的連線請求。

在Shared server環境中也存在不足,當某一個請求需要處理並返回大量資料的時候,將會
導致其它新的請求得不到及時的響應。所以對於這樣的請求,最好使用專用服務程序。同時
,部分資料庫管理操作需要使用專用服務程序,比如資料庫啟動關閉,資料庫備份恢復等等,
對於表分析、大量資料載入、索引重建等操作也建議使用專用服務程序。

監聽器在Shared server環境中也扮演著重要的角色。PMON程序定期檢測排程器的負載情況,
並將這些資訊反饋給監聽器。監聽器記錄著每個排程器的地址資訊及負載情況(當前服務多
少個連線等等),當有新的連線請求的時候,監聽器將負載較低的排程器地址資訊返回給客
戶端,客戶端根據地址資訊連線到相應的排程器。

 

如果使用者程序不能夠連線到排程程序,或者使用者請求的是一個專有伺服器連線,則監聽器將
建立一個專有伺服器程序(dedicated server process),並把這個使用者程序連線到這個服務
器程序

 

shared_server structure


下面談談如何配置Oracle shared server環境。

可以通過多種方法來配置shared server,包括建立資料庫的時候指定引數、EM、修改初始化
引數檔案,還有可以通過Alter system進行修改,因為這些引數都是動態引數。


設定連線池:
dispatchers="(protocol=tcp)(serv=orcl)(list=orcl)(pool=on)(TICK=1)(disp=5)(con=33)(sess=224)

上面表示啟動連線池,一個排程器的連線數最大為33個,sessions數目最大為224個,並10分鐘後自動斷開未活動的連線。(TICK=1表示10分鐘)


shared_servers:指定oracle啟動時,啟動的共享伺服器程序的最小數量,對於很繁忙的系統,這個值設定的大一些
               對於很空閒的系統,這個值設定的小一些,對於一般的系統這個值設定是連線數的十分之一,
        預設值庫1。設定為0表示不使用SHARED_SERVER。

dispatchers 用於設定排程程序,其中,protocol用於設定排程程序支援的協議,poo用於設定是否啟用共享程序;poo=on
表示啟用共享程序,disp用於設定排程程序的數量;con使用者設定每個排程程序3的最大網路連線數量;sess使用者設定每個排程
程序的最大會話數(session)。排程器數量 = 資料庫最大session數 /每個排程器服務的session數;

 

dispatchers還有如下屬性:

 

service:dispatcher註冊的net service name,沒有給出採用services_name中的;
listener:監聽動態註冊,非預設埠1521或沒有在local_listener中給出時需使用;
sessions:每個dispacther的會話數
connections:每個dispacther連線數

MAX_DISPATCHERS:設定最大的排程器數,可以動態調整,如:ALTER SYSTEM SET MAX_DISPATCHERS=10;


SHARED_SERVER_SESSIONS:設定ORACLE SHARED SERVER的最大session數。
當連線到SHARED SERVER的session數超過此值的話,將報錯:
ERROR:
ORA-00018 maximum number of sessions exceeded

不過當資料庫session超過此值的時候,仍然可以通過專用伺服器連線進行連線。

 
MAX_SHARED_SERVERS:設定最大的SHARED_SERVER數。如果未給此引數附值,那麼SHARED_SERVER數庫無限制。

 

原來oracle服務在註冊到監聽器是預設到1521埠的,如果沒有註冊上則監聽的狀態始終會為unknow狀態,
不過客戶端通過tns的配置專用服務請求還是能找到相應的資料服務的,但是共享服務就沒有辦法了,因為
埠不是預設的1521,因此共享伺服器的排程器dispatcher找不到監聽所在的埠41521,因此找不到排程
服務,至使與監聽不能互相通訊。

 

上面連線就講了如何讓oracle服務註冊到特殊的監聽埠。
其實很簡單:
在oracle資料庫伺服器上配置上本地的oracle的tnsname連線。
sdb =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = sdb)(PORT =41521))
)
(CONNECT_DATA =
(SID = sdb)
(SERVER = DEDICATED)
)
)


然後修改引數:
alter system set local_listener = "sdb";
alter system register;
之前local_listener是為空的,此時本地oracle服務就知道可以通過sdb這個tnsname到本地的監聽伺服器進行
註冊,狀態變成了ready,這時排程器也一併被進行了註冊。

參考文件:http://rainbowbridg.itpub.net/post/23663/262006


資料庫的session數可以通過下面的檢視獲得:
1、 v$session:獲得當前資料庫的session數
SQL> select count(*) from v$session where username is not null;
2、 V$LICENSE:獲得當前資料庫的session數及資料庫啟動以來最大的session數
SQL> select sum(sessions_current) cur_sessions,sum(sessions_highwater) high_sessions from V$LICENSE;
比如資料庫當前有500個TCP/IP session,每個排程器管理50個session,那麼就需要10(500/50)個排程器。引數設定如下:
DISPATCHERS=”(PRO=TCP)(DIS=10)”
當然也可以根據資料庫當前的負載,使用ALTER SYSTEM命令動態的增加或減少排程器的資料,如下:
ALTER SYSTEM SET DISPATCHERS=”(PRO=TCP)(DIS=5)”;


2)從動態效能圖獲得資訊:
V$CIRCUIT  :select * from v$circuit;
V$QUEUE
V$SESSION
V$DISPATCHER:顯示當前排程器的一些資訊,包括排程器的狀態(等待還是繁忙)、當前的連線數、歷史的連線數等等。
V$DISPATCHER_CONFIG:顯示排程器的一些配置引數。
V$SHARED_SERVER:顯示當前資料庫SHARED SERVER的一些狀態資訊
V$SHARED_SERVER_MONITOR:顯示當前資料庫SHARED SERVER的一些統計資訊,包括SHARED SERVER的最大連線數,會話數及啟動的SHARED SERVER數等等。
同時,在ORACLE SHARED SERVER環境中,也可以配置專用伺服器連線,但只有當你是使用Localnaming方法的時候才可以,如果你是使用Hostnaming方法的話則不可以。有幾個方法進行配置,如下:
1、 手工修改Tnsname檔案
ora10g =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.172)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ora10g)
)
)
2、通過Oracle net manager進行配置


3)對於配置了ORACLE SHARED SERVER的資料庫,有一些引數需要值得我們的關注:
1、LARGE POOL SIZE
在ORACLE SHARED SERVER環境中,ORACLE 將UGA存放在LARGE POOL中,而在沒有LARGE POOL或者LARGE POOL太小的資料庫中,
UGA將存放於SHARED POOL中,這樣將影響到資料庫其它的效能。所以LARGE POOL的大小也值得我們考究。LARGE POOL最小為300K,
最大為2G(不同作業系統可能有所不同)。一般來講,在ORACLE SHARED SERVER環境中,一個連線將佔用1-3M的記憶體,不過要看
會話做了哪些操作。我們可以通過下面的語句獲得資料庫啟動以來,最大的UGA值:

select sum(value) "Max MTS Memory Allocated"from v$sesstat ss, v$statname st
where name = 'session uga memory max'and ss.statistic# =st.statistic#;
Max MTS Memory Allocated
------------------------------------
244416

可以看到,ORACLE分配的最大UGA庫240K,如果資料庫同時支援100個併發連線,那麼可以將LARGE POOL設定庫23M(240K*100)。如果LARGE POOL設定過小,可能遇到下面的錯誤:
ORA-04031: unable to allocate 490 bytes of shared memory
("large pool","MWEIS","session heap","define var info")
可以通過ALTER SYSTEM命令進行動態修改。
ALTER SYSTEM SET LARGE_POOL_SIZE = 51200000 SCOPE=SPFILE;
2、 排程器數目
可以通過查詢V$DISPATCHER檢視來檢視排程器的狀態:
SQL> desc v$dispatcher;
Name Type Nullable Default Comments
--------- ------------- -------- ------- --------
NAME VARCHAR2(4) Y
NETWORK VARCHAR2(128) Y
PADDR RAW(4) Y
STATUS VARCHAR2(16) Y
ACCEPT VARCHAR2(3) Y
MESSAGES NUMBER Y
BYTES NUMBER Y
BREAKS NUMBER Y
OWNED NUMBER Y
CREATED NUMBER Y
IDLE NUMBER Y
BUSY NUMBER Y
LISTENER NUMBER Y
CONF_INDX NUMBER Y
SQL> Select name, (busy / (busy + idle))*100
2 "Dispatcher % busy Rate"
3 From V$DISPATCHER
4 /
NAME Dispatcher % busy Rate
---- ----------------------
D000 0.0052861386871346
如果繁忙的百分比超過50%,那麼可以考慮增加排程器,可以使用下面的語句動態修改:
ALTER SYSTEM SET DISPATCHERS=“(PRO=TCP)(DIS=2)”;
3、 排程器響應時間
可以通過檢視V$QUEUE 和 V$DISPATCHER來獲得連線等待排程器響應的時間:
SELECT decode(sum(totalq),0,’No Responses’,
Sum(wait)/sum(totalq)) “Average Wait time”
FROM V$QUEUE q, V$DISPATCHER d
WHERE q.type = ‘DISPATCHER’
AND q.paddr = d.paddr;
Average Wait Time
------------------
.0413
4、 連線等待shared server處理請求的時間
Select decode(totalq,0,’No Requests’) “Wait Time”,
Wait/totalq || ‘ hundredths of seconds’
“Average Wait time per request”
from V$QUEUE
where type = ‘COMMON’
Wait Time Average Wait time per request
-------- -----------------------------------
.023132 hundredths of a second
 


1。是否為配置為共享伺服器,最主要的引數是

8i mts_servers

9i shared_server

show parameter shared_server mts_servers

如果數值 > 0 ,就是enable了共享伺服器.

 

2。在配置為共享伺服器的情況,Client可以選擇用共享伺服器或者專用伺服器來連線到資料庫,這個引數的控制是在tnsnames.ora裡設定的

aaaa=

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = aaaa)(PORT = 1521))

)

(CONNECT_DATA =

(SID = aa)

(SERVER = DEDICATED)

)

)

紅色部分指定了用DEDICATED方式連線DB.

另外,Background process ,以及通過本地連線進來的,只能是DEDICATED

比如說sqlplus user/pass 形式

如果DB沒有配置共享伺服器,那麼Client只能以DEDICATED方式連線DB.
(
1. 如果是dedicated server,則客戶端只能建立dedicated server connection
2. 如果是shared server,則客戶端能建立dedicated server connection和shared server connection,
只要在service name中指定server=dedicated or server=shared.
)

 

3.判斷一個已經連線的session的連線方式有兩種方法

A

select username,server from v$session;

如果server = 'DEDICATED'則是DEDICATED方式

server='SHARED'則是shared方式,並且正有shared_server_process為其服務

server='NONE'的話,則是shared方式,並且當前沒有shared_server_process為其服務。


B. 僅用於Unix 底下,似乎windown不行

連線v$session, v$process 看process中的program

1 select p.program,s.server from v$session s , v$process p

2* where s.paddr = p.addr

如果 program 為 。。(S0NN) 的,則是shared方式,並且正有shared_server_process為其服務

如果 program 為 。。(D0NN) 的,則是shared方式,並且當前沒有shared_server_process為其服務

如果 program 為 其它的,則是'DEDICATED'方式

 

參考文件:

http://www.blogjava.net/lucky/archive/2009/03/20/261124.html

http://rainbowbridg.itpub.net/post/23663/262006

http://www.linuxidc.com/Linux/2008-10/17007.htm

http://fusnow.itpub.net/post/681/214188

http://www.itus.cn/database/1/Oracle-6959.shtml

 

-----續-----

 

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述