pgpool-II 4.3 中文手册-前言

  • 2022 年 4 月 20 日
  • 筆記

image

什么是 Pgpool-II?

Pgpool II 管理一个 PostgreSQL 服务器池,以实现单个 PostgreSQL 安装无法实现的一些功能。这些功能包括:

高可用

  • Pgpool-II 通过使用多个 PostgreSQL 服务器提供高可用性 (HA) 功能,以便它自动从服务器池中删除损坏的服务器以继续执行数据库任务。这称为自动故障转移(automatic failover)Pgpool-II 还为 Pgpool-II 本身提供了一个 HA 功能,称为 Watchdog。此外,Pgpool-II 采用复杂的仲裁算法来避免误报错误和脑裂问题,使整个 HA 系统高度可靠。

负载均衡

  • Pgpool-II 将读取查询分布在多个 PostgreSQL 服务器上以获得更高的性能。此功能称为负载平衡。 写查询被发送到主服务器(在流复制模式下)或所有服务器(在原生复制模式和快照隔离模式下)。在任何情况下,Pgpool-II 都会自动区分读查询和写查询。

除了这些基本功能之外,Pgpool-II 还提供了一些有用的功能,例如:

连接池

  • Pgpool-II 维护与 PostgreSQL 服务器的已建立连接,并在具有相同属性(即用户名、数据库、协议版本和其他连接参数,如果有的话)的新连接进入时重用它们。它减少了连接开销,并改进了 系统的整体吞吐量。

在线恢复

  • Pgpool-II 可以通过执行一条命令进行数据库节点的在线恢复。 当在线恢复与自动故障转移一起使用时,通过故障转移分离的节点可以自动附加为备用节点。 也可以同步和附加新的 PostgreSQL 服务器。

限制超出的连接

  • PostgreSQL 的最大并发连接数是有限制的,当达到这个数量时,新的连接会被拒绝。 但是,提高此最大连接数会增加资源消耗并对整体系统性能产生负面影响。Pgpool-II 对最大连接数也有限制,但是额外的连接会排队而不是立即返回错误。 但是,您可以配置为在超出连接限制时返回错误(4.1 或更高版本)。

Watchdog

  • Watchdog 可以协调多个 Pgpool-II,创建一个健壮的集群系统,避免单点故障或脑裂。 为避免脑裂,您至少需要 3Pgpool-II 节点。Watchdog 可以针对其他 pgpool-II 节点执行生命检查,以检测 Pgpool-II 的故障。如果活动 Pgpool-II 宕机,备用 Pgpool-II 可以升级为活动,并接管 Virtual IP

内存中查询缓存

  • 在内存中查询缓存允许保存一对 SELECT 语句及其结果。如果有相同的 SELECT 进入,Pgpool-II 从缓存中返回值。由于不涉及 SQL 解析和对 PostgreSQL 的访问,因此使用内存缓存非常快。 另一方面,在某些情况下它可能比正常路径慢,因为它增加了存储缓存数据的一些开销。

Pgpool-II 使用 PostgreSQL 的后端和前端协议,并在后端和前端之间中继消息。 因此,数据库应用程序(前端)认为 Pgpool-II 是实际的 PostgreSQL 服务器,而服务器(后端)将 Pgpool-II 视为其客户端之一。因为 Pgpool-II 对服务器和客户端都是透明的,所以现有的数据库应用程序可以与 Pgpool-II 一起使用,几乎不需要更改其源代码。

Pgpool-II 适用于 LinuxFreeBSD 和大多数类 UNIX 架构。不支持 Windows。支持的 PostgreSQL 服务器版本为 7.4 或更高版本(某些功能可能不适用于旧版本的 PostgreSQL)。您还必须确保所有 PostgreSQL 服务器都使用相同的主要版本。除此之外,我们不建议将不同的 PostgreSQL 安装与不同的构建选项混合使用:包括是否支持 SSL、是否使用 --disable-integer-datetimes、不同的块大小。这些可能会影响 Pgpool-II 的部分功能。PostgreSQL 次要版本的差异通常不是问题。但是,我们不会测试所有出现的次要版本,我们建议使用完全相同的 PostgreSQL 次要版本。

Pgpool-II 简史

Pgpool-II 的生命始于 Tatsuo Ishii 的个人项目。在项目中它只是一个简单的连接池软件。所以 Pgpool 这个名字来源于这个事实。第一个版本于 2003 年公开。

2004 年,Pgpool 1.0 发布,带有原生复制功能(基于 SQL 语句的复制)。同年 2.0 发布了负载均衡,并支持第 3 版前端/后端协议。2005 年,添加了自动故障转移和主从模式支持。

