PostgreSQL 採用多進程架構,main() 函數是所有後端進程 (postmaster、backend、bootstrap、standalone 等) 的統一入口,透過參數判斷進入不同啟動路徑。
main(argc, argv)
│
├── 解析命令列參數 (getopt_long)
│
├── 判斷執行模式
│ ├── -b / --boot → BootstrapMain() (單用戶模式/初始化)
│ ├── -C / --describe-config → GucInfoMain() (輸出設定參數)
│ ├── --single → PostgresMain() (單用戶後端)
│ └── (預設) → PostmasterMain() (多用戶伺服器模式)
│
└── 共用初始化
├── 記憶體上下文建立 (MemoryContextInit)
├── 訊號處理安裝 (pqsignal)
├── 區域/編碼初始化 (pg_set_locale)
└── 動態載入器初始化 (dlopen 等)
職責:監聽連線、管理共享記憶體、衍生子進程、處理崩潰復原、信號處理。
PostmasterMain()
├── CreateSharedMemoryAndSemaphores() -- 共享記憶體/訊號量
├── InitializePostmaster() -- 鎖檔、PID檔、通訊端
├── StartupDataBase() -- 崩潰復原 (WAL replay)
├── ServerLoop() -- 主事件迴圈
│ ├── select()/poll() 等待連線
│ ├── fork() 衍生 backend 進程
│ ├── 管理 bgwriter、checkpointer、walwriter、autovacuum 等輔助進程
│ └── 處理 SIGTERM/SIGINT/SIGHUP 等信號
└── PostmasterShutdown() -- 關閉序列
觸發時機:initdb 建立新資料庫叢集時,或 postgres --single -b 手動啟動。
關鍵任務:建立 pg_catalog 系統表、載入 postgres.bki 定義、建立 template0/template1 模板資料庫。
啟動路徑:Postmaster fork() 後,子進程呼叫 PostgresMain(argc, argv, username)。
核心流程:
PostgresMain()
├── BaseInit() -- 基礎初始化 (不含共享記憶體)
├── InitProcess() -- 連接共享記憶體、鎖管理器
├── InitPostgres() -- 開啟資料庫、載入快取、建立 Portal
├── BackendInitialize() -- 解析器/規劃器/執行器初始化
├── PostgresMainLoop() -- 主命令迴圈
│ ├── 讀取客戶端查詢 (簡單/擴充查詢協定)
│ ├── 剖析 → 分析 → 重寫 → 規劃 → 執行
│ └── 回傳結果
└── proc_exit() -- 正常退出清理
postgres -C parameter_name 列印參數值,postgres --describe-config 輸出完整設定文件 (含預設值、單位、上下文)。供外部工具 (如 pg_ctl、Ansible) 程式化讀取設定。
| 變數/結構 | 定義位置 | 用途 |
|---|---|---|
| PostmasterPid | postmaster.c | Postmaster PID,供子進程識別父進程 |
| MyProcPid | proc.c | 當前進程 PID |
| MyBackendId | proc.c | Backend 在 ProcArray 中的索引 |
| SharedMemoryConfig | shmem.c | 共享記憶體配置大小 |
| DataDir | guc.c | 資料目錄路徑 ($PGDATA) |
| IsUnderPostmaster | postmaster.c | 標記是否由 Postmaster 啟動 (影響共享記憶體連接方式) |
pqsignal() 封裝 sigaction(),確保跨平台一致性 (SA_RESTART 旗標)# 編譯時啟用除錯符號
./configure --enable-debug --enable-cassert CFLAGS="-ggdb -O0"
# 啟動單用戶模式除錯
gdb --args postgres --single -D /path/to/data postgres
# 追蹤 Postmaster fork 行為
strace -f -o trace.log postgres -D /path/to/data
# 記憶體上下文檢查 (需 enable_cassert)
SELECT * FROM pg_stat_clear_snapshot();
src/backend/main/main.c - main() 入口點src/backend/postmaster/postmaster.c - PostmasterMain()src/backend/bootstrap/bootstrap.c - BootstrapMain()src/backend/tcop/postgres.c - PostgresMain()src/backend/utils/init/miscinit.c - 共用初始化函數src/backend/utils/init/globals.c - 全域變數定義