首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

PostgreSQL 原始碼分析:main() 入口點與啟動流程

     編輯:關於SqlServer

PostgreSQL 後端進程啟動架構總覽

PostgreSQL 採用多進程架構,main() 函數是所有後端進程 (postmaster、backend、bootstrap、standalone 等) 的統一入口,透過參數判斷進入不同啟動路徑。

main() 核心邏輯流程圖

main(argc, argv)
    │
    ├── 解析命令列參數 (getopt_long)
    │
    ├── 判斷執行模式
    │       ├── -b / --boot          → BootstrapMain()      (單用戶模式/初始化)
    │       ├── -C / --describe-config → GucInfoMain()       (輸出設定參數)
    │       ├── --single             → PostgresMain()       (單用戶後端)
    │       └── (預設)               → PostmasterMain()     (多用戶伺服器模式)
    │
    └── 共用初始化
            ├── 記憶體上下文建立 (MemoryContextInit)
            ├── 訊號處理安裝 (pqsignal)
            ├── 區域/編碼初始化 (pg_set_locale)
            └── 動態載入器初始化 (dlopen 等)

四大啟動入口點詳細分析

1. PostmasterMain() - 主伺服器進程 (生產模式)

職責:監聽連線、管理共享記憶體、衍生子進程、處理崩潰復原、信號處理。

PostmasterMain()
    ├── CreateSharedMemoryAndSemaphores()  -- 共享記憶體/訊號量
    ├── InitializePostmaster()             -- 鎖檔、PID檔、通訊端
    ├── StartupDataBase()                  -- 崩潰復原 (WAL replay)
    ├── ServerLoop()                       -- 主事件迴圈
    │       ├── select()/poll() 等待連線
    │       ├── fork() 衍生 backend 進程
    │       ├── 管理 bgwriter、checkpointer、walwriter、autovacuum 等輔助進程
    │       └── 處理 SIGTERM/SIGINT/SIGHUP 等信號
    └── PostmasterShutdown()               -- 關閉序列

2. BootstrapMain() - 系統目錄初始化 (initdb 內部)

觸發時機:initdb 建立新資料庫叢集時,或 postgres --single -b 手動啟動。
關鍵任務:建立 pg_catalog 系統表、載入 postgres.bki 定義、建立 template0/template1 模板資料庫。

3. PostgresMain() - 一般後端進程 (處理用戶查詢)

啟動路徑:Postmaster fork() 後,子進程呼叫 PostgresMain(argc, argv, username)。
核心流程:

PostgresMain()
    ├── BaseInit()                         -- 基礎初始化 (不含共享記憶體)
    ├── InitProcess()                      -- 連接共享記憶體、鎖管理器
    ├── InitPostgres()                     -- 開啟資料庫、載入快取、建立 Portal
    ├── BackendInitialize()                -- 解析器/規劃器/執行器初始化
    ├── PostgresMainLoop()                 -- 主命令迴圈
    │       ├── 讀取客戶端查詢 (簡單/擴充查詢協定)
    │       ├── 剖析 → 分析 → 重寫 → 規劃 → 執行
    │       └── 回傳結果
    └── proc_exit()                        -- 正常退出清理

4. GucInfoMain() - 設定參數描述輸出

postgres -C parameter_name 列印參數值,postgres --describe-config 輸出完整設定文件 (含預設值、單位、上下文)。供外部工具 (如 pg_ctl、Ansible) 程式化讀取設定。

關鍵資料結構與全域狀態

變數/結構定義位置用途
PostmasterPidpostmaster.cPostmaster PID,供子進程識別父進程
MyProcPidproc.c當前進程 PID
MyBackendIdproc.cBackend 在 ProcArray 中的索引
SharedMemoryConfigshmem.c共享記憶體配置大小
DataDirguc.c資料目錄路徑 ($PGDATA)
IsUnderPostmasterpostmaster.c標記是否由 Postmaster 啟動 (影響共享記憶體連接方式)

訊號處理機制

  • Postmaster:SIGTERM (快速關閉)、SIGINT (智慧關閉)、SIGHUP (重讀設定)、SIGCHLD (子進程回收)
  • Backend:SIGTERM (查詢取消)、SIGINT (中斷當前查詢)、SIGHUP (重讀 postgresql.conf)、SIGUSR1 (同步鎖表轉储)
  • 使用 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 - 全域變數定義
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved