设为首页 收藏本站
查看: 1289|回复: 0

[经验分享] 对PostgreSQL 后台进程名称的再认知

[复制链接]

尚未签到

发表于 2016-11-21 10:38:52 | 显示全部楼层 |阅读模式
  看 Postmaster 中如下的代码



/* StartChildProcess -- start an auxiliary process for the postmaster                           
*                           
* xlop determines what kind of child will be started.    All child types                        
* initially go to AuxiliaryProcessMain, which will handle common setup.                           
*                           
* Return value of StartChildProcess is subprocess' PID, or 0 if failed                           
* to start subprocess.                           
*/                           
static pid_t                           
StartChildProcess(AuxProcType type)                           
{                           
pid_t    pid;                    
char    *av[10];                    
int    ac = 0;                    
char    typebuf[32];                    
/*                        
* Set up command-line arguments for subprocess                        
*/                        
av[ac++] = "postgres";                        
#ifdef EXEC_BACKEND                        
av[ac++] = "--forkboot";                    
av[ac++] = NULL;            /* filled in by postmaster_forkexec */        
#endif                        
snprintf(typebuf, sizeof(typebuf), "-x%d", type);                        
av[ac++] = typebuf;                        
av[ac] = NULL;                        
Assert(ac < lengthof(av));                        
#ifdef EXEC_BACKEND                        
pid = postmaster_forkexec(ac, av);                    
#else    /* !EXEC_BACKEND */                    
pid = fork_process();                    
if (pid == 0)        /* child */            
{                    
IsUnderPostmaster = true;                /* we are a postmaster subprocess now */
/* Close the postmaster's sockets */               
ClosePostmasterPorts(false);               
/* Lose the postmaster's on-exit routines and port connections */               
on_exit_reset();               
/* Release postmaster's working memory context */               
MemoryContextSwitchTo(TopMemoryContext);               
MemoryContextDelete(PostmasterContext);               
PostmasterContext = NULL;               
AuxiliaryProcessMain(ac, av);               
ExitPostmaster(0);               
}                    
#endif   /* EXEC_BACKEND */                        
……
/*                        
* in parent, successful fork                        
*/                        
return pid;                        
}
  AuxiliaryProcessMain 是各个子进程的入口点。
  那么为何 ps -ef | grep post 可以看到各个子进程的不同的名字呢:
  这和 AuxiliaryProcessMain的实现有关, 其代码在  bootstrap.c 中,下面缩略一下,只考虑我关心的代码:



/*                                    
*     AuxiliaryProcessMain                                
*                                    
*     The main entry point for auxiliary processes, such as the bgwriter,                                
*     walwriter, walreceiver, bootstrapper and the shared memory checker code.                                
*                                    
*     This code is here just because of historical reasons.                                
*/                                    
void                                    
AuxiliaryProcessMain(int argc, char *argv[])                                    
{                                    
……                                
/* If no -x argument, we are a CheckerProcess */                                
MyAuxProcType = CheckerProcess;                                
while ((flag = getopt(argc, argv, "B:c:d:D:Fr:x:-:")) != -1)                                
{                                
switch (flag)                           
{                           
……                        
case 'x':                        
MyAuxProcType = atoi(optarg);                    
break;                    
……                        
}                           
}                                
……                                
/*                                
* Identify myself via ps                                
*/                                
if (IsUnderPostmaster)                                
{                                
const char *statmsg;                           
switch (MyAuxProcType)                           
{                           
case StartupProcess:                        
statmsg = "startup process";                    
break;                    
case BgWriterProcess:                        
statmsg = "writer process";                    
break;                    
case CheckpointerProcess:                        
statmsg = "checkpointer process";                    
break;                    
case WalWriterProcess:                        
statmsg = "wal writer process";                    
break;                    
case WalReceiverProcess:                        
statmsg = "wal receiver process";                    
break;                    
default:                        
statmsg = "??? process";                    
break;                    
}                           
init_ps_display(statmsg, "", "", "");                           
}                                
……                                
/*                                
* XLOG operations                                
*/                                
SetProcessingMode(NormalProcessing);                                
switch (MyAuxProcType)                                
{                                
case CheckerProcess:                           
/* don't set signals, they're useless here */                        
CheckerModeMain();                        
proc_exit(1);        /* should never return */               
case BootstrapProcess:                           
bootstrap_signals();                        
BootStrapXLOG();                        
BootstrapModeMain();                        
proc_exit(1);        /* should never return */               
case StartupProcess:                           
/* don't set signals, startup process has its own agenda */                        
StartupProcessMain();                        
proc_exit(1);        /* should never return */               
case BgWriterProcess:                           
/* don't set signals, bgwriter has its own agenda */                        
BackgroundWriterMain();                        
proc_exit(1);        /* should never return */               
case CheckpointerProcess:                           
/* don't set signals, checkpointer has its own agenda */                        
CheckpointerMain();                        
proc_exit(1);        /* should never return */               
case WalWriterProcess:                           
/* don't set signals, walwriter has its own agenda */                        
InitXLOGAccess();                        
WalWriterMain();                        
proc_exit(1);        /* should never return */               
case WalReceiverProcess:                           
/* don't set signals, walreceiver has its own agenda */                        
WalReceiverMain();                        
proc_exit(1);        /* should never return */               
default:                           
elog(PANIC, "unrecognized process type: %d", (int) MyAuxProcType);                        
proc_exit(1);                        
}                                
}                                    
  可以看到,会根据调用的时候,所传递的flag,来设定各子进程的 显示名称:
  主要是这一段:
  switch (MyAuxProcType)
{
  case StartupProcess:
    statmsg = "startup process";
    break;
  case BgWriterProcess:
    statmsg = "writer process";
    break;
  case CheckpointerProcess:
    statmsg = "checkpointer process";
    break;
  case WalWriterProcess:
    statmsg = "wal writer process";
    break;
  case WalReceiverProcess:
    statmsg = "wal receiver process";
    break;
  default:
    statmsg = "??? process";
    break;
}  
init_ps_display(statmsg, "", "", "");
  其中 ,init_ps_display 起到了关键的作用。但是具体在合适才导致 ps 时可以看到各个不同的名称,还有待进一步的观察。
  可以先作一个实验来看:
  在bootstrap 的 init_ps_dispalya(statmsg,"","",""); 完毕后,加一句:
  //added by gaojian , sleep 3 minutes
   fprintf(stderr,"sleeping...\n");
   sleep(180);
  让它停顿三秒种,此时用ps 命令看, 然后,三秒过后,再用ps 命令看,看到的结果如下:
  启动 Postgres ,看到 sleeeping...信息后,立即执行如下命令:
  [iyunv@localhost ~]# ps -ef|grep post