2006 年,Pgpool 更名为 Pgpool-II。第一个版本 1.0 取消了 Pgpool 中的许多限制,例如 PgpoolPostgreSQL 服务器的数量最多为 2 个。 还添加了许多新功能,例如并行查询模式和 PCP 命令(PCP 代表 "Pgpool Control Protocol")。PgpoolPgpool-II 之间最重要的变化可能是项目从个人项目更改为 Pgpool Development Group 拥有的团体项目。

约定

在命令概要中使用以下约定:括号([])表示可选部分。(在 Tcl 命令的概要中,使用问号 (?) 代替,这在 Tcl 中很常见。)大括号({})和竖线(|)表示您必须选择一种替代方法。点 (...) 表示前面的元素可以重复。

在提高清晰度的地方,SQL 命令前面有提示符 =>shell 命令前面有提示符 $。 但是,通常不会显示提示。

administrator 通常是负责安装和运行服务器的人。用户可以是正在使用或想要使用 Pgpool-II 系统的任何部分的任何人。这些术语不应被解释得太狭隘;本文档没有关于系统管理程序的固定假设。

更多的信息

网站

  • Pgpool-II 网站是提供有关 Pgpool-II 官方信息的中心位置:下载、文档、常见问题解答、邮件列表存档等。

邮件列表

  • 邮件列表是回答您的问题、与其他用户分享经验以及联系开发人员的好地方。有关详细信息,请参阅 Pgpool-II 网站。

你自己!

  • pgpool-II 是一个开源项目。因此,它依赖于用户社区的持续支持。当您开始使用 Pgpool-II 时,您将依赖其他人的帮助,无论是通过文档还是通过邮件列表。考虑回馈您的知识。阅读邮件列表并回答问题。 如果您学到了文档中没有的内容,请将其写下来并贡献出来。如果您向代码添加功能,请贡献它们。

限制

本节介绍 Pgpool-II 的当前限制。

PostgreSQL 的功能

  • 如果您使用 pg_terminate_backend() 停止后端,这将触发故障转移。发生这种情况的原因是 PostgreSQL 为终止的后端发送与完全关闭 postmaster 完全相同的消息。3.6 版之前没有解决方法。从版本 3.6 开始,此限制已得到缓解。如果函数的参数(即进程 ID)是常量,则可以安全地使用该函数。 在扩展协议模式下,您无法使用该功能。

负载均衡

多语句查询(单行多个 SQL 命令)总是发送到主节点(在流复制模式下)或主节点(在其他模式下)。通常 Pgpool-II 将查询分派到适当的节点,但不适用于多语句查询。

身份验证/访问控制

  • replication 模式或 native replication 模式下,支持 trustpam 方法。自 Pgpool-II 3.0 起也支持 md5。 使用身份验证文件 pool_passwd 支持 md5。自 Pgpool-II 4.0 起,还支持 scram-sha-256、证书和明文密码。 pool_passwd 是认证文件的默认名称。以下是启用 md5 身份验证的步骤:

    1. 以数据库的操作系统用户身份登录并输入:
    pg_md5 --md5auth --username=your_username your_passwd
    

    用户名和 md5 加密密码注册到 pool_passwd 中。 如果 pool_passwd 还不存在,pg_md5 命令会自动为你创建它。 pool_passwd 的格式是 username:encrypted_passwd

    1. 您还需要将适当的 md5 条目添加到 pool_hba.conf
    2. 请注意,用户名和密码必须与在 PostgreSQL 中注册的相同。
    3. 更改 md5 密码后(当然在 pool_passwdPostgreSQL 中),您需要执行 pgpool reload

大对象

  • 在流复制模式下,Pgpool-II 支持大对象。
  • 在原生复制模式下,如果后端是 PostgreSQL 8.1 或更高版本,Pgpool-II 支持大对象。为此,您需要在 pgpool.conf 中启用 lobj_lock_table 指令。但是,不支持使用后端函数 lo_import 进行大对象复制。
  • 在其他模式下,包括 Slony 模式,不支持大对象。

临时表

  • 创建/插入/更新/删除临时表始终在原生复制模式下的主节点上执行。 这些表上的 SELECT 也在 primary 表上执行。但是,如果临时表名在 SELECT 中用作文字,则无法检测到它,并且 SELECT 将进行负载均衡。 这将触发 "not found the table" 错误或将找到另一个具有相同名称的表。 为避免此问题,请使用 SQL 注释。
  • 请注意,用于访问系统目录的查询中使用的此类文字表名称确实会导致上述问题。psql\d 命令产生这样的查询:
SELECT 't1'::regclass::oid;

在这种情况下,Pgpool-II 总是将查询发送到主节点并且不会导致问题。

如果您使用的是 PostgreSQL 8.3 或更高版本,则通过在 reset_query_list 中指定 DISCARD ALL 将在会话结束时删除由 CREATE TEMP TABLE 创建的表。

