PostgreSQL 复制与高可用系列(七):架构全景与选型决策——从单点到韧性系统

PostgreSQL 复制与高可用系列(七):架构全景与选型决策——从单点到韧性系统 前六期围绕 PostgreSQL 的复制与高可用展开了一次系统性探索:从 WAL 日志的物理本质,到流复制与逻辑复制的协同;从同步/异步的模式权衡,到 PITR 的恢复实践;最后以 Patroni 的生产级部署收束,完成了高可用技术的完整拼图。 作为系列收官之作,第七期将鸟瞰全局:比较主流高可用方案的适用边界,剖析级联复制与读写分离的水平扩展形态,给出业务导向的选型模型,并展望云原生与智能化时代的技术演进方向。最终帮助读者建立起从“能搭”到“会选”再到“懂演进”的完整能力。 一、补充篇:级联复制与读写分离 前六期主要聚焦于主从两层架构。但在实际大型系统中,级联复制和读写分离往往是必须具备的能力,本节系统地补上这两块知识。 1.1 级联复制(Cascading Replication) 定义:备库不仅可以从主库接收 WAL 流,还可以将 WAL 转发给下游的其他备库,形成以主库为根、多级节点的树状复制拓扑。 使用场景: 减轻主库连接压力:当从库数量众多时(如 50 个),主库的 max_wal_senders 可能成为瓶颈。级联复制允许将大部分从库挂载在少数几个第一层备库下,大幅减少主库的 walsender 进程数。 跨地域部署优化:主库在北京,第一层备库部署在上海(跨地域 WAL 传输一次),上海再向杭州、南京等更多备库分发。这样只有一条跨地域链路,其它为低成本地域内链路。 隔离读取负载:报表分析等重型查询可挂在二级备库上,避免与核心备库争抢 I/O 资源。 配置方法:在一台备库的 postgresql.conf 中设置 max_wal_senders > 0,并将其 hot_standby = on。然后在更下游的备库的 primary_conninfo 中指向该级联备库的 IP 和端口。Patroni 支持通过 cascade_replication 参数来声明级联关系。 限制与注意事项: 级联层数不宜过深(建议 1~2 层),每增加一层,复制延迟会累加。 如果级联备库还开启了同步复制,需要仔细设计同步备库的确认链,避免 WAL 在中间节点阻塞。 1.2 读写分离架构 读写分离是扩展读能力的标准模式。在 PostgreSQL 生态中,通常有两种实现路径: 路径 实现方式 优点 缺点 内置流复制 + 中间件 主库处理写,备库(可多个)处理读,由中间件(PgBouncer、HAProxy、pgpool-II)根据 SQL 类型或语句关键字路由 透明、灵活、对应用影响小 中间件成为潜在瓶颈;需要识别只读事务 逻辑复制 + 应用层路由 应用代码里显式区分读写连接池 无需中间件,全掌控 侵入代码,容易遗漏 生产环境推荐使用 PgBouncer 或 HAProxy + pg_stat_replication 的轻量级方案。PgBouncer 不仅支持读/写分离池,还能复用连接,减少后端连接数。 拆分读请求时,需要注意: 延迟敏感型读:必须读主库(如刚提交的订单详情) 最终一致性读:可以读备库,即使有几百毫秒延迟也可以接受 SHOW 命令如何处理?SHOW ALL 等命令在不同节点上返回结果可能不同,建议一律路由到主库。 pgpool-II 的局限性:pgpool-II 是比较老牌的中间件,但它采用了部分侵入式解析 SQL 进行负载均衡的策略,在一些 ORM 复杂查询场景下易出 Bug,目前使用 Patroni + HAProxy + PgBouncer 组合更普遍。 二、主流高可用方案全景对比 除了 Patroni,PostgreSQL 生态中还有多种高可用方案可供选择。它们的设计哲学和适用场景各有不同。 方案 选主依赖 自动切换 脑裂防护 运维复杂度 典型场景 Patroni DCS(etcd/Consul/ZooKeeper/K8s) ✅ 是 Watchdog + 多数派 中等 绝大多数生产环境(推荐) repmgr 自研选举,基于 pg 元数据表 ✅ 是 多数派投票 较低 中小规模、不想引入外部依赖的口碑工具 pg_auto_failover 内置监视器(PostgreSQL + 监听组) ✅ 是 自动隔离节点(Citus Data 出品) 较低 云场景、托管服务、简化运维 Stolon DCS(etcd/Consul) ✅ 是 DCS 租约 + 代理层屏蔽 较高 Kubernetes 早期选手,曾流行但社区趋缓 PAF (ClusterLabs) Pacemaker + Corosync ✅ 是 资源约束 + 隔离设备 高 传统数据中心,已有 Pacemaker 运维体系的团队 自写脚本 + 流复制 无 / 手工 ❌ 否 无 高 简单测试或非常规需求(不推荐生产) 云托管(RDS/Aurora) 云厂商内部实现 ✅ 是 云平台保障 极低(SaaS) 不想自建基础设施、追求极简运维 选型解读: Patroni 是社区事实标准,适合需要成熟、可控、可扩展的企业。 repmgr 更轻量,适合不想引入第三方 DCS(如 etcd)的团队,但它的脑裂防护能力弱于 […]

PostgreSQL 复制与高可用系列(六):Patroni生产级高可用集群部署——自动容灾与 K8s 集成

