首页数据库PostgreSQL pg

PostgreSQL pg

时间2024-02-29 12:03:03发布访客分类数据库浏览634
导读:收集整理的这篇文章主要介绍了PostgreSQL pg_ctl start启动超时实例分析,觉得挺不错的,现在分享给大家,也给大家做个参考。 一、问题pg_ctl start启动时报错退...
收集整理的这篇文章主要介绍了PostgreSQL pg_ctl start启动超时实例分析,觉得挺不错的,现在分享给大家,也给大家做个参考。

一、问题

pg_ctl start启动时报错退出:pg_ctl:server did not start in time。超时时间是多少?从什么时候到哪个阶段算超时?

二、分析:该信息打印位置,从后面代码段do_start函数中可以看出

1、pg_ctl start调用start_postmaster启动PG的主进程后,每隔0.1ms检查一次postmaster.pid文件,是否已写入ready/standby

2、总共会检查600次,即从启动主进程后,最多等待60s,如果没有写入ready/standby则打印上述日志并退出

3、默认等待时间是60s,如果pg_ctl start -t指定等待时间,则等待时间为该指定时间

三、什么时候postmaster.pid文件写入ready/standby

1、如果是主机不管有没有设置hot standby

1)当startup进程恢复完成退出时,调用PRoc_exIT函数向主进程发送SIGCHLD信号并退出

2)主进程接收到信号后,signal处理函数reaPEr调用AddToDataDirLockFile向postmaster.pid文件写入ready

2、如果是备机即data目录下有recovery.cnf文件,且设置了hot standby,在实际恢复前没有到达一致性位置

1)startup进程向主进程发送PMSIGNAL_RECOVERY_STARTED信号,主进程调用信号处理函数sigusr1_handler,将pmstate=PM_RECOVERY

2)每次读取下一个xLOG前都会调用CheckRecoveryConsistency函数进行一致性检查:

2.1 进入一致性状态,starup进程向主进程发送PMSIGNAL_BEgin_HOT_STANDBY信号,主进程接收到信号后调用sigusr1_handler-> AddToDataDirLockFile向postmaster.pid文件写入ready

3、如果是备机即data目录下有recovery.cnf文件,且设置了hot standby,在实际恢复前没有到达一致性位置

1)startup进程向主进程发送PMSIGNAL_RECOVERY_STARTED信号,主进程调用信号处理函数sigusr1_handler,将pmState=PM_RECOVERY

2)每次读取下一个xlog前都会调用CheckRecoveryConsistency函数进行一致性检查。如果没有进入一致性状态

3)本地日志恢复完成,切换日志源时同样调用CheckRecoveryConsistency函数进行一致性检查

3.1 进入一致性状态,starup进程向主进程发送PMSIGNAL_BEGIN_HOT_STANDBY信号,主进程接收到信号后调用sigusr1_handler-> AddToDataDirLockFile向postmaster.pid文件写入ready

4、如果是备机即data目录下有recovery.cnf文件,且设置了hot standby,在实际恢复前到达一致性位置

1)startup进程向主进程发送PMSIGNAL_RECOVERY_STARTED信号,主进程调用信号处理函数sigusr1_handler,将pmState=PM_RECOVERY

2)CheckRecoveryConsistency函数进行一致性检查,向主进程发送PMSIGNAL_BEGIN_HOT_STANDBY信号,主进程接收到信号后调用sigusr1_handler-> AddToDataDirLockFile向postmaster.pid文件写入ready

5、如果是备机即data目录下有recovery.cnf文件,没有设置hot standby

1)startup进程向主进程发送PMSIGNAL_RECOVERY_STARTED信号

2)主进程接收到信号后,向postmaster.将pmState=PM_RECOVERY

四、代码分析

1、pg_ctl start流程

do_start->
     pm_pid = start_postmaster();
 if (do_wait){
      print_msg(_("waiting for server to start..."));
  switch (wait_for_postmaster(pm_pid, false)){
       case POSTMASTER_READY:    print_msg(_(" done\n"));
        print_msg(_("server started\n"));
        break;
       case POSTMASTER_STILL_STARTING:    print_msg(_(" stopped waiting\n"));
        write_stderr(_("%s: server did not start in time\n"), progname);
        exit(1);
        break;
       case POSTMASTER_FAILED:    print_msg(_(" stopped waiting\n"));
        write_stderr(_("%s: could not start server\n" "Examine the log output.\n"), progname);
        exit(1);
        break;
  }
 }
    else  print_msg(_("server starting\n"));
    
