Slony-I中对storelisten出错的处理
客户质询的现象是:
Slony-I运行中,log中发现FATAL信息:
- FATAL storeListen: unknown node ID
出现了上述错误后,再看后继的log,又恢复正常运行了。
客户的问题在于:如何看待这个错误信息,它是否是设计上就是这样的?
言外之意,这到底是否是一个bug?
设计上是否是这样,是无从知晓的,只有问Vendor。而我的想法是,先分析源代码看看:
- /* ----------
- * SlonWatchdog
- * ----------
- */
- static void
- SlonWatchdog(void)
- {
- …
- slon_log(SLON_INFO, "slon: watchdog process started\n");
- slon_log(SLON_CONFIG, "slon: watchdog ready - pid = %d\n", slon_watchdog_pid);
- slon_worker_pid = fork();
- if (slon_worker_pid == )
- {
- SlonMain();
- exit(-);
- }
- …
- if (install_signal_handler(SIGUSR1,sighandler) == SIG_ERR)
- {
- slon_log(SLON_FATAL, "slon: SIGUSR1 signal handler setup failed -(%d) %s\n", errno, strerror(errno));
- slon_exit(-);
- }
- …
- slon_log(SLON_CONFIG, "slon: worker process created - pid = %d\n",
- slon_worker_pid);
- while(!shutdown)
- {
- while ((pid = wait(&child_status)) != slon_worker_pid)
- {
- …
- }
- …
- slon_log(SLON_CONFIG, "slon: child terminated %s: %d; pid: %d, current worker pid: %d\n",
- termination_reason,return_code, pid, slon_worker_pid);
- switch (watchdog_status)
- {
- …
- case SLON_WATCHDOG_NORMAL:
- case SLON_WATCHDOG_RETRY:
- watchdog_status = SLON_WATCHDOG_RETRY;
- if (child_status != )
- {
- slon_log(SLON_CONFIG, "slon: restart of worker in 10 seconds\n");
- (void)sleep();
- }
- else
- {
- slon_log(SLON_CONFIG, "slon: restart of worker\n");
- }
- if (watchdog_status == SLON_WATCHDOG_RETRY)
- {
- slon_worker_pid=fork();
- if(slon_worker_pid == )
- {
- worker_restarted=;
- SlonMain();
- exit(-);
- }
- …
- watchdog_status=SLON_WATCHDOG_NORMAL;
- continue;
- }
- break;
- default:
- shutdown=;
- break;
- } /*switch*/
- }/*while*/
- …
- }
- /* ----------
- * SlonMain
- * ----------
- */
- static void
- SlonMain(void)
- {
- …
- for (i = , n = PQntuples(res); i < n; i++)
- {
- …
- rtcfg_storePath(pa_server, pa_conninfo, pa_connretry);
- }
- PQclear(res);
- …
- }
- /* ----------
- * rtcfg_storePath
- * ----------
- */
- void
- rtcfg_storePath(int pa_server, char *pa_conninfo, int pa_connretry)
- {
- …
- /*
- * Store the (new) conninfo to the node
- */
- 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);- …
- /*
- * Eventually start communicating with that node
- */
- rtcfg_startStopNodeThread(node);
- }
- /* ----------
- * rtcfg_startStopNodeThread
- * ----------
- */
- static void
- rtcfg_startStopNodeThread(SlonNode * node)
- {
- …
- if (sched_get_status() == SCHED_STATUS_OK && node->no_active)
- {
- /*
- * Make sure the node worker exists
- */
- switch (node->worker_status)
- {
- case SLON_TSTAT_NONE:
- if (pthread_create(&(node->worker_thread), NULL, remoteWorkerThread_main, (void *)node) < )
- {
- …
- }
- node->worker_status = SLON_TSTAT_RUNNING;
- break;
- …
- }
- }
- …
- }
- /* ----------
- * slon_remoteWorkerThread
- *
- * Listen for events on the local database connection. This means, events
- * generated by the local node only.
- * ----------
- */
- void *
- remoteWorkerThread_main(void *cdata)
- {
- …
- while (true)
- {
- …
- else /* not SYNC */
- {
- …
- else if (strcmp(event->ev_type, "STORE_LISTEN") == )
- {
- …
- if (li_receiver == rtcfg_nodeid)
- rtcfg_storeListen(li_origin, li_provider);
- …
- }
- …
- }
- …
- }
- …
- }
- /* ----------
- * rtcfg_storeListen
- * ----------
- */
- void
- rtcfg_storeListen(int li_origin, int li_provider)
- {
- …
- node = rtcfg_findNode(li_provider);
- if (!node)
- {
- slon_log(SLON_FATAL,"storeListen: unknown node ID %d\n", li_provider);
- slon_retry();
- return;
- }
- …
- }
- #define slon_retry() \
- do { \
- pthread_mutex_lock(&slon_watchdog_lock); \
- if (slon_watchdog_pid >= ) { \
- slon_log(SLON_DEBUG2, "slon_retry() from pid=%d\n", slon_pid); \
- (void) kill(slon_watchdog_pid, SIGUSR1); \
- slon_watchdog_pid = -; \
- } \
- pthread_mutex_unlock(&slon_watchdog_lock); \
- pthread_exit(NULL); \
- } while ()
- /* ----------
- * sighandler
- * ----------
- */
- static void
- sighandler(int signo)
- {
- switch (signo)
- {
- …
- case SIGUSR1:
- watchdog_status = SLON_WATCHDOG_RETRY;
- slon_terminate_worker();
- break;
- …
- }
- }
- /* ----------
- * slon_terminate_worker
- * ----------
- */
- void
- slon_terminate_worker()
- {
- (void) kill(slon_worker_pid, SIGKILL);
- }
上述是对代码的简略整理。
在其中:
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出错的处理的更多相关文章
- Ubuntu虚机中SVN连接出错,虚机本机可正常CO,CIN,解决方法
Ubuntu虚机中SVN连接出错,虚机本机可正常CO,CIN,外面机器无法正常连接. 解决: 虚机换个IP即可正常连接,原因不明,有可能为公司网管对该IP做了某些限制. PS:VMware中只需将网络 ...
- 向Oracle数据库中插入数据出错:ORA-01036 无效的变量名或数据
向Oracle数据库中插入数据出错: 经过排查,因为Update数据时没有出错,所以OracleHelper没有问题: 看异常信息提示:无效的变量和数据,应该是SQL语句的问题,调试时所传的实例Use ...
- VS的ASP.NET项目中cshtml关键词出错 红线,当前上下文中不存在名称
[参考]VS的ASP.NET项目中cshtml突然出错,当前上下文中不存在名称“ViewBag” 原因:web.config 配置错误 这种情况是因为两个web.config文件版本不匹配,需要进行修 ...
- NFine中权限判断出错的问题
NFine中权限判断出错的问题 问题描述:登录后点击栏目一,弹出了窗口一,再点击栏目二,弹出了窗口二,然后再点击窗口一,再执行窗口一中的操作时,发现已没有任何权限,调试后发现在HandlerAutho ...
- 【动手学深度学习】Jupyter notebook中 import mxnet出错
问题描述 打开d2l-zh目录,使用jupyter notebook打开文件运行,import mxnet 出现无法导入mxnet模块的问题, 但是命令行运行是可以导入mxnet模块的. 原因: 激活 ...
- (转)WCF中调用WebService出错,大家帮忙看看,回答就有分
http://bbs.csdn.net/topics/390542345 在WCF项目里面添加了一个WebService引用,然后在我们调用这个WCF服务时,老出错,提示在 ServiceModel ...
- delphi中 dataset容易出错的地方
最近写delphi项目,用到的数据集中的dataset,一直修改exception啊,写下过程. 在对数据集进行任何操作之前,首先要打开数据集.要打开数据集,可以把Active属性设为True,例如: ...
- 解决Pycharm中matplotlib画图出错问题(AttributeError: module 'matplotlib' has no attribute 'verbose')
最近在Linux中使用pycharm过程中使用matplotlib无法画图,总是提示错误 /usr/bin/python3. /home/leo/PycharmProjects/untitled1/E ...
- 发现Mathematica中求逆出错
发现Mathematica中应用Inverse求逆时出错.
随机推荐
- 如何在MySql中记录SQL日志
SQL server有一个sql profiler可以实时跟踪服务器执行的SQL语句,这在很多时候调试错误非常有用.例如:别人写的复杂代码.生产系统.无调试环境.无原代码... ... 查了一下资 ...
- Android圆形图片--ImageView
[ RoundImageView.java ] package com.dxd.roundimageview; import android.content.Context; import andro ...
- Http中Cookie和Session介绍
先介绍下B/S系统的工作的完整过程.首先客户端的浏览器发出请求,服务端的webserver接受到请求后,调用相关请求的页面进行处理,处理完后将结果发送给客户端的浏览器进行显示.只能是浏览器向webse ...
- Jersey搭建Restful服务器 on Ubuntu
自己试着在Ubuntu上搭建一个 1.首先安装eclipse和tomcat sudo apt-get install eclipse tomcat7 -y 2.把tomcat的group assign ...
- LR录制脚本IE不能打开解决方法
运行环境:win7 64位 解决方法:1.卸载IE11 2.计算机——属性——高级系统设置——性能里的设置——数据执行保护——选择“为除下列选定程序之外的所有程序和服务启用”——添加IE浏览器和VUG ...
- 自动抓取java堆栈
参数1 进程名字,参数2 最大线程数 例: pid为8888,达到1000个线程时自动抓取堆栈信息 ./autojstack.sh 8888 1000 & #!/bin/bashfileNam ...
- Java中的路径问题
Java中的路径问题 代码说明,如下: package com.merlin.test; import java.io.InputStream; public class Test { public ...
- Mac OS10.9 下python开发环境(eclipse)以及自然语言包NLTK的安装与注意
折腾了大半天,终于把mbp上python自然语言开发环境搭建好了. 第一步,安装JDK1.7 for mac MacOS10.9是自带python2.7.5的,够用,具体的可以打开终端输入python ...
- To follow the path
look to the master, follow the master, walk with the master, see through the master, bec ...
- C使用FILE指针文件操作
文件的基本概念 所谓“文件”是指一组相关数据的有序集合. 这个数据集有一个名称,叫做文件名.实际上在前面的各章中我们已经多次使用了文件,例如源程序文件.目标文件.可执行文件.库文件 (头文件)等.文件 ...