PostgreSQL 复制与高可用系列(六):Patroni生产级高可用集群部署——自动容灾与 K8s 集成 前五期完成了从物理流复制到逻辑复制、从 WAL 内核到 PITR 备份恢复的全链路学习。每一期都在夯实一个核心理念:高可用不仅仅是一句口号,而是由一套环环相扣的技术体系保障的运行韧性。 但前五期的所有知识还存在一个缺口:故障切换需要人工介入。当主库在凌晨三点宕机时,依赖值班工程师执行pg_ctl promote的方式既慢又不安全。第六期将填补这个缺口——全面系统地介绍 Patroni,这款 PostgreSQL 生态中最流行的高可用自动化管理工具。 一、为什么需要 Patroni 1.1 传统方案的痛点 前五期中,我们已经掌握了手动搭建流复制集群的全部技能,包括配置同步/异步模式、修复pg_rewind回切等。然而,仅靠手工运维,会持续面临三个令人头疼的问题: 主库故障时,切换需要人工介入:DBA 需要登录备库执行pg_ctl promote、确认新主库并重新配置其他备库的primary_conninfo。RTO 取决于人的响应速度,通常在数分钟到数十分钟之间,且在凌晨故障时会被拉得更长。 最令人担忧的是:如果故障发生在深夜,RTO 可能被拉长到小时级,甚至需要等工程师醒来。 脑裂风险难以消除:流复制本身没有选主机制。当网络分区发生时,旧主库继续接收写入,新提升的备库也在接收写入,两套数据同时在线且产生分歧——后期很难恢复。 配置变更需要逐节点手动操作:修改流复制参数或集群规模时,需要在每个节点上分别编辑配置文件并重启,极易出现人为疏漏。 Patroni 的核心价值:将这些令人头疼的操作——故障检测、选主、切换、配置同步、备库重建——全部自动化,让 DBA 从”应急抢险”转向”架构设计”。 流复制解决的是数据同步问题(技术能力),Patroni 解决的是故障切换的自动化问题(运维闭环)。二者的关系是:流复制是 Patroni 赖以工作的数据同步底座,Patroni 则是流复制的自动化管理中枢。 1.2 Patroni 是什么 Patroni 是一个用 Python 编写的 PostgreSQL 高可用管理工具,起源于 Compose 公司的 Governor 项目,经过社区持续开发后成为业界事实标准。它在每个数据库节点上运行一个 Patroni 进程,控制本地的 PostgreSQL 实例,同时通过一个分布式配置存储(DCS,Distributed Configuration Store)来协调集群状态和领导选举。 核心设计理念:数据库的自治化运维——数据库的健康检查、角色切换、配置更新等由控制器自动完成。 DCS 在 Patroni 架构中的作用,可以理解为以下三个维度: 功能维度 DCS 存储的内容 对集群的意义 领导选举 Leader Key + TTL 确保持锁的唯一节点是主库 成员注册 每个 Patroni 节点的 IP、端口、角色、LSN 位置 所有实例知晓集群完整拓扑 集群配置 PostgreSQL 参数、同步复制模式、TTL 等 一次修改、全体生效 二、Patroni 架构全景 2.1 核心组件 组件 角色 说明 Patroni 高可用管理器 每个 PostgreSQL 节点运行一个实例,负责启动/停止/监控 PG 并参与 DCS 选主 DCS(etcd/Consul/ZooKeeper) 分布式配置存储 存储集群拓扑、Leader 锁、同步复制状态;使用 Raft 协议确保一致性 Watchdog 防脑裂守护 监控 Patroni 心跳,若 Patroni 僵死则重启系统,防止旧主库继续提供写服务 HAProxy 负载均衡器 作为接入层,根据 Patroni REST API 将写流量路由到主库、读流量路由到从库 Keepalived VIP 管理器 为 HAProxy 节点提供虚拟 IP 漂移,消除负载均衡器本身的单点 2.2 故障切换的时间线 当主库宕机时,Patroni 的自动故障转移过程如下: T+0s: 主库(PostgreSQL进程或所在主机)崩溃 T+10s: Patroni 通过健康检查检测到主库无响应(取决于 loop_wait 配置) T+30s: Leader key 在 DCS 中的 TTL 租约超时,Leader 锁自动释放 T+31s: 各备库的 Patroni 竞争 Leader 锁 T+32s: 某一备库赢得锁,执行 pg_promote 将自己提升为新主库 T+33s: 其他备库重新配置,将新主库设为上游,继续流复制 T+35s: HAProxy 通过 Patroni REST API 感知到主库变化,开始将写流量路由到新主库 故障转移可在约 35 秒内完成。如果业务对 RTO 要求更严,可调低ttl和loop_wait,但需要谨慎权衡网络波动带来的误切换风险。 2.3 Watchdog 如何防止脑裂 脑裂(Split-Brain)是最危险的高可用故障场景:旧主库因网络分区与集群隔离,但仍以为自己持有 Leader 锁,继续对外提供写服务,同时 DCS 侧选出了一个新主库也在写——两边数据分道扬镳,事后无法合并。 Patroni 的解决方案是 DCS TTL + 本地的 Watchdog 双线保护: DCS 层防护:Leader 锁带有 TTL 租约,旧主库若无法续租,Leader 锁自动释放,集群将选出一个新主库。但如果旧主库处于单机网络分区,它看不到锁已释放,仍可能自认为还持有锁——这是风险依然存在的地方。 Watchdog 层(最后一道防线):在每个数据库节点上运行,Patroni 会周期性向 Watchdog 发送心跳信号。当 Patroni 因故障或无法续租而无法发送心跳时,Watchdog 会强制执行系统重启(硬重启物理机),彻底将旧主库踢出服务,以此物理抹除任何对外服务的可能性。 […]

PostgreSQL 复制与高可用系列(五):WAL 内核揭秘与 PITR 备份恢复——把时间掌握在自己手中

PostgreSQL 复制与高可用系列(五):WAL 内核揭秘与 PITR 备份恢复——把时间掌握在自己手中 前四期我们系统学习了物理复制与逻辑复制的完整知识体系,从单机到主从,从同步到异步,从物理到逻辑。 但必须正视一个现实:复制虽然解决了连续性问题,却并非万能的。当一条 DELETE 语句漏写了 WHERE 条件,主从集群中的所有副本会忠实地复制这份错误,瞬间删除整张表。面对这样的情况,高可用方案往往无能为力——它只能应对硬件故障,而非人为失误。 第五期将深入 WAL 这一数据库的”黑匣子”,系统梳理基于连续归档的备份恢复体系,这是数据安全的最后一道防线,也是每一位数据库工程师必须掌握的核心能力。 一、一个真实的事故与两条不可替代的生命线 事故还原:某企业在生成环境的一次数据迁移过程中,误执行了 TRUNCATE TABLE orders CASCADE,涉及近两年的核心交易数据。幸存的物理备库忠实地重放了这条 WAL 记录,同样的错误如同蝴蝶效应般在两套副本间先后完成。 危机:总共有三份数据——一份主、两份备——却在几分钟内全部被清空。团队试图从昨天的全量备份恢复,但恢复后需手动重跑丢失的 WAL,人工介入成本极高。 两条生命线:事故之后,团队复盘出两条必须并行的生命线: 场景 应对技术 作用 硬件故障 / 服务器宕机 高可用主从切换(流复制 + Patroni) 秒级恢复,RTO 分钟内 数据误删除 / 逻辑破坏 PITR(基础备份 + WAL 持续归档) 可回滚至任意时间点 本期的核心观点:高可用不等于备份恢复。两套体系必须同时存在、互为补充。正如《PostgreSQL Backup and Disaster Recovery Strategies》中所述:“Backups are only valuable when you can restore them reliably, quickly, and to the right point in time.” 备份只有在“确实可用”且“能恢复到正确的时间点”时才有价值。 在正式展开之前,需要先澄清一个概念:在 PostgreSQL 中,“复制”和“归档”是两个平行且互补的机制——复制是流式的、实时的、用于连续性;归档是批量的、历史的、用于可恢复性。两者的差异如下: 维度 流复制(Replication) 持续归档 + PITR 数据流向 主库 → 备库(实时流式) 主库 → 归档存储(批量完成) 主要目标 高可用 + 读扩展 + RPO 极低 时间点恢复 / 人为错误回滚 WAL 来源 流式传输,尚在 pg_wal 中 已完成的 WAL 段文件 适用场景 硬件/网络/OS 故障容灾 数据误删、逻辑错误回溯 可恢复的时间窗口 仅当前(备库状态) 任意历史时间点(只要有完整 WAL 链) 二、WAL 原理:PostgreSQL 的数据动脉 2.1 一句话定义 预写式日志(Write-Ahead Logging,WAL)的核心原则是:在数据页落盘之前,对应的日志记录必须先安全地写入磁盘。这个简单的顺序约束是 PostgreSQL 持久性的坚实保障。 2.2 WAL 的运行时结构 WAL 机制在运行时的核心结构可概括为:一个不断增长的有序日志文件集合 + 一个记录当前进度的 LSN 指针系统。 更具体地说,WAL 运行时的结构包含以下要素: LSN(Log Sequence Number):WAL 中以字节为单位的单调递增偏移量,标记日志记录在 WAL 中的逻辑位置。LSN 是复制进度、恢复起止、延迟计算的唯一标尺。 WAL 段文件:物理存于 $PGDATA/pg_wal/ 目录,每个段文件默认 16 MB,文件名按 时间线ID+逻辑ID+物理ID 三级编码,格式为 24 位十六进制数。 WAL 页面(Page):每个段文件分为 8 KB 的页面,存储日志记录头部与内容。 后台进程: WAL Writer:负责将 WAL 缓冲区刷写到磁盘。与数据写不同,它运行在一个专用的后台进程中,且不受 bgwriter 控制。 Checkpointer:周期性执行,记录检查点(Checkpoint)位置,待崩溃恢复时从该点开始重放所有后续 WAL 记录。 2.3 pg_control:崩溃恢复的”起爆点” 当数据库崩溃后重启,如何知道从哪里开始重放 WAL?答案藏在 pg_control 文件中。Checkpointer 进程每次完成检查点后,会将当前重做点的位置写入 pg_control 文件中。崩溃恢复启动时,系统首先读取 pg_control 找到最新的检查点位置,然后从此处开始向前扫描 WAL 记录执行 REDO 操作。 2.4 检查点:既要安全,也要性能 自动检查点:由 checkpoint_timeout(默认 5 min)和 max_wal_size 共同触发。 full_page_writes:在每次检查点后的第一次页修改时,WAL 中记录完整的数据页副本,以保证部分写入故障时能恢复完整的页内容。此参数默认为 on,关闭会显著降低 WAL 写量,但会破坏备库从基础备份恢复的能力。 2.5 WAL 的两种”生命路径” 崩溃恢复路径:WAL 顺序重放至最新状态,数据文件更新到崩溃前一刻——每次数据库启动都隐含执行此过程。 复制与归档的路径:WAL 段落被完整复制到其它节点,或移入归档目录以用于 PITR。 2.6 WAL […]

