您好,登錄后才能下訂單哦!
在部署應用的時候,有時候應用可以直接啟動,但偶爾應用卻無法啟動,報錯信息是:
java.sql.SQLRecoverableException: IO Error: Got minus one from a read call 如圖:
原因及解決方法
我有好幾個應用系統需要連接數據庫,測試發現如果這個應用在最開始啟動就不會報錯,如果是啟動了好幾個應用之后再啟動的話就會報錯了。
一個應用連接數據庫的時候是通過連接池的機制來連接的,數據庫用一個參數max-session來描述連接池的大小,而應用同樣也有一個參數,這個參數表示它連接數據庫連接池所占用的最少資源,例如:總共有10個應用需要連接數據庫,如果每個應用連接數據庫的最小連接數為10,那么10個應用總共會有100個連接(可以看做是線程數),這樣就要求數據庫連接池的max-session必須大于100,否則就會報“ Got minus one from a read call”的錯誤。
因此,有兩種方法可以解決這個問題:
(1)擴大數據庫連接池,這個需要系統數據庫管理員來協助完成
(2)減小應用連接數據庫時需要的初始化連接數
我的這個應用是java應用,關于數據庫的設置在配置文件jdbc.properties里面,內容如下:
jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@nantianpaydb.baidupay.com:8002:ntpzn
jdbc.user=cif
jdbc.password=cif
#druid datasource
druid.initialSize=10
druid.minIdle=10
druid.maxIdle=100
druid.maxActive=500
druid.maxWait=30000
druid.timeBetweenEvictionRunsMillis=60000
druid.minEvictableIdleTimeMillis=300000
druid.validationQuery=SELECT 1 from dual
druid.testWhileIdle=true
druid.testOnBorrow=false
druid.testOnReturn=false
druid.poolPreparedStatements=true
druid.maxPoolPreparedStatementPerConnectionSize=20
druid.filters=wall,stat
其中
druid.initialSize=10
就是一個應用連接數據庫的初始化參數,只要將之調小即可解決問題。
擴展:如果由于調整了process 導致 數據庫啟動不來,報錯如下
ORA-27154: post/wait create failed
ORA-27300: OS system dependent operation:semget failed with status: 28
ORA-27301: OS failure message: No space left on device
ORA-27302: failure occurred at: sskgpcreates
確認 df -h 、free -m 存儲與內存充足情況下, 留意是不是 sem 信號量設置不當
# cat /proc/sys/kernel/sem
250 32000 32 128
-- 與上面對應
# semaphores: semmsl, semmns, semopm, semmni
設置 SEMMSL
SEMMSL 內核參數用于控制每個信號集合的最大信號數。
Oracle 建議將 SEMMSL 設置為 init.ora 文件(適用于 Linux 系統上所有數據庫)中的最大 PROCESS 實例參數設置再加上 10。此外,Oracle 建議將 SEMMSL 設置為不小于 100。
設置 SEMMNI
SEMMNI 內核參數用于控制整個 Linux 系統中信號集的最大數量。Oracle 建議將 SEMMNI 設置為不小于 100。
設置 SEMMNS
SEMMNS 內核參數用于控制整個 Linux 系統中的信號(而非信號集)的最大數量。
Oracle 建議將 SEMMNS 設置為系統上每個數據庫的 PROCESSES 實例參數設置之和,加上最大的 PROCESSES 的兩倍,最后為系統上的每個 Oracle 數據庫加上 10。
使用以下計算式確定可以在 Linux 系統上分配的信號的最大數量。它將是以下兩者中較小的一個值:
SEMMNS -or- (SEMMSL * SEMMNI)
設置 SEMOPM
SEMOPM 內核參數用于控制每個 semop 系統調用可以執行的信號操作數。
semop 系統調用(函數)能夠使用一個 semop 系統調用完成多個信號的操作。一個信號集可以擁有每個信號集中最大數量的 SEMMSL,因此建議將 SEMOPM 設置為等于 SEMMSL。
Oracle 建議將 SEMOPM 設置為不小于 100。
設置信號內核參數
最后,我們來看如何使用一些方法來設置所有信號參數。在下文中,我想更改(增加)的唯一參數是 SEMOPM。所有其他的默認設置可以完全滿足我們的示例安裝。
可以通過使用以下命令直接更改 /proc 文件系統 (/proc/sys/kernel/sem) 來更改所有信號設置的默認設置,而不必重新引導計算機:
# sysctl -w kernel.sem="250 32000 100 128"
然后,通過將該內核參數插入到 /etc/sysctl.conf 啟動文件中,您可以使這種更改永久有效:
# echo "kernel.sem=250 32000 100 128" >> /etc/sysctl.conf
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。