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環境中,一個排程器服務多個連線的請求,並將請求放到請求佇列(request queue)
中,所有排程器共用一個請求佇列,接著由共享服務程序(Shared Server processes)來處理這些請
求,並將處理後的結果返回到響應佇列(response queue),與請求佇列不同,每個排程器都有自己
的一個響應佇列,然後由排程器把響應佇列中的結果返回給客戶端。其中請求佇列和響應佇列都是SGA中的一部分。
在一個共享服務環境中,一個客戶端請求的步驟是這樣的:
1、 客戶端傳送一個請求到排程器
2、 排程器將請求放入到請求佇列中
3、 共享服務程序從請求佇列中取出請求進行處理
4、 共享服務程序將處理後的結果放到排程器的響應佇列中
5、 排程器從響應佇列中取出結果返回給客戶端
同時,在Shared server環境中,也可以使用連線池的方法來存放多個連線請求,資料庫定
時斷開空閒的連線來服務其它新的連線請求。
在Shared server環境中也存在不足,當某一個請求需要處理並返回大量資料的時候,將會
導致其它新的請求得不到及時的響應。所以對於這樣的請求,最好使用專用服務程序。同時
,部分資料庫管理操作需要使用專用服務程序,比如資料庫啟動關閉,資料庫備份恢復等等,
對於表分析、大量資料載入、索引重建等操作也建議使用專用服務程序。
監聽器在Shared server環境中也扮演著重要的角色。PMON程序定期檢測排程器的負載情況,
並將這些資訊反饋給監聽器。監聽器記錄著每個排程器的地址資訊及負載情況(當前服務多
少個連線等等),當有新的連線請求的時候,監聽器將負載較低的排程器地址資訊返回給客
戶端,客戶端根據地址資訊連線到相應的排程器。
如果使用者程序不能夠連線到排程程序,或者使用者請求的是一個專有伺服器連線,則監聽器將
建立一個專有伺服器程序(dedicated server process),並把這個使用者程序連線到這個服務
器程序
下面談談如何配置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
-----續-----