PostgreSQL 复制与高可用系列(四):逻辑复制深度实战——跨版本迁移、数据分发与冲突处理

PostgreSQL 复制与高可用系列(四):逻辑复制深度实战——跨版本迁移、数据分发与冲突处理 前三期我们完成了物理流复制从理论到实战的全链路学习,掌握了高可用架构的基石。 但物理复制有一个天然局限:它复制的是整个数据库集群,无法“选择性地同步几张表”,也不能在主备之间做异构同步(比如 12 → 17 跨大版本)。 第四期将聚焦逻辑复制——这张灵活的“手术刀”,为您打开数据同步的全新维度。 一、逻辑复制是什么? 1.1 定义与定位 逻辑复制是一种基于数据对象的复制标识(通常是主键)来复制数据对象及其更改的方法。这里使用“逻辑”一词来与物理复制(基于块地址和逐字节复制)加以区分——物理复制关注的是磁盘上数据块的变化,而逻辑复制关注的是数据的语义变化(插入、更新、删除)。 核心特点:PostgreSQL 同时支持物理复制和逻辑复制两种机制,两者可以并行运行,不互斥。这给了架构设计极大的灵活性。 1.2 架构:一次 WAL 的两面使用 逻辑复制的架构与物理流复制类似,同样由 walsender 和 apply 进程协作实现: 发布者:walsender 进程启动对 WAL 的逻辑解码,加载标准输出插件 pgoutput。该插件将从 WAL 读取的变更转化为逻辑复制协议,并根据发布(Publication)规范进行筛选。 传输:数据通过流复制协议持续传输到订阅者的 apply 工作进程。 订阅者:apply 进程将数据映射到本地表,并按照发布者上的提交顺序应用这些变更,确保事务一致性。 一个关键差异在于:逻辑复制 不会复制 DDL 命令——数据库模式和 DDL 命令不被复制。这一点下文会单独讨论。 至于订阅者的触发器行为,默认设置是会话复制角色为 replica,因此默认情况下触发器不触发;但用户可以通过 ALTER TABLE ... ENABLE TRIGGER 手动启用。 1.3 WAL 级别要求:一个关键决策点 逻辑复制要求 wal_level 设置为 logical。这个级别会写入比 replica 更多的 WAL 信息,以满足逻辑解码器的需求。请注意,设置为 logical 会增加 WAL 日志体积,可能对性能产生一定负面影响,因此在选择前需要审视具体的业务负载。如果只是临时启用逻辑复制(如一次性迁移),建议完成后恢复到 replica 以降低 WAL 开销。 二、发布与订阅模型 逻辑复制基于发布/订阅(Publication/Subscription)模型。概念定义如下: 发布者:数据来源方,定义哪些表需要被复制(发布或 Publication) 订阅者:数据目标方,定义连接信息和要订阅的发布(订阅或 Subscription) 复制槽:发布者上持久化的标记,记录每个订阅者的消费进度,防止 WAL 被过早回收 2.1 创建发布(Publication) -- 发布指定表的 INSERT 和 UPDATE(默认同步所有 DML) CREATE PUBLICATION my_publication FOR TABLE users, orders; -- 发布所有表(慎用,对系统表也会产生影响) CREATE PUBLICATION all_tables FOR ALL TABLES; -- 控制发布的 DML 类型:只复制 INSERT 和 UPDATE,不复制 DELETE CREATE PUBLICATION insert_update_only FOR TABLE users WITH (publish = 'insert, update'); -- 仅发布部分列(最小化发送开销) CREATE PUBLICATION limited_columns FOR TABLE users (id, name, email); publish 参数的可选值包括:insert、update、delete、truncate,默认为全部四种。 2.2 创建订阅(Subscription) -- 基础订阅:连接发布者并开始实时复制 CREATE SUBSCRIPTION my_subscription CONNECTION 'host=192.168.1.10 port=5432 dbname=mydb user=replicator password=xxx' PUBLICATION my_publication; -- 仅复制新增数据,不拷贝已有数据(用于已有数据的场景) CREATE SUBSCRIPTION delta_only CONNECTION '...' PUBLICATION my_publication WITH (copy_data = false); -- 禁用复制槽自动创建(专家场景,性能调优用) CREATE SUBSCRIPTION manual_slot CONNECTION '...' PUBLICATION my_publication WITH (create_slot = false, enabled = false); 一个订阅可以订阅来自同一个发布者的多个发布。当创建订阅时,如果 copy_data = true(默认),将在开始逻辑复制前,自动将发布者上的已有数据快照拷贝到订阅者。 2.3 查看与管理 -- 查看发布列表 SELECT * FROM pg_publication; -- 查看发布的表 SELECT * FROM pg_publication_tables; -- 查看订阅列表与状态 SELECT * FROM […]

PostgreSQL 复制与高可用系列(三):同步与异步复制工程实践——RPORTO 量化与性能权衡