root      2928  2906  0 13:42 pts/1    00:00:00 grep post
[iyunv@localhost ~]# ps -ef|grep post
root      2953  2932  0 13:42 pts/2    00:00:00 su - postgres
postgres  2954  2953  0 13:42 pts/2    00:00:00 -bash
postgres  2989  2954  0 13:42 pts/2    00:00:00 /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
postgres  2990  2989  0 13:42 pts/2    00:00:00 postgres: startup process                             
root      2992  2906  0 13:42 pts/1    00:00:00 grep post
  可以看到有一个叫 postgres: startup process 的子进程出现。后面这个进程不见了。这是很有趣的。
  然后等过了几秒钟,再用ps 命令来看:
  [iyunv@localhost ~]# ps -ef|grep post
root      2953  2932  0 13:42 pts/2    00:00:00 su - postgres
postgres  2954  2953  0 13:42 pts/2    00:00:00 -bash
postgres  2989  2954  0 13:42 pts/2    00:00:00 /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
postgres  3000  2989  0 13:45 ?        00:00:00 postgres: checkpointer process                        
postgres  3001  2989  0 13:45 ?        00:00:00 postgres: writer process                              
postgres  3002  2989  0 13:45 ?        00:00:00 postgres: wal writer process                          
postgres  3003  2989  0 13:45 ?        00:00:00 postgres: autovacuum launcher process                 
postgres  3004  2989  0 13:45 ?        00:00:00 postgres: stats collector process                     
root      3018  2906  0 13:53 pts/1    00:00:00 grep post
  --------------------------------------------------------------------------------------------------
  对此暂时先放一放。我想,更重要的是如下这样的代码:
  switch (MyAuxProcType)
{
  ......
  case BgWriterProcess:
  /* don't set signals, bgwriter has its own agenda */
  BackgroundWriterMain();
  proc_exit(1);
      ......
} 
  可以打个比方: 一个父亲有几个儿子,有一天他问几个儿子,你们长大想做什么呢?
  老大说,我想当将军,保家卫国。老二说,我想当医生,救死扶伤。 老三说,我想当教师,桃李满天下。
  于是父亲说,好啊,他给每个儿子作了一定帽子,写着 将军、医生、教师。在人们的嘲笑声中,三个儿子一个去了部队,一个去了医学院,一个去了师范学院。走上了各自不同的道路,后来真的成就了各自的梦想。
  这就是不同的子进程拥有不同的名称的类比了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-303366-1-1.html 上篇帖子: PostgreSQL远程连接配置 下篇帖子: Postgresql允许远程访问配置修改
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表