2025年6月,Snowflake宣布以约2.5亿美元收购Crunchy Data。多数解读停留在品类扩张的层面,把这件事看成云数仓厂商买了一张进入事务数据库市场的门票。从工程角度看,这笔交易至少有三个彼此独立的技术切面,每一个切面都对应着不同的产品意图与落地难度,也对应着不同的失败方式。本文不讨论资本逻辑,只讨论一个云数仓产品要想真正接住PostgreSQL生态,需要改动哪些层、付出什么代价、在哪里最容易翻车。
收购事实的三个技术切面
第一个切面是负载类型的补齐。Snowflake的主营负载是批量分析与交互式报表,存储格式为列式微分区,执行模型以大规模并行扫描为基础。这类系统在扫描数十亿行时效率极高,但在按主键取一行、按唯一约束插入一行、按外键校验引用完整性这类操作上,先天不占优势。企业数据平台一旦要承接应用系统的读写,就必须具备行级点查与事务提交的能力,这是列存引擎难以通过参数调优弥补的结构性差距。
第二个切面是元数据与控制面的标准化。PostgreSQL的catalog本身就是一组普通表,可以查询、可以复制、可以做版本比对。这让它天然适合作为数据平台的控制面,把库表定义、权限、血缘、注释统一挂在一个可编程的目录之下。数仓厂商长期头疼的问题是元数据服务与计算引擎分离后带来的口径漂移,而PG的catalog模型提供了一种把元数据拉回数据库内部的思路。
第三个切面是AI应用对低延迟读写的刚性需求。检索增强生成的应用链路里,向量索引、会话状态、权限过滤、结果缓存都要求毫秒级点查与写入。把这些状态放在对象存储之上做批量刷新,端到端延迟会被放大到秒级,交互体验无法接受。pgvector这类扩展把向量检索做进了行存数据库,配合事务能力形成了完整的应用侧数据闭环。
三个切面放在一起,收购的实质不是买一个数据库产品,而是买一条能够承接操作型负载与AI应用状态的通道。通道的价值取决于它与既有分析能力的接缝是否足够窄,接缝越窄,客户就越不需要维护两套系统与两条数据链路,运维成本和数据一致性风险同步下降。
云数仓与行存数据库的能力边界
列存与行存在物理布局上的差异决定了两类系统的能力边界,这条边界不会因为加了索引或缓存而消失。
列存把同一列的数值连续存放,配合字典编码、游程编码和轻量压缩,单次扫描的IO量可以降到行存的十分之一以下。代价是读取整行时需要把多列拼接回来,点查的放大倍数与表的列数成正比。一张两百列宽表按主键取一行,列存要触达两百个列块,而行存只需要读一两个数据页。云数仓用微分区元数据做裁剪,能把扫描范围缩小到单个分区,但分区内部的解码成本依然存在。
行存把一行记录的所有字段放在同一个数据页,主键索引是独立的B树结构,一次点查的路径是根节点到叶节点再到堆表页,页命中时开销只有微秒级。B树索引还带来了范围扫描、唯一性校验、外键检查这些列存难以低成本实现的能力。约束的强制执行需要随机读,随机读需要索引,索引需要行级定位,这是一条闭环依赖链。
事务提交路径的差异更为根本。云数仓的写入通常走批量装载,提交语义接近文件级原子替换,没有细粒度锁,没有多版本并发控制的开销,也没有回滚段。行存数据库的每次提交都要写WAL、刷盘、更新事务状态、维护快照,还要处理并发冲突与死锁检测。前者吞吐高但粒度粗,后者粒度细但每次提交都有固定成本。
并发控制模型的差异会直接体现在混合负载上。云数仓的查询大多是无状态的短任务,资源由调度器按队列分配。行存数据库的会话是有状态的,连接持有快照、锁、临时空间和游标,长事务会阻塞清理,宽查询会挤占连接池。把分析查询直接丢进行存实例,最常见的后果不是慢,而是膨胀。
把边界写清楚之后,判断就很直接。凡是需要唯一约束、外键、细粒度更新、低延迟点查的负载,行存是唯一选择。凡是需要全表聚合、大宽表扫描、复杂多表关联的负载,列存有明显优势。两者不是替代关系,是分工关系,任何试图用一套引擎同时做好两件事的方案,都要在某一侧让步。
PostgreSQL生态的锁定效应来源
PostgreSQL的生态壁垒不在内核性能,而在接口稳定性与扩展自由度。这两点决定了厂商愿意围绕它做长期投入,也决定了客户迁移成本的真实高度。
协议层面,PG使用前后端协议,几乎每种语言都有成熟驱动,连接池、ORM、迁移工具、监控探针全部围绕这套协议构建。一个数据库只要能说这套协议,就能立刻接入现有工具链,客户不需要改一行应用代码。这种兼容性带来的迁移成本优势,是任何新方言都换不来的。
扩展层面,PG提供了相对完整的挂接点。扩展可以注册新的类型、操作符、索引访问方法、表访问方法、外部数据包装器,还可以挂接执行器回调与计划器回调。这意味着厂商可以在不改内核主干的前提下,把列存、向量索引、时序压缩、地理计算塞进同一个实例。扩展机制的工程价值在于它把创新成本从改内核降到了写插件。
许可证层面,PG使用宽松许可,允许修改后闭源分发。云厂商可以基于它做深度定制而不必开源自己的改动,这是商业上可行的前提。对比之下,一些使用严格许可证的数据库在云上托管时面临法律风险,直接限制了云厂商的产品化空间。
人才层面,PG的SQL方言、系统视图、运维命令在DBA群体中普及度极高。一个产品只要兼容PG,客户的DBA就能上手,厂商的交付成本随之下降。反过来,自研方言的产品往往要配套培训体系,交付周期被拉长数倍。
托管服务商的价值在这里显现。Crunchy Data的核心资产不是数据库内核,而是把PG做成可运维产品的那些东西,包括高可用编排、备份恢复、版本升级路径、安全合规认证、监控指标口径。云数仓厂商自建这套体系需要三到五年,收购可以在一年内拿到。
扩展机制带来的工程可塑性
扩展机制是这套生态最有工程价值的部分,也是最容易被低估的风险源。
PG的扩展本质是一个动态库,通过控制文件描述自身元数据,在CREATE EXTENSION时执行安装脚本,把函数、类型、操作符注册进catalog。运行时通过 hook 机制挂接内核行为,例如可以拦截查询计划生成、修改执行器行为、替换存储访问层。表访问方法接口允许扩展定义全新的存储格式,让一张表以列式或时序方式落盘,同时保留SQL层的透明访问。
sql
CREATE EXTENSION vector;
CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION postgres_fdw;
SELECT extname, extversion
FROM pg_extension
ORDER BY extname;
这段代码看起来平淡,实际含义是把三类能力装进了同一个实例,向量检索、语句级性能统计、跨库联邦查询。客户不需要为每种能力单独部署一套系统,运维面收敛到一个进程组。
可塑性的代价首先体现在ABI绑定上。扩展编译时链接的是特定主版本的头文件与符号表,主版本升级后必须重新编译,否则实例启动直接失败。云厂商如果对内核做了私有修改,第三方扩展就无法直接用官方二进制,必须自行维护一条编译流水线。扩展数量越多,升级窗口越长,升级风险越高。
第二个代价是扩展质量参差。社区扩展没有统一的质量门槛,内存泄漏、并发缺陷、崩溃恢复不正确的问题并不罕见。一个扩展在单机测试环境跑得通,不代表在崩溃恢复、主备切换、并行查询下也正确。生产环境引入扩展前必须做故障注入验证,而不是只看功能是否可用。
第三个代价是安全边界。多数扩展安装需要超级用户权限,扩展代码运行在数据库进程内,一旦有缺陷就是整个实例的权限。托管服务因此通常只允许白名单扩展,客户想装一个自研扩展要走审核流程。这个限制在自建环境不存在,在托管环境是硬约束,选型时必须提前确认。
逻辑复制与变更数据捕获的接缝
把事务数据同步进数仓,工程上最常用的手段是逻辑复制。它比批量抽取延迟低,比触发器侵入小,但接缝处的坑非常集中。
逻辑复制的工作方式是主库把WAL中的行级变更解码成逻辑消息,通过复制槽保留,订阅端按事务顺序重放。发布端只需要声明哪些表对外可见,订阅端负责建立初始快照并持续追平。整个过程对应用透明,不需要改业务代码。
sql
CREATE PUBLICATION pub_orders FOR TABLE orders, order_items;
SELECT slot_name, active, restart_lsn, confirmed_flush_lsn
FROM pg_replication_slots;
这条查询是关键运维视图,保留量可以用 pg_wal_lsn_diff 计算 restart_lsn 与当前LSN的差值得到。复制槽会阻止WAL被回收,订阅端一旦停止消费,主库的WAL目录就会持续膨胀,直到磁盘写满。这个故障在生产中极其常见,根因往往不是复制本身,而是订阅端被重启、网络分区、或者某个大事务重放失败。
初始快照阶段的开销也常被低估。建立订阅时需要对每张表做一致性快照,大表会长时间持有快照,阻塞 vacuum 清理死元组。千万级以上的表建议分批建立订阅,或者在只读副本上做初始同步,再切换到主库增量。
冲突处理是逻辑复制的先天缺陷。PG的逻辑复制不提供自动冲突消解,遇到主键冲突时订阅端直接报错并停止重放,需要人工介入。双向同步场景下,两边同时更新同一行的概率不低,最终只能退化成后写覆盖,业务语义上并不等价于强一致。把双向逻辑复制当作双活方案,是架构设计里最常见的误判之一。
DDL的同步同样不在逻辑复制的能力范围内。发布端加一列,订阅端不会自动跟着加,重放时会因为列数不匹配而失败。生产环境必须把DDL纳入变更流程,先同步结构变更再放行数据变更,靠工具链保证顺序,而不是靠人记住。
sql
SELECT pid, state, wait_event_type, wait_event, xact_start, query
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY xact_start ASC
LIMIT 20;
这条查询用于排查长事务,按事务开始时间升序排列,最老的排在最前。逻辑复制卡住时,先用它确认主库是否有长事务阻止清理,再看复制槽的保留量,最后看订阅端日志。顺序反了会浪费大量时间。
数仓厂商切入事务负载的三条路径
面对事务负载,云数仓厂商只有三条路,每条路的成本结构和风险结构完全不同。
第一条是自研行存引擎。优势是架构可以彻底为存算分离设计,元数据、事务、日志、索引全部自主可控,长期看没有上游依赖。劣势是从零构建一个具备完整SQL语义、完整优化器、完整并发控制的引擎需要巨大的持续投入,而且生态为零,客户的应用、驱动、工具链全部要重新适配。历史上走通这条路的产品屈指可数,多数在半途转向兼容既有生态。
第二条是fork PostgreSQL做深度改造。优势是起步快,SQL语义、优化器、扩展生态直接继承。劣势是维护成本随时间线性增长,上游每发布一个大版本,合并工作量都会增加,私有改动越多,合并越困难。三年之后通常会出现两条分叉,一条跟上游,一条跟客户,团队被迫在两者之间反复取舍。
第三条是托管原生PostgreSQL并做互操作。优势是最快形成产品,客户拿到的就是标准PG,兼容性没有争议。劣势是两套系统并存,跨系统的查询、事务、权限、计费都要额外设计,产品体验上会出现明显的接缝。收购Crunchy Data走的正是这条路,短期内产品化速度最快,长期要看接缝能不能被抹平。
三条路的权衡可以压缩成一句话。自研买的是长期自由,fork买的是中期速度,托管买的是短期速度。选择哪条路取决于厂商对这块业务的时间窗口判断,而不是技术偏好。
值得注意的是,三条路并非互斥。实践中常见的组合是先用托管切入市场,同时用扩展方式把差异化能力注入,等客户规模起来后再考虑把热点路径下沉到自研层。这种渐进路线的风险在于,每一层都会留下技术债,后期收敛的代价可能超过一次性投入。
存算分离架构下引入行存的代价
存算分离是云数仓的架构基石,也是引入行存时最硬的一道坎。
数仓的存储层通常是对象存储,优势是容量无限、成本极低、多副本可靠。劣势是延迟。对象存储的一次GET请求在网络良好时也要十几毫秒,遇到元数据热点或限流会更糟。分析负载能容忍这个延迟,因为扫描是并行的,延迟被吞吐掩盖。事务负载不能容忍,因为每次提交都要等持久化确认,延迟直接叠加到用户请求上。
行存的提交路径要求日志先落盘再返回。把WAL写到对象存储,单次提交延迟会被放大到二十毫秒以上,TPS直接掉到几十。这个数量级无法支撑任何在线业务。
可行的折中是分层持久化。计算节点挂本地NVMe,WAL先写本地盘并刷盘,返回提交成功,再异步把日志段推到远端做冗余。本地盘故障时最多丢失几秒的日志,用多数派复制可以把窗口压到零,代价是每次提交多一次网络往返。
text
提交延迟预算拆解
本地NVMe刷盘 0.3 到 0.8 毫秒
同可用区副本确认 0.5 到 1.5 毫秒
跨可用区副本确认 2 到 4 毫秒
远端日志归档 异步,不计入提交路径
这张预算表说明,行存的提交延迟主要由副本确认决定,而不是由存储介质决定。想把P99压到五毫秒以内,副本必须放在同可用区,跨区容灾只能做成异步。这个结论对产品设计有直接影响,因为它决定了高可用等级与延迟之间的取舍点。
数据文件的布局也要重新考虑。列存的数据文件一旦写好就不再修改,适合直接放对象存储。行存的数据页会被原地更新,产生随机写,对象存储不支持原地修改,只能整对象重写。可行的方案是行存数据页放在块存储上,用日志结构的方式批量下推到对象存储做冷数据归档,热数据保持在本地缓存。
缓存命中率成为新的关键指标。行存的工作集如果超出本地缓存容量,每次点查都会穿透到远端,延迟从微秒级跳到毫秒级,性能曲线出现断崖。容量规划必须按工作集而不是按数据总量来做,这一点和数仓按总容量规划的习惯完全不同。
元数据目录统一的实现难点
两套系统并存时,元数据是最容易失控的地方。
数仓的元数据通常由独立服务管理,库表定义、分区信息、统计信息、权限策略都存在服务端的元数据存储里,计算引擎启动时拉取。这种集中式模型的优势是全局一致、便于治理,劣势是元数据操作与数据操作不在同一个事务里,DDL的可见性有延迟。
PG的catalog在库内,是普通表,DDL与DML共享同一个事务边界。建表语句提交后立刻对所有会话可见,回滚则完全消失。这种事务性DDL带来的语义强度更高,但和数仓的异步元数据模型天然冲突。
统一目录的第一种做法是把PG的catalog作为唯一真相,数仓侧拉取镜像。问题是PG的catalog结构复杂,系统表之间有大量内部引用,跨版本还会变化,做镜像等于把PG的版本演进绑进自己的产品节奏。第二种做法是双写,两边各自维护,用同步器保证最终一致。问题是同步器一旦滞后,客户端看到的口径就会分裂,排查成本极高。第三种做法是建立独立的元数据服务作为真相,两边都向它注册。这种做法的工程量大,但解耦最彻底。
权限模型的差异同样棘手。PG的权限体系基于角色、对象、授权链,支持列级权限和行级安全策略,检查发生在执行期。数仓的权限体系通常基于标签与策略引擎,检查发生在计划期或代理层。把两套模型对齐,需要定义一套公共语义,再为每个引擎实现映射。行级安全策略在跨引擎场景下几乎无法保证一致,这是实际项目里最常被跳过、也最容易出事的环节。
命名解析也需要统一。PG用search_path决定未限定表名的解析顺序,数仓通常用三段式命名空间。同名的表在不同schema下含义不同,跨引擎查询时必须显式限定,否则结果会静默错位。这类错误不会报错,只会返回错误的数据,是最危险的一类缺陷。
版本漂移是长期问题。PG每年发布一个大版本,系统视图、参数默认值、优化器行为都会变化。如果产品对外暴露的是某个特定版本的行为,客户升级就会踩坑。稳妥的做法是把对外契约限定在SQL标准与稳定接口上,不承诺系统视图的字段稳定性,同时在文档里明确标注版本差异。
混合负载下的隔离级别冲突
把分析查询放进事务实例,最先出问题的不是CPU,而是清理机制。
PG使用多版本并发控制,更新不覆盖旧行,而是写入新版本并把旧版本标记为死元组。死元组由vacuum异步回收。回收的前提是没有更老的事务还需要看到旧版本。一个跑了两小时的分析查询会持有一个老快照,导致这两小时内产生的所有死元组都无法回收,表体积持续膨胀。
膨胀的后果是连锁的。表变大,扫描变慢,索引变深,缓存命中率下降,更多查询变慢,长事务更多。这是一个正反馈回路,一旦进入就很难靠加资源解决。
隔离级别本身也有语义差异。PG默认的read committed在每个语句开始时取新快照,同一条语句内看到一致的数据,不同语句之间可能看到不同版本。数仓通常提供语句级或事务级的快照隔离,一个查询全程看到同一时刻的数据。把依赖快照一致性的报表逻辑搬到read committed下,会出现同一张报表内数字对不上的情况。
sql
SHOW default_transaction_isolation;
SET statement_timeout = 30000;
SET idle_in_transaction_session_timeout = 60000;
这三个参数是混合负载环境的最低防护线。语句超时防止单条查询无限占用资源,空闲事务超时防止应用忘记提交导致快照长期持有。生产环境还应该配置连接池级的事务超时,因为应用层的连接泄漏往往比SQL本身更常见。
更彻底的做法是物理隔离。事务实例只承接点查与短事务,分析查询路由到只读副本或独立的列存引擎,两者之间用逻辑复制同步。副本上的长查询不会阻塞主库清理,主库的膨胀风险被隔离。代价是副本延迟,读到的数据可能落后几百毫秒,业务上需要明确哪些读可以接受延迟。
还有一种折中是资源组。PG本身没有内置的资源组,需要依赖cgroup或扩展做CPU与IO的配额划分。这类方案能隔离CPU,但隔离不了共享缓冲区与锁,效果有限。真正需要强隔离的场景,还是应该走物理分离。
跨引擎查询路由与优化器改造
客户不会满足于两套系统各自为政,跨引擎查询是必然需求。实现方式主要有两种,联邦查询与集中路由。
联邦查询依赖外部数据包装器。postgres_fdw允许一个PG实例把远端PG的表映射成本地表,查询时把谓词、聚合、连接下推到远端执行,只把结果拉回本地。这套机制的成熟度高,但下推能力有限,复杂的窗口函数、部分聚合、非等值连接往往无法下推,退化成全表拉取。
sql
EXPLAIN VERBOSE
SELECT o.id, o.amount, c.region
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.created_at > reference_time
ORDER BY o.created_at DESC
LIMIT 100;
看执行计划时重点关注Remote SQL部分。如果远端SQL里没有时间条件,说明谓词没有下推,等于把整表拉到了本地。这种情况在跨引擎场景下极其常见,根因通常是统计信息缺失或类型不匹配导致优化器判断下推不划算。
集中路由是另一条路。在引擎之上加一层代理,解析SQL,按表血缘判断每张表落在哪个引擎,生成分布式执行计划,把子查询分发下去再归并结果。这套架构的灵活性高,但需要自己实现SQL解析、代价估算、结果归并、事务语义,工程量相当于造一个分布式查询层。
代价模型的差异是跨引擎优化的核心难题。两个引擎的统计信息口径不同,行数估算、选择率、IO成本、CPU成本的量纲都不一样。用一个统一的代价模型去比较两个引擎的执行方案,结论往往不可靠。实践中更稳的做法是基于规则的静态路由,按表的数据量、查询类型、是否点查做硬判定,把优化交给各引擎自己。
路由的边界要写进文档,不能靠优化器猜。哪些查询走行存,哪些走列存,超过多少行强制走列存,跨引擎连接禁止超过几张表,这些规则必须是显式的、可测试的、可回滚的。把路由策略当成黑盒,出问题时无法定位。
结果归并阶段还要处理类型对齐。两个引擎对数值精度、时间戳时区、字符串排序规则的处理可能不同,归并时会出现精度丢失或排序错乱。跨引擎查询的测试用例必须覆盖这些边界,而不是只测功能是否跑通。
成本模型与计价口径的重构
两套系统并存,账单会成为第二个战场。
数仓的计价通常按计算资源的使用时长折算成信用点,存储按容量计费,查询按扫描字节数计费。这种模型鼓励客户把数据压缩好、分区设计好,因为扫描越少越便宜。事务数据库的计价通常按实例规格加存储加IOPS计费,与查询复杂度无关,与连接数无关。两种模型的激励方向完全不同。
混合部署后,一个客户可能同时产生两类账单。如果分析查询被路由到事务实例上执行,客户会看到事务实例的CPU被打满,同时数仓的信用点消耗没有变化。账单上看不出问题,性能上已经出事。这类错配在实际项目里非常普遍,根因是路由策略与计价模型没有对齐。
合理的做法是让计价口径跟随执行位置,而不是跟随数据位置。查询在哪个引擎执行,就按那个引擎的计价规则计费,并在账单上标注执行引擎。这样客户能直观看到成本分布,也能据此调整路由策略。
TCO对比要拆到具体项,不能只看单价。数仓的单价看似高,但按需启停、无运维人力,闲时成本接近零。事务实例的单价看似低,但要按峰值配置,且需要DBA投入。混合架构还要加上跨引擎同步的链路成本、双份存储成本、以及数据一致性校验的工程成本。这三项在早期评估里几乎总被忽略,上线后往往占总成本的相当比例。
存储成本的计算也要小心。行存的存储效率远低于列存,同样的数据量,行存占用可能是列存的三到五倍,因为列存有压缩而行存没有。把明细数据同时放进两套系统,存储成本会翻倍增长。可行的做法是热数据放行存、冷数据放列存,用生命周期策略自动迁移,而不是全量双写。
迁移落地的分阶段步骤
把一套系统从纯数仓迁到混合架构,必须分阶段推进,每个阶段有明确的验收标准与回滚方案。
第一阶段是盘点与分级。把所有表和查询打上标签,标注访问模式、数据量、更新频率、延迟要求、一致性要求。分级结果决定每张表落在哪个引擎。这一步的产出是一张清单,不是一份方案文档。清单不完整的项目,后面必然返工。
第二阶段是建立双写通道。新写入同时进两套系统,用逻辑复制或应用层双写。这个阶段只验证写入链路是否通,不切换读流量。验收标准是两边行数一致、校验和一致、延迟在阈值内。校验要按分区做,全表校验在大数据量下跑不完。
第三阶段是灰度读切流。按查询维度切,先切低风险报表,再切点查接口,最后切核心交易链路。每次切流后观察错误率、延迟分位值、慢查询数量。任何一项超标立即回滚。灰度比例按1%、10%、50%、100%推进,每个档位至少观察一个业务高峰。
第四阶段是一致性验证。切流稳定后,用影子读比对两边结果。比对不能只比行数,要比值级校验和,按主键分桶抽样。差异必须逐条归因,不能笼统归为精度问题。
text
迁移验收清单
写入延迟 P99 小于 10 毫秒
复制延迟 P99 小于 2 秒
行数差异为零
值级校验和差异为零
慢查询数量不高于基线
回滚演练通过一次
第五阶段是回滚能力验证。回滚方案必须在切流前演练过一次,而不是写在文档里。演练内容包括切换开关、数据回补、缓存清理、下游通知。没有演练过的回滚方案等于没有方案。
第六阶段是旧链路下线。切流稳定运行两周后,可以下线旧写入通道,但要保留只读访问至少一个月,用于历史数据查询和事后审计。下线太快会导致无法追溯,这在合规场景下是硬伤。
典型失败案例与误区清单
第一个误区是把报表直接迁到行存。报表的典型特征是宽表全扫、多表关联、聚合计算,这些恰好是行存的弱项。迁移后单条报表从三秒变成三分钟,根因不是参数没调好,而是存储布局不匹配。正确的做法是把报表留在列存,只把点查和事务迁到行存。
第二个误区是忽略膨胀治理。行存上线三个月后表体积涨了三倍,查询变慢,磁盘告警。排查发现是长事务阻塞了清理,而长事务来自一个忘记提交的定时任务。这类问题的解法不是加磁盘,是把监控做到事务年龄维度,超过阈值就告警。
第三个误区是用逻辑复制做双向同步。两边同时写入,冲突无法自动消解,重放报错后整条链路停摆。正确的做法是明确单向主写,另一边只读,需要双向时必须做应用层的冲突规避,而不是指望数据库解决。
第四个误区是扩展版本升级断裂。生产环境装了一个社区扩展,PG主版本升级后扩展没有对应版本,实例起不来。这类问题的解法是在选型阶段就确认扩展的维护活跃度与版本支持矩阵,并且把扩展升级纳入例行演练。
第五个误区是认为行存能替代MPP。行存在单节点上很强,但跨节点的并行扫描、数据重分布、大规模聚合是另一套工程。把百亿级明细放进行存做分析,节点数加到一个临界点后,网络与协调开销会吃掉所有收益。这个临界点通常在几十个节点,具体取决于查询的关联深度。
第六个误区是低估运维复杂度。两套系统意味着两套备份、两套监控、两套升级流程、两套故障预案。团队规模不变的情况下,运维负担翻倍,最终表现为告警响应变慢、变更事故增多。混合架构的前提是运维能力先到位,而不是上线后再补。
第七个误区是把兼容性当成等价性。能连上、能跑SQL,不代表语义一致。空值排序、字符串比较、除零行为、时间戳精度、隐式类型转换,这些细节在两个引擎之间几乎必然存在差异。迁移测试必须覆盖这些边界,否则会出现静默的错误结果。
技术选型的观察指标
判断一个云数仓厂商的PostgreSQL能力是否可用,看指标比看发布会靠谱。
提交延迟的P99是第一指标。平均值没有意义,事务负载的体验由尾部延迟决定。要求厂商给出同可用区、跨可用区两种部署下的P99数据,并说明测量方法。没有测量方法的数字不可信。
单节点事务吞吐与连接数是第二指标。PG的进程模型决定了连接数上去后上下文切换开销显著,连接池是必需品而非优化项。要确认厂商是否提供内置连接池,以及池化后的事务语义是否保持。
复制延迟是第三指标。跨引擎同步的延迟直接决定了分析结果的时效性。要区分常态延迟与追平能力,后者指积压一小时后能否在合理时间内追平。只有常态数据的产品,遇到批量导入就会崩。
扩展兼容矩阵是第四指标。哪些扩展可以装、哪些版本、升级路径如何、是否支持客户自带扩展。这份矩阵的完整度反映了厂商对生态的理解深度。只支持少数几个扩展的产品,本质上还是一个封闭系统套了一层PG协议。
上游贡献度是第五指标。厂商向上游提交了多少补丁、合并周期多长、是否参与社区版本发布。贡献度高的厂商,其私有改动更容易回流,长期维护成本更低。完全不贡献的厂商,其分支会随时间与上游越走越远。
故障恢复指标是第六指标。主备切换耗时、切换后的数据丢失窗口、脑裂防护机制、备份恢复的RTO与RPO。这些指标在平稳期看不出差别,在故障时才决定业务能否存活。
最后要看的是一致性承诺的表述精度。强一致、最终一致、读己之写这些词在不同产品里的含义差别很大。要求厂商给出具体场景下的行为描述,例如主备切换后多久能读到最新写入、跨引擎查询能否保证同一快照。表述越具体,产品越可信。
把这几项指标放在一起,可以对一个产品的成熟度做出相对可靠的判断。收购只是起点,把PostgreSQL真正做成可运维、可扩展、可承诺的产品,还需要在存储层、元数据层、事务层各走一遍完整的工程路径。这条路没有捷径,只能一版一版地磨。