PostgreSQL 复制与高可用系列(三):同步与异步复制工程实践——RPO/RTO 量化与性能权衡 第二期我们亲手搭建了流复制集群,验证了异步与同步两种模式的基本行为。 但生产环境中,“选同步还是异步”从来不是一道非黑即白的选择题——它涉及到业务对数据丢失的容忍度、对写入延迟的敏感度、网络基础设施的可靠性,以及预算与运维成本的综合权衡。 第三期将系统分析同步与异步复制的工程取舍,并给出可量化的决策模型。 一、开篇:一个真实的生产事故 某互联网公司采用 PostgreSQL 异步流复制搭建了主备高可用架构。某日凌晨,主库所在物理机因 SSD 损坏而宕机,系统按预案自动切换到备库。恢复服务后才发现,故障前 5 秒内写入的一笔高价值订单数据永远丢失了——因为该事务的 WAL 记录尚在主库内存中,未传输到备库。 事后分析,RPO 约等于 5 秒。对于该公司的主力业务,RPO 要求是 0。这次事故直接推动他们将核心支付库从异步复制改造为同步复制,代价是写入延迟从 0.5ms 上升至 3ms,但换回了“零数据丢失”的确定性。 这个案例揭示了一个核心命题:异步与同步之间的选择,本质上是业务价值与技术成本的量化博弈。 二、从原理出发:异步与同步的运行时差异 在深入性能数据之前,先精确理解两种模式在事务提交路径上的差异。 2.1 异步复制的提交链路 客户端发起 COMMIT 主库将事务的 WAL 记录写入本地 WAL 缓冲区,并落盘到 pg_wal(如果 synchronous_commit = on,这里会等待本地磁盘确认;若设为 off,则延迟落盘) 主库向客户端返回“提交成功” 与此同时(步骤 2 之后,主库返回之前或之后,取决于实现细节),walsender 进程异步地将 WAL 记录发送给备库 关键点:主库不等待备库确认,RPO > 0。备库的接收进度落后于主库的写入进度,差额大小取决于网络延迟、带宽和主库写入负载。 2.2 同步复制的提交链路 客户端发起 COMMIT 主库将事务的 WAL 记录写入本地 WAL 并落盘 (同步点)主库阻塞,等待 synchronous_standby_names 中指定的备库返回确认(write、flush 或 apply 级别的确认) 收到确认后,主库向客户端返回“提交成功” 关键点:事务的持久化范围从主库扩大到了至少一个备库,RPO = 0(仅当确认级别为 flush 或 apply)。代价是主库提交延迟增加了至少一个网络 RTT + 备库落盘时间。 2.3 确认级别对延迟和数据安全的影响 PostgreSQL 通过 synchronous_commit 参数的多种取值,在性能与耐久性之间提供了精细的调节粒度: 参数值 含义 延迟影响 数据安全级别 off 本地 WAL 可延迟落盘(最多 64KB 或 commit_delay 毫秒) 最低 事务可能丢失(操作系统崩溃时) on 等待备库确认收到(write_lsn) 中等 备库确认即安全(但未刷新到备库磁盘) remote_write 等待备库确认写入内核 Page Cache 较低 备库宕机时可能丢失尚未落盘的数据 remote_apply 等待备库应用重放到数据文件 最高 读备库可保证读到已提交事务 生产建议:synchronous_commit = on(等待备库 flush)是最常用的“零数据丢失”配置。remote_apply 多数场景下过于严苛,仅在需要备库提供严格一致读时采用。 三、RPO/RTO 量化模型:用数据做决策 3.1 异步复制的 RPO 估算 在异步模式下,RPO 取决于在故障发生时刻,主库已提交但尚未被备库接收的 WAL 数据量。该滞后量的估算公式: RPO_max ≈ (主库写入速率 × 复制延迟窗口) 复制延迟窗口 = 网络 RTT + 主库 wal_sender 排队时间 + 备库接收处理时间 一个典型估算示例: 主库峰值写入:200 MB/s 复制延迟:平均 500ms RPO_max ≈ 200 MB/s × 0.5s = 100 MB 数据,对应约 20000 条 TPC-C 订单记录 如果业务无法承受这种量级的数据丢失,异步复制不可接受。 3.2 同步复制的 RTO 风险 同步复制虽然 RPO = 0,但引入了新的 RTO 风险:同步备库故障可能导致主库写入阻塞。假设同步备库因磁盘满而宕机,主库上所有写事务将 hang 住,直到人为干预(修改配置或将 synchronous_standby_names 置空)。这会导致业务不可用时间 RTO 迅速膨胀。 为了量化这种风险,可以采用 多数派同步 机制(见下文 4.2 节),将故障容忍性从单点提升到集群级别。 3.3 决策矩阵 业务场景 推荐模式 核心理由 金融支付、账户余额、订单核心链路 同步复制 + 多数派 零数据丢失是法律或合同要求 用户评论、行为日志、分析型数据 异步复制 丢失少量数据可接受,延迟敏感 跨地域灾备(RPO < 1s) 异步复制 + […]

PostgreSQL 复制与高可用系列(二):物理流复制实战——从零搭建主从集群

