PostgreSQL 恢复进程startup hang住的原因分析一例

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介:
最近在一个跨广域网的PostgreSQL primary standby环境中遇到一个比较奇特的问题。
首先primary standby是跨广域网的,但这不是问题的重点。重点是归档也是跨光域网并且使用NFS来让standby访问归档文件。
standby通过NFS获取归档,通过TCP连接primary实现流复制。
但是不知道什么原因,NFS出现了问题,即standby无法正常的访问归档文件了,访问NFS的命令会hang住。
接下来描述一下问题,然后再从PostgreSQL源码分析问题的原因。
1. standby的restore_command命令(cp /nfsdir/%f %p)hang住,停留在拷贝某个归档xlog的状态。
2. 手工kill 这个cp命令,紧接着standby数据库crash了。
3. 重启standby数据库,发现hang在cp /nfsdir/0000009.history %p的状态,然而实际上0000009.history是不存在的,主库的时间线是8,备库的时间线也是8,那么是什么原因导致standby要去找一个不存在的时间线文件呢?
这个原因要到源代码去寻找答案。
    我们一般配置流复制环境,会设置recovery_target_timeline=latest,这样做的目的是配置一个hot_standby,如果上游切换了时间线,可以自动跟上。
    而这个就可以解释为什么standby recovery的时候要去找一个不存在的时间线文件?

见源码:
src/backend/access/transam/timeline.c
/*
 * Find the newest existing timeline, assuming that startTLI exists.
 *
 * Note: while this is somewhat heuristic, it does positively guarantee
 * that (result + 1) is not a known timeline, and therefore it should
 * be safe to assign that ID to a new timeline.
 */
TimeLineID
findNewestTimeLine(TimeLineID startTLI)
{
        TimeLineID      newestTLI;
        TimeLineID      probeTLI;

        /*
         * The algorithm is just to probe for the existence of timeline history
         * files.  XXX is it useful to allow gaps in the sequence?
         */
        newestTLI = startTLI;

        for (probeTLI = startTLI + 1;; probeTLI++)      # 问题就出在这里, 探测下一个时间线是否存在。
        {
                if (existsTimeLineHistory(probeTLI))
                {
                        newestTLI = probeTLI;           /* probeTLI exists */
                }
                else
                {
                        /* doesn't exist, assume we're done */
                        break;
                }
        }

        return newestTLI;
}

src/backend/access/transam/xlog.c
/*
 * See if there is a recovery command file (recovery.conf), and if so
 * read in parameters for archive recovery and XLOG streaming.
 *
 * The file is parsed using the main configuration parser.
 */
static void
readRecoveryCommandFile(void)
......
                else if (strcmp(item->name, "recovery_target_timeline") == 0)
                {
                        rtliGiven = true;
                        if (strcmp(item->value, "latest") == 0)
                                rtli = 0;
.....
        /*
         * If user specified recovery_target_timeline, validate it or compute the
         * "latest" value.  We can't do this until after we've gotten the restore
         * command and set InArchiveRecovery, because we need to fetch timeline
         * history files from the archive.
         */
        if (rtliGiven)
        {
                if (rtli)
                {
                        /* Timeline 1 does not have a history file, all else should */
                        if (rtli != 1 && !existsTimeLineHistory(rtli))
                                ereport(FATAL,
                                                (errmsg("recovery target timeline %u does not exist",
                                                                rtli)));
                        recoveryTargetTLI = rtli;
                        recoveryTargetIsLatest = false;
                }
                else
                {
                        /* We start the "latest" search from pg_control's timeline */   # 问题出在这里,我配置的就是recovery_target_timeline=latest, 所以需要调用findNewestTimeLine. 控制文件是8,所以find 0000009.history.
                        recoveryTargetTLI = findNewestTimeLine(recoveryTargetTLI);
                        recoveryTargetIsLatest = true;
                }
        }

找到原因后,把NFS的问题解决掉,重启数据库就好了,再也不会hang住。

[参考]
1. src/backend/access/transam/xlog.c
2. src/backend/access/transam/timeline.c
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
7月前
|
Linux
一个进程最多可以创建多少个线程基本分析
一个进程最多可以创建多少个线程基本分析
470 1
|
4月前
|
Linux
Linux源码阅读笔记10-进程NICE案例分析2
Linux源码阅读笔记10-进程NICE案例分析2
|
4月前
|
Linux
Linux源码阅读笔记09-进程NICE案例分析1
Linux源码阅读笔记09-进程NICE案例分析1
|
22天前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
39 4
|
6月前
|
监控 Linux 应用服务中间件
探索Linux中的`ps`命令:进程监控与分析的利器
探索Linux中的`ps`命令:进程监控与分析的利器
137 13
|
1月前
|
运维 JavaScript jenkins
鸿蒙5.0版开发:分析CppCrash(进程崩溃)
在HarmonyOS 5.0中,CppCrash指C/C++运行时崩溃,常见原因包括空指针、数组越界等。系统提供基于posix信号机制的异常检测能力,生成详细日志辅助定位。本文详解CppCrash分析方法,涵盖异常检测、问题定位思路及案例分析。
50 4
|
1月前
|
运维 监控 JavaScript
鸿蒙next版开发:分析JS Crash(进程崩溃)
在HarmonyOS 5.0中,JS Crash指未处理的JavaScript异常导致应用意外退出。本文详细介绍如何分析JS Crash,包括异常捕获、日志分析和典型案例,帮助开发者定位问题、修复错误,提升应用稳定性。通过DevEco Studio收集日志,结合HiChecker工具,有效解决JS Crash问题。
51 4
|
6月前
|
算法 Linux 编译器
技术笔记:LINUX2.6.32下的进程分析
技术笔记:LINUX2.6.32下的进程分析
34 0
|
3月前
|
Oracle NoSQL 关系型数据库
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
630 2
|
7月前
|
缓存 监控 调度
第六十一章 使用 ^PERFSAMPLE 监控进程 - 分析维度
第六十一章 使用 ^PERFSAMPLE 监控进程 - 分析维度
50 0

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版