对于 8.2.x 或更早版本,由 CREATE TEMP TABLE 创建的表在退出会话后不会被删除。这是因为连接池,从 PostgreSQL 的后端角度来看,它使会话保持活动状态。为避免这种情况,您必须通过发出 DROP TABLE 显式删除临时表,或在事务块内使用 CREATE TEMP TABLE ... ON COMMIT DROP

Native Replication 模式下的函数等

无法保证使用上下文相关机制(例如 random number, transaction ID, OID, SERIAL, sequence)提供的任何数据将在多个后端正确复制。 对于 SERIAL,启用 insert_lock 将有助于复制数据。insert_lock 还有助于 SELECT setval()SELECT nextval()

使用 CURRENT_TIMESTAMPCURRENT_DATEnow()INSERT/UPDATE 将被正确复制。使用 CURRENT_TIMESTAMPCURRENT_DATEnow() 作为默认值的表的 INSERT/UPDATE 也将被正确复制。 这是通过在查询执行时用从 primary 获取的常量替换这些函数来完成的。 但是有一些限制:

Pgpool-II 3.0 或之前的版本中,在某些情况下,表默认值中时态数据的计算并不准确。 例如下面的表定义:

CREATE TABLE rel1(
d1 date DEFAULT CURRENT_DATE + 1
)

被视为:

CREATE TABLE rel1(
d1 date DEFAULT CURRENT_DATE
)

Pgpool-II 3.1 或更高版本可以正确处理这些情况。 因此,"d1" 列将明天作为默认值。但是,如果使用扩展协议(例如,在 JDBCPHP PDO 中使用)或 PREPARE,则此增强不适用。

请注意,如果列类型不是时间类型,则不执行重写。这样的例子:

foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision)

假设我们有下表:

CREATE TABLE rel1(
c1 int,
c2 timestamp default now()
)

我们可以复制

INSERT INTO rel1(c1) VALUES(1)

因为这变成

INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09')

然而,

INSERT INTO rel1(c1) SELECT 1

无法转换,因此无法在当前实现中正确复制。 仍然会插入值,根本没有任何转换。

SQL 类型命令

  • SQL 类型的命令不能用于扩展查询模式。

多字节字符

  • Pgpool-II 不会在客户端和 PostgreSQL 之间对多字节字符进行编码转换。客户端和后端的编码必须相同。

多语句查询

  • Pgpool-II 不能处理多语句查询。但是,当 Pgpool-II 通过 psql 连接时,是没有问题的。psql 解析多条语句,逐个发送一条语句。

libpq

  • libpq 在构建 Pgpool-II 时被链接。libpq 版本必须是 3.0 或更高版本。使用 libpq 2.0 版构建 Pgpool-II 将失败。

参数状态

  • 当客户端连接到 PostgreSQL 时,PostgreSQL 将一些 parameter/value 对发送回客户端。该协议称为 ParameterStatus。参数/值对可以通过 libpqPQParameterStatusAPI 提取。Pgpool-II 从多个 PostgreSQL 服务器收集 ParameterStatus 值,并且这些值可能在服务器之间有所不同。一个典型的例子是 in_hot_standby,它是在 PostgreSQL 14 中引入的。该变量的值在主服务器为 off 和备用服务器上为 on。问题是,Pgpool-II 必须只返回其中一个客户端。 在这种情况下,它选择主服务器报告的值。所以 PQParameterStatus 将返回 off。 另一方面,当客户端发出 show in_hot_standby 时,返回值可以 onoff,具体取决于会话的负载均衡节点。
  • 请注意,如果服务器之间的值不同,Pgpool-II 将发出除 in_hot_standby 之外的日志消息。这是为了防止日志文件被淹没,因为 in_hot_standby 总是不同的。

set_config

  • PostgreSQL 具有 set_config 功能,它允许在当前会话中更改参数值,如 SET 命令(实际上 set_configSET 具有更多功能。有关详细信息,请参阅 PostgreSQL 手册)。当 Pgpool-II 在集群模式设置为 streaming_replication 的情况下运行时,它只将函数发送到主服务器。由于该函数不发送到备用服务器,因此每个服务器的参数值不同。为避免该问题,您可以使用 SET 命令代替 set_config。 由于 SET 命令已发送到用于此会话的所有服务器,因此不会发生此问题。但是,如果您使用超过 2PostgreSQL 服务器,则需要禁用 statement_level_load_balance 并使用 SET 命令。这是因为,如果启用了 statement_level_load_balance,查询可能会发送到除主服务器和分配给负载均衡节点的服务器之外的第三台服务器。
  • 如果需要使用 set_config,请关闭 session 的负载均衡(不仅对于 set_config,还应在整个会话中禁用负载均衡)。你可以通过牺牲性能来避免这个问题。

更多