PostgreSQL pg_ctl start超时分析

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: 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

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
关系型数据库 物联网 PostgreSQL
沉浸式学习PostgreSQL|PolarDB 11: 物联网(IoT)、监控系统、应用日志、用户行为记录等场景 - 时序数据高吞吐存取分析
物联网场景, 通常有大量的传感器(例如水质监控、气象监测、新能源汽车上的大量传感器)不断探测最新数据并上报到数据库. 监控系统, 通常也会有采集程序不断的读取被监控指标(例如CPU、网络数据包转发、磁盘的IOPS和BW占用情况、内存的使用率等等), 同时将监控数据上报到数据库. 应用日志、用户行为日志, 也就有同样的特征, 不断产生并上报到数据库. 以上数据具有时序特征, 对数据库的关键能力要求如下: 数据高速写入 高速按时间区间读取和分析, 目的是发现异常, 分析规律. 尽量节省存储空间
764 1
|
2月前
|
Oracle NoSQL 关系型数据库
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
426 2
|
关系型数据库 定位技术 分布式数据库
沉浸式学习PostgreSQL|PolarDB 18: 通过GIS轨迹相似伴随|时态分析|轨迹驻点识别等技术对拐卖、诱骗场景进行侦查
本文主要教大家怎么用好数据库, 而不是怎么运维管理数据库、怎么开发数据库内核.
1310 1
|
6月前
|
存储 关系型数据库 MySQL
TiDB与MySQL、PostgreSQL等数据库的比较分析
【2月更文挑战第25天】本文将对TiDB、MySQL和PostgreSQL等数据库进行详细的比较分析,探讨它们各自的优势和劣势。TiDB作为一款分布式关系型数据库,在扩展性、并发性能等方面表现突出;MySQL以其易用性和成熟性受到广泛应用;PostgreSQL则在数据完整性、扩展性等方面具有优势。通过对比这些数据库的特点和适用场景,帮助企业更好地选择适合自己业务需求的数据库系统。
1105 4
|
6月前
|
SQL 关系型数据库 MySQL
PostgreSQL【异常 01】java.io.IOException:Tried to send an out-of-range integer as a 2-byte value 分析+解决
PostgreSQL【异常 01】java.io.IOException:Tried to send an out-of-range integer as a 2-byte value 分析+解决
444 1
|
SQL 关系型数据库 MySQL
《PostgreSQL与MySQL:详细对比与分析》
《PostgreSQL与MySQL:详细对比与分析》
589 0
|
SQL 监控 关系型数据库
Navicat 面向 PostgreSQL 查询超时的工具解决方案
Navicat 面向 PostgreSQL 查询超时的工具解决方案
189 0
|
存储 关系型数据库 PostgreSQL
Postgresql内核源码分析-heapam分析
Postgresql内核源码分析-heapam分析
184 1
|
SQL 存储 自然语言处理
玩转阿里云PostgreSQL,通过pg_jieba对豆瓣影评进行热评分析
在当今社交媒体的时代,人们通过各种平台分享自己的生活、观点和情感。然而,对于平台管理员和品牌经营者来说,了解用户的情感和意见变得至关重要。为了帮助他们更好地了解用户的情感倾向,我们可以使用PostgreSQL中的pg_jieba插件对这些发帖进行分词和情感分析,来构建一个社交媒体情感分析系统,系统将根据用户的发帖内容,自动判断其情感倾向是积极、消极还是中性,并将结果存储在数据库中。 本文通过针对kaggle数据集中的豆瓣影评的中文评论数据,通过阿里云的PostgreSQL中的pg_jieba插件进行分词(可自定义多个词典,并且切换自定义词典进行分词),基于分词的结果进行统计分析。
|
关系型数据库 分布式数据库 PolarDB
沉浸式学习PostgreSQL|PolarDB 15: 企业ERP软件、网站、分析型业务场景、营销场景人群圈选, 任意字段组合条件数据筛选
本篇文章目标学习如何快速在任意字段组合条件输入搜索到满足条件的数据.
611 0