全局一致性

本文档介绍了全局一致性功能的前提条件、背景信息、技术方案、开启方式以及常见问题。

概述

PolarDB PostgreSQL版提供全局一致性功能,在数据库内核层面提供全局一致性的能力,保证发往集群任意节点的读请求都可以获得强一致性的结果。

前提条件

PolarDB PostgreSQL版14版本,且内核小版本需为2.0.14.22.0及以上。

说明

您可通过如下语句查看PolarDB PostgreSQL版的内核小版本号:

SHOW polar_version;
 polar_version 
---------------
 2.0.14.22.0
(1 row)

SHOW polar_release_date;
 polar_release_date 
--------------------
 20240630
(1 row)

背景信息

在原有的PolarDB一写多读的数据库架构中,RO节点默认提供会话一致性读取功能。物理复制和共享存储技术虽然可以有效降低RO节点的复制延迟,但不能保证发往RO节点的只读请求读取到RW节点上最新写入的数据。在一些对数据延迟比较敏感的金融行业和游戏行业中,RO节点延迟读取会造成业务逻辑的一致性问题。

image

如上图所示,业务应用经常通过微服务框架进行解耦,服务A写入数据后,产生一条写入成功的消息,通过消息队列组件通知到服务B。在会话一致性的场景下,服务A在col被更新到20后,使用同一个会话立即去读,,哪怕是请求路由到RO,也能读到最新的结果20,但是在服务A通知服务B数据更新后,服务B直接读RO,很可能无法保证得到最新结果,还是读到10。此种情况可能给上层业务带来数据一致性问题,面对该场景,业务侧只能将读请求转发到RW节点上,以保证写后读的数据一致性,RO节点资源也因此被闲置。

技术方案

PolarDB PostgreSQL版在数据库内核层面提供了RO节点的强一致性读能力,始终保证能看到RW节点最新写入的数据,从而提供了集群维度的强一致性读能力。在开启全局一致性功能后,RW节点上每个读写事务提交时,都会赋予一个CSN(Commit Sequence Number),表示事务提交序,用来构建更高效的事务快照,以替代原生PostgreSQL的活跃事务列表。同时,RW节点会把CSN记录到WAL中,RO节点通过回放WAL构建出完整的事务状态。

RO节点强一致性读能力的SQL执行过程如下:

  1. 客户端向RO节点发起查询请求。

  2. RO节点通过网络获取RW节点当前最大的CSN(Commit Sequence Number)。

  3. RO节点根据RW节点的最大CSN构建强一致性只读视图,并等到RO节点事务状态回放到相应位点。

  4. RO节点根据强一致性读视图判断数据可见性,给客户端返回结果。

image

开启步骤

  1. 登录PolarDB控制台

  2. 在左侧导航栏单击集群列表

  3. 在左上角,选择集群所在地域。

  4. 找到目标集群,单击集群ID。

  5. 在左侧导航栏中,选择配置与管理 > 参数配置设置polar_csn_enablepolar_global_csn_enable的值为on,用于开启事务CSN(Commit Sequence Number)的特性。

    说明

    需要注意的是,参数修改需要重启集群,请在修改参数前做好业务安排,谨慎操作。通过控制台设置集群参数详细介绍,请参考设置集群参数

  6. 在目标集群的基本信息页面的数据库连接区域,单击集群地址右侧的配置或弹窗页面的点击设置

    image

  7. 在编辑地址配置页面设置一致性级别为全局一致性(强),同时需要配置另外两个关联参数:

    参数

    描述

    全局一致性读超时时间

    为了保证一致性,等待只读节点同步到最新数据的超时时间。

    全局一致性读超时策略

    在只读节点等待超时的执行策略。取值范围如下:

    • 0,发送该请求到主节点(默认值)

    • 1,超时报错,客户端返回错误提示信息。

    • 2,超时降级自动降级为非一致性读取。

    image

常见问题

开启全局一致性功能后,如果某些查询不需要使用全局一致性读,该如何操作?

在RO节点开启全局一致性后,默认对所有的新建连接生效。如果某些查询不需要使用该功能,可以通过以下命令来关闭当前连接的全局一致性读:

SET polar_scc_enable = off;

如何设置全局一致性读超时时间

您可以登录PolarDB控制台,设置全局一致性读超时时间参数polar_scc_wait_timeout的值来设置。如果超时,客户端会收到以下错误信息:

SCC timeout waiting for WAL replay
说明

对于写入压力较大,或写入压力不稳定的集群,您可以将该参数polar_scc_wait_timeout的值设置大一些。

全局一致性读超时后,如何降级?

您需要登录PolarDB控制台,修改参数polar_scc_timeout_degrade_enable的值设置为ON,当全局一致性读超时后,查询操作会自动降级为非一致性读取,且客户端不会收到报错信息。

如何避免低写入负载场景下的读延迟?

您可以登录PolarDB控制台,将高性能参数synchronous_commit的值设置为on,以避免低写入场景下的读延迟。