PostgreSQL 复制与高可用系列(二):物理流复制实战——从零搭建主从集群 第一期我们搭建了知识框架,认识了 WAL 基石、物理复制与逻辑复制的差异、同步与异步的血肉权衡。 第二期不再纸上谈兵——我们将动手搭建一个完整的流复制主从集群,逐行验证每个配置参数的实际效果。 一、搭建前的脑内基建 物理流复制的核心机制是将数据变更按字节级别复制到备库,这背后涉及三个核心进程的协作。主库上的 walsender 持续向外发送 WAL 流,并为每个备库分配一个独立进程;备库上的 walreceiver 接收传来的 WAL 数据;后台的 startup 进程将这些数据重放到数据文件中。当备库配置为 hot_standby = on 时,重放期间即可处理只读查询,这便是”热备”的技术实质。 在这一原理下,搭建一套主从集群只需完成三件事:全量基础备份初始化备库数据、配置连接与复制参数、启动备库并维持持续同步。 此外,PostgreSQL 12 是一个关键分界岭——recovery.conf 文件被正式废弃,所有配置统一纳入 postgresql.conf,备库模式通过创建 standby.signal 标记文件来声明。操作时务必确认版本差异。 二、环境准备 2.1 节点规划 角色 IP 地址 主机名 PostgreSQL 版本 主库 192.168.1.10 pg-primary 16+ 备库 192.168.1.20 pg-standby 16+ 两节点均建议使用同一 Linux 发行版,已安装相同版本的 PostgreSQL,并能相互网络可达。若两节点不同时初始化,需确保备库的 data 目录为空。 2.2 复制用户的创建 在主库上创建专用复制用户。REPLICATION 权限与 LOGIN 必须同时授予: CREATE USER replicator WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'SecureP@ssw0rd'; 主库的 pg_hba.conf 需要显式允许该用户从备库 IP 发起复制连接: # 考虑主备角色互换,建议主备 pg_hba.conf 保持一致 host replication replicator 192.168.1.20/32 md5 修改完 pg_hba.conf 后,执行 pg_ctl reload 使配置生效。 三、主库配置:开启复制的”开关” 编辑主库的 postgresql.conf,至少配置以下核心参数: # 基本复制配置 wal_level = replica # 生成足够 WAL 信息,物理复制必需 max_wal_senders = 10 # 最大 walsender 数量,每个复制消费者占用一个 wal_keep_size = 1GB # 主库保留的 WAL 总量,备库离线时的缓冲 synchronous_commit = off # 关闭同步提交(先行配置异步模式) # 热备支持(备库端生效,主库可选但建议保留) hot_standby = on 参数说明:wal_level 决定了 WAL 中包含的信息量,物理复制最低需要 replica 级别;max_wal_senders 需要至少大于备库数量,以便后续增加备库或执行 pg_basebackup 备份时留有裕量。wal_keep_size 可用于限制主库保留 WAL 的总量,避免磁盘被 WAL 撑满。 配置修改完成后,执行 sudo systemctl restart postgresql 重启让主库生效。 四、备库初始化:从主库拉取基础数据 4.1 备份主库数据并自动生成备库配置 PostgreSQL 提供了 pg_basebackup 工具,可对正在运行的主库进行一致性热备份,同时在线生成备库所需的连接与配置标记。这一工具不要求访问数据库底层文件系统,只需通过流复制协议连接即可安全完成备份。 由于 pg_basebackup 会覆盖目标目录,如备库的 data 目录已有数据,需先停止备库服务并清理目录: sudo systemctl stop postgresql sudo rm -rf /var/lib/postgresql/*/main/* 然后执行 pg_basebackup 从主库拉取完整数据: sudo -u postgres pg_basebackup -h 192.168.1.10 -D /var/lib/postgresql/16/main -U replicator -P -v -R -X stream -C -S pgstandby1 各参数含义如下: 参数 说明 -h / -U 指定主库地址与复制用户名 -D 指定备库数据存放路径 -P -v 显示备份进度与详细输出 -R 自动在数据目录中生成 standby.signal […]

PostgreSQL 复制与高可用系列(一):从单点到集群,构建生产级数据基石

PostgreSQL 复制与高可用系列(一):从单点到集群,构建生产级数据基石 PostgreSQL 已成为无数企业核心系统的首选数据库,但单机部署始终是一个绕不开的问题:单点就是风险。当硬件故障、网络波动或人为误操作不期而至时,缺乏高可用架构的应用将面临不可预测的停机时间,甚至数据丢失。 本系列旨在系统梳理 PostgreSQL 复制与高可用技术,从原理到实践,从基础到进阶。作为开篇,本文将聚焦于核心概念、技术演进与关键原理,帮助读者建立完整的知识框架,为后续的动手实践打下坚实基础。 一、为什么要谈复制与高可用? 1.1 核心驱动力 在生产环境中建设高可用体系,根本目的是满足两个关键指标: RPO(Recovery Point Objective):能容忍的最大数据丢失量,即灾难发生后,最多能接受丢失多长时间的数据。 RTO(Recovery Time Objective):能容忍的最大恢复时间,即从故障发生到服务恢复,允许经过多长时间。 这两个指标直接决定了架构设计的走向。追求 RPO=0(零数据丢失)往往意味着采用同步复制,而这可能牺牲写入性能;追求极低 RTO 则需要自动化故障切换能力,但又可能引入脑裂等风险。 1.2 复制的三大价值 复制不仅仅是高可用的技术手段,它带来的核心价值体现在三个层面: 价值维度 说明 高可用与容灾 主库故障时,备库可在秒级内接管服务,将停机时间从小时级压缩到秒级 读负载扩展 将读查询分发到只读备库,大幅提升系统整体吞吐能力 零停机运维 通过主从切换实现版本升级、硬件更换、系统维护,业务无感知 一个简单的论断值得记住:备份给你的是恢复能力,复制给你的是连续性。 二、技术演进与应用场景 PostgreSQL 的高可用与复制能力并非一蹴而就,其演进大致可划分为三个阶段: 时期 定位 关键成果 2000–2010 单机深耕 WAL 机制奠基,ACID 与 SQL 标准为核心,追求强一致性 2010–2020 复制时代 流复制(9.0)、热备(9.0)、逻辑复制(10.0)相继落地,读写分离成为标准能力 2020至今 云原生智能 Patroni、Kubernetes Operator、声明式运维、自愈系统成为主流 不同场景对复制技术有着不同的诉求。例如,金融交易系统需要同步复制来保证零数据丢失(RPO=0),而报表分析场景可能只需异步复制的读扩展能力即可满足要求。理解这一演进脉络,有助于我们在选型时做出符合自身业务阶段的决策。 三、数据同步的基石:WAL 在深入具体的复制方案之前,需要先认识 PostgreSQL 的核心机制——预写日志(Write-Ahead Log,WAL)。 3.1 WAL 的工作原理 WAL 记录了对数据库数据文件所做的所有更改。其核心原则是:在数据变更写入数据文件之前,先将变更记录写入日志。当系统崩溃时,PostgreSQL 可以通过“重放”自上次检查点以来的 WAL 记录,将数据库恢复到一致状态。 这个机制有两个关键意义: 崩溃恢复:无需依赖日志文件系统即可保证数据完整性。 复制的基础:WAL 记录正是数据同步的核心传输单位——无论是物理复制还是逻辑复制,数据变更的源头都来自 WAL。 3.2 持续归档与 PITR 除了用于崩溃恢复,WAL 还支撑着持续归档(Continuous Archiving)与时间点恢复(Point-in-Time Recovery,PITR)。这一能力的实现方式是:周期性执行文件系统级别的全量备份,同时持续归档此后生成的 WAL 文件。当需要恢复时,先还原全量备份,再按顺序重放归档的 WAL 文件,即可将数据库恢复到任意指定的时间点。 PITR 是应对数据误删除等人为错误的重要手段,属于备份恢复体系的利器,它与复制(维持在线备库)各司其职、互为补充。 四、物理复制 vs 逻辑复制:殊途同归的两种模型 PostgreSQL 提供两种核心复制技术——物理流复制和逻辑复制。理解两者的区别,是设计高可用架构的第一步。 4.1 物理流复制 原理:主节点将 WAL 日志(块级别的 REDO 记录)实时传输给从节点,从节点以相同顺序重放这些日志,从而在主从间建立起一份字节级别完全相同的副本。 从架构上看,主库通过 wal_sender 进程将 WAL 记录实时发送给备库,备库的 wal_receiver 进程接收并应用这些记录。配置层面的关键参数包括:wal_level = replica、max_wal_senders 用于控制并发发送进程数量,备库启用 hot_standby = on 以支持只读查询。 特点与适用: 维度 说明 粒度 整个数据库集群级别,不支持选择性复制 延迟 极低,可用于高可用和实时灾备 备库可读写 备库默认只读 跨版本 通常要求主备版本一致,升级时需要停机 典型场景 主从高可用、读写分离、灾难恢复 一句话总结:物理流复制是 PostgreSQL 高可用的主力方案,简单、可靠、高效。 4.2 逻辑复制 原理:基于发布/订阅(Publication/Subscription)模型,主节点将指定表的 WAL 日志解析为逻辑变更(如 INSERT/UPDATE/DELETE),订阅节点接收并应用。 逻辑复制的架构与物理流复制类似,同样通过 walsender 和 apply 进程实现,但工作在不同层次。其关键配置要求为 wal_level = logical,同时需要提前创建发布和订阅对象。 特点与适用: 维度 说明 粒度 表级选择性复制,可按需同步 灵活性 订阅端可写入其他数据,甚至可与其他版本 PG 同步 限制 需手动处理 DDL 变更,不支持 DDL 自动同步 典型场景 数据集成、跨版本迁移(如 12→15)、微服务数据分片 值得注意的是,物理复制与逻辑复制并非互斥——在实际生产中,经常将两者结合使用,例如通过物理复制构建高可用集群,同时在从库上配置逻辑复制将特定表数据同步至分析型数据库。 4.3 选型决策:一张表快速判断 如果您的需求是… 推荐方案 整个集群的高可用容灾 ✅ 物理流复制 读写分离、读负载扩展 ✅ 物理流复制 跨 PostgreSQL 大版本升级 ✅ 逻辑复制 仅同步部分表到另一个库 ✅ 逻辑复制 接收端也需要写入 ✅ 逻辑复制(需处理冲突) 零数据丢失(RPO=0) ✅ 物理同步复制 + 多数派确认 五、同步 vs 异步:性能与安全之间的权衡 在物理流复制的基础之上,还有一个至关重要的配置选项:同步模式。 5.1 异步复制 主库提交事务后无需等待备库接收确认,直接返回客户端成功。这是 PostgreSQL 流复制的默认模式。 优势:对主库性能影响最小,备库不可用时不影响主库服务。 风险:主库宕机时,可能丢失尚未传输到备库的 WAL 数据,RPO > […]

