一、問題描述
在虛擬機環境(4核16GB內存)上部署 truevoly/oracle-12c
容器鏡像時,一切運行正常。然而,當在一臺?128 核 CPU 和 512GB 內存的物理服務器上運行時,容器啟動時出現了 ORA-00821
等錯誤,提示 SGA 的內存配置不足。
二、原因
通過在 GitHub 上查找相關資料,發現每個單獨的線程大約會增加 22MB 的內存需求。因此,當核心數增多時,Oracle 數據庫啟動時會嘗試為每個 CPU 核心分配內存,這就導致了內存需求大幅增加。
三、排查思路
剛開始可能走了點彎路,主要是在問AI,而忽略GitHub案例
1、啟動鏡像
docker run --restart always -d -p 8081:8080 -p 1522:1521 -v /usr/local/oracle/data_temp:/home/oracle/data_temp -v /etc/localtime:/etc/localtime:ro --name orac1 truevoly/oracle-12c
2、查看啟動日志
docker logs -f 4eea316971a1706b1faf6dd469c276c334234f1f6f63824997aa71c00670abd5
正常情況下可以走到100%,訪問數據庫
Database not initialized. Initializing database.
Starting tnslsnr
Copying database files
1% complete
2% complete
4% complete
DBCA Operation failed.
Look at the log file "/u01/app/oracle/cfgtoollogs/dbca/xe/xe.log" for further details.
3、登錄容器內部查看報錯日志
docker exec -it orac1 bash
cat? /u01/app/oracle/cfgtoollogs/dbca/xe/xe.log
Unique database identifier check passed.
/ has enough space. Required space is 6140 MB , available space is 2318404 MB.
File Validations Successful.
Copying database files
DBCA_PROGRESS : 1%
DBCA_PROGRESS : 2%
ORA-00821: Specified value of sga_target 1536M is too small, needs to be at least 1968M
ORA-01078: failure in processing system parameters
DBCA_PROGRESS : 4%
ORA-01034: ORACLE not available
ORA-01034: ORACLE not available
DBCA_PROGRESS : DBCA Operation failed.
我的第一反應是服務器資源充足,內存并不缺乏,因此懷疑是否是之前調整的內核參數,尤其是大頁內存設置,導致了這個問題,把配置還原后不是這個原因。
報錯解釋
- ORA-00821: Specified value of sga_target 1536M is too small, needs to be at least 1968M
- 這個錯誤表示 Oracle 在初始化時嘗試為
sga_target
設置 1536M 的內存大小,但實際上 Oracle 需要的最小值是 1968M。因此,sga_target
設置過小,導致初始化失敗。- ORA-01078: failure in processing system parameters
- 這個錯誤通常是在處理系統參數(如
sga_target
)時失敗,通常與內存設置有關,表明數據庫無法使用當前配置啟動。- ORA-01034: ORACLE not available
- 這個錯誤表明 Oracle 實例在嘗試啟動時沒有成功運行。通常是由于數據庫無法使用給定的內存配置而未能啟動。
錯誤的根本原因是數據庫初始化時內存分配不足,導致
sga_target
的值過小,無法滿足 Oracle 數據庫的需求。
3、限制容器的內存和 CPU 配置
github上面有說通過限制CPU來解決,這個思路有點啟發
通過 docker run
命令,限制容器的內存和 CPU 使用,確保容器的資源分配符合 Oracle 數據庫的要求,然后沒有解決我的問題。
docker run --memory-swappiness=0 --memory="1g" --cpus="1.0" --rm=true --name=oracle1 -p 1521:1521 -e ORACLE_PASSWORD=123456 orac1 truevoly/oracle-12c
--memory="1g":限制容器使用的內存為 1GB。
--cpus="1.0":限制容器使用 1 個 CPU 核心。
--memory-swappiness=0:禁用容器的交換內存,避免性能下降。
?對資源限制感興趣的話可以去docker幫助文檔
https://docs.docker.com/config/containers/resource_constraints/#configure-the-default-cfs-scheduler
4、容器內部修改內存配置
進入容器后,設置適當的 DBCA_TOTAL_MEMORY
來解決內存不足的問題,并重新執行初始化腳本:
想起來了之前做RAC的時候好像碰到過類似的問題
docker exec -it 4eea316971a1 bash
export DBCA_TOTAL_MEMORY=4096
執行腳本驗證
root@4eea316971a1:/# bash entrypoint.sh
通過設置 DBCA_TOTAL_MEMORY 環境變量為 4096MB,能夠幫助 Oracle 在容器中成功初始化。
已經生效了,看到了問題解決
四、優化Dockerfile
1、構建Dockerfile
將entrypoint.sh 拷貝到本地
修改腳本,重新build
2、重新運行觀察
可以正常初始化
數據庫鏈接正常
總結:
在虛擬機上運行時,由于核心數較少,內存需求較低,容器能夠成功啟動。但在物理機上,由于 128 核 CPU,內存需求顯著增加,導致了內存分配不足,進而觸發了錯誤。
這個鏡像很好用的,我看網上分享oracle 12c快速啟動大部分都在用這個鏡像,估計很少在128C內存上運行吧。