Unix/Linux 下 Pro*C 程式 fork() 大量子進程各自連線 Oracle,極易觸發 ORA-12549: TNS:operating system resource quota exceeded 並產生大量殭屍進程。本文分析根因並提供連線池、參數調整、訊號處理三大解決方案。
fork() 約 760 子進程,各子進程獨立 CONNECT、INSERT、COMMIT、DISCONNECT。ORA-12549(作業系統資源配額超限,實際為 Process/Session 上限)。defunct(殭屍)進程,最終導致 fork function failed。PROCESSES 參數較小,大量並發連線超限。fork() 失敗。SIGCHLD 處理器,Server Process 會變殭屍。ALTER SYSTEM SET PROCESSES = 2000 SCOPE=SPFILE; -- 視預估並發上限設定
-- 需重啟資料庫生效
POOL=YES 選項,或程式中使用 EXEC SQL CONTEXT ALLOCATE 管理連線池上下文。Pro*C/C++ Programmer's Guide 章節「Connection Pooling」。在 fork() 前註冊 SIGCHLD 忽略或自訂處理器,讓父進程自動回收子進程:
#include
signal(SIGCHLD, SIG_IGN); // 最簡單:交給 init 進程回收
// 或自訂 handler 記錄退出碼
void sigchld_handler(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
signal(SIGCHLD, sigchld_handler);
若使用 Bequeath 協議(本地連線無 Listener),還需在sqlnet.ora設定BEQUEATH_DETACH=YES,將 Server Process 移交給 init 進程,避免殭屍。
int main() {
signal(SIGCHLD, SIG_IGN); // 1. 防殭屍
// 2. 初始化連線池(Pro*C POOL=YES 或手動管理)
for (int i=0; i 0);
return 0;
}
PROCESSES / SESSIONS 參數足夠大SIGCHLD(SIG_IGN 或 waitpid)BEQUEATH_DETACH=YESROLLBACK、CONTEXT FREE