wait_for_postmaster->
     for (i = 0;
     i  wait_seconds * WAITS_PER_SEC;
 i++){
      if ((optlines = reaDFile(pid_file, &
    nuMLines)) != NULL &
    &
     numlines >
= LOCK_FILE_LINE_PM_STATUS){
       pmpid = atol(optlines[LOCK_FILE_LINE_PID - 1]);
       pmstart = atol(optlines[LOCK_FILE_LINE_START_TIME - 1]);
       if (pmstart >
    = start_time - 2 &
    &
 pmpid == pm_pid){
        char  *pmstatus = optlines[LOCK_FILE_LINE_PM_STATUS - 1];
    if (strcmp(pmstatus, PM_STATUS_READY) == 0 || strcmp(pmstatus, PM_STATUS_STANDBY) == 0){
         /* postmaster is done starting up */     free_readfile(optlines);
         return POSTMASTER_READY;
    }
   }
  }
      free_readfile(optlines);
      if (waitpid((pid_t) pm_pid, &
    exitstatus, WNOHANG) == (pid_t) pm_pid)   return POSTMASTER_FAILED;
      pg_usleep(USEC_PER_SEC / WAITS_PER_SEC);
 }
     /* out of patience;
     report that postmaster is still starting up */ return POSTMASTER_STILL_STARTING;
    

2、server主进程及信号处理函数

PostmasterMain->
     pqsignal_no_restart(SIGUSR1, sigusr1_handler);
     /* message From child process */ pqsignal_no_restart(SIGCHLD, reaper);
     /* handle child termination */ ... StartupXLOG();
     ... proc_exit(0);
    //exit函数向主进程发送SIGCHLD信号
reaper->
    //进程终止或者停止的信号 AddToDataDirLockFile(LOCK_FILE_LINE_PM_STATUS, PM_STATUS_READY);
    
postmaster进程接收信号:sigusr1_handler->
     if (CheckPostmasterSignal(PMSIGNAL_RECOVERY_STARTED) &
    &
      pmState == PM_STARTUP &
    &
 Shutdown == NoShutdown){
      CheckpointerPID = StartCheckpointer();
      BgWriterPID = StartBackgroundWriter();
      if (XLogArchivingAlways())   PgArchPID = pgarch_start();
  //hot_standby在PostgreSQL.conf文件中配置TRUE  //表示在恢复的时候允许连接  if (!EnableHotStandby){
       //将standby写入postmaster.pid文件,表示up但不允许连接   AddToDataDirLockFile(LOCK_FILE_LINE_PM_STATUS, PM_STATUS_STANDBY);
  }
      pmState = PM_RECOVERY;
 }
     if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) &
    &
      pmState == PM_RECOVERY &
    &
 Shutdown == NoShutdown){
      PgStatPID = pgstat_start();
      //将ready写入postmaster.pid文件,允许连接  AddToDataDirLockFile(LOCK_FILE_LINE_PM_STATUS, PM_STATUS_READY);
      pmState = PM_HOT_STANDBY;
 }
     ...

3、Startup进程

StartupXLOG->
     ReadCheckpointRecord if (ArchiveRecoveryRequested &
    &
 IsUnderPostmaster){
    //有recovery.conf文件则ArchiveRecoveryRequested为TRUE  //有recovery.conf文件则ArchiveRecoveryRequested为TRUE  PublishStartupProcessInformation();
      SetForwardFsyncRequests();
      //向master进程发送PMSIGNAL_RECOVERY_STARTED信号  SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
      bgwriterLaunched = true;
 }
     CheckRecoveryConsistency();
    -->
    ... |-- if (standbyState == STANDBY_SNAPSHOT_READY &
    &
     !LocalHotStandbyActive &
    &
     |  reachedConsistency &
    &
 IsUnderPostmaster){
     |  SpinLockAcquire(&
    XLogCtl->
    info_lck);
     |  XLogCtl->
    SharedHotStandbyActive = true;
     |  SpinLockRelease(&
    XLogCtl->
    info_lck);
     |  LocalHotStandbyActive = true;
     |  SendPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY);
 |-- }
     ... 回放一个record后,每次读取下一个record前都会调用CheckRecoveryConsistency

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。

您可能感兴趣的文章:
  • 解决postgreSql远程连接数据库超时的问题
  • postgresql 性能参数配置方式
  • postgresql SQL语句变量的使用说明
  • postgresql 实现查询出的数据为空,则设为0的操作
  • postgresql 补齐空值、自定义查询字段并赋值操作
  • 解决PostgreSQL 执行超时的情况

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: PostgreSQL pg
本文地址: https://pptw.com/jishu/632840.html
PostgreSQL实现一个通用标签系统 PostgreSQL实现批量插入、更新与合并操作的方法

游客 回复需填写必要信息