亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

PostgreSQL源碼閱讀筆記——postgres主進程啟動過程

2024-11-08 09:21:26
89
0

1. main

這是整個postgres進程的程序入口。

  • 首先在startup_hacks函數中初始化全局的自旋鎖dummy_spinlock
  • 調用save_ps_display_args函數,使用saved_argv保存初始的argv地址,然后將argv的內容拷貝到新申請的內存中,并讓argv指向新的內存。這樣做是因為postgres(master)進程在創建backend進程時,為了讓用戶通過ps命令可以看到不同的進程信息(包含:用戶名、數據庫、客戶端信息等),需要將這些信息填寫到原始的argv處,以便ps命令能夠正確顯示。同時因為在填入這些信息時,會破壞argv原有的內容,而很多系統的environ是緊挨著argv的,這樣有可能導致環境變量被破壞,因此這個函數里回分配一塊新的內存,將environ的內容拷貝過去,然后將environ指向新內存。
  • 調用MemoryContextInit函數創建并初始化TopMemoryContextErrorContext這兩個內存管理器
  • 進行locale設置
  • 檢查是否root用戶啟動,如果是就退出
  • 單進程模式(調試用)調用PostgresMain,多進程模式調用PostmasterMain

2. PostmasterMain

這是多進程postgres(master)進程的程序入口。

  • 取進程id保存到MyProcPidPostmasterPid中,取當前時間保存到MyStartTime
  • 設置IsPostmasterEnvironmenttrue,表示是在多進程模式中
  • 創建PostmasterContext內存管理器,并換為當前內存管理器
  • 取當前進程二進制文件全路徑保存到my_exec_path,取庫文件全路徑保存到pkglib_path,并檢查庫文件路徑是否能正確打開
  • 設置信號處理方式:屏蔽或設置處理函數
  • 調用InitializeGUCOptions完成配置項的初始化,主要是加載默認配置項,然后從環境變量加載配置項(詳見[2.1])。
  • 處理命令行啟動參數,設置配置項
  • 調用SelectConfigFiles函數加載配置文件,設置數據庫的主數據目錄。
  • 調用checkDataDir檢查主數據目錄是否可訪問,以及目錄下的PG_VERSION文件中記錄的版本號是否正確
  • 當前工作目錄切換到主數據目錄
  • 調用CheckDateTokenTables對兩個時間日期格式的保留字表進行正確性校驗
  • 調用CreateDataDirLockFile在主數據目錄下創建postmaster.pid,并在里面記錄下:pid、主數據目錄、啟動時間和監聽端口等信息。然后將該文件加入到全局的鏈表lock_files中,這個列表中的文件在進程退出時會被清理
  • 調用ApplyLauncherRegister注冊1個后臺worker。這里只是指定這個worker的主入口函數、訪問權限、啟動時機等信息,然后加入到一個就緒列表中,等待后續合適時機再啟動進程。這里注冊的worker入口函數是ApplyLauncherMain。看注釋應該是注冊了一個負責邏輯復制的work
  • 調用process_shared_preload_libraries加載配置文件中指定(參數: shared_preload_libraries)需要加載的插件so
  • 調用InitializeMaxBackends初始化全局變量MaxBackends,表示系統信息的進程數。該值 = 客戶端最大連接數 + 自動vacuum進程數 + 最大后臺進程數 + 1
  • 注冊atexit回調函數:CloseServerPorts。這個函數主要就是關閉監聽的所有tcp端口(記錄在ListenSocket數組中),回收所有的unix socket(記錄在sock_paths列表中)
  • 綁定配置中指定的所有TCP監聽服務地址(ip:port),并將這些監聽socket放到全局的ListenSocket數組中(步驟16中注冊的回調函數會釋放這些socket)。同時會把監聽的第一個host記錄到postmaster.pid的第6行
  • 綁定配置中指定的所有unix socket目錄,在這些目錄下創建unix socket句柄以及對應的lock文件句柄,并將其lock文件加入到sock_paths列表中(步驟16中注冊的回調函數會釋放這些unix socket)。同時會把創建的第一個unix socket記錄到postmaster.pid的第5行
  • 調用reset_shared函數創建共享內存和信號量。該函數直接調用CreateSharedMemoryAndSemaphores函數(詳見[2.2])
  • 調用set_max_safe_fds函數計算每個backend進程最大能打開的文件句柄數,保持在全局變量:max_safe_fds
  • 調用set_stack_base設置全局變量stack_base_ptr,這個是值取該函數第1個函數局部變量的指針值,也就是set_stack_base這個函數的棧起始地址。后面可以用這個值配合檢查函數的棧起始地址是否偏移過多,也就是限制調用棧的大小
  • 調用InitPostmasterDeathWatchHandle函數創建匿名管道,讀寫句柄保持在全局數組:postmaster_alive_fds中。postgres(master)負責寫,backend進程負責監聽讀,用于postgres(master)在退出時通知喚醒backend進程
  • 調用CreateOptsFile函數創建$DataDir/postmaster.opts文件,并將執行本進程的命令行保存在其中
  • 調用RemovePgTempFiles函數刪除$DataDir/base/pgsql_tmp$DataDir/base$DataDir/pg_tablspc下的臨時文件和關系對象
  • 調用RemovePromoteSignalFiles函數刪除$DataDir/promote$DataDir/fallback_promote文件,猜測這兩個文件用于將從實例提升為主
  • 刪除用于保存當前日志文件名的$DataDir/current_logfiles文件
  • 調用pgstat_init函數創建一個用于收發統計信息的udp端口
  • 調用load_hba函數,讀取加載$DataDir/pg_hba.conf文件,初始化用于客戶端連接權限控制的全局對象parsed_hba_lines列表,和用于保存這個列表的MemoryContext對象:parsed_hba_context
  • 調用load_ident函數,讀取加載$DataDir/pg_ident.conf文件,初始化用于維護操作系統用戶到數據庫用戶映射關系的全局對象parsed_ident_lines列表,和用于保存這個列表的MemoryContext對象:parsed_ident_context
  • 獲取當前時間保存到全局對象:PgStartTime
  • $DataDir/postmaster.pid文件的第8行添加字符串starting,主要是為了讓pg_ctl進程能正確看到該進程的運行狀況
  • 調用maybe_start_bgworkers根據情況啟動一些后臺進程
  • 調用ServerLoop啟動postgres(master)進程的主循環:通過select處理客戶端請求,如果有新的連接請求,則調用BackendStartup創建子進程。此外在處理完客戶端連接請求后,還會檢查所有的后臺進程,如果發現有異常退出的后臺進程,就嘗試拉起

