Slony-I中对storelisten出错的处理

简介:

客户质询的现象是:

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

FATAL  storeListen: unknown node ID 3

出现了上述错误后,再看后继的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 == 0)
   {
       SlonMain();
       exit(-1);
   }
   …
   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(-1);
   }
   …
   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 != 0)
            {
                slon_log(SLON_CONFIG, "slon: restart of worker in 10 seconds\n");
                (void)sleep(10);
            }
            else
            {
                slon_log(SLON_CONFIG, "slon: restart of worker\n");
            }
if (watchdog_status == SLON_WATCHDOG_RETRY) { slon_worker_pid=fork(); if(slon_worker_pid == 0) { worker_restarted=1; SlonMain(); exit(-1); } … watchdog_status=SLON_WATCHDOG_NORMAL; continue; } break; default: shutdown=1; break; } /*switch*/ }/*while*/ … }
/* ---------- * SlonMain * ---------- */ static void SlonMain(void) { … for (i = 0, 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) < 0) { … } 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") == 0) { … 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 >= 0) { \ slon_log(SLON_DEBUG2, "slon_retry() from pid=%d\n", slon_pid); \ (void) kill(slon_watchdog_pid, SIGUSR1); \ slon_watchdog_pid = -1; \ } \ pthread_mutex_unlock(&slon_watchdog_lock); \ pthread_exit(NULL); \ } while (0)

/* ---------- * 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;

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

 






本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/p/3227000.html,如需转载请自行联系原作者


目录
相关文章
|
8天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
7天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
344 130
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
19天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1331 8
|
7天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
333 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
6天前
|
监控 JavaScript Java
基于大模型技术的反欺诈知识问答系统
随着互联网与金融科技发展,网络欺诈频发,构建高效反欺诈平台成为迫切需求。本文基于Java、Vue.js、Spring Boot与MySQL技术,设计实现集欺诈识别、宣传教育、用户互动于一体的反欺诈系统,提升公众防范意识,助力企业合规与用户权益保护。
|
18天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1419 87
|
6天前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。