OpenGauss线程管理-数据库启动线程-Startup

OpenGauss线程管理-数据库启动线程-Startup

术语解释

  • 日志REDO(重做):让已经提交了的事务对数据库所做的修改永久生效,即使后来系统崩溃,在重启后也可以把之前的修改恢复。即在系统崩溃重启时按照记录的步骤重新更新数据页。
  • 主备机:为了保证故障的可恢复,需要将数据写多份,设置主备多个副本,通过日志进行数据同步,实现节点故障、停止后重启。在主备环境下可以支持主备和一主多备两种模式。主备模式下,备机需要重做日志,可以升主;在一主多备模式下,所有的备机都需要重做日志,都可以升主。
  • 备机:openGauss双机方案中的一个节点,用于作为主机的备份,在主机异常时,备机会切换到主机状态,以确保能正常提供数据服务。
  • DCF:Distributed Consensus Framework,即分布式一致性共识框架。使用DCF可以提供日志复制、集群高可用(以减少服务中断时间为目的的服务器集群技术)等能力。

startup线程

Startup线程是数据库在启动时创造的第一个子线程,主要用来完成数据库的日志REDO操作,从而进行数据库的恢复。当日志REDO操作结束,数据库完成恢复后,如果不是备机,Startup线程就退出了;如果是备机,那么Startup线程一直在运行,REDO备机接收到新的日志。
数据库在启动过程初始化服务器并执行已指定的任何恢复操作。且没有“主循环”,因为启动过程在初始化完成后立即结束。

StartupProcessMain函数

路径:openGauss-server\src\gausskernel\process\postmaster\startup.cpp

主线程中的位置

startup线程在主线程中的位置是在GaussDbAuxiliaryThreadMain函数中,通过thread_role来判断是否执行startup线程
startup线程在主线程中的位置

函数代码
void StartupProcessMain(void)
{
    /*
     * 正确接受或忽略postmaster可能发送给我们的信号。 
     * 注意:理想情况下,除非实际执行热备用,否则我们不会启用handle_standby_sig_alarm,
     * 但我们还不知道。 依靠它不做任何不该做的事情。
     */
    /*
     * 重置一些被postmaster接受但未在此处接受的信号
     */
    (void)gspqsignal(SIGHUP, StartupProcSigHupHandler);    /* 重新加载配置文件 */
    (void)gspqsignal(SIGINT, StartupProcSigIntHandler);    /* 检查修复页面和文件 */
    (void)gspqsignal(SIGTERM, StartupProcShutdownHandler); /* 请求关闭 */
    (void)gspqsignal(SIGQUIT, startupproc_quickdie);       /* 硬崩溃时间 */

    if (g_instance.attr.attr_storage.EnableHotStandby)
        (void)gspqsignal(SIGALRM, handle_standby_sig_alarm); /* ignored unless

                                                      * InHotStandby */
    else
        (void)gspqsignal(SIGALRM, SIG_IGN);

    (void)gspqsignal(SIGPIPE, SIG_IGN);
    (void)gspqsignal(SIGUSR1, StartupProcSigUsr1Handler);
    (void)gspqsignal(SIGUSR2, StartupProcSigusr2Handler);

    /*
     * 重置一些被postmaster接受但未在此处接受的信号
     */
    (void)gspqsignal(SIGCHLD, SIG_DFL);
    (void)gspqsignal(SIGTTIN, SIG_DFL);
    (void)gspqsignal(SIGTTOU, SIG_DFL);
    (void)gspqsignal(SIGCONT, SIG_DFL);
    (void)gspqsignal(SIGWINCH, SIG_DFL);

    (void)RegisterRedoInterruptCallBack(HandleStartupProcInterrupts);
    (void)RegisterRedoPageRepairCallBack(HandleStartupPageRepair);
    /*
     * 取消阻止信号(当postmaster创造我们时,它们被阻止)
     */
    gs_signal_setmask(&t_thrd.libpq_cxt.UnBlockSig, NULL);
    (void)gs_signal_unblock_sigusr2();

    t_thrd.utils_cxt.CurrentResourceOwner = ResourceOwnerCreate(NULL, "StartupXLOG",
        THREAD_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE));

    SetStaticConnNum();
    pgstat_report_appname("Startup");
    pgstat_report_activity(STATE_IDLE, NULL);

    if (dummyStandbyMode) {
        StartupDummyStandby();
    } else {
        on_shmem_exit(StartupReleaseAllLocks, 0);

#ifdef ENABLE_MOT
        /*
         * 初始化 MOT 第一
         */
        InitMOT();

        /*
         * MOT恢复是StartupXlog的一部分
         */
#endif
        DeleteDisConnFileInClusterStandby();
        if (!dummyStandbyMode) {
            Assert(g_instance.startup_cxt.badPageHashTbl == NULL);
            g_instance.startup_cxt.badPageHashTbl = parallel_recovery::BadBlockHashTblCreate();
        }

        StartupXLOG();
    }

    /*
     * 正常退出。退出代码 0 告诉postmaster我们已成功完成恢复。
     */
    proc_exit(0);
}

startup.cpp中其他函数的简要解读

函数功能
static void startupproc_quickdie(SIGNAL_ARGS)进行信号处理程序例程
static void StartupProcSigUsr1Handler(SIGNAL_ARGS)SIGUSR1:让锁存器处理信号
static void WaitApplyAllDCFLog(void)检查 walreceiver 是否已将所有 DCF 日志写入且应用 xlog
static void StartupProcSigusr2Handler(SIGNAL_ARGS)SIGUSR2:设置标志以完成恢复
static void StartupProcSigHupHandler(SIGNAL_ARGS)SIGHUP:设置标志以在下一个方便的时间重新读取配置文件
static void StartupProcSigIntHandler(SIGNAL_ARGS)SIGINT:设置标志以检查修复页面
static void StartupProcShutdownHandler(SIGNAL_ARGS)SIGTERM:设置标志以中止重做并退出
void HandleStartupProcInterrupts(void)处理启动过程的 SIGHUP 和 SIGTERM 信号
static void StartupReleaseAllLocks(int code, Datum arg)释放所有锁
void DeleteDisConnFileInClusterStandby()删除群集备用中的文件
void PreRestoreCommand(void)预恢复命令
void PostRestoreCommand(void)发布恢复命令
bool IsFailoverTriggered(void)判断是否触发了故障转移
bool IsSwitchoverTriggered(void)判断是否触发切换
bool IsPrimaryTriggered(void)判断是否主要触发
bool IsStandbyTriggered(void)判断是否触发待机
void SendNotifySignal(NotifyReason reason, ThreadId ProcPid)在通知信号共享内存中设置原因,并将 SIGUSR2 发送到进程
bool CheckNotifySignal(NotifyReason reason)检查通知信号
static void SetStaticConnNum(void)更新 HaSHmData 中的静态连接号
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值