2.1 InitializeGUCOptions

這是初始化用戶配置的主函數。

  • pg_timezone_initialize函數中初始化時區
  • 調用build_guc_variables函數,將所有配置項放到一個大數組guc_variables中,并按配置項的字符串值排序
  • 循環調用InitializeOneGUCOption函數初始化guc_variables數組中的所有配置項,主要是加載默認值
  • 設置transaction_isolationtransaction_read_onlytransaction_deferrable三個配置項
  • 調用InitializeGUCOptionsFromEnvironment函數,從環境變量中獲取配置值進行設置

2.2 CreateSharedMemoryAndSemaphores

這是創建共享內存和信號量的主函數。

  • 首先判斷不能是backend進程,因為這種情況下,共享內存應該已經存在,只需要attach上去
  • 計算需要的信號量個數 = MaxBackends + 輔助進程數(NUM_AUXILIARY_PROCS)
  • 根據共享內存需要存儲的內存,估算其大小
  • 調用PGSharedMemoryCreate創建存放PGShmemHeader的共享內存
    • 調用CreateAnonymousSegment創建匿名的共享內存,因為是匿名的,所以應該就是這個進程自己使用,有什么作用目前還沒看到
      • 如果設置使用huge page,則從/proc/meminfo中獲取huge page的大小,然后將共享內存的大小擴大到huge page的整數倍,然后使用MAP_HUGETLB標志位調用mmap,這樣就是使用了huge page
      • 如果使用huge page失敗或者設置就是不使用,則正常調用mmap
    • 將匿名的共享內存地址記錄到AnonymousShmem,其大小記錄到AnonymousShmemSize
    • 注冊AnonymousShmemDetach函數在on_shmem_exit_list中,以便postgres(master)退出時調用munmap釋放共享內存
    • 調用InternalIpcMemoryCreate創建大小為sizeof(PGShmemHeader)的共享內存
      • 調用shmget分配共享內存
      • 注冊IpcMemoryDelete函數在on_shmem_exit_list中,以便進程退出時釋放共享內存
      • 調用shmat綁定共享內存
      • 注冊IpcMemoryDetach函數在on_shmem_exit_list中,以便進程退出時解綁內存
      • 將共享內存的keyid記錄到postmaster.pid的第7行
    • 將內存映射到PGShmemHeader對象指針,進行復制,初始化如下字段:
      • creatorPID:當前的進程id
      • magic:一個固定的整數值
      • dsm_control:共享內存的id號,在postgres(master)中為0
      • device:主數據目錄的dev
      • inode:主數據目錄的inode
      • totalsize:匿名共享內存的大小
      • freeoffset:剩余空閑空間的偏移量,這里其值為sizeof(PGShmemHeader)
    • 將該共享內存的地址保存到UsedShmemSegAddr,將key保存到UsedShmemSegID
    • 將共享內存的內容拷貝到匿名的共享內存AnonymousShmem中,返回AnonymousShmem(這里為什么要同時有個AnonymousShmemUsedShmemSegAddr,現在還搞不清楚)
  • 調用InitShmemAccess初始化3個全局變量:
    • ShmemSegHdr:指向上面分配的AnonymousShmem,表示PGShmemHeader對象
    • ShmemBase:數值上等于ShmemSegHdr,表示起始地址
    • ShmemEnd:AnonymousShmem的結束地址
  • 調用PGReserveSemaphores從共享內存中預留信號量對象數組的空間。其實就是在ShmemBase的共享內存空閑處(ShmemSegHdr->freeoffset)預留出足夠的空間,并更新ShmemSegHdr->freeoffset。同時也會初始化3個全局變量:
    • numSems:已經實際創建的信號量,這里為:0
    • maxSems:最大能創建的信號量,這里就是前面計算的結果
    • nextSemKey:下一個信號量的key,從綁定端口號計算得到,避免不同實例沖突
  • 如果是postgres(master),則調用InitShmemAllocation初始化共享內存分配機制
    • 從共享內存中分配1個全局自旋鎖對象ShmemLock,并初始化。后面從共享內存中申請空間會調用ShmemAlloc(之前都是ShmemAllocUnlocked),此函數會對ShmemLock加鎖
    • 從共享內存中分配1個全局的ShmemVariableCache對象,這個對象主要保存了維護OIDXID需要的一些變量
  • 調用CreateLWLocks創建LWLock數組,如果是postgres(master),要完成下面全部操作,如果是backend進程,只需要最后一步RegisterLWLockTranches
    • 首先預估需要的內存大小,然后從共享內存中分配足夠的空間
    • 將全局變量MainLWLockArray指向LWLock數組起始地址
    • 調用InitializeLWLocks初始化LWLock數組
    • 調用RegisterLWLockTranches對固定的LWLock對象進行注冊,主要是分配1個全局字符串數組LWLockTrancheArray,數組大小為LWLockTranchesAllocated(該數組的下標就是某類LWLock對象的TrancheID,而其字符串就是這個對象的名字,所以實際上表示LWLock對象的TrancheID到名字的映射關系)。然后注冊TranchID為64以下的固定LWLock對象的名字
  • 調用InitShmemIndex在共享內存中創建1個hash表,將ShmemSegHdr->index以及全局對象ShmemIndex指向它,后續接口絕大部分內存對象都是由這個hash表來管理
  • 調用XLOGShmemInit函數初始化pg_control對象和XLOG對象
  • 調用CLOGShmemInit函數初始化CLOG相關對象
  • 調用CommitTsShmemInit函數初始化CommitTs相關對象
  • 調用SUBTRANSShmemInit函數初始化SubTrans相關對象
  • 調用MultiXactShmemInit函數初始化MultiXact相關對象
  • 調用InitBufferPool初始化共享內存池
  • 調用InitLocks初始化鎖管理對象
  • 調用InitPredicateLocks初始化predicate鎖管理對象
  • 調用InitProcGlobal初始化全局進程表
  • 調用CreateSharedProcArray函數初始化ProcArray相關對象
  • 調用CreateSharedBackendStatus函數初始化BackendStatusArray相關對象
  • 調用TwoPhaseShmemInit函數初始化TwoPhaseState相關對象
  • 調用BackgroundWorkerShmemInit函數初始化BackgroundWorkerData相關對象
  • 調用CreateSharedInvalidationState函數初始化shmInvalBuffer相關對象
  • 調用PMSignalShmemInit函數初始化PMSignalState相關對象
  • 調用ProcSignalShmemInit函數初始化ProcSignalSlots相關對象
  • 調用CheckpointerShmemInit函數初始化CheckpointerShmem相關對象
  • 調用AutoVacuumShmemInit函數初始化AutoVacuumShmem相關對象
  • 調用ReplicationSlotsShmemInit函數初始化ReplicationSlotCtl相關對象
  • 調用ReplicationOriginShmemInit函數初始化replication_states_ctl相關對象
  • 調用WalSndShmemInit函數初始化WalSndCtl相關對象
  • 調用WalRcvShmemInit函數初始化WalRcv相關對象
  • 調用ApplyLauncherShmemInit函數初始化LogicalRepCtx相關對象
  • 調用SnapMgrInit函數初始化oldSnapshotControl相關對象
  • 調用BTreeShmemInit函數初始化btvacinfo相關對象
  • 調用SyncScanShmemInit函數初始化scan_locations相關對象
  • 調用AsyncShmemInit函數初始化asyncQueueControlAsyncCtl相關對象
  • 調用BackendRandomShmemInit函數初始化TwoPhaseState相關對象
  • 調用dsm_postmaster_startup創建共享內存對象dsm_control,映射到文件/dev/shm/PostgreSQL.<handleID>,這個HandleID是個隨機數,保存在UsedShmemSegAddr->dsm_control字段