PostgreSQL 存储与索引系列(四):高级调优与内核机制——并发、日志、内存与分区

PostgreSQL 存储与索引系列(四):高级调优与内核机制——并发、日志、内存与分区 这是系列第四期,也是收官之篇。我们将深入 PostgreSQL 的高级特性与性能调优核心:并发控制与锁、事务隔离级别、预写日志(WAL)与检查点、关键内存参数调优,以及分区表的维护策略。结合前三期的存储和索引知识,你已具备构建高可用、高性能 PostgreSQL 系统的完整视图。 1. 并发控制与锁机制:避免踩踏的艺术 PostgreSQL 采用 MVCC(多版本并发控制) 实现读写不互斥,读不阻塞写,写不阻塞读。但某些操作(如 DDL、外键维护、显式锁)仍需传统锁机制。理解锁层级是避免死锁和性能瓶颈的前提。 表级锁模式(从弱到强) ACCESS SHARE:SELECT 获取,与 ROW EXCLUSIVE 兼容。 ROW SHARE:SELECT FOR UPDATE/SHARE,防止并发 DROP TABLE。 ROW EXCLUSIVE:INSERT/UPDATE/DELETE 默认锁,允许并发读取但阻止 DDL 修改表结构。 SHARE UPDATE EXCLUSIVE:VACUUM、CREATE INDEX CONCURRENTLY、REINDEX CONCURRENTLY。防止并发 schema 变更和某些 vacuum。 SHARE:CREATE INDEX(非并发),阻止写但允许读。 SHARE ROW EXCLUSIVE:CREATE TRIGGER 等较少使用。 EXCLUSIVE:REFRESH MATERIALIZED VIEW CONCURRENTLY,阻止并发读写。 ACCESS EXCLUSIVE:DROP TABLE、TRUNCATE、REINDEX(非并发)、VACUUM FULL。最强锁,与所有其他锁冲突。 行级锁与死锁检测 行锁不是通过内存中的锁结构,而是通过元组头部的 t_xmax 和事务状态实现。 SELECT FOR UPDATE 会真正锁定行,防止其他事务修改或加锁。 死锁自动检测:PostgreSQL 有 deadlock_timeout(默认 1 秒)参数,超时后检测并回滚其中一个事务。 避免锁争用的最佳实践 长事务:避免在事务中执行不必要的 SELECT 或等待用户输入,会长时间持有锁。 在线 DDL:优先使用 CREATE INDEX CONCURRENTLY、REINDEX CONCURRENTLY、ALTER TABLE ... ADD COLUMN ... DEFAULT ...(非空默认值重写表,注意!)。 批量删除/更新:分批处理,减少单事务持锁时间。 监控锁等待:pg_locks + pg_stat_activity 定位阻塞链。 -- 查看当前锁等待 SELECT blocked_locks.pid AS blocked_pid, blocking_locks.pid AS blocking_pid, blocked_activity.query AS blocked_query FROM pg_locks blocked_locks JOIN pg_locks blocking_locks ON blocked_locks.locktype = blocking_locks.locktype AND blocked_locks.relation = blocking_locks.relation AND blocked_locks.pid != blocking_locks.pid JOIN pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid WHERE NOT blocked_locks.granted; 2. 事务隔离级别:平衡一致性与性能 PostgreSQL 支持 SQL 标准定义的四种隔离级别,但实际只有三种可配置:READ COMMITTED(默认)、REPEATABLE READ、SERIALIZABLE。 隔离级别 脏读 不可重复读 幻读 序列化异常 READ COMMITTED 不可能 可能 可能 可能 REPEATABLE READ 不可能 不可能 不可能(PG 实现) 可能 SERIALIZABLE 不可能 不可能 不可能 不可能 实现原理: READ COMMITTED:每条语句看到语句开始时的已提交快照。可能出现同一事务内两次查询结果不同的不可重复读。 REPEATABLE READ:使用事务第一个语句时的快照(MVCC 快照)。基于 xmin/xmax 判断可见性。如果事务中有更新被另一并发事务提交并影响本事务更新条件,会收到 could not serialize access 错误(PostgreSQL 的严格实现)。 SERIALIZABLE:使用 Serializable Snapshot Isolation (SSI) 技术,检测读写冲突构成的环,回滚事务以避免序列化异常。并发度较低。 最佳实践 大多数 OLTP 使用 READ COMMITTED 足够,配合乐观锁(应用层版本号)处理写冲突。 报表/统计类查询使用 REPEATABLE READ 保证数据一致性。 高冲突场景(如库存扣减)使用 SELECT ... FOR UPDATE 显式锁定行,或改用 SERIALIZABLE […]

PostgreSQL 存储与索引系列(三):查询优化实战——执行计划、统计信息与反模式诊断

