客户质询的现象是:

Slony-I运行中,log中发现FATAL信息:

  1. FATAL storeListen: unknown node ID

出现了上述错误后,再看后继的log,又恢复正常运行了。

客户的问题在于:如何看待这个错误信息,它是否是设计上就是这样的?

言外之意,这到底是否是一个bug?

设计上是否是这样,是无从知晓的,只有问Vendor。而我的想法是,先分析源代码看看:

  1. /* ----------
  2. * SlonWatchdog
  3. * ----------
  4. */
  5. static void
  6. SlonWatchdog(void)
  7. {

  8. slon_log(SLON_INFO, "slon: watchdog process started\n");
  9. slon_log(SLON_CONFIG, "slon: watchdog ready - pid = %d\n", slon_watchdog_pid);
  10. slon_worker_pid = fork();
  11. if (slon_worker_pid == )
  12. {
  13. SlonMain();
  14. exit(-);
  15. }

  16. if (install_signal_handler(SIGUSR1,sighandler) == SIG_ERR)
  17. {
  18. slon_log(SLON_FATAL, "slon: SIGUSR1 signal handler setup failed -(%d) %s\n", errno, strerror(errno));
  19. slon_exit(-);
  20. }

  21. slon_log(SLON_CONFIG, "slon: worker process created - pid = %d\n",
  22. slon_worker_pid);
  23. while(!shutdown)
  24. {
  25. while ((pid = wait(&child_status)) != slon_worker_pid)
  26. {

  27. }

  28. slon_log(SLON_CONFIG, "slon: child terminated %s: %d; pid: %d, current worker pid: %d\n",
  29. termination_reason,return_code, pid, slon_worker_pid);
  30. switch (watchdog_status)
  31. {

  32. case SLON_WATCHDOG_NORMAL:
  33. case SLON_WATCHDOG_RETRY:
  34. watchdog_status = SLON_WATCHDOG_RETRY;
  35. if (child_status != )
  36. {
  37. slon_log(SLON_CONFIG, "slon: restart of worker in 10 seconds\n");
  38. (void)sleep();
  39. }
  40. else
  41. {
  42. slon_log(SLON_CONFIG, "slon: restart of worker\n");
  43. }
  44. if (watchdog_status == SLON_WATCHDOG_RETRY)
  45. {
  46. slon_worker_pid=fork();
  47. if(slon_worker_pid == )
  48. {
  49. worker_restarted=;
  50. SlonMain();
  51. exit(-);
  52. }

  53. watchdog_status=SLON_WATCHDOG_NORMAL;
  54. continue;
  55. }
  56. break;
  57. default:
  58. shutdown=;
  59. break;
  60. } /*switch*/
  61. }/*while*/

  62. }
  63. /* ----------
  64. * SlonMain
  65. * ----------
  66. */
  67. static void
  68. SlonMain(void)
  69. {

  70. for (i = , n = PQntuples(res); i < n; i++)
  71. {

  72. rtcfg_storePath(pa_server, pa_conninfo, pa_connretry);
  73. }
  74. PQclear(res);

  75. }
  76. /* ----------
  77. * rtcfg_storePath
  78. * ----------
  79. */
  80. void
  81. rtcfg_storePath(int pa_server, char *pa_conninfo, int pa_connretry)
  82. {

  83. /*
  84. * Store the (new) conninfo to the node
  85. */
  86. slon_log(SLON_CONFIG, "storePath: pa_server=%d pa_client=%d pa_conninfo=\"%s\" pa_connretry=%d\n",
    pa_server, rtcfg_nodeid, pa_conninfo, pa_connretry);

  87. /*
  88. * Eventually start communicating with that node
  89. */
  90. rtcfg_startStopNodeThread(node);
  91. }
  92. /* ----------
  93. * rtcfg_startStopNodeThread
  94. * ----------
  95. */
  96. static void
  97. rtcfg_startStopNodeThread(SlonNode * node)
  98. {

  99. if (sched_get_status() == SCHED_STATUS_OK && node->no_active)
  100. {
  101. /*
  102. * Make sure the node worker exists
  103. */
  104. switch (node->worker_status)
  105. {
  106. case SLON_TSTAT_NONE:
  107. if (pthread_create(&(node->worker_thread), NULL, remoteWorkerThread_main, (void *)node) < )
  108. {

  109. }
  110. node->worker_status = SLON_TSTAT_RUNNING;
  111. break;

  112. }
  113. }

  114. }
  115. /* ----------
  116. * slon_remoteWorkerThread
  117. *
  118. * Listen for events on the local database connection. This means, events
  119. * generated by the local node only.
  120. * ----------
  121. */
  122. void *
  123. remoteWorkerThread_main(void *cdata)
  124. {

  125. while (true)
  126. {

  127. else /* not SYNC */
  128. {

  129. else if (strcmp(event->ev_type, "STORE_LISTEN") == )
  130. {

  131. if (li_receiver == rtcfg_nodeid)
  132. rtcfg_storeListen(li_origin, li_provider);

  133. }

  134. }

  135. }

  136. }
  137. /* ----------
  138. * rtcfg_storeListen
  139. * ----------
  140. */
  141. void
  142. rtcfg_storeListen(int li_origin, int li_provider)
  143. {

  144. node = rtcfg_findNode(li_provider);
  145. if (!node)
  146. {
  147. slon_log(SLON_FATAL,"storeListen: unknown node ID %d\n", li_provider);
  148. slon_retry();
  149. return;
  150. }

  151. }
  152. #define slon_retry() \
  153. do { \
  154. pthread_mutex_lock(&slon_watchdog_lock); \
  155. if (slon_watchdog_pid >= ) { \
  156. slon_log(SLON_DEBUG2, "slon_retry() from pid=%d\n", slon_pid); \
  157. (void) kill(slon_watchdog_pid, SIGUSR1); \
  158. slon_watchdog_pid = -; \
  159. } \
  160. pthread_mutex_unlock(&slon_watchdog_lock); \
  161. pthread_exit(NULL); \
  162. } while ()
  163.  
  164. /* ----------
  165. * sighandler
  166. * ----------
  167. */
  168. static void
  169. sighandler(int signo)
  170. {
  171. switch (signo)
  172. {

  173. case SIGUSR1:
  174. watchdog_status = SLON_WATCHDOG_RETRY;
  175. slon_terminate_worker();
  176. break;

  177. }
  178. }
  179. /* ----------
  180. * slon_terminate_worker
  181. * ----------
  182. */
  183. void
  184. slon_terminate_worker()
  185. {
  186. (void) kill(slon_worker_pid, SIGKILL);
  187. }

