天天看點

一則資料庫無法重新開機的案例分析

  今天一個開發的同僚找到我,說有個問題想咨詢一下我,突然想起他昨天讓我幫他處理一個工單,他這麼一問我才想起來還沒做,結果他說是另外一件事,說有個開發測試的環境,資料庫報04031的錯誤,想讓我幫忙看看是怎麼回事,這種問題剛好就找對了。首先開發測試環境,通路量不高,業務量不大,環境也要簡單很多,出現這個問題,讓我能夠唯一覺得可能的原因就是sga設定太小了。當然帶着這個想法也讓另外一個同僚去現場看看問題,如果問題确實要複雜一些,那我們再采取其它的措施,當然解決不了問題也沒關系,權當是給新同僚的一次曆練吧。

   然後很快從同僚那裡得到了回報,說調整了sga為200M之後資料庫貌似起不來了。如果是這樣的情況,也是意料之中,報錯資訊是:

ORA-27102:

out of memory

Linux-x86_64 Error: 12: Cannot allocate memory

對于ORA-27102的錯誤,其實也是一個經典的錯誤了。這個報錯主要和核心參數的設定相關,shmall和shmmax,可以參考ID

301830.1

其實27102的錯誤如果系統級的報錯是

ORA-27102: out of memory

Linux-x86_64 Error: 28: No space left on

device

那麼和核心參數shmall和shmmax關聯要大一些,而目前的是 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,啟動就沒有任何問題了,不過确實能夠明顯感受到啟動的時候還是很遲緩的。這兩個參數在有些優化場景中還是有一席之地,但是相對來說使用範圍還是有限。