PostgreSQL 存储与索引系列(三):查询优化实战——执行计划、统计信息与反模式诊断 这是系列第三期,聚焦查询优化。我们将深入解读执行计划,学习如何利用统计信息和 ANALYZE 做出正确决策,识别并避免常见的慢查询反模式,并借助 pg_stat_statements 等工具定位真实瓶颈。前两期关于存储页、可见性映射和各类索引的知识,将在这里融会贯通。 1. 执行计划:读懂 PostgreSQL 的每一步 EXPLAIN 是分析查询性能的首要工具。加上 ANALYZE 会真实执行并返回实际行数、耗时、内存等;加上 BUFFERS 可查看缓存命中情况;加上 VERBOSE 输出额外细节。 核心节点类型 顺序扫描 (Seq Scan) 性能特点:读取表的全部页面,适合小表或预计返回大部分行的查询。 是否应该出现:大表上出现 Seq Scan 通常意味着缺少有效索引,或优化器低估了选择性。 索引扫描 (Index Scan) 过程:通过索引获得匹配行的 ctid,逐个回表获取元组。 效率条件:回表次数多时可能慢,因为随机 I/O 成本高。如果表页面已经缓存,影响会减小。 仅索引扫描 (Index Only Scan) 原理:索引包含查询所需的所有列,且可见性映射(VM)标记相应页面为 all_visible,因此无需回表。 关键:定期 VACUUM 保证 VM 及时更新。如果扫描发现 VM 过时,仍会回表并更新 VM。 位图扫描 (Bitmap Scan) 组成:Bitmap Index Scan + Bitmap Heap Scan。 过程:先通过索引收集所有匹配行的 ctid,生成位图(每个数据页一个比特);然后按磁盘顺序回表扫描页面。适合返回较多行(如 5%~20%)时,减少随机 I/O。 为什么好:避免 Index Scan 的大量离散随机回表。 连接节点 Nested Loop:对左表的每一行,扫描右表。适合小表驱动或右表有高效索引。复杂度 O(N * M)。 Hash Join:构建右表的哈希表,然后左表探测。适合无索引的大表连接,内存足够时速度快。 Merge Join:两边按连接键排序后合并。适合两表已有序或连接条件为等值且列可排序。 解读 EXPLAIN ANALYZE 的关键指标 actual time:实际执行时间(首次行产出到完成)。 rows:实际行数 vs 估计行数 —— 如果偏差巨大,说明统计信息过期或分布不均。 loops:某些节点(如 Nested Loop 内层)可能执行多次。 buffers:shared hit(缓存命中)、read(磁盘读)、dirtied、written。高 read 说明冷数据或内存不足。 Planning Time 和 Execution Time:规划时间过长可能因为复杂视图或大量分区。 示例分析 EXPLAIN (ANALYZE, BUFFERS, VERBOSE) SELECT * FROM orders WHERE customer_id = 12345 AND status = 'paid'; 如果看到 Seq Scan on orders,且 filter 条件为 customer_id=12345,则需要检查索引。 若使用 Bitmap Index Scan 然后 Bitmap Heap Scan,实际行数远大于估计,则需 ANALYZE。 若执行 Index Only Scan 却回表很多(Heap Fetches 列),说明 VM 不够新,应运行 VACUUM。 2. 统计信息:优化器的眼睛 PostgreSQL 优化器基于表、列、表达式和索引的统计信息估算行数和成本。统计信息存储在 pg_statistic 中,可通过 pg_stats 视图方便查看。 关键统计指标 n_distinct:唯一值数量。负数表示比例(如 -0.1 代表 10% 的行是唯一值)。影响等值查询选择性估算。 most_common_vals / most_common_freqs:高频值及其频率。优化器知道 status='paid' 占 90% 时会选择全表扫描。 histogram_bounds:直方图边界,用于范围查询估算。 correlation:物理存储顺序与逻辑顺序的相关性(-1 到 1)。绝对值接近 1 说明列值与物理位置排序一致,利于索引范围扫描(例如自增主键)。接近 0 则不适合 BRIN 或重点考虑聚类。 ANALYZE 与统计信息维护 手动执行:ANALYZE table_name; 它会收集当前表及其所有索引的统计信息。 Autovacuum 会自动触发 ANALYZE,当表中修改行数超过阈值(autovacuum_analyze_threshold + autovacuum_analyze_scale_factor * reltuples)。 调整统计精度:ALTER TABLE ... ALTER COLUMN ... SET STATISTICS 1000;(默认 100)。更高的值让直方图更精确,但增加分析时间。 极端情况:对于一些不均匀分布或非常活跃的表,可以增加统计目标,甚至手动设置某些列的 […]

PostgreSQL 存储与索引系列(二):索引的艺术——从 B-tree 到 BRIN 的全景指南

PostgreSQL 存储与索引系列(二):索引的艺术——从 B-tree 到 BRIN 的全景指南 这是系列第二期,聚焦 PostgreSQL 的索引世界。我们会逐一拆解 B-tree、Hash、GiST、GIN、BRIN 等索引的内部机理与适用场景,并介绍部分索引、表达式索引等高级特性。结合上一期关于存储页、ctid、可见性映射的知识,你将对索引如何加速查询、何时失效、如何选型有系统的认知。 0. 索引基础:快速回顾 索引本质:一种有序的“目录”结构,通过少数列的值快速定位表中行的物理位置(ctid:页号+偏移)。 访问路径:索引扫描 → 获取 ctid → 回表(除非是仅索引扫描,需借助 Visibility Map)。 代价:额外的存储空间、写入时的维护开销(INSERT/UPDATE/DELETE需要同步更新索引)。 优化器决策:基于统计信息(pg_statistic)和成本参数,选择全表扫描或不同索引。 1. B-tree:全场景主力 B-tree 是 PostgreSQL 的默认索引类型,适用绝大多数等值、范围、排序、前缀匹配(如 LIKE 'abc%')查询。 内部结构 采用 平衡树 结构,非叶子节点存储键值和下层节点的指针,叶子节点存储键值和对应的 ctid 列表(或堆指针)。 同一层的页面通过双向链表串联,支持高效的范围扫描(正向/反向)。 页面默认 8 KB,每个索引元组包含索引键和堆指针。B-tree 会尽量保证页面半满(通过 fillfactor 控制),为更新预留空间。 查询支持 =、>、>=、<、<=、BETWEEN、IN(转为多个等值)。 LIKE 或 ~~ 仅当模式常亮前缀时可用(如 col LIKE 'john%'),因为 B-tree 按二进制排序;对于 %john% 则无法使用。 ORDER BY 可返回有序输出,避免显式排序(需索引排序方向匹配查询的 ASC/DESC)。 创建与维护 CREATE INDEX idx_user_name ON users(name); CREATE INDEX idx_user_created ON users(created_at DESC); -- 支持降序排序 支持唯一约束:CREATE UNIQUE INDEX ...。 多列索引:B-tree 支持最多 32 列,遵循最左前缀原则——查询条件必须覆盖索引的第一列才可能使用该索引。 调优:对于频繁更新的表,降低 fillfactor(如 70)以减少分裂;对于只读或静态表,提高 fillfactor(如 100)节省空间。 2. Hash:恰到好处的等值利器 Hash 索引只支持 = 等值查询,不适合范围或排序。在 PostgreSQL 10 之前 Hash 索引不记录 WAL,易损坏;10+ 版本已完整支持 crash-safe,性能有时优于 B-tree。 内部原理 对索引键计算哈希值(函数 hash_any),映射到哈希桶(bucket)。桶内存储该哈希值的所有行 ctid。 当桶溢出时,会分裂成两个桶,采用线性哈希算法,避免全局重哈希。 由于哈希值有冲突,同一个哈希值可能对应多个实际键值,检索时需回表验证真实值(以防哈希碰撞)。 适用场景 只做等值查询的大表,且索引列值分布差异大(B-tree 叶子层深度高时 Hash 可能更快)。 例如:用户ID表、状态码表。 注意事项 CREATE INDEX idx_session_hash ON sessions USING hash (session_id); Hash 索引不支持唯一约束。 不能用于 ORDER BY 或 LIKE。 同等条件下,B-tree 更通用,除非明确测试 Hash 胜出。 3. GiST:平衡树的多面手 GiST(Generalized Search Tree)是一种平衡树框架,允许实现多种非传统数据类型和查询操作符(如几何重叠、全文搜索、距离搜索)。PostgreSQL 内置了用于几何、范围、全文、数组等类型。 核心思想 节点存储“谓词”(如 bounding box),用以描述子树的覆盖范围。 搜索时剪枝:若查询条件与节点谓词不匹配,则跳过整个子树。 支持最近邻搜索(ORDER BY col <-> point),例如“附近的人”。 常用操作符类 几何类型(point、box、circle):<<(左于)、>>(右于)、&&(重叠)、<->(距离)。 范围类型(int4range、tsrange):&&、@>(包含)、<@(被包含)。 全文搜索(tsvector + tsquery):实际上更推荐 GIN,但 GiST 变体 tsvector_ops 构建更快、更新开销更低,适合动态数据。 示例:地理坐标搜索 CREATE INDEX poi_gist ON points_of_interest USING gist (location); SELECT name FROM points_of_interest WHERE location <-> point '(x,y)' < 1000 -- 1000单位内 ORDER BY location <-> point '(x,y)'; 扩展性 GiST 支持自定义操作符类,常用于实现空间数据库扩展(PostGIS 实际上是基于 GiST 和 SP-GiST)。对于开发专用索引很有价值。 4. GIN:倒排索引大师 […]
Recent Posts