上述是对代码的简略整理。

在其中:

  SlonWatchdog函数中,通过fork生成子进程。

 此子进程的SlonMain函数里、通过rtcfg_storePath --> rtcfg_storePath -->rtcfg_startStopNodeThread的调用关系,

 作了一个线程,该线程启动是,调用 remoteWorkerThread_main 函数。

remoteWorkerThread_main函数里,调用rtcfg_storeListen函数的时候,

如果获得 Node情报的时候,发生了错误,就会导致向SlonWatchdog运行时的主进程发送SIGUSR信号。

另一方面:

 主进程的SlonWatchdog函数中,早已经准备了对应SIGUSR信号的函数sighandler。

 在此sighandler函数中,SIGUSR信号发生时,会把上述的子进程kill掉。

 而且,此主进程中通过wait调用,准备好了当上述子进程一旦被kill掉或者自己死掉时的代码逻辑:

通过while循环,再次采用fork操作,调用fork后子进程的SlonMain函数,一切又周而复始了:

     如果SlonMain函数调用rtcfg_storeListen失败,就再次发生死亡,回到主进程再次fork;

如果成功,就跳出循环,进入下一步的处理。

Slony-I中对storelisten出错的处理的更多相关文章

  1. Ubuntu虚机中SVN连接出错,虚机本机可正常CO,CIN,解决方法

    Ubuntu虚机中SVN连接出错,虚机本机可正常CO,CIN,外面机器无法正常连接. 解决: 虚机换个IP即可正常连接,原因不明,有可能为公司网管对该IP做了某些限制. PS:VMware中只需将网络 ...

  2. 向Oracle数据库中插入数据出错:ORA-01036 无效的变量名或数据

    向Oracle数据库中插入数据出错: 经过排查,因为Update数据时没有出错,所以OracleHelper没有问题: 看异常信息提示:无效的变量和数据,应该是SQL语句的问题,调试时所传的实例Use ...

  3. VS的ASP.NET项目中cshtml关键词出错 红线,当前上下文中不存在名称

    [参考]VS的ASP.NET项目中cshtml突然出错,当前上下文中不存在名称“ViewBag” 原因:web.config 配置错误 这种情况是因为两个web.config文件版本不匹配,需要进行修 ...

  4. NFine中权限判断出错的问题

    NFine中权限判断出错的问题 问题描述:登录后点击栏目一,弹出了窗口一,再点击栏目二,弹出了窗口二,然后再点击窗口一,再执行窗口一中的操作时,发现已没有任何权限,调试后发现在HandlerAutho ...

  5. 【动手学深度学习】Jupyter notebook中 import mxnet出错

    问题描述 打开d2l-zh目录,使用jupyter notebook打开文件运行,import mxnet 出现无法导入mxnet模块的问题, 但是命令行运行是可以导入mxnet模块的. 原因: 激活 ...

  6. (转)WCF中调用WebService出错,大家帮忙看看,回答就有分

    http://bbs.csdn.net/topics/390542345 在WCF项目里面添加了一个WebService引用,然后在我们调用这个WCF服务时,老出错,提示在 ServiceModel  ...

  7. delphi中 dataset容易出错的地方

    最近写delphi项目,用到的数据集中的dataset,一直修改exception啊,写下过程. 在对数据集进行任何操作之前,首先要打开数据集.要打开数据集,可以把Active属性设为True,例如: ...

  8. 解决Pycharm中matplotlib画图出错问题(AttributeError: module 'matplotlib' has no attribute 'verbose')

    最近在Linux中使用pycharm过程中使用matplotlib无法画图,总是提示错误 /usr/bin/python3. /home/leo/PycharmProjects/untitled1/E ...

  9. 发现Mathematica中求逆出错

    发现Mathematica中应用Inverse求逆时出错.

