postgresql源码学习(39)—— 崩溃恢复① - Startup进程的三大作用

67 篇文章 52 订阅
14 篇文章 4 订阅

如果数据库宕机或者服务器故障,缓存中的脏页可能尚未被刷入磁盘,磁盘中的数据处于不一致状态。在数据库重新启动时,需要借助WAL日志将数据库恢复到一致的状态。

  • Startup进程的三大作用

崩溃恢复的核心进程是Startup进程,核心函数是StartupXLOG函数,它在pg启动时就会被调用,读取配置信息,应用WAL日志。

通过读取不同参数,Startup进程可以完成3大功能——崩溃恢复、从库日志应用、PITR(基于时间点的恢复)。可以看到,这3大功能与WAL日志应用都是分不开的。

二、 配置信息读取

  1. 判断方式

用户可以在数据目录下创建standby.signal或者recovery.signal文件,Startup进程会检查这两个文件是否存在:

  1. 若都不存在,执行普通的崩溃恢复,应用到最新日志
  2. 若standby.signal存在,则当前数据库是个从库,持续进行日志应用
  3. 若recovery.signal文件存在,则进行PITR操作,根据recovery_target应用日志。注意从pg 12开始已经不再支持recovery.conf文件,如果检测到会报错。

  1. readRecoverySignalFile函数
/*
 * See if there are any recovery signal files and if so, set state for
 * recovery.
 *
 * See if there is a recovery command file (recovery.conf), and if so
 * throw an ERROR since as of PG12 we no longer recognize that.
 */
static void
readRecoverySignalFile(void)
{
    struct stat stat_buf;

    if (IsBootstrapProcessingMode())
        return;

    /*
     * Check for old recovery API file: recovery.conf,检查recovery.conf文件,如果有则报错
     */
    if (stat(RECOVERY_COMMAND_FILE, &stat_buf) == 0)
        ereport(FATAL,
                (errcode_for_file_access(),
                 errmsg("using recovery command file \"%s\" is not supported",
                        RECOVERY_COMMAND_FILE)));

    /*
     * Remove unused .done file, if present. Ignore if absent.如果存在.done文件,将其删除
     */
    unlink(RECOVERY_COMMAND_DONE);

    /* 若standby.signal存在,将standby_signal_file_found标签设置为true,说明当前数据库是个从库 */
    if (stat(STANDBY_SIGNAL_FILE, &stat_buf) == 0)
    {
        int         fd;

        fd = BasicOpenFilePerm(STANDBY_SIGNAL_FILE, O_RDWR | PG_BINARY | get_sync_bit(sync_method),
                               S_IRUSR | S_IWUSR);
        if (fd >= 0)
        {
            (void) pg_fsync(fd);
            close(fd);
        }
        standby_signal_file_found = true;
    }
    /* 若recovery.signal存在,将recovery_signal_file_found标签设置为true,说明当前在执行PITR */
    else if (stat(RECOVERY_SIGNAL_FILE, &stat_buf) == 0)
    {
        int         fd;

        fd = BasicOpenFilePerm(RECOVERY_SIGNAL_FILE, O_RDWR | PG_BINARY | get_sync_bit(sync_method),
                               S_IRUSR | S_IWUSR);
        if (fd >= 0)
        {
            (void) pg_fsync(fd);
            close(fd);
        }
        recovery_signal_file_found = true;
    }

/* 如果都不是,将下面两个参数设置为false */
    StandbyModeRequested = false;
    ArchiveRecoveryRequested = false;
    if (standby_signal_file_found)
    {
        StandbyModeRequested = true;
        ArchiveRecoveryRequested = true;
    }
    else if (recovery_signal_file_found)
    {
        StandbyModeRequested = false;
        ArchiveRecoveryRequested = true;
    }
    else
/* 如果都不是,直接返回,说明是普通的崩溃恢复 */
        return;

    /*
     * We don't support standby mode in standalone backends; that requires other processes such as the WAL receiver to be alive.
     */
    if (StandbyModeRequested && !IsUnderPostmaster)
        ereport(FATAL,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("standby mode is not supported by single-user servers")));
}

下一篇,我们正式学习StartupXLOG函数,看不同场景下如何进行日志应用。

参考

《PostgreSQL技术内幕:事务处理深度探索》第4章

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hehuyi_In

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值