PostgreSQL在shutdown时会进行checkpoint。其流程如下。 1、在主进程中,会首先注册一个信号处理函数reaper,用于向checkpoint等子进程发送信号。向checkpoint进程发送SIGUSR2信号 PostmasterMain(int argc, char argv[]) pqsignal_no_restart(SIGCHLD, reaper); / handle child termination */ reaper: while ((pid = waitpid(-1, &exitstatus, WNOHANG)) > 0){ ... if (pid == CheckpointerPID){ ... SignalChildren(SIGUSR2); } ... } ... PostmasterStateMachine();//向checkpoint进程发送SIGUSR2信号 |----------------------- | if (pmState == PM_WAIT_BACKENDS){ | if (CountChildren(BACKEND_TYPE_NORMAL | BACKEND_TYPE_WORKER) == 0 && | StartupPID == 0 && | WalReceiverPID == 0 && | BgWriterPID == 0 && | (CheckpointerPID == 0 ||(!FatalError && Shutdown < ImmediateShutdown)) && | WalWriterPID == 0 && | AutoVacPID == 0){ | //pg_ctl stop -m immediate不会向checkpoint进程发送信号,即不会做checkpoint | if (Shutdown >= ImmediateShutdown || FatalError){ | pmState = PM_WAIT_DEAD_END; | }else{ | if (CheckpointerPID != 0){ | signal_child(CheckpointerPID, SIGUSR2); | pmState = PM_SHUTDOWN; | } } | } |-------} 2、checkpoint进程,也会注册一个信号处理函数ReqShutdownHandler,用于处理主进程发送过来的SIGUSR2信号。接收到该信号后将shutdown_requested置为TRUE。在checkpoint进程的for循环中,如果shutdown_requested为TRUE,则进入shutdown流程:stop每个sender进程,所有sender进程stop后,根据条件进行checkpoint:CreateRestartPoint后者CreateCheckPoint CheckpointerMain(void)-> //为信号SIGUSR2安装信号处理函数ReqShutdownHandler pqsignal(SIGUSR2, ReqShutdownHandler); / request shutdown / ... for (;;){ if (shutdown_requested){ / Close down the database / ShutdownXLOG(0, 0); |-- WalSndInitStopping();//向每个sender进程发送信号修改到stopping状态 | WalSndWaitStopping(); | if (RecoveryInProgress()) | CreateRestartPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE); | else{ | if (XLogArchivingActive() && XLogArchiveCommandSet()) | RequestXLogSwitch(false); | CreateCheckPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE); | } |-- ... proc_exit(0); } ... checkpoint } 3、ReqShutdownHandler函数将shutdown_requested置为TRUE ReqShutdownHandler(SIGNAL_ARGS) { shutdown_requested = true; SetLatch(MyLatch); } (责任编辑:IT) |