随机推荐

  1. 如何在MySql中记录SQL日志

    SQL server有一个sql profiler可以实时跟踪服务器执行的SQL语句,这在很多时候调试错误非常有用.例如:别人写的复杂代码.生产系统.无调试环境.无原代码... ...   查了一下资 ...

  2. Android圆形图片--ImageView

    [ RoundImageView.java ] package com.dxd.roundimageview; import android.content.Context; import andro ...

  3. Http中Cookie和Session介绍

    先介绍下B/S系统的工作的完整过程.首先客户端的浏览器发出请求,服务端的webserver接受到请求后,调用相关请求的页面进行处理,处理完后将结果发送给客户端的浏览器进行显示.只能是浏览器向webse ...

  4. Jersey搭建Restful服务器 on Ubuntu

    自己试着在Ubuntu上搭建一个 1.首先安装eclipse和tomcat sudo apt-get install eclipse tomcat7 -y 2.把tomcat的group assign ...

  5. LR录制脚本IE不能打开解决方法

    运行环境:win7 64位 解决方法:1.卸载IE11 2.计算机——属性——高级系统设置——性能里的设置——数据执行保护——选择“为除下列选定程序之外的所有程序和服务启用”——添加IE浏览器和VUG ...

  6. 自动抓取java堆栈

    参数1 进程名字,参数2 最大线程数 例: pid为8888,达到1000个线程时自动抓取堆栈信息 ./autojstack.sh 8888 1000 & #!/bin/bashfileNam ...

  7. Java中的路径问题

    Java中的路径问题 代码说明,如下: package com.merlin.test; import java.io.InputStream; public class Test { public ...

  8. Mac OS10.9 下python开发环境(eclipse)以及自然语言包NLTK的安装与注意

    折腾了大半天,终于把mbp上python自然语言开发环境搭建好了. 第一步,安装JDK1.7 for mac MacOS10.9是自带python2.7.5的,够用,具体的可以打开终端输入python ...

  9. To follow the path

    look to the master,    follow the master,    walk with the master,    see through the master,    bec ...

  10. C使用FILE指针文件操作

    文件的基本概念 所谓“文件”是指一组相关数据的有序集合. 这个数据集有一个名称,叫做文件名.实际上在前面的各章中我们已经多次使用了文件,例如源程序文件.目标文件.可执行文件.库文件 (头文件)等.文件 ...