0條評論
0 / 1000
胡****彬
3文章數
0粉絲數
胡****彬
3 文章 | 0 粉絲
原創

PostgreSQL源碼閱讀筆記——postgres主進程啟動過程

2024-11-08 09:21:26
89
0

1. main

這是整個postgres進程的程序入口。

  • 首先在startup_hacks函數中初始化全局的自旋鎖dummy_spinlock
  • 調用save_ps_display_args函數,使用saved_argv保存初始的argv地址,然后將argv的內容拷貝到新申請的內存中,并讓argv指向新的內存。這樣做是因為postgres(master)進程在創建backend進程時,為了讓用戶通過ps命令可以看到不同的進程信息(包含:用戶名、數據庫、客戶端信息等),需要將這些信息填寫到原始的argv處,以便ps命令能夠正確顯示。同時因為在填入這些信息時,會破壞argv原有的內容,而很多系統的environ是緊挨著argv的,這樣有可能導致環境變量被破壞,因此這個函數里回分配一塊新的內存,將environ的內容拷貝過去,然后將environ指向新內存。
  • 調用MemoryContextInit函數創建并初始化TopMemoryContextErrorContext這兩個內存管理器
  • 進行locale設置
  • 檢查是否root用戶啟動,如果是就退出
  • 單進程模式(調試用)調用PostgresMain,多進程模式調用PostmasterMain

