Oracle 解决4031错误
生活随笔
收集整理的這篇文章主要介紹了
Oracle 解决4031错误
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這篇文章是參考甲骨論老相老師的教學視頻:
http://v.youku.com/v_show/id_XMzkyMTkzNjg4.html
所做的學習筆記.
什么是4031錯誤和4031錯誤產生的原因:
詳細請看這里:
http://v.youku.com/v_show/id_XMzkyMTkzNjg4.html
簡單一個句話概括:
???? 由于服務器一直在執行大量的硬解析,導致Oracle 的shared pool Free空間碎片過多,大的chunk不足, 當又一條復雜的sql語句要硬解析時, 缺少1個足夠大的Free chunk, 通常就會報4031錯誤.
解決方法:
方法1.清空Shared pool緩存.
執行Alter system flush shared_pool;
這樣的話釋放出大量的free 空間, 不過由于緩存都沒了,接下來肯定會發生大量的硬解析,這是1個指標不治本的方法..
方法2.共享SQL
詳細請看這里:
http://nvd11.blog.163.com/blog/static/200018312201301945631729/
方法3. 將復雜sql語句及執行計劃強制保留在緩存? dbms.shared_pool.keep('object_name')
?????? 此話怎么理解?? 其實導致4031錯誤的原因是shared_pool空間沒有足夠大的chunk提供給新的復雜sql語句進行硬解析, 其實也不是單純地因為free 空間碎片太多,? 其實當free空空間沒有足夠大的chunk時, oracle 會釋放 Library cache中長時間不使用的chunk.
??????? 舉個例子, 1個數據庫實例中, free空間中chunk數量很少了,而且沒有足夠大的chunk, 這時有1個中等規模的sql要硬解析,就會從library cache中找那些不長用的chunk釋放出來,? 如果釋放里面若干個小規模的chunk, 是無問題的.
???????? 但是如果其中library cache 有個很大的chunk存放著1個很復雜的sql語句, 但是長時間沒有被使用了, 有可能這個chunk被釋放出來被使用, 而且被拆解了...? 其中一部分別使用, 另1部分被放入free空間中.
??????? 而之后偏偏那個很復雜的sql語句又執行了,需要硬解析, 而那個足夠大的chunk已被分解.. 則有可能報4031錯誤.
?????? 所以方法3就是指定一些sql語句的緩存長期保留, 不讓他們被釋放, 避免這種情況的發生.
????? 步驟1
????? 首先是找出Library cache中那些占用大的對象啦.
????? 語法如下:
????? select name from v$db_object_cache where sharable_mem > 10000
????????????????? and type in ('PACKAGE','PACKAGE BODY','FUNCTION','PROCEDURE')
????????????????? and kept = 'NO';
????? 注意紅色數字單位是kb, 生產中要根據實際情況修改..
???? 如圖:
??
?
我找到1個包 PAK_EMP, 占用超過10k以上的(其實10k是很小的值了).
接下來就執行 dbms.shared_pool.keep了?
但是實際上dbms.shared_pool這個默認不會安裝在數據庫的如下圖:
不過提供了安裝腳本:
路徑是
$ORACLE_HOME/rdbms/admin/dbmspool.sql
所以在sqlplus執行:
@?/rdbms/admin/dbmspool.sql?? 就可以安裝這個系統包了, 如圖:
?
接下來就可以執行
exec dbms_shared_pool.keep('SCOTT.PAK_EMP')??
如上圖, 這個對象一直會保留在shared_pool緩存了. 注意對象名字要帶模式名啦.
這時在查看對象緩存:
?
見到kept 字段變成yes了!
如果想撤銷點算: 執行
exec dbms_shared_pool.unkeep('SCOTT.PAK_EMP')??
就得了
?方法4 增加shared pool空間.
一般當服務器增加內存的時候,? 就可以給shared pool增加空間:
一般來講Oracle 10g以后 SGA里面各大池空間都是動態分配的, 一般增加SGA大小即可.
alter system set sga_target = 2000M;????????????????? --注意不能超過sga_max_size
alter system set sga_max_size = 2000M;????????????? --該這個必須重啟數據庫, 目的
??????????????????????????????????????????????????????????????????????????? 是限制sga_target, 以免sga_target
??????????????????????????????????????????????????????????????????????????? 不小心設置過大,倒置服務器內存耗盡掛掉
也可以單獨設置shared pool的大小:??????????????
alter system set shared_pool_size? = 200M;????????
???????? 注意默認情況下 用show parameter 來查查看 sga_target 和 shared_pool的話, value 都是0的, 并不是說它們的當前值就真的是0了,只是0是代表交由Oracle自己管理的意思.
可以用這個語句可以查看當前的各大池占用大小:
select component, current_size from v$sga_dynamic_components;
?
可以看出其實當前shared pool大小接近250m了
我們現在做個實驗,? 我們手動將shared pool設置為60m 看看神馬情況
再查看一次大小:
?
居然沒有任何變化,
?????? 實際情況是這樣的:? 當dba 設置了1個sga_target后, sga就根據sga_target的設置大小自動為shared pool設置1個最小的值, 假如這個值是150m, 而當我將shared pool手動設置為60m時, 小于這個值, oracle就會無視這個命令的..
方法5: 保留區
oracle 為了避免4031錯誤,? 其實還可以在shared pool劃出1個保留的free 空間, 平時不會使用, 專門應對突然出現的復雜sql語句硬解析,相當與應急用的空間啦. 這個方法相當有效, 可以避免大部分的4031錯誤, 不過缺點就是平時減少了shared pool的可用空間, 減低了數據庫緩存性能啦~
我們可以用下面這條語句來查看 在保留區請求失敗的次數:
select request_misses from v$shared_pool_reserved;
?
注意這個次數一旦 大于1, 就證明發生過4031錯誤! 因為既然去保留區申請空間了, 證明是1個復雜的sql語句, 還申請失敗的話,就會報4031錯誤啦~ 所以這個次數最好就是0啦.
可以用下面語句去查看當前 shared pool保留區的大小
?
可以看到保留去有10m多啦~
還見到 shared_pool_size 只有60m, 頭先設置的啦,無視他吧~ 將其設置會0就會自動由 oracle 管理了.
設置保留區大小都一樣啦:
alter system set shared_pool_reserved_size = 100m;
注意不要設置過大啦, 你懂的.
?
總結
以上是生活随笔為你收集整理的Oracle 解决4031错误的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 查看library cac
- 下一篇: 转:让 ThinkPad 的中键加小红帽