一則資料庫無法重啟的案例分析

dbhelper發表於2016-05-26
  今天一個開發的同事找到我,說有個問題想諮詢一下我,突然想起他昨天讓我幫他處理一個工單,他這麼一問我才想起來還沒做,結果他說是另外一件事,說有個開發測試的環境,資料庫報04031的錯誤,想讓我幫忙看看是怎麼回事,這種問題剛好就找對了。首先開發測試環境,訪問量不高,業務量不大,環境也要簡單很多,出現這個問題,讓我能夠唯一覺得可能的原因就是sga設定太小了。當然帶著這個想法也讓另外一個同事去現場看看問題,如果問題確實要複雜一些,那我們再採取其它的措施,當然解決不了問題也沒關係,權當是給新同事的一次歷練吧。
   然後很快從同事那裡得到了反饋,說調整了sga為200M之後資料庫貌似起不來了。如果是這樣的情況,也是意料之中,報錯資訊是:

ORA-27102: out of memory
Linux-x86_64 Error: 12: Cannot allocate memory

對於ORA-27102的錯誤,其實也是一個經典的錯誤了。這個報錯主要和核心引數的設定相關,shmallshmmax,可以參考ID 301830.1
其實27102的錯誤如果系統級的報錯是

ORA-27102: out of memory

Linux-x86_64 Error: 28: No space left on device

那麼和核心引數shmallshmmax關聯要大一些,而目前的是 Linux-x86_64 Error: 12: Cannot allocate memory其實另有原因,但是當時也沒有多想。
就讓同事繼續提供free -m的結果
[oracle@dev_mobileBI dbs]$ free -m
             total used free shared buffers cached
Mem: 5709 4762 946 0 39 3365

核心引數的值如下:
kernel.shmmax = 2147483648
kernel.shmall = 536870912
其實這個時候看,剩餘記憶體還多,shmmax儘管有些小,但是完全是可以支援200M的SGA的。
所以這個核心引數的修改也是一種方式,但不是解決這個問題的根本。
我們就回到了引數檔案上,這個時候和同事重新審視這個檔案,把SGA改為原值,仍然啟動失敗,報27012的錯誤。
這個時候感覺問題就比較蹊蹺,資料庫停了之後重啟竟然就報錯,其它引數的設定都恢復了原來的值還是啟動報錯。
這個時候感覺是引數檔案哪裡出現了問題,所幸這個環境的定製引數也不多,我們可以理一理建立資料庫的一個環節,手工建庫,其實在10g中只要保留4個引數就可以了,11g3個,即db_name,control_files,sga_target(或者其他的記憶體元件引數),所以就把引數檔案改為最簡單的方式,啟動到nomount,就可以了。
從這個情況可以推理出來應該是在當前的引數檔案中存在著一些引數的限制導致啟動失敗。
引數檔案的設定大體是下面的樣子:
mbidev.__oracle_base='/home/U01/app/oracle'#ORACLE_BASE set from environment
*.audit_file_dest='/home/U01/app/oracle/admin/mbidev/adump'
*.audit_trail='db'
*.compatible='11.2.0.0.0'
*.control_files='/home/U01/app/oracle/oradata/mbidev/control01.ctl',/oradata/mbidev/control03.ctl'
*.db_block_size=8192
*.db_domain=''
*.db_name='mbidev'
*.db_recovery_file_dest='/home/U01/app/oracle/fast_recovery_area'
*.db_recovery_file_dest_size=10737418240
*.diagnostic_dest='/home/U01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=mbidevXDB)'
*.lock_sga=TRUE
*.open_cursors=300
*.pre_page_sga=TRUE
*.processes=300
*.remote_login_passwordfile='EXCLUSIVE'
*.undo_tablespace='UNDOTBS1'
所以檢查了一圈,印象中也沒有很特別的引數,所以就採用了排除法,先從自己熟悉的引數開始縮減,排除了domain,remote_login_password,compatible,audit的引數
那麼接下來就是不大熟悉的引數了,有兩個pre_page_sga和lock_sga,經過排除,發現最後的癥結在於引數lock_sga
如果去掉這個引數設定,資料庫就能夠正常啟動,經過驗證,發現預設值為false
這個時候,我們不能太偏離問題的方向,我們需要調整SGA,這個時候問題已經解決了,我們先處理SGA的部分,至於lock_sga的部分可以暫時放一放回頭再來深究為什麼有這種情況。
所以調整SGA之後,發現核心引數shmmax,shmall還是有一些問題,經過調整,就達到了開發同學的預期目標。
我們再來看一下lock_sga的奇怪問題,這個引數預設值為false,如果設定為true,可以保證整個sga被鎖定在實體記憶體中,可以防止sga被換出到swap中,還有輔助的引數pre_page_sga來保證在資料庫初始化的時候把sga都放入記憶體中。
而為什麼這個引數設定為true,會有27102的錯誤呢,其實和系統的資源配置有關。可以透過ulimit -a檢視相關的資訊
預設locked memory為32KB,肯定無法滿足,所以我們需要設定memlock
$ ulimit -a|grep lock
max locked memory       (kbytes, -l) unlimited
file locks                      (-x) unlimited
比如對oracle使用者設定較高的資源使用許可權。
oracle           soft    memlock         unlimited
oracle           hard    memlock         unlimited
這個時候設定lock_sga和pre_page_sga為true,啟動就沒有任何問題了,不過確實能夠明顯感受到啟動的時候還是很遲緩的。這兩個引數在有些最佳化場景中還是有一席之地,但是相對來說使用範圍還是有限。

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

相關文章