2. PostmasterMain

這是多進程postgres(master)進程的程序入口。

  • 取進程id保存到MyProcPidPostmasterPid中,取當前時間保存到MyStartTime
  • 設置IsPostmasterEnvironmenttrue,表示是在多進程模式中
  • 創建PostmasterContext內存管理器,并換為當前內存管理器
  • 取當前進程二進制文件全路徑保存到my_exec_path,取庫文件全路徑保存到pkglib_path,并檢查庫文件路徑是否能正確打開
  • 設置信號處理方式:屏蔽或設置處理函數
  • 調用InitializeGUCOptions完成配置項的初始化,主要是加載默認配置項,然后從環境變量加載配置項(詳見[2.1])。
  • 處理命令行啟動參數,設置配置項
  • 調用SelectConfigFiles函數加載配置文件,設置數據庫的主數據目錄。
  • 調用checkDataDir檢查主數據目錄是否可訪問,以及目錄下的PG_VERSION文件中記錄的版本號是否正確
  • 當前工作目錄切換到主數據目錄
  • 調用CheckDateTokenTables對兩個時間日期格式的保留字表進行正確性校驗
  • 調用CreateDataDirLockFile在主數據目錄下創建postmaster.pid,并在里面記錄下:pid、主數據目錄、啟動時間和監聽端口等信息。然后將該文件加入到全局的鏈表lock_files中,這個列表中的文件在進程退出時會被清理
  • 調用ApplyLauncherRegister注冊1個后臺worker。這里只是指定這個worker的主入口函數、訪問權限、啟動時機等信息,然后加入到一個就緒列表中,等待后續合適時機再啟動進程。這里注冊的worker入口函數是ApplyLauncherMain。看注釋應該是注冊了一個負責邏輯復制的work
  • 調用process_shared_preload_libraries加載配置文件中指定(參數: shared_preload_libraries)需要加載的插件so
  • 調用InitializeMaxBackends初始化全局變量MaxBackends,表示系統信息的進程數。該值 = 客戶端最大連接數 + 自動vacuum進程數 + 最大后臺進程數 + 1
  • 注冊atexit回調函數:CloseServerPorts。這個函數主要就是關閉監聽的所有tcp端口(記錄在ListenSocket數組中),回收所有的unix socket(記錄在sock_paths列表中)
  • 綁定配置中指定的所有TCP監聽服務地址(ip:port),并將這些監聽socket放到全局的ListenSocket數組中(步驟16中注冊的回調函數會釋放這些socket)。同時會把監聽的第一個host記錄到postmaster.pid的第6行
  • 綁定配置中指定的所有unix socket目錄,在這些目錄下創建unix socket句柄以及對應的lock文件句柄,并將其lock文件加入到sock_paths列表中(步驟16中注冊的回調函數會釋放這些unix socket)。同時會把創建的第一個unix socket記錄到postmaster.pid的第5行
  • 調用reset_shared函數創建共享內存和信號量。該函數直接調用CreateSharedMemoryAndSemaphores函數(詳見[2.2])
  • 調用set_max_safe_fds函數計算每個backend進程最大能打開的文件句柄數,保持在全局變量:max_safe_fds
  • 調用set_stack_base設置全局變量stack_base_ptr,這個是值取該函數第1個函數局部變量的指針值,也就是set_stack_base這個函數的棧起始地址。后面可以用這個值配合檢查函數的棧起始地址是否偏移過多,也就是限制調用棧的大小
  • 調用InitPostmasterDeathWatchHandle函數創建匿名管道,讀寫句柄保持在全局數組:postmaster_alive_fds中。postgres(master)負責寫,backend進程負責監聽讀,用于postgres(master)在退出時通知喚醒backend進程
  • 調用CreateOptsFile函數創建$DataDir/postmaster.opts文件,并將執行本進程的命令行保存在其中
  • 調用RemovePgTempFiles函數刪除$DataDir/base/pgsql_tmp$DataDir/base$DataDir/pg_tablspc下的臨時文件和關系對象
  • 調用RemovePromoteSignalFiles函數刪除$DataDir/promote$DataDir/fallback_promote文件,猜測這兩個文件用于將從實例提升為主
  • 刪除用于保存當前日志文件名的$DataDir/current_logfiles文件
  • 調用pgstat_init函數創建一個用于收發統計信息的udp端口
  • 調用load_hba函數,讀取加載$DataDir/pg_hba.conf文件,初始化用于客戶端連接權限控制的全局對象parsed_hba_lines列表,和用于保存這個列表的MemoryContext對象:parsed_hba_context
  • 調用load_ident函數,讀取加載$DataDir/pg_ident.conf文件,初始化用于維護操作系統用戶到數據庫用戶映射關系的全局對象parsed_ident_lines列表,和用于保存這個列表的MemoryContext對象:parsed_ident_context
  • 獲取當前時間保存到全局對象:PgStartTime
  • $DataDir/postmaster.pid文件的第8行添加字符串starting,主要是為了讓pg_ctl進程能正確看到該進程的運行狀況
  • 調用maybe_start_bgworkers根據情況啟動一些后臺進程
  • 調用ServerLoop啟動postgres(master)進程的主循環:通過select處理客戶端請求,如果有新的連接請求,則調用BackendStartup創建子進程。此外在處理完客戶端連接請求后,還會檢查所有的后臺進程,如果發現有異常退出的后臺進程,就嘗試拉起