HiddenMerit Daily · Issue 60

# 📊 HiddenMerit Daily · Issue 60 > **Focus on Database Frontiers, Practical Insights for DBAs** > July 22, 2026 | 5 Selected Global Breaking News ## 01|Oracle Releases Largest Quarterly Patch in History: 1,449 Patches Fix 1,235 CVEs, 261 Critical On July 21, Oracle released its July 2026 Critical Patch Update (CPU), setting a record for the largest single patch release in the company’s history. This CPU contains **1,449 security patches** fixing **1,235 independent CVEs** across 32 Oracle product families, of which **261 patches are rated Critical**. **Patch Distribution by Product Family**: | Product Family | Patches | Remotely Exploitable Without Authentication | |—————-|———|———————————————| | Oracle E‑Business Suite | 410 | 45 | | Oracle Fusion Middleware | 355 | 219 | | Oracle Communications | 168 | 122 | | Oracle MySQL | 54 | 9 | | Oracle Database Server | 15 | 6 | **Context for This Patch**: Oracle had already issued an urgent “Prepare Now” warning a week earlier, emphasising that AI is fundamentally lowering the barrier to discovering and exploiting vulnerabilities – frontier AI models can analyse software changes, reverse‑engineer security patches, and develop attack paths at unprecedented speed. Oracle has collaborated with state‑of‑the‑art […]

HiddenMerit Daily · Issue 59

# 📊 HiddenMerit Daily · Issue 59 > **Focus on Database Frontiers, Practical Insights for DBAs** > July 21, 2026 | 5 Selected Global Breaking News ## 01|Oracle Issues Urgent Warning: July 21 Release Update to Fix Large Number of High‑Risk Vulnerabilities, Immediate Deployment Recommended On July 13, Oracle issued an urgent security warning, strongly recommending that all customers running supported Oracle Database versions (including Oracle Database 19c and Oracle AI Database 26ai) immediately test and deploy the Release Update (RU) after its release on July 21. **Background**: New frontier AI models are significantly lowering the barrier to discovering and exploiting software vulnerabilities – these models can identify weaknesses, analyse software changes, reverse‑engineer security patches, and develop potential attack paths at unprecedented speed and scale. AI models are also becoming increasingly adept at combining multiple weaknesses across the application and data stack into complex attacks, even when individual weaknesses do not themselves pose a serious risk. As a result, protecting systems solely at the network or application layer is no longer sufficient; enterprises must protect the entire technology stack. **Fixes Included in This RU**: Oracle has collaborated with state‑of‑the‑art models from Anthropic and OpenAI to proactively identify and fix potential […]

HiddenMerit Daily · Issue 58

# 📊 HiddenMerit Daily · Issue 58 > **Focus on Database Frontiers, Practical Insights for DBAs** > July 20, 2026 | 5 Selected Global Breaking News ## 01|CAICT: Domestic Databases Enter Core System “Deep Water,” AI‑Native Leads New Industry Landscape On July 9, at the 2026 Trustworthy Database Development Conference, CAICT released the “Database Development Research Report (2026).” The report notes that domestic databases have basically completed peripheral system replacement and have officially entered the **critical business system breakthrough phase**. **Key Data**: – The global database market reached **$131.6 billion** in 2025 (approximately RMB 894.09 billion). – The Chinese database market reached **$9.49 billion** in 2025 (approximately RMB 64.48 billion), and is expected to reach **RMB 97.974 billion** by 2028, with a CAGR of 13.06%. – The number of domestic database vendors has shrunk from a peak of 167 to 94, with a clear head‑concentration effect and an intensifying “Matthew effect.” **AI‑Native Becomes the Main Theme**: The report points out that database technology is accelerating its evolution toward the **AI‑native direction**, and the global database industry is entering a new phase of landscape restructuring. The role of databases is upgrading from “underlying support systems” to “core engines enabling intelligent decision‑making […]

HiddenMerit Daily · Issue 56

# 📊 HiddenMerit Daily · Issue 56 > **Focus on Database Frontiers, Practical Insights for DBAs** > July 6, 2026 | 5 Selected Global Breaking News ## 01|Kingware Releases Manufacturing Scenario Database Evolution White Paper: SQL Server Replacement Enters “Deep Water” On July 5, CETC Kingware published a technical article titled “Database Evolution in Manufacturing Scenarios: How Kingware Replaces SQL Server,” pointing out that the data surge on industrial shop floors has exceeded the processing capacity of single‑node systems. Traditional database architectures that rely on vertical scaling are facing unprecedented performance challenges. Over the next 1‑3 years, manufacturing enterprises will no longer face only the “choice of replacement,” but must answer the strategic question: “How do we build an autonomous data foundation in the context of de‑IOE?” **Three Paradigm Shifts**: 1. **Hybrid Workloads Become the Norm**: The IT architecture of modern factories is shifting from separated OLTP and OLAP to HTAP mode. The same data system must simultaneously handle tens of thousands of device instruction writes per second and minute‑level production report analysis. 2. **Distributed Architecture Becomes a Hard Requirement**: When a single table exceeds 100 million rows with daily increments exceeding 1 million rows, the index maintenance cost of […]