MPP数仓主备搭建全攻略:从Standby配置到故障切换实战

发布时间:2026/10/22 16:53:26
MPP数仓主备搭建全攻略:从Standby配置到故障切换实战
前阵子帮一个客户做MPP数仓的高可用体检发现他们的集群跑了大半年居然一直没有配置 Standby 节点。问就是“数据都在 Segment 上Master 挂了重启不就行了”这种认知其实挺危险的MPP 主备搭建不是锦上添花而是数仓能不能扛住故障的关键防线。这篇就把我在实际项目里搭主备的完整过程、踩过的坑、以及切换时的心智模型一次讲清楚。1. 为什么MPP的主备不是“两台机器装两套库”1.1 先搞清楚MPP架构里的单点在哪很多人一听到“主备”第一反应是像 MySQL 那样搞两台机器互相复制。MPP 数仓不一样它天生是多节点架构。拿我这边长期维护的某款开源MPP数仓来说集群里有一个协调节点Master/Coordinator和一堆数据节点Segment/DataNode。协调节点本身不存业务数据它维护的是全局元数据——表结构、分布键、数据文件映射、事务状态所有查询计划都由它生成再把任务分发给各个 Segment 并行执行。所以真正存数据的节点是 Segment而 Segment 本身还可以配置镜像Mirror。但协调节点一旦出问题整个集群就没法接收新查询所有业务直接断掉。这就是最典型的单点。MPP 主备搭建实际上干的就是消除这个协调节点的单点让一个 Standby 节点实时同步主节点的元数据主节点挂了以后由它接管。1.2 主备同步的本质是元数据热备不是数据拷贝Standby 节点上不会存放 Segment 里的业务数据分片它同步的是协调节点的系统表、事务日志WAL、配置文件这些元数据信息。运作原理跟 PostgreSQL 的流复制很像主节点每产生一条元数据变更就写入 WAL 日志通过流复制协议把 WAL 片段持续推给 StandbyStandby 收到后不断重放保持跟主节点几乎一致的状态。这里有个容易误解的点执行一条CREATE TABLE或者ALTER TABLE真正数据文件的分布动作是由 Segment 节点完成的协调节点只记录“哪张表、按什么键分布、落在哪些 Segment 上”这些元数据。所以 Standby 同步的是这些“指挥信息”而不是业务表里的数据行。理解了这个后面配置同步参数、看日志、排故障都会清晰很多。1.3 两套高可用机制别搞混协调节点主备 vs Segment 镜像我在和用户交流时发现很多人把“主备”和“节点镜像”混为一谈。实际上 MPP 数仓的高可用通常有两条线机制保护对象同步内容触发场景协调节点主备StandbyMaster / Coordinator全局元数据 WAL协调节点宕机、网络隔离Segment 镜像MirrorDataNode 数据分片业务数据物理块数据节点磁盘故障混合方案全链路元数据 数据机房级容灾实操中这两套机制常常要一起配但它们的部署步骤、恢复命令完全不同。这篇博文只聚焦协调节点的主备搭建Segment 镜像属于另一个话题等后续再单独写一篇。2. 搭建前最容易翻车的几件事版本、网络和资源规划2.1 版本一致性和集群名称同步我在搭主备之前先强调一个硬性要求主备两台机器上的数据库软件版本必须完全一致小版本号也不能差。有一次某个测试环境主节点是 6.9 的 patch备机装的却是 6.8结果备机的 WAL 重放一直报could not open file的错误排查半天才发现是版本差异导致的日志格式不兼容。另外集群名称Cluster Name也要一致。MPP 数仓在初始化集群时会写入一个集群标识初始化备机时的工具会自动读取主节点的标识并写到备机配置里。如果你手动改过主节点的主机名或集群名备机那边会同步失败。规则很简单先确认主节点能正常启动、集群状态正常再动手搭备机不要在一个本来就有问题的集群上做高可用。2.2 网络、hostname 解析和进程通信配置主备节点之间的 WAL 同步走的是 TCP 流复制对网络质量非常敏感。生产环境我强烈建议主备之间用独立的万兆内网不要跟业务网络挤在一起。WAL 同步的数据量没有业务流量那么大但延迟一旦波动备机就会反复触发重连日志里刷一堆could not receive data from WAL stream看着很吓人其实根因就是网络抖动。还有 hostname 解析主备两台机器都要把彼此的 hostname 写进/etc/hosts并保证hostname -i能解析到正确的内网 IP。MPP 的进程间通信依赖主机名的双向解析配好后建议先执行gpssh或者ssh到对端测一下确保免密互通。顺带一提时钟同步也要提前做好主备时间差太大会导致 WAL 时间戳判断出问题。2.3 磁盘规划和 WAL 目录的独立化备机上的数据目录规划最好和主节点保持一致。很多团队图省事备机的 Master 数据目录和系统盘放在一起这是隐患。WAL 重放是高频写操作如果备机磁盘 IO 性能跟不上就会拖累整体同步进度。合理做法是把pg_wal目录单独放到一块 SSD 或者独立的挂载点上跟数据目录分开。主节点也一样我在初始化集群时通常会调整wal_keep_size或者配置归档目录避免 WAL 文件堆积把磁盘撑满。提示搭建前建议先跑一轮主节点的gpcheckperf和磁盘读写测试确认备机硬件能力不低于主节点。Standby 平时看似空闲切换后要承担全部协调工作性能差了会直接拖垮恢复后的集群。3. 主备搭建核心步骤从元数据准备到同步启动3.1 准备主节点的复制用户和访问权限搭建前先确认主节点的postgresql.conf和pg_hba.conf配置。流复制需要专门的复制账号我通常直接用集群超级用户或者单独建一个repl_user-- 在主节点执行 CREATE ROLE repl_user WITH REPLICATION LOGIN PASSWORD strong_password;然后在pg_hba.conf里加一条允许备机 IP 以复制协议访问的规则。注意这条规则必须加在最前面因为pg_hba.conf是自上而下匹配的host replication repl_user 192.168.10.20/32 md5postgresql.conf里至少要确认这几个参数。不同版本参数名略有差异我以常见 MPP 环境为例wal_level replica max_wal_senders 10 wal_keep_size 1GB改完参数重启主节点然后用pg_stat_replication确认主节点已经在监听复制连接。这一步很重要如果参数没生效后面初始化备机工具跑一半会报复制无法建立。3.2 用官方工具初始化备机一次完整的元数据快照我用的这款 MPP 数仓提供了一条命令gpinitstandby它会自动完成三件事在主节点上做一次物理备份把 Master 数据目录完整拷贝到备机、在备机上配置 Standby 节点信息、然后启动备机的恢复进程开始追 WAL。整个过程不需要手动拷贝数据命令大概是gpinitstandby -s mpp-standby-host执行过程中会输出类似Standby hostname has been initialized的日志表示备份阶段完成。之后工具会自动把备机拉起进入持续恢复状态。这里要提醒一下有些版本还支持通过配置文件指定 Standby 主机即先在gp_segment_configuration里注册好备机角色再执行初始化。我建议第一次搭建就直接用命令行指定简单直观。执行完成后跑一下gpstate -s会看到Standby Master的状态是Synchronized或者Change Tracking。前者表示已经完全追上主节点后者表示正在追赶属正常现象。如果状态一直停在Resynchronization说明 WAL 回放速度跟不上主节点的写入需要检查网络和磁盘。提示初始化备机的过程本质上是做了一次基础备份Base Backup耗时取决于 Master 数据目录的大小。元数据通常不会太大但如果历史日志堆积很多备份时间会变长。我一般会先清理过期的日志文件再执行能省不少时间。3.3 备机恢复进程的运作方式初始化完成后备机的数据目录里会生成一个recovery.conf新版可能叫standby.signal里面写明了主备连接信息。备机的 PostgreSQL 进程以热备模式运行持续重放主节点推送过来的 WAL 记录。你可以通过以下 SQL 在备机确认状态SELECT pg_is_in_recovery();返回true说明备机正处于恢复状态这是正常的。如果返回false说明备机被意外提升为主节点了要立刻排查原因。在主节点上还可以用SELECT client_addr, state, sent_lsn, replay_lsn FROM pg_stat_replication;通过对比sent_lsn和replay_lsn是否一致来判断同步是否实时。这两个字段的值差距越大说明备机落后越多。3.4 验证同步状态不是只看“绿灯”搭建完成不等于万事大吉我在每次搭建后都会做一轮完整的功能验证在主节点随便建一个测试表并插入一条记录。等几秒然后到备机查询系统表中是否有这个表的元数据记录。故意在主节点执行一条DROP TABLE观察备机能否同步到删除操作。查看主备两侧的 WAL 文件数量和位置是否一致。第3步很多人不敢做但元数据同步验证必须覆盖 DDL 操作。因为生产环境里协调节点最重要的职责就是处理 DDLStandby 如果同步不了 DDL切换后业务侧的表结构变更就会出大问题。我用这个方法抓出过一次主备之间权限配置不一致的问题所以强烈建议不要只看到Synchronized状态就收工。4. 故障切换不是“登一下录”主备切换实战与坑4.1 手动激活备机切换到接管模式主节点宕机后Standby 不会自动接管所有 MPP 产品里自动切换依赖集群管理工具的故障检测机制FTS但在没有配置自动切换模块的环境里最常见的是人工介入。手动激活备机的命令在我的环境里是gpactivatestandby执行后备机会重放完所有已收到的 WAL 记录把自己提升为新的主节点并更新集群状态。整个过程会持续一小段时间输出末尾会有类似standby has been activated的提示。升主之后原来指向旧主节点的客户端连接需要重新配置指向新节点。这时有个关键细节激活备机前必须确认旧主节点已经彻底停止或者至少把它从网络上隔离掉。否则旧主节点在故障恢复后可能继续对外提供服务两个节点同时认为自己是主节点这种“双主脑裂”会让元数据出现不可修复的分裂比单纯宕机严重得多。注意实际生产里我见过有人在没确认旧主进程是否退出时就匆忙激活备机结果两边同时写元数据整个集群的系统表乱成一团。正确做法是先检查旧主节点上的数据库进程是否还在ps -ef | grep postgres确认无存活进程后再执行切换。4.2 切换后的旧主节点怎么处理新主节点运行稳定后旧主节点就成了“孤儿节点”。它不能再以主节点身份拉回集群唯一的出路是把它重新配置成新的备机。步骤如下清理旧主节点的数据目录先备份必要的配置。用初始化备机的工具把新主节点的数据重新同步过去。恢复集群的复制关系gpinitstandby -s old-master-host。也就是说每一次主备切换之后都要重新搭建一次备机这个过程不可跳过。很多人第一次切换后只顾着业务恢复忘了修复备机导致集群又回到单点状态这是高可用管理里最常见的疏忽。4.3 用备机做只读查询要谨慎部分 MPP 数仓允许备机在待命状态下接受只读连接。表面上这能分摊一些查询压力但我个人建议在生产环境不要这么干。备机的核心职责是随时准备接管让它跑业务查询会带来两个问题一是查询会占据 CPU 和 IO影响 WAL 重放速度二是备机看到的数据可能落后于主节点几秒甚至更久业务侧拿到不一致的查询结果反而容易引发事故。如果确实有只读分析需求正确的做法是单独开一套只读副本而不是在 Standby 上做。主备系统最宝贵的属性是“确定性”备机状态越纯粹切换时越可靠。5. 我踩过的几个真实问题从日志异常到切换失败5.1 备机 WAL 说明为何一直卡住有次客户环境里备机状态长期等于“Change Tracking”迟迟追不上。我先在主节点跑pg_stat_replication发现replay_lsn远远落后于sent_lsn说明日志已经推过去了但对端回放很慢。进一步排查后发现备机的 Master 数据目录居然和系统日志放在同一块机械盘上IO 队列一直处于打满状态。后来把 WAL 目录迁到单独的 SSD回放速度立刻提上去了。这个案例说明主备同步瓶颈往往不在网络而在备机的磁盘写入速度。如果备机是虚拟机还要特别注意 CPU 限制和存储类型。5.2 时间线分裂与恢复混乱还有一次备机激活后旧的 WAL 日志跟主节点的 WAL 时间线对不上导致新主节点启动时报timeline 2和新日志无法匹配。这其实是 PostgreSQL 流复制的常见现象每次提升备机都会产生一条新的时间线标识旧的时间线日志不能再用于回放。处理思路是彻底清理旧的归档日志并确保新主节点只使用新时间线的日志。对 MPP 数仓来说切换完成后我就把整个集群的 WAL 归档目录清理一遍避免残留日志干扰后续恢复。5.3 自动切换的边界不是配了就高枕无忧有些团队会配第三方的集群管理软件实现自动切换。但自动切换依赖健康检查、仲裁节点、网络分区探测这些机制配置复杂不说在某些场景下反而可能引发错误的切换。我之前碰到过一次网络抖动导致主备之间互相探测超时仲裁机制误判主节点故障强行激活了备机结果旧主节点网络恢复后两边同时操作集群直接瘫痪。所以我的观点是自动切换不是不能用但必须配合 fencing 机制比如切掉旧主节点的网络或电源确保任意时刻只有一个主节点。如果团队还没有能力维护这整套机制宁可先用手动切换也别让一个误判把整个集群搞崩。6. 主备之外的最后一公里备份、演练与监控6.1 主备不能替代备份别把高可用当容灾这点我必须反复强调主备同步解决的是“节点故障”解决不了“逻辑错误”。如果有人在主节点上误执行了一条DROP DATABASE这条操作会原样同步到备机备机根本不会拒绝。想恢复数据只能靠物理备份、逻辑备份或者时间点恢复工具。我负责的环境里备份策略跟主备完全是两条线主备保证元数据节点的高可用备份工具按天做全量备份并按小时归档 WAL。只有这样误操作、病毒、软件 bug 这类故障才有退路。6.2 定期做切换演练别等真出事才第一次切主备搭建完成后我通常会建议团队每季度做一次切换演练。流程大概是提前通知所有业务方记录当前正在跑的 ETL 任务。选择一个低峰窗口确认没有正在执行的长事务。手动激活备机观察新主节点能否正常接收查询、执行 DDL。把旧主节点重新初始化为备机恢复主备状态。检查各 Segment 与主节点之间的心跳状态。演练不只是验证切换命令好不好使更重要的是让团队熟悉整个流程。真出事的时候大家根本没时间现翻文档平时练过的动作会自然反应出来。6.3 该盯的几个监控指标最后分享一下我日常会重点盯的监控项基本能覆盖主备健康状态备机同步状态pg_is_in_recovery()是否持续为真。WAL 重放延迟replay_lsn与sent_lsn的差值超过一定阈值就要告警。主备之间网络丢包率用最简单的 ping 监控都能提前发现不少问题。备机磁盘空间WAL 堆积如果超过磁盘的 70%就要注意了。这些指标可以集成到现有的监控系统里不必非得上复杂的工具。最怕的是备机状态从未被观察等切换时才发现备机早就掉线几个月了。主备搭建这件事说到底是在为最坏的情况做预案。我见过太多集群平时跑得好好的真出事故时才发现备机从来没真正同步过或者切换脚本根本跑不通。花一两个小时把备机搭好、把切换流程验证一遍远比事后抢救省心得多。这次分享的主要是我的实操流程和排查思路具体命令在不同 MPP 产品里略有差异但底层的 WAL 复制、时间线、脑裂防范这些原理是通用的。希望这篇能帮你少走些弯路。