2.1 InitializeGUCOptions

這是初始化用戶配置的主函數。

  • pg_timezone_initialize函數中初始化時區
  • 調用build_guc_variables函數,將所有配置項放到一個大數組guc_variables中,并按配置項的字符串值排序
  • 循環調用InitializeOneGUCOption函數初始化guc_variables數組中的所有配置項,主要是加載默認值
  • 設置transaction_isolationtransaction_read_onlytransaction_deferrable三個配置項
  • 調用InitializeGUCOptionsFromEnvironment函數,從環境變量中獲取配置值進行設置

2.2 CreateSharedMemoryAndSemaphores

這是創建共享內存和信號量的主函數。

  • 首先判斷不能是backend進程,因為這種情況下,共享內存應該已經存在,只需要attach上去
  • 計算需要的信號量個數 = MaxBackends + 輔助進程數(NUM_AUXILIARY_PROCS)
  • 根據共享內存需要存儲的內存,估算其大小
  • 調用PGSharedMemoryCreate創建存放PGShmemHeader的共享內存
    • 調用CreateAnonymousSegment創建匿名的共享內存,因為是匿名的,所以應該就是這個進程自己使用,有什么作用目前還沒看到
      • 如果設置使用huge page,則從/proc/meminfo中獲取huge page的大小,然后將共享內存的大小擴大到huge page的整數倍,然后使用MAP_HUGETLB標志位調用mmap,這樣就是使用了huge page
      • 如果使用huge page失敗或者設置就是不使用,則正常調用mmap
    • 將匿名的共享內存地址記錄到AnonymousShmem,其大小記錄到AnonymousShmemSize
    • 注冊AnonymousShmemDetach函數在on_shmem_exit_list中,以便postgres(master)退出時調用munmap釋放共享內存
    • 調用InternalIpcMemoryCreate創建大小為sizeof(PGShmemHeader)的共享內存
      • 調用shmget分配共享內存
      • 注冊IpcMemoryDelete函數在on_shmem_exit_list中,以便進程退出時釋放共享內存
      • 調用shmat綁定共享內存
      • 注冊IpcMemoryDetach函數在on_shmem_exit_list中,以便進程退出時解綁內存
      • 將共享內存的keyid記錄到postmaster.pid的第7行
    • 將內存映射到PGShmemHeader對象指針,進行復制,初始化如下字段:
      • creatorPID:當前的進程id
      • magic:一個固定的整數值
      • dsm_control:共享內存的id號,在postgres(master)中為0
      • device:主數據目錄的dev
      • inode:主數據目錄的inode
      • totalsize:匿名共享內存的大小
      • freeoffset:剩余空閑空間的偏移量,這里其值為sizeof(PGShmemHeader)
    • 將該共享內存的地址保存到UsedShmemSegAddr,將key保存到UsedShmemSegID
    • 將共享內存的內容拷貝到匿名的共享內存AnonymousShmem中,返回AnonymousShmem(這里為什么要同時有個AnonymousShmemUsedShmemSegAddr,現在還搞不清楚)
  • 調用InitShmemAccess初始化3個全局變量:
    • ShmemSegHdr:指向上面分配的AnonymousShmem,表示PGShmemHeader對象
    • ShmemBase:數值上等于ShmemSegHdr,表示起始地址
    • ShmemEnd:AnonymousShmem的結束地址
  • 調用PGReserveSemaphores從共享內存中預留信號量對象數組的空間。其實就是在ShmemBase的共享內存空閑處(ShmemSegHdr->freeoffset)預留出足夠的空間,并更新ShmemSegHdr->freeoffset。同時也會初始化3個全局變量:
    • numSems:已經實際創建的信號量,這里為:0
    • maxSems:最大能創建的信號量,這里就是前面計算的結果
    • nextSemKey:下一個信號量的key,從綁定端口號計算得到,避免不同實例沖突
  • 如果是postgres(master),則調用InitShmemAllocation初始化共享內存分配機制
    • 從共享內存中分配1個全局自旋鎖對象ShmemLock,并初始化。后面從共享內存中申請空間會調用ShmemAlloc(之前都是ShmemAllocUnlocked),此函數會對ShmemLock加鎖
    • 從共享內存中分配1個全局的ShmemVariableCache對象,這個對象主要保存了維護OIDXID需要的一些變量
  • 調用CreateLWLocks創建LWLock數組,如果是postgres(master),要完成下面全部操作,如果是backend進程,只需要最后一步RegisterLWLockTranches
    • 首先預估需要的內存大小,然后從共享內存中分配足夠的空間
    • 將全局變量MainLWLockArray指向LWLock數組起始地址
    • 調用InitializeLWLocks初始化LWLock數組
    • 調用RegisterLWLockTranches對固定的LWLock對象進行注冊,主要是分配1個全局字符串數組LWLockTrancheArray,數組大小為LWLockTranchesAllocated(該數組的下標就是某類LWLock對象的TrancheID,而其字符串就是這個對象的名字,所以實際上表示LWLock對象的TrancheID到名字的映射關系)。然后注冊TranchID為64以下的固定LWLock對象的名字
  • 調用InitShmemIndex在共享內存中創建1個hash表,將ShmemSegHdr->index以及全局對象ShmemIndex指向它,后續接口絕大部分內存對象都是由這個hash表來管理
  • 調用XLOGShmemInit函數初始化pg_control對象和XLOG對象
  • 調用CLOGShmemInit函數初始化CLOG相關對象
  • 調用CommitTsShmemInit函數初始化CommitTs相關對象
  • 調用SUBTRANSShmemInit函數初始化SubTrans相關對象
  • 調用MultiXactShmemInit函數初始化MultiXact相關對象
  • 調用InitBufferPool初始化共享內存池
  • 調用InitLocks初始化鎖管理對象
  • 調用InitPredicateLocks初始化predicate鎖管理對象
  • 調用InitProcGlobal初始化全局進程表
  • 調用CreateSharedProcArray函數初始化ProcArray相關對象
  • 調用CreateSharedBackendStatus函數初始化BackendStatusArray相關對象
  • 調用TwoPhaseShmemInit函數初始化TwoPhaseState相關對象
  • 調用BackgroundWorkerShmemInit函數初始化BackgroundWorkerData相關對象
  • 調用CreateSharedInvalidationState函數初始化shmInvalBuffer相關對象
  • 調用PMSignalShmemInit函數初始化PMSignalState相關對象
  • 調用ProcSignalShmemInit函數初始化ProcSignalSlots相關對象
  • 調用CheckpointerShmemInit函數初始化CheckpointerShmem相關對象
  • 調用AutoVacuumShmemInit函數初始化AutoVacuumShmem相關對象
  • 調用ReplicationSlotsShmemInit函數初始化ReplicationSlotCtl相關對象
  • 調用ReplicationOriginShmemInit函數初始化replication_states_ctl相關對象
  • 調用WalSndShmemInit函數初始化WalSndCtl相關對象
  • 調用WalRcvShmemInit函數初始化WalRcv相關對象
  • 調用ApplyLauncherShmemInit函數初始化LogicalRepCtx相關對象
  • 調用SnapMgrInit函數初始化oldSnapshotControl相關對象
  • 調用BTreeShmemInit函數初始化btvacinfo相關對象
  • 調用SyncScanShmemInit函數初始化scan_locations相關對象
  • 調用AsyncShmemInit函數初始化asyncQueueControlAsyncCtl相關對象
  • 調用BackendRandomShmemInit函數初始化TwoPhaseState相關對象
  • 調用dsm_postmaster_startup創建共享內存對象dsm_control,映射到文件/dev/shm/PostgreSQL.<handleID>,這個HandleID是個隨機數,保存在UsedShmemSegAddr->dsm_control字段
文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0