Last modified: Wed Jun 29 09:50:01 JST 2011
欢迎来到 pgpool -II 页面 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
[英语页面]
[日语页面] |
什么是 pgpool-II?pgpool-II 是一个位于 PostgreSQL 服务器和 PostgreSQL 数据库客户端之间的中间件,它提供以下功能:
pgpool-II 保持已经连接到 PostgreSQL 服务器的连接,并在使用相同参数(例如:用户名,数据库,协议版本)连接进来时重用它们。它减少了连接开销,并增加了系统的总体吞吐量。 pgpool-II 可以管理多个 PostgreSQL 服务器。激活复制功能并使在2台或者更多 PostgreSQL 节点中建立一个实时备份成为可能,这样,如果其中一台节点失效,服务可以不被中断继续运行。 如果数据库进行了复制,则在任何一台服务器中执行一个 SELECT 查询将返回相同的结果。pgpool-II 利用了复制的功能以降低每台 PostgreSQL 服务器的负载。它通过分发 SELECT 查询到所有可用的服务器中,增强了系统的整体吞吐量。在理想的情况下,读性能应该和 PostgreSQL 服务器的数量成正比。负载均很功能在有大量用户同时执行很多只读查询的场景中工作的效果最好。 PostgreSQL 会限制当前的最大连接数,当到达这个数量时,新的连接将被拒绝。增加这个最大连接数会增加资源消耗并且对系统的全局性能有一定的负面影响。pgpoo-II 也支持限制最大连接数,但它的做法是将连接放入队列,而不是立即返回一个错误。 使用并行查询时,数据可以被分割到多台服务器上,所以一个查询可以在多台服务器上同时执行,以减少总体执行时间。并行查询在查询大规模数据的时候非常有效。 pgpool-II 使用 PostgreSQL 的前后台程序之间的协议,并且在前后台之间传递消息。因此,一个(前端的)数据库应用程序认为 pgpool-II 就是实际的 PostgreSQL 数据库,而后端的服务进程则认为 pgpool-II 是它的一个客户端。因为 pgpool-II 对于服务器和客户端来说是透明的,现有的数据库应用程序基本上可以不需要修改就可以使用 pgpool-II 了。 通过 pgpool-II 使用 SQL 有一些限制条件。参考 限制 获得详细信息。 支持的平台pgpool-II 可以运行在 Linux,Solaris,FreeBSD 以及基本上所有的类 UNIX 架构的平台上。不支持 Windows。支持 6.4 以上版本的 PostgreSQL 服务器。然而,如果要使用并行查询功能,需要 7.4 或更高版本。 如果你在使用 7.3 或者更老版本的 PostgreSQL,一些 pgpool-II 的功能将无法使用。但无论如何你不应该还在用这么老的版本了。 你还要确保你所有的 PostgreSQL 服务器运行相同主版本号的 PostgreSQL 程序。另外,如果你想要使用在线恢复,硬件架构和操作系统必须一致。 pgpool-II 的安装pgpool-II 可以在 pgpool 开发页面下载到。而且也提供包括 CentOS,RedHat Enterprise Linux,Fedora 和 Debian 在内的大量平台的二进制包。请检查相关的软件库。 pgpool-II 可以在以下位置下载源码:pgpool 开发页面。 从源码安装 pgpool-II 需要 2.9 甚至或更高版本的 gcc,以及 GNU make。而且,pgpool-II 需要链接到 libpq 库,所以在构建 pgpool-II 的机器上必须安装 libpq 库和它的开发头文件。另外,还需要 OpenSSL 库和它的头文件以便在 pgpool-II 中提供 OpenSSL 支持。
安装过程至此完成。如果你是使用 Solaris 或者 FreeBSD,你需要在以上的描述中用 “gmake” 代替 “make”,因为这些操作系统需要 GNU make。 配置 pgpool-IIpgpool-II 的默认配置文件为
配置
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 模式 | 示例文件 |
|---|---|
| 复制模式 | pgpool.conf.sample-replication |
| 主/备模式(Slony-I) | pgpool.conf.sample-master-slave |
| 主/备模式(流复制) | pgpool.conf.sample-stream |
空行或者以“#”开始的行将被认为是注释,会被忽略掉。
指定 pgpool-II 将接受 TCP/IP 连接的主机名或者IP地址。'*' 将接受所有的连接。'' 将禁用 TCP/IP 连接。默认为 'localhost'。总是支持接受通过 UNIX 域套接字发起的连接。需要重启 pgpool-II 以使改动生效。
pgpool-II 监听 TCP/IP 连接的端口号。默认为 9999。需要重启 pgpool-II 以使改动生效。
pgpool-II 建立用于建立接受 UNIX 域套接字连接的目录。默认为 '/tmp'。注意,这个套接字可能被 cron 任务删除。我们建议设置这个值为 '/var/run' 或类似目录。需要重启 pgpool-II 以使改动生效。
PCP 进程接受连接的端口号。默认为 9898。本参数必须在服务器启动前设置。
PCP 进程用于建立接受 UNIX 域套接字连接的目录。默认为 '/tmp'。注意,这个套接字可能被 cron 任务删除。我们建议设置这个值为 '/var/run' 或类似目录。需要重启 pgpool-II 以使改动生效。
本参数定义了 PostgreSQL 服务器的 UNIX 域套接字目录。默认为 '/tmp'。本参数必须在服务器启动前设置。
PCP 连接超时值,单位为秒。如果客户端在设置的秒数内没有响应,PCP 关闭到这个客户端的连接。默认为 10 秒。0 表示没有超时。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
预先生成的 pgpool-II 服务进程数。默认为 32。num_init_children 也是 pgpool-II 支持的从客户端发起的最大并发连接数。如果超过 num_init_children 数的客户端尝试连接到 pgpool-II,它们将被阻塞(而不是拒绝连接),直到到任何一个 pgpool-II 进程的连接被关闭为止。最多有 2*num_init_children 可以被放入等待队列。
对于以上内容的一些提示:
归纳起来,max_pool,num_init_children,max_connections 和 superuser_reserved_connections 必须符合以下规则:
max_pool*num_init_children <= (max_connections - superuser_reserved_connections) (不需要取消查询) max_pool*num_init_children*2 <= (max_connections - superuser_reserved_connections) (需要取消查询)
本参数必须在服务器启动前设置。
pgpool-II 子进程的生命周期,单位为秒。如果子进程空闲了这么多秒,它将被终止,一个新的子进程将被创建。这个参数是用于应对内存泄露和其他不可预料错误的一个措施。默认值为 300 (5分钟)。0 将禁用本功能。注意它不影响尚未接受任何连接的进程。如果改变了这个值,你需要重新加载 pgpool.conf 以使变动生效。
当 pgpool-II 子进程处理这么多个客户端连接后,它将被终止。这个参数在繁忙到 child_life_time 和 connection_life_time 永远不会触发的服务器上有效。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
当一个客户端在执行最后一条查询后如果空闲到了 client_idle_limit 秒数,到这个客户端的连接将被断开。这在避免 pgpool 子进程被懒客户端占用或者探测断开的客户端和 pgpool 之间的 TCP/IP 连接非常有用。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
指定 pgpool 认证超时的时长。0 指禁用超时,默认值为 60 。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
保存日志文件的目录。 pgpool_status 将被写入这个目录。
pgpool-II 支持多种记录服务器消息的方式,包括 stderr 和 syslog。默认为记录到 stderr。
注:要使用syslog 作为 log_destination 的选项,你将需要更改你系统的 syslog 守护进程的配置。pgpool-II 可以记录到 syslog 设备 LOCAL0 到 LOCAL7 (参考 syslog_facility), 但是大部分平台的默认的 syslog 配置将忽略这些消息。你需要添加如下一些内容
local0.* /var/log/pgpool.log
到 syslog 守护进程的配置文件以使它生效。
当记录日志到 syslog 被启用,本参数确定被使用的 syslog “设备”。你可以使用 LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7;默认为 LOCAL0。还请参考你系统的 syslog 守护进程的文档。
当记录日志到 syslog 被启用,本参数确定用于标记 syslog 中 pgpool-II 消息的程序名。默认为“pgpool”。
到包含 pgpool-II 进程 ID 的文件的完整路径名。默认为 '/var/run/pgpool/pgpool.pid'。需要重启 pgpool-II 以使改动生效。
如果本值被设置为 true ,则将在日志中添加时间戳。默认值为 true。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
如果本值被设置为 true,则缓存到 PostgreSQL 的连接。默认为 true。需要重启 pgpool-II 以使改动生效。
pgpool-II 定期尝试连接到后台以检测服务器是否在服务器或网络上有问题。这种错误检测过程被称为“健康检查”。如果检测到错误,则 pgpool-II 会尝试进行故障恢复或者退化操作。本参数用于避免健康检查在例如网线断开等情况下等待很长时间。超时值的单位为秒。默认值为 20 。 0 禁用超时(一直等待到 TCP/IP 超时)。健康检查需要额外的到后端程序的连接,所以 postgresql.conf 中的 max_connections 需要加一。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
本参数指出健康检查的间隔,单位为秒。默认值为 0 ,代表禁用健康检查。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
用于执行健康检查的用户。用户必须存在于 PostgreSQL 后台中。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
用于执行健康检查的用户的密码。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
本参数指定当一个节点断开连接时执行的命令。pgpool-II 使用后台对应的信息代替以下的特别字符。
特殊字符 描述 %d 断开连接的节点的后台 ID。 %h 断开连接的节点的主机名。 %p 断开连接的节点的端口号。 %D 断开连接的节点的数据库实例所在目录。 %M 旧的主节点 ID。 %m 新的主节点 ID。 %H 新的主节点主机名。 %P 旧的第一节点 ID。 %% '%' 字符
如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
当进行故障切换时,pgpool 杀掉它的所有子进程,这将顺序终止所有的到 pgpool 的会话。然后,pgpool 调用 failover_command 并等待它完成。然后,pgpool 启动新的子进程并再次开始从客户端接受连接。
本参数指定当一个节点连接时执行的命令。pgpool-II 使用后台对应的信息代替以下的特别字符。
特殊字符 描述 %d 新连接上的节点的后台 ID。 %h 新连接上的节点的主机名。 %p 新连接上的节点的端口号。 %D 新连接上的节点的数据库实例所在目录。 %M 旧的主节点 ID。 %m 新的主节点 ID。 %H 新的主节点主机名。 %P 旧的第一节点 ID。 %% '%' 字符
如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
本参数指定一个在主备流复制模式中发生主节点故障恢复后执行的命令。pgpool-II 使用后台对应的信息代替以下的特别字符。
特殊字符 描述 %d 断开连接的节点的后台 ID。 %h 断开连接的节点的主机名。 %p 断开连接的节点的端口号。 %D 断开连接的节点的数据库实例所在目录。 %M 旧的主节点 ID。 %m 新的主节点 ID。 %H 新的主节点主机名。 %P 旧的第一节点 ID。 %% '%' 字符
如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
如果 follow_master_commnd 不为空,当一个主备流复制中的主节点的故障切换完成,pgpool 退化所有的除新的主节点外的所有节点并启动一个新的子进程,再次准备好接受客户端的连接。在这之后,pgpool 针对每个退化的节点运行 ‘follow_master_command’ 指定的命令。通常,这个命令应该用于调用例如 pcp_recovery_node 命令来从新的主节点恢复备节点。
如果为 true,当往后台进程的通信中写入数据时发生错误,pgpool-II 将触发故障处理过程。这和 pgpool-II 2.2.x 甚至以前版本的行为一样。如果设置为 false,则 pgpool 将报告错误并断开该连接。请注意如果设置为 true,当连接到一个后台进程失败或者 pgpool 探测到 postmaster 由于管理原因关闭,pgpool 也会执行故障恢复过程。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
在负载均衡模式中 pgpool-II 忽略 SQL 查询语句前面的空白字符。如果使用类似于 DBI/DBD:Pg 一类的在用户的查询前增加空白的 API 中非常有用。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
当设置为 true 时生成 SQL 日志消息。这类似于 PostgreSQL 中的 log_statement 参数。即使调试选项没有在启动的时候传递到 pgpool-II,它也会产生日志。
类似于 log_statement,除了它是针对每个 DB 节点产生日志外。例如它对于确定复制是否正常运行非常有用。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
如果为 true,ps 命令将显示客户端的主机名而不是 IP 地址。而且,如果 log_connections 被开启,也会将主机名写入日志。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
如果为 true,进入的连接将被打印到日志中。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
如果为 true,则使用 pgpool_hba.conf 来进行客户端认证。参考设置用于客户端认证的 pool_hba.conf。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
指出连接到 PostgreSQL 后台程序的地址。它用于 pgpool-II 与服务器通信。如果你改变了这个值,需要重新加载 pgpool.conf 以使变动生效。
对于 TCP/IP 通信,本参数可以是一个主机名或者IP地址。如果它是从斜线开始的,它指出是通过 UNIX 域套接字通信,而不是 TCP/IP 协议;它的值为存储套接字文件所在的目录。如果 backend_host 为空,则它的默认行为是通过 /tmp 中的 UNIX 域套接字连接。
可以通过在本参数名的末尾添加一个数字来指定多个后台程序(例如backend_hostname0)。这个数字对应为“数据库节点 ID”,是从 0 开始的正整数。被设置数据库节点ID为 0 的后台程序后台程序将被叫做“主数据库”。当定义了多个后台程序时,即使主数据库当机后依然能继续(某些模式下不行)。在这种情况下,存活的最小的数据库节点编号的数据库将被变成新的主数据库。
如果你只计划使用一台 PostgreSQL 服务器,可以通过 backend_hostname0 指定。
可以通过配置本参数后重新加载配置文件添加新的节点。但是,对已有的值无法更新,所以这种情况下你必须重启 pgpool-II。
指定后台程序的端口号。可以通过在本参数名的末尾添加一个数字来指定多个后台程序(例如backend_port0)。如果你只计划使用一台 PostgreSQL 服务器,可以通过 backend_port0 指定。
可以通过配置本参数后重新加载配置文件添加新的后台端口。但是,对已有的值无法更新,所以这种情况下你必须重启 pgpool-II。
指定后台程序的负载均衡权重。可以通过在本参数名的末尾添加一个数字来指定多个后台程序(例如backend_weight0)。如果你只计划使用一台 PostgreSQL 服务器,可以通过 backend_weight0 指定。
可以通过配置本参数后重新加载配置文件添加新的负载均衡权重。但是,对已有的值无法更新,所以这种情况下你必须重启 pgpool-II。
在 pgpool-II 2.2.6/2.3 或者更新的版本中,你可以通过重新加载配置文件来改变本值。但这只对新连接的客户会话生效。这在主备模式中可以避免任何执行一些管理工作的查询被发送到备用节点上。
指定后台的数据库实例的目录。可以通过在本参数名的末尾添加一个数字来指定多个后台程序(例如backend_data_directory0)。如果你不打算使用在线恢复,你可以不设置本参数。
可以通过配置本参数后重新加载配置文件添加新的后台的数据库实例目录。但是,对已有的值无法更新,所以这种情况下你必须重启 pgpool-II。
控制大量的后台程序的行为。可以通过在本参数名的末尾添加一个数字来指定多个后台程序(例如backend_flag0)
当前支持以下的内容。多个标志可以通过“|”来分隔。
如果设置为 ture,则启用了到前端程序和后端程序的连接的 ssl 支持。注意为了能与前端程序进行 SSL 连接,必须设置 ssl_key 和 ssl_cert。
SSL 默认被关闭。就像在 pgpool-II 的安装 小节所说的,注意必须在编译时配置 OpenSSL 支持才能打开 SSL 支持。
如果修改了 SSL 相关的设置, pgpool-II 守护进程必须重启。
对于进入的连接使用的私钥文件所在路径。
本选项没有默认值,如果本值不设置,则对于进入的连接将禁用 SSL。
对于进入的连接使用的公共 x509 证书文件所在的路径。
本选项没有默认值,如果本值不设置,则对于进入的连接将禁用 SSL。
调试消息详细程度级别。0 表示没有消息。大于 1 表示更详细的消息。默认值为 0。
关系缓存的生命周期。0(默认值)表示没有缓冲区过期。关系缓存用于缓存用来获取包含表结构信息或一个表是不是一个临时表等大量信息的相关的 PostgreSQL 系统 catalog 的查询结果。缓存位于 pgpool 子进程的本地,并被保存到它的生命结束。如果某些人使用了 ALTER TABLE 修改了表结构或其他类似内容,关系缓存不再一致。为了这个目的,relcache_expire 控制缓存的生命周期。
证书处理不在本文档讨论范围。postgresql.org 的 Secure TCP/IP Connections with SSL 页面指出了一些用来生成自签名证书的示例命令。
如果定义了多个服务器,可以在原始模式中进行故障切换。pgpool-II 在普通操作中通常访问 backend_hostname0 指定的后台程序。如果 backend_hostname0 因为某些原因不能正常工作,pgpool-II 尝试访问 backend_hostname1 指定的后台程序。如果它也不能正常工作,pgpool-II 尝试访问 backend_hostname2,3 等等。
在连接池模式中,所有在原始模式中的功能以及连接池功能都可以使用。要启用本模式,设置原始模式的配置参数以及以下的参数。
在 pgpool-II 子进程中缓存的最大连接数。当有新的连接使用相同的用户名连接到相同的数据库,pgpool-II 将重用缓存的连接。如果不是,则 pgpool-II 建立一个新的连接到 PostgreSQL。如果缓存的连接数达到了 max_pool,则最老的连接将被抛弃,并使用这个槽位来保存新的连接。默认值为 4。请小心通过 pgpool-II 进程到后台的连接数可能达到 num_init_children * max_pool 个。需要重启 pgpool-II 以使改动生效。
缓存的连接的过期时长,单位为秒。过期的缓存连接将被关闭。默认值为 0,表示缓存的连接将不被关闭。
指定在推出一个会话时发送到后台程序的SQL命令。多个命令可以通过“;”隔开。默认为以下的设置但你可以根据你的需求改变。
reset_query_list = 'ABORT; DISCARD ALL'
不同版本的 PostgreSQL 需要使用不同的命令。以下为推荐的设置。
| PostgreSQL 版本 | reset_query_list 的值 |
|---|---|
| 7.1 或更老的版本 | ABORT |
| 7.2 到 8.2 | ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT |
| 8.3 或更新的版本 | ABORT; DISCARD ALL |
修改本参数后需要重新加载 pgpool.conf 以使改变生效。
连接池模式中的故障切换
连接池模式中的故障切换和原始模式的相同。
本模式在后台程序间启用了数据复制。以下配置参数必须在设置以上参数之外另外设置。
设置为 true 以启用复制模式。默认值为 false。
当设置为 true 时,SELECT 查询将被分发到每个后台程序上用于负载均衡。默认值为 false。本参数必须在服务器启动前设置。
当设置为 true 时,在执行 INSERT/UPDATE/DELETE 后不同的后台程序返回不同的生效记录数,则和其他后台程序差别最大的后台程序将被退化。如果设置为 false,则会话被终止但后台程序不被退化。默认值为 false。
当设置为 true 时,当不同的后台程序返回不同的包类型时,则和其他后台程序差别最大的后台程序将被退化。 一个典型的用例为一个事务中的 SELECT 语句,在 replicate_select 设置为 true 的情况下,一个 SELECT 语句从不同的后台程序中返回不同的行数。非 SELECT 语句也可能触发这种情况。 例如,一个后台程序执行 UPDATE 成功但其他的失败。注意 pgpool 不会检查 SELECT 返回的记录的内容。如果设置为 false,则会话被终止但后台程序不被退化。默认值为 false。
指定一系列用逗号隔开的不会更新数据库的函数名。在复制模式中,不在本列表中指定的函数将即不会被负载均衡,也不会被复制。在主备模式中,这些 SELECT 语句只被发送到主节点。
你可以使用正则表达式来匹配函数名,例如你通过前缀“get_”或“select_”来作为你只读函数的开头:
white_function_list = 'get_.*,select_.*'
指定一系列用逗号隔开的会更新数据库的函数名。在复制模式中,在本列表中指定的函数将即不会被负载均衡,也不会被复制。在主备模式中,这些 SELECT 语句只被发送到主节点。
你可以使用正则表达式来匹配函数名,例如你通过前缀“set_”、“update_”、“delete_”或“insert_”来作为你只读函数的开头:
black_function_list = 'nextval,setval,set_.*,update_.*,delete_.*,insert_.*'
以上两项不能同时配置。
在 pgpool-II 3.0 之前,nextval() 和 setval() 是已知的会写入数据库的函数。你可以通使用 white_function_list 好 balck_function_list 来做到:
white_function_list = '' black_function_list = 'nextval,setval,lastval,currval'
注意我们在 nextval 和 setval 后面追加了 lastval 和 currval。虽然 lastval() 和 currval() 不是会写入的函数,但添加 lastval() 和 currval() 可以避免这些函数被无意地被负载均衡到其他的数据库节点而导致错误。添加到 black_function_list 将避免它们被负载均衡。
当设置为 true,pgpool-II 在复制模式中将复制 SELECT 语句。如果为 false,则 pgpool-II 只发送它们到主数据库。默认为 false。
如果 SELECT 查询是在一个显式的事务块中,replicate_select 和 load_balance_mode 将影响复制的工作模式。以下为具体的细节。
| SELECT 在一个事务块中 | Y | Y | Y | N | N | N | Y | N |
| replicate_select 为 true | Y | Y | N | N | Y | Y | N | N |
| load_balance_mode 为 true | Y | N | N | N | Y | N | Y | Y |
| 结果(R: 负载均衡, M: 只发送到主节点, L: 负载均衡) | R | R | M | M | R | R | M | L |
如果在包含 SERIAL 类型的表中做复制, SERIAL 列的值在不同后台间可能不同。这个问题可以通过显式的锁表解决(当然,事务的并发性将被严重退化)。为了达到这个目的,必须做以下的改变:
INSERT INTO ...
改变为
BEGIN;
LOCK TABLE ...
INSERT INTO ...
COMMIT;
当 insert_lock 为 true 时,pgpool-II 自动在每次执行 INSERT 时添加以上的查询(如果已经在事务中,它只是简单地添加 LOCK TABLE ... )。
pgpool-II 2.2 或更高的版本中,可以自动探测是否表拥有 SERIAL 类型的列,所以如果没有 SERIAL 类型的列,则将不会锁表。
pgpool-II 3.0 系列直到 3.0.4 为止针对串行的关系使用一个行锁,而不是表锁。这使在 VACUUM(包括 autovacuum)时的锁冲突最小。但这会导致另一个问题。如果发生了嵌套事务,对串行的关系使用行所会导致 PostgreSQL 的内部错误(确切地说,保存事务状态的 pg_clog 会发生访问错误)。为了避免这个问题,PostgreSQL 核心开发者决定禁止对串行的关系加锁,当然这也会让 pgpool-II 无法工作("修复"后的 PostgreSQL 版本为 9.0.5, 8.4.9, 8.3.16 和 8.2.22)。
由于新版的 PostgreSQL 不允许对串行的关系加锁,pgpool-II 3.0.5 或更新的版本针对 pgpool_catalog.insert_lock 使用行锁。所以需要预先在通过 pgpool-II 访问的数据库中建立 insert_lock 表。详细内容请参考建立 insert_lock 表。如果不存在 insert_lock 表,pgpool-II 将锁定插入的目标表。这种行为和 pgpool-II 2.2 和 2.3 系列相同。如果你希望使用与旧版本兼容的 insert_lock,你可以在配置脚本中指定锁定模式。详细内容请参考 configure 。
你也许需要更好(针对每个事务)的控制手段:
insert_lock 为 true,并添加 /*NO INSERT LOCK*/ 代码到你不想要表锁的 INSERT 语句的开始位置。insert_lock 为 false,并添加 /*INSERT LOCK*/ 到你需要表锁的 INSERT 语句的开始位置。
默认值为 false。如果 insert_lock 被启用,则(通过 pgpool-II 运行的) PostgreSQL 8.0 的事务、权限、规则和 alter_table 的回归测试会失败。原因是 pgpool-II 会尝试 LOCK 这些规则测试的 VIEW ,并产生以下的错误消息:
! ERROR: current transaction is aborted, commands ignored until
end of transaction block
例如,事务测试尝试 INSERT 到一个不存在的表,而 pgpool-II 导致 PostgreSQL 在这之前请求锁。事务将被终止,而之后的 INSERT 语句会产生以上的错误消息。
本参数指定一个用于在线恢复的 PostgreSQL 用户名。改变本参数不需要重启。
本参数指定一个用于在线恢复的 PostgreSQL 密码。改变本参数不需要重启。
本参数指定一个在在线恢复第一阶段在主(Primary)PostgreSQL 服务器上运行的命令。处于安全原因,本命令必须被放置在数据库实例目录中。例如,如果 recovery_1st_stage_command = 'sync-command',那么 pgpool-II 将执行 $PGDATA/sync-command。
recovery_1st_stage_command 将接受以下 3 个参数:
注意 pgpool-II 在执行 recovery_1st_stage_command 时接收连接和查询。在本阶段中,你可以查询和更新数据。
改变本参数不需要重启。
本参数指定一个在在线恢复第二阶段在主(Primary)PostgreSQL 服务器上运行的命令。处于安全原因,本命令必须被放置在数据库实例目录中。例如,如果 recovery_2st_stage_command = 'sync-command',那么 pgpool-II 将执行 $PGDATA/sync-command。
recovery_2nd_stage_command 将接受以下 3 个参数:
注意 pgpool-II 在运行 recovery_2nd_stage_command 时不接收连接和查询。因此如果一个客户端长时间持有一个连接,则恢复命令不会被执行。pgpool-II 等待所有的客户端关闭它们的连接。这个命令只在没有任何客户端连接到 pgpool-II 时才执行。
改变本参数不需要重启。
pgpool 在第二阶段不接受新的连接。如果一个客户端在恢复过程中连接到 pgpool,它必须等待到恢复结束。
本参数指定恢复超时的时间,单位为秒。如果到达了本超时值,则 pgpool 取消在线恢复并接受连接。0 表示不等待。
改变本参数不需要重启。
类似于 client_idle_limit 但是只在恢复的第二阶段生效。从执行最后一个查询后空闲到 client_idle_limit_in_recovery 秒的客户端将被断开连接。 这对避免 pgpool 的恢复被懒客户端扰乱或者客户机和 pgpool 之间的 TCP/IP 连接被意外断开(例如网线断开)非常有用。如果设置为 -1 ,则立即断开客户端连接。 client_idle_limit_in_recovery 的默认值为 0,表示本功能不启用。
如果你的客户端非常繁忙,则无论你将 client_idle_limit_in_recovery 设置为多少 pgpool-II 都无法进入恢复的第二阶段。在这种情况下, 你可以设置 client_idle_limit_in_recovery 为 -1 因而 pgpool-II 在进入第二阶段前立即断开这些繁忙的客户端的连接。
如果你改变了 client_idle_limit_in_recovery 你需要重新加载 pgpool.conf 。
本参数指定一个表名用于大对象的复制控制。如果它被指定,pgpool 将锁定由 lobj_lock_table 指定的表并通过查找 pg_largeobject 系统 catalog 生产一个大对象 id,并调用 lo_create 来建立这个大对象。这个过程保证 pgpool 在复制模式中在所有的数据库节点中获得相同的大对象 id。注意 PostgreSQL 8.0 或者更老的版本没有 lo_create,因此本功能将无法工作。
对 libpq 的 lo_creat() 函数的调用将触发本功能。通过 Java API(JDBC 驱动),PHP API(pg_lo_create,或者 PHP 库中类似的 API 例如 PDO)进行的大对象创建,以及其他各种编程语言中相同的 API 使用相同的协议,因此也应该能够运行。
以下的大对象建立操作将无法运行:
lobj_lock_table 存储在哪个 schema 并不重要,但是这个表必须对任何用户都可以写入。以下为如何建立这样一个表的示例:
CREATE TABLE public.my_lock_table (); GRANT ALL ON public.my_lock_table TO PUBLIC;
lobj_lock_table 指定的表必须被预先建立。如果你在 template1 中建立这个表,之后建立的任何数据库都将有这个表。
如果 lobj_lock_table 为空字符串(''),这个功能被禁用(大对象的复制将无法工作)。lobj_lock_table is 的默认值为''。
负载均衡的条件
需要对一个查询使用负载均衡,需要满足以下的所有条件:
注意你可以通过在 SELECT 语句之前插入任意的注释来禁止负载均衡:
/*REPLICATION*/ SELECT ...
请参考replicate_select。也可以参考flow chart。
注:JDBC 驱动有自动提交的选项。如果自动提交为 false,则 JDBC 驱动将自己发送 "BEGIN" 和 "COMMIT"。因此 pgpool-II 无法做任何负载均衡。你需要调用 setAutoCommit(true) 来启用自动提交。
复制模式中的故障切换
pgpool-II 退化一个死掉的后台并继续提供服务。只要最少还有一个后台还或者,服务就可以继续。
复制模式中的特有错误
在复制模式中,如果 pgpool 发现 INSERT,UPDATE 和 DELETE 生效的行数不同,如果 failover_if_affected_tuples_mismatch 被设置为 false,则 pgpool 将发送错误的 SQL 语句到所有的数据库节点来取消当前当前事务(如果为 false 则发生退化)。 在这种情况下,你将在客户端终端中看到以下错误信息:
=# UPDATE t SET a = a + 1; ERROR: pgpool detected difference of the number of update tuples Possible last query was: "update t1 set i = 1;" HINT: check data consistency between master and other db node
你将在 PostgreSQL 的日志中看到更新的行数(在本例中,数据库节点 0 更新了 0 行而数据库节点 1 更新了 1 行)。
2010-07-22 13:23:25 LOG: pid 5490: SimpleForwardToFrontend: Number of affected tuples are: 0 1 2010-07-22 13:23:25 LOG: pid 5490: ReadyForQuery: Degenerate backends: 1 2010-07-22 13:23:25 LOG: pid 5490: ReadyForQuery: Number of affected tuples are: 0 1
本模式用于使用其他负责完成实际的数据复制的主/备复制软件(类似于 Slong-I 和 基于流复制)来连接 pgpool-II。数据库节点的信息(如果你需要在线恢复功能,backend_hostname、backend_port、backend_weight、backend_flag 和 backend_data_directory )必须被设置,和复制模式中的方法相同。另外,还需要设置 master_slave_mode 和 load_balance_mode 为 true。pgpool-II 将发送需要复制的查询到主数据库,并在必要时将其他的查询将被负载均衡。不能被负载均衡而发送到主数据库的查询当然也是受负载均衡逻辑控制的。
在主/备模式中,对于临时表的 DDL 和 DML 操作只能在主节点上被执行。SELECT 也可以被强制在主节点上执行,但这需要你在 SELECT 语句前添加一个 /*NO LOAD BALANCE*/ 注释。
在主/备模式中, replication_mode 必须被设置为 false ,并且 master_slave_mode 为 true。
主/备模式有一个“master_slave_sub mode”。默认值为 'slony',用于 Slony-I。你也可以设置它为 'stream',它在你想使用 PostgreSQL 内置的复制系统(基于流复制)时被设置。用于 Slony-I 子模式的示例配置文件为 pgpool.conf.sample-master-slave,用于基于流复制的子模式的示例文件为 sub-module is pgpool.conf.sample-stream。
修改以上任何参数都需要重新启动 pgpool-II。
在主/备模式中,你可以通过设置 white_function_list 和 black_function_list 来控制负载均衡。参考 white_function_list 获得详细信息。
就像以上规定的,pgpool-II 可以与 PostgreSQL 9.0 带来的基于流复制协同工作。要使用它,启用“master_slave_mode”并设置“master_slave_sub_mode”为“stream”。 pgpool-II 认为基于流复制启用了热备,也就是说备库是以只读方式打开的。以下参数可以用于本模式:
指定能够容忍的备机上相对于主服务器上的 WAL 的复制延迟,单位为字节。如果延迟到达了 delay_threshold,pgpool-II 不再发送 SELECT 查询到备机。所有的东西都被发送到主服务器,即使启用了负载均衡模式,直到备机追赶上来。如果 delay_threshold 为 0 或者流复制检查被禁用,则延迟检查不被执行。这个检查在每“sr_check_period”周期执行一次。delay_threshold 的默认值为 0。要使对本参数的改动生效,你需要重新加载 pgpool.conf。
本参数指出基于流复制的延迟检查的间隔,单位为秒。默认为 0,表示禁用这个检查。如果你修改了 sr_check_period,需要重新加载 pgpool.conf 以使变动生效。
执行基于流复制检查的用户名。用户必须存在于所有的 PostgreSQL 后端上。否则,检查将出错。注意即使 sr_check_period 为 0, sr_check_user 和 sr_check_password 也会被使用。要识别主服务器,pgpool-II 发送函数调用请求道每个后端。sr_check_user 和 sr_check_password 用于这个会话。如果你修改了 sr_check_user,需要重新加载 pgpool.conf 以使变动生效。
执行基于流复制检查的用户的密码。如果不需要密码,指定空字符串('')。如果你修改了 sr_check_password,需要重新加载 pgpool.conf 以使变动生效。
指出如何记录复制延迟。如果指定 'none',则不写入日志。如果为 'always',在每次执行健康检查时记录延迟。如果 'if_over_threshold' 被指定,只有当延迟到达 delay_threshold 时记录日志。log_standby_delay 的默认值为 'none'。要使对本参数的改动生效,你需要重新加载 pgpool.conf。
你也可以使用“show pool_status”命令监控复制延迟。列名为“standby_delay#”(其中 '#' 需要用数据库节点编号代替)。
在使用流复制的主/备模式中,如果主节点或者备节点失效,pgpool-II 可以被设置为触发一个故障切换。节点可以被自动断开而不需要进行更多设置。 当进行流复制的时候,备节点检查一个“触发文件”的存在,一旦发现它,则备节点停止持续的恢复并进入读写模式。通过使用这种功能,我们可以使备数据库在主节点失效的时候进行替换。
警告:如果你计划使用多个备节点,我们建议设置一个 delay_threshold 值来避免任何查询由于查询被发送到其他备节点而导致获取旧数据。
如果第二个备节点在第一个备节点已经发生替换的时候替换主节点,你会从第二备节点获取错误的数据。我们不推荐计划使用这种配置。
以下例举了如何设置一个故障切换的配置。
$ cd /usr/loca/pgsql/bin $ cat failover_stream.sh #! /bin/sh # Failover command for streaming replication. # This script assumes that DB node 0 is primary, and 1 is standby. # # If standby goes down, do nothing. If primary goes down, create a # trigger file so that standby takes over primary node. # # Arguments: $1: failed node id. $2: new master hostname. $3: path to # trigger file. failed_node=$1 new_master=$2 trigger_file=$3 # Do nothing if standby goes down. if [ $failed_node = 1 ]; then exit 0; fi # Create the trigger file. /usr/bin/ssh -T $new_master /bin/touch $trigger_file exit 0; chmod 755 failover_stream.sh
failover_command = '/usr/local/src/pgsql/9.0-beta/bin/failover_stream.sh %d %H /tmp/trigger_file0'
standby_mode = 'on' primary_conninfo = 'host=name of primary_host user=postgres' trigger_file = '/tmp/trigger_file0'
wal_level = hot_standby max_wal_senders = 1
host replication postgres 192.168.0.10/32 trust
启动首要 PostgreSQL 节点和第二 PostgreSQL 节点来初始化基于流复制。如果主节点失效,备节点将自动启动为普通 PostgreSQL 并准备好接受写查询。
当使用流复制和热备的时候,确定哪个查询可以被发送到主节点或备节点或者不能被发送到备节点非常重要。pgpool-II 的流复制模式可以很好的处理这种情况。在本章,我们将解释 pgpool-II 如何做到这一点的。
我们通过检查查询来辨别哪个查询应该被发送到哪个节点。
在一个显式的事务中:
在扩展协议中,在负载均衡模式中在分析查询时,有可能探测是否查询可以被发送到备节点。规则和非扩展协议下相同。例如,INSERT 被发送到主节点。接下来的 bind,describe 和 execute 也将被发送到主节点。
[注:如果对 SELECT 语句的分析由于负载均衡被发送到备节点,然后一个 DML 语句,例如一个 INSERT ,被发送到 pgpool-II,那么,被分析的 SELECT 必须在主节点上执行。因此,我们会在主节点上重新分析这个 SELECT 语句。]
最后,pgpool-II 的分析认为有错误的查询将被发送到主节点。
在流复制的主/备模式中,可以执行在线恢复。在在线恢复过程中,首要务器扮演了主服务器的角色并恢复到指定的备服务器。因此恢复过程需要首要服务器启动并运行。 如果第一服务器失效且没有备用服务器被提升,你需要停止 pgpool-II 和所有的 PostgreSQL 服务器并手动恢复它们。
recovery_user = 'postgres'
recovery_password = 't-ishii'
recovery_1st_stage_command = 'basebackup.sh'
recovery_2nd_stage_command = ''
# cd pgpool-II-x.x.x/sql/pgpool-recovery # make # make install # psql -f pgpool-recovery.sql template1
以上未全部内容。现在你可以使用 pcp_recovery_node (作为备用节点的步骤)或者点击 pgpoolAdmin 的“恢复”按钮来执行在线恢复了。如果出现问题,请检查 pgpool-II 的日子,首要服务器的日志和备用服务器的日志。
作为参考,以下为恢复过程的步骤。
本模式实现了查询的并行执行。表可以被分割,数据分布在每个节点中。而且,复制和负载均衡功能也可以同时使用。在并行模式中,pgpool.conf 中的 replication_mode 和 load_balance_mode 被设置为 ture,master_slave 被设置为 false,parallel_mode 被设置为 false。当你改变这些参数后,需要重启 pgpool-II。
配置 System DB
如果想使用并行模式,System DB 需要被正确配置。System DB 包含存储在一个表中的,用于选择被分区的数据将被发送到的恰当后端程序的规则。
System DB 不一定要和 pgpool-II 在同一台主机上。System DB 的配置由 pgpool.conf 完成。
System DB 所在的主机名。给出空字符串('')表示 SystemDB 和 pgpool-II 在同一台主机,且将通过 UNIX 域套接字访问。
System DB 使用的端口号
分区规则和其他的信息将被定义到这里指定的数据库中。默认值为:'pgpool'。
分区规则和其他的信息将被定义到这里指定的模式中。默认值为:'pgpool_catalog'。
连接到 System DB 的用户名。
连接到 System DB 的密码,如果不需要密码,则设置为空字符串('')。
到达用于校验后台服务器的 PEM 格式的包含一个或者多个 CA 根证书的文件的路径。这类似于 OpenSSL 的 verify(1) 命令的 -CAfile 选项。
默认值为未设置,也就是不进行认证。如果本选项未设置但是 ssl_ca_cert_dir被设置了,则认证过程依旧会发生。
到达包含用于校验后台服务器的 PEM 格式的 CA 证书的目录的路径。这类似于 OpenSSL 的 verify(1) 命令的 -CApath 选项。
默认值为未设置,也就是不进行认证。如果本选项未设置但是 ssl_ca_cert 被设置了,则认证过程依旧会发生。
初始化 System DB 的配置
首先,需要建立 pgpool.conf 文件中指定的数据库和模式。可以在 $prefix/share/system_db.sql 找到一个示例脚本。如果你指定了不同的数据库名和模式,在脚本中相应地修改它们。
psql -f $prefix/share/system_db.sql pgpool
注册一条分区规则
用于数据分区的规则必须被注册到 pgpool_catalog.dist_def 表中。
CREATE TABLE pgpool_catalog.dist_def( dbname TEXT, -- database name schema_name TEXT, -- schema name table_name TEXT, -- table name col_name TEXT NOT NULL CHECK (col_name = ANY (col_list)), -- partitioning key column name col_list TEXT[] NOT NULL, -- names of table attributes type_list TEXT[] NOT NULL, -- types of table attributes dist_def_func TEXT NOT NULL, -- name of the partitioning rule function PRIMARY KEY (dbname,schema_name,table_name) );
注册一条复制规则
未被分发的表必须被复制. 当一个查询对一个分发表和另外一个表进行连接时,pgpool-II 从 pgpool_catalog.replicate_def 表获取复制信息。一个表只能被复制或被分发。
CREATE TABLE pgpool_catalog.replicate_def( dbname TEXT, --database name schema_name TEXT, --schema name table_name TEXT, --table name col_list TEXT[] NOT NULL, -- names of table attributes type_list TEXT[] NOT NULL, -- types of table attributes PRIMARY KEY (dbname,schema_name,table_name) );
分区 pgbench 表示例
在这个示例中,accounts 表被分区,branches 和 tellers 表被复制。accounts 表和 branches 表通过 bid 进行连接。branches 表注册到复制表中,若这三个表(accounts, branches 和 tellers)将被连接的话,有必要也为 tellers 表注册一条复制规则。
INSERT INTO pgpool_catalog.dist_def VALUES ( 'pgpool', 'public', 'accounts', 'aid', ARRAY['aid','bid','abalance','filler'], ARRAY['integer','integer','integer','character(84)'], 'pgpool_catalog.dist_def_accounts' ); INSERT INTO pgpool_catalog.replicate_def VALUES ( 'pgpool', 'public', 'branches', ARRAY['bid','bbalance','filler'], ARRAY['integer','integer','character(84)'] );
分区规则函数(此处是 pgpool_catalog.dist_def_accounts )需要一个值作为分区的关键字列,并返回相应的DB节点ID。注意节点ID必须从0开始, 下面是为pgbench写的函数示例。
CREATE OR REPLACE FUNCTION pgpool_catalog.dist_def_accounts (val ANYELEMENT) RETURNS INTEGER AS ' SELECT CASE WHEN $1 >= 1 and $1 <= 30000 THEN 0 WHEN $1 > 30000 and $1 <= 60000 THEN 1 ELSE 2
和 PostgreSQL 中使用的 pg_hba.conf 文件类似,pgpool-II 使用一个称之为 "pool_hba.conf" 的配置文件来支持类似的客户端认证功能。
当安装 pgpool 的时候,pool_hba.conf.sample 文件将被安装在"/usr/local/etc"目录下,该位置也是配置文件的默认目录。拷贝 pool_hba.conf.sample 为 pool_hba.conf,如果必要的话并修改它。默认的情况下,pool_hba 认证被开启,详见"6. 设置 pgpool.conf"。
pool_hba.conf 文件的格式和 PostgreSQL 的 pg_hba.conf 的格式遵循的非常相近。
local DATABASE USER METHOD [OPTION]
host DATABASE USER CIDR-ADDRESS METHOD [OPTION]
查看 "pool_hba.conf.sample" 文件获取每个字段详细的解释。
下面是 pool_hba 的一些限制。
尽管"hostssl"不能被使用,pgpool-II 2.3或更高版本支持SSL,详见SSL。
尽管 pgpool 并不知道后端服务器的用户的任何信息,但是将通过 pool_hba.conf 中的 DATABASE 字段项对数据库名进行简单的检查。
这与上面介绍的 "samegroup" 原因相同,将通过 pool_hba.conf 中 USER 字段项对用户名进行简单的检查。
pgpool 当前不支持 IPv6.
再次,这与上面介绍的 "samegroup" 原因相同, pgpool 不能够访问 user/password 信息。
要使用md5认证,你需要在 "pool_passwd" 中注册你的名字和密码。详见认证/访问控制。
注意本节描述的所有认证发生在客户端和 pgpool-II 之间;客户端仍然需要继续通过 PostgreSQL 的认证过程。 pool_hba 并不关心客户端提供的用户名/数据库名(例如 psql -U testuser testdb)是否真实存在于后端服务器中。pool_hba 仅仅关心是否在 pool_hba.conf 中存在匹配。
PAM 认证使用 pgpool 运行的主机上的用户信息来获得支持。若让 pgpool 支持PAM,需要在 configure 时指定"--with-pam"选项。
configure --with-pam
若启用 PAM 认证,你需要为 pgpool 在系统的 PAM 配置目录(通常是在"/etc/pam.d")中创建一个 service-configuration 文件。 一个 service-configuration 的示例文件被安装为安装目录下的"share/pgpool.pam"。
Query cache 可以在 pgpool-II 的所有模式中使用。在 pgpool.conf 中启用它如下:
enable_query_cache = true
你还需要在 System DB 中创建下面的表:
CREATE TABLE pgpool_catalog.query_cache ( hash TEXT, query TEXT, value bytea, dbname TEXT, create_time TIMESTAMP WITH TIME ZONE, PRIMARY KEY(hash, dbname) );
然而,如果你不使用"pgpool_catalog"的话,你可能需要修改该语句中的 schema。
所有后端服务器和System DB(若需要)都必须在启动 pgpool-II 之前启动。
pgpool [-c][-f config_file][-a hba_file][-F pcp_config_file][-n][-D][-d]
| -c --clear-cache | 删除 query cache |
| -f config_file --config-file config-file | 指定 pgpool.conf |
| -a hba_file --hba-file hba_file | 指定 pool_hba.conf |
| -F pcp_config_file --pcp-password-file | 指定 pcp.conf |
| -n --no-daemon | 非daemon mode (terminal没有被detached) |
| -D --discard-status | 丢弃 pgpool_status 文件且不恢复到先前的状态 |
| -d --debug | debug mode |
pgpool [-f config_file][-F pcp_config_file] [-m {s[mart]|f[ast]|i[mmediate]}] stop
-m s[mart]--mode s[mart] |
等待客户端断开连接,然后关闭(默认) |
-m f[ast]--mode f[ast] |
并不等待客户端; 立即关闭 |
-m i[mmediate]--mode i[mmediate] |
同 '-m f' |
pgpool 记录后端服务器的状态到 [logdir]/pgpool_status 文件中,当 pgpool 重启时,它读该文件并恢复后端服务器的状态。 这将避免可能由于下述原因造成的DB节点间的具有不同的数据:
如果由于某些原因,例如,停止的DB已经通过其它另外的方式已经获得了同步,则 pgpool_status 可在启动 pgpool 之前被安全的移除。
pgpool-II 能够不需要重启而重新加载配置文件。
pgpool [-c][-f config_file][-a hba_file][-F pcp_config_file] reload
| -f config_file --config-file config-file | 指定 pgpool.conf |
| -a hba_file --hba-file hba_file | 指定 pool_hba.conf |
| -F pcp_config_file --pcp-password-file | 指定 pcp.conf |
需要指出的是,一些配置项并不能通过重新加载来改变。新的修改后的配置将在新会话上生效。
pgpool-II 通过 SHOW 命令提供一些信息。SHOW 是一个真实的 SQL 语句, 但是如果该命令查询 pgpool-II 信息的话,pgpool-II 解释了该命令。可选项如下:
注意:术语 'pool' 指的是一个 pgpool 进程所拥有的 PostgreSQL 会话池,并非指所有的 pgpool 所拥有的会话。
SQL语句中的 "pool_status" 在以前的版本中已经存在,但是其它可选项在 3.0 中才出现。
"SHOW pool_status" 返回配置参数列表,包含参数的 name, value, 和 description。下面是返回结果的一个摘录:
benchs2=# show pool_status;
item | value | description
-------------------------------+---------------------------------+------------------------------------------------------------------
listen_addresses | 127.0.0.1 | host name(s) or IP address(es) to listen to
port | 9999 | pgpool accepting port number
socket_dir | /tmp | pgpool socket directory
num_init_children | 5 | # of children initially pre-forked
child_life_time | 300 | if idle for this seconds, child exits
"SHOW pool_nodes" 返回所有配置节点的列表.它显示了节点的 id, hostname, port, status, 以及权重 weight (仅在使用负载均衡模式时有意义)。status 列可能的值可在 pcp_node_info reference 里获得解释。
benchs2=# show pool_nodes; id | hostname | port | status | lb_weight ------+-------------+------+--------+----------- 0 | 127.0.0.1 | 5432 | 2 | 0.5 1 | 192.168.1.7 | 5432 | 3 | 0.5 (2 lignes)
"SHOW pool_processes" 返回 pgpool-II 所有进程的信息,这些进程正等待连接或在处理一个连接。
结果有 6 列:
结果将一直返回 num_init_children 行。
benchs2=# show pool_processes; pool_pid | start_time | database | username | create_time | pool_counter ----------+---------------------+----------+-----------+---------------------+-------------- 8465 | 2010-08-14 08:35:40 | | | | 8466 | 2010-08-14 08:35:40 | benchs | guillaume | 2010-08-14 08:35:43 | 1 8467 | 2010-08-14 08:35:40 | | | | 8468 | 2010-08-14 08:35:40 | | | | 8469 | 2010-08-14 08:35:40 | | | | (5 lines)
"SHOW pool_pools" 返回 pgpool-II 所处理的连接池列表,包含它们的 name, value, 和 description,下面是结果的一个摘录:
共 11 列:
结果将一直返回num_init_children*max_pool 行.
pool_pid | start_time | pool_id | backend_id | database | username | create_time | majorversion | minorversion | pool_counter | pool_backendpid | pool_connected ----------+---------------------+---------+------------+----------+-----------+---------------------+--------------+--------------+--------------+-----------------+---------------- 8465 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 0 | 0 | benchs | guillaume | 2010-08-14 08:35:43 | 3 | 0 | 1 | 8473 | 1 8466 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | (20 lines)
"SHOW pool_version" 将显示包含 pgpool-II 版本号的一个字符串。下面是一个示例:
benchs2=# show pool_version;
pool_version
------------------------
3.0-dev (umiyameboshi)
(1 line)
pgpool-II,在复制模式下在给客户端提供服务的同时,能够同步一个数据库并关联(attach)一个节点,我们称这项特性为"在线恢复"。
在执行在线恢复之前,一个恢复的目标节点必须处于 detached 状态。如果你想动态的增加一个 PostgreSQL server,则在pgpool.conf中增加'backend_hostname'及其相关的参数并重新加载该配置文件。 pgpool-II 把该新的节点注册为 detached 节点。
注意:停止 master 节点(第一个启动和运行的节点)上的autovacuum。如果Autovacuum运行的话,它可能会改变数据的内容并可能造成在线恢复后的不一致性。这仅适用于使用简单的复制机制的恢复,例如下文将会讨论的 rsync 方式,而对使用 PostgreSQL 的PITR机制进行在线恢复的并不适用。
若目标 PostgreSQL 服务器已经启动开,你需要关闭它。
pgpool-II 以两个阶段来执行在线恢复。当一个恢复节点同步数据库时,客户端可能需要等待几秒到几分钟不等的时间来连接 pgpool-II。下面是这些步骤:
数据同步的第一个步称之为"第一阶段"。 数据在第一阶段中被同步,在第一阶段中,数据能够被并行的从任意表更新或获取。
你可以指定第一阶段中执行的脚本。pgpool-II传递三个参数到该脚本中。
数据同步在称之为"第二阶段"中完成。在进入第二阶段前,pgpool-II 等待所有的客户端断开连接。它阻塞所有新来的连接直到第二阶段完成。当所有的连接被中断后,pgpool-II合并在第一和第二阶段中更新的数据。这是同步的最终数据。
注意:关于在线恢复有一个限制。如果 pgpool-II 本身安装在多个主机上,在线恢复则不能正确的工作,这是因为 pgpool-II需要在在线恢复的第二阶段中断所有客户端连接。如果存在多个 pgpool-II 主机,只有一个主机能收到在线恢复命令,然后阻塞连接。
为在线恢复在pgpool.conf中设置如下参数:
你需要为在线恢复在所有的后端节点中的"template1"数据库中安装c语言函数。源代码在pgpool-II的压缩包中。
pgpool-II-x.x.x/sql/pgpool-recovery/
改变相应的目录,并执行"make install"。
% cd pgpool-II-x.x.x/sql/pgpool-recovery/ % make install
然后安装 SQL 函数。
% cd pgpool-II-x.x.x/sql/pgpool-recovery/ % psql -f pgpool-recovery.sql template1
我们必须在数据库实例目录($PGDATA)中部署一些数据同步脚本和一个远程启动脚本。在pgpool-II-x.x.x/sample 目录中可找到一些示例脚本文件。
本节说明如何通过基于时间点的恢复(Point In Time Recovery,PITR)执行在线恢复。PITR 在 PostgreSQL 8.2 以及后续版本可用。注意所有的涉及的 PostgreSQL 服务器都需要支持 PITR。
在第一阶段,需要一个脚本从主节点获取一个备份库,然后把它拷贝到恢复目标节点中去。该脚本可命名为如"copy-base-backup"。下面是个示例:
#! /bin/sh
DATA=$1
RECOVERY_TARGET=$2
RECOVERY_DATA=$3
psql -c "select pg_start_backup('pgpool-recovery')" postgres
echo "restore_command = 'scp $HOSTNAME:/data/archive_log/%f %p'" > /data/recovery.conf
tar -C /data -zcf pgsql.tar.gz pgsql
psql -c 'select pg_stop_backup()' postgres
scp pgsql.tar.gz $RECOVERY_TARGET:$RECOVERY_DATA
该脚本把主数据库设成backup模式,生成如下的 recovery.conf:
restore_command = 'scp master:/data/archive_log/%f %p'
执行备份,接着把主数据库不再设成备份模式,然后拷贝备份库到选择的目标节点。
该过程的第二阶段是一个脚本进行强制 XLOG 文件转换。该脚本此处命名为"pgpool_recovery_pitr"。它强制执行事务日志的一个转换。为此,pg_switch_xlog可能会被用到。然后它可能在转换执行完前返回,这样可能会导致在线恢复过程的失败。Pgpool-II提供了一个更加安全的称之为"pgpool_switch_xlog"的函数,该函数等待一直到事务日志转换实际被完成后。pgpool_switch_xlog 在安装 C 函数小节过程执行时被安装。
下面是示例脚本。
#! /bin/sh
# Online recovery 2nd stage script
#
datadir=$1 # master dabatase cluster
DEST=$2 # hostname of the DB node to be recovered
DESTDIR=$3 # database cluster of the DB node to be recovered
port=5432 # PostgreSQL port number
archdir=/data/archive_log # archive log directory
# Force to flush current value of sequences to xlog
psql -p $port -t -c 'SELECT datname FROM pg_database WHERE NOT datistemplate AND datallowconn' template1|
while read i
do
if [ "$i" != "" ];then
psql -p $port -c "SELECT setval(oid, nextval(oid)) FROM pg_class WHERE relkind = 'S'" $i
fi
done
psql -p $port -c "SELECT pgpool_switch_xlog('$archdir')" template1
该序列注入(flushing of sequences)仅在复制模式下有效:在该情况下,序列不得不在所有节点上具有同一个起点。在主/备模式下并不可用。脚本中的循环强制 PostgreSQL 发出所有数据库中序列生成器的当前值到事务日志中,这样它就传播到恢复的目标节点中去。
我们部署这些脚本到 $PGDATA 目录中去。
最后,我们修改pgpool.conf。
recovery_1st_stage_command = 'copy-base-backup' recovery_2nd_stage_command = 'pgpool_recovery_pitr'
我们已完成通过PITR进行在线恢复的准备工作。
pgpool_remote_start
该脚本启动远程主机的 postmaster 进程。pgpool-II 以如下方式执行。
% pgpool_remote_start remote_host remote_datadir remote_host: Hostname of a recovery target. remote_datadir: Database cluster path of a recovery target.
在该示例脚本中,我们通过 ssh 启动 postmaster 进程。所以如果你想要它能够运行,你需要提供不需要密码输入的 ssh 连接。
如果你使用PITR进行恢复,你需要部署一个库备份。PostgreSQL 将自动启动一个 PITR 恢复,然后它开始接受连接。
#! /bin/sh DEST=$1 DESTDIR=$2 PGCTL=/usr/local/pgsql/bin/pg_ctl # Deploy a base backup ssh -T $DEST 'cd /data/;le config-file
需要指出的是,一些配置项并不能通过重新加载来改变。新的修改后的配置将在新会话上生效。
pgpool-II 通过 SHOW 命令提供一些信息。SHOW 是一个真实的 SQL 语句, 但是如果该命令查询 pgpool-II 信息的话,pgpool-II 解释了该命令。可选项如下:
注意:术语 'pool' 指的是一个 pgpool 进程所拥有的 PostgreSQL 会话池,并非指所有的 pgpool 所拥有的会话。
SQL语句中的 "pool_status" 在以前的版本中已经存在,但是其它可选项在 3.0 中才出现。
"SHOW pool_status" 返回配置参数列表,包含参数的 name, value, 和 description。下面是返回结果的一个摘录:
benchs2=# show pool_status;
item | value | description
-------------------------------+---------------------------------+------------------------------------------------------------------
listen_addresses | 127.0.0.1 | host name(s) or IP address(es) to listen to
port | 9999 | pgpool accepting port number
socket_dir | /tmp | pgpool socket directory
num_init_children | 5 | # of children initially pre-forked
child_life_time | 300 | if idle for this seconds, child exits
"SHOW pool_nodes" 返回所有配置节点的列表.它显示了节点的 id, hostname, port, status, 以及权重 weight (仅在使用负载均衡模式时有意义)。status 列可能的值可在 pcp_node_info reference 里获得解释。
benchs2=# show pool_nodes; id | hostname | port | status | lb_weight ------+-------------+------+--------+----------- 0 | 127.0.0.1 | 5432 | 2 | 0.5 1 | 192.168.1.7 | 5432 | 3 | 0.5 (2 lignes)
"SHOW pool_processes" 返回 pgpool-II 所有进程的信息,这些进程正等待连接或在处理一个连接。
结果有 6 列:
结果将一直返回 num_init_children 行。
benchs2=# show pool_processes; pool_pid | start_time | database | username | create_time | pool_counter ----------+---------------------+----------+-----------+---------------------+-------------- 8465 | 2010-08-14 08:35:40 | | | | 8466 | 2010-08-14 08:35:40 | benchs | guillaume | 2010-08-14 08:35:43 | 1 8467 | 2010-08-14 08:35:40 | | | | 8468 | 2010-08-14 08:35:40 | | | | 8469 | 2010-08-14 08:35:40 | | | | (5 lines)
"SHOW pool_pools" 返回 pgpool-II 所处理的连接池列表,包含它们的 name, value, 和 description,下面是结果的一个摘录:
共 11 列:
结果将一直返回num_init_children*max_pool 行.
pool_pid | start_time | pool_id | backend_id | database | username | create_time | majorversion | minorversion | pool_counter | pool_backendpid | pool_connected ----------+---------------------+---------+------------+----------+-----------+---------------------+--------------+--------------+--------------+-----------------+---------------- 8465 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 0 | 0 | benchs | guillaume | 2010-08-14 08:35:43 | 3 | 0 | 1 | 8473 | 1 8466 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | (20 lines)
"SHOW pool_version" 将显示包含 pgpool-II 版本号的一个字符串。下面是一个示例:
benchs2=# show pool_version;
pool_version
------------------------
3.0-dev (umiyameboshi)
(1 line)
pgpool-II,在复制模式下在给客户端提供服务的同时,能够同步一个数据库并关联(attach)一个节点,我们称这项特性为"在线恢复"。
在执行在线恢复之前,一个恢复的目标节点必须处于 detached 状态。如果你想动态的增加一个 PostgreSQL server,则在pgpool.conf中增加'backend_hostname'及其相关的参数并重新加载该配置文件。 pgpool-II 把该新的节点注册为 detached 节点。
注意:停止 master 节点(第一个启动和运行的节点)上的autovacuum。如果Autovacuum运行的话,它可能会改变数据的内容并可能造成在线恢复后的不一致性。这仅适用于使用简单的复制机制的恢复,例如下文将会讨论的 rsync 方式,而对使用 PostgreSQL 的PITR机制进行在线恢复的并不适用。
若目标 PostgreSQL 服务器已经启动开,你需要关闭它。
pgpool-II 以两个阶段来执行在线恢复。当一个恢复节点同步数据库时,客户端可能需要等待几秒到几分钟不等的时间来连接 pgpool-II。下面是这些步骤:
数据同步的第一个步称之为"第一阶段"。 数据在第一阶段中被同步,在第一阶段中,数据能够被并行的从任意表更新或获取。
你可以指定第一阶段中执行的脚本。pgpool-II传递三个参数到该脚本中。
数据同步在称之为"第二阶段"中完成。在进入第二阶段前,pgpool-II 等待所有的客户端断开连接。它阻塞所有新来的连接直到第二阶段完成。当所有的连接被中断后,pgpool-II合并在第一和第二阶段中更新的数据。这是同步的最终数据。
注意:关于在线恢复有一个限制。如果 pgpool-II 本身安装在多个主机上,在线恢复则不能正确的工作,这是因为 pgpool-II需要在在线恢复的第二阶段中断所有客户端连接。如果存在多个 pgpool-II 主机,只有一个主机能收到在线恢复命令,然后阻塞连接。
为在线恢复在pgpool.conf中设置如下参数:
你需要为在线恢复在所有的后端节点中的"template1"数据库中安装c语言函数。源代码在pgpool-II的压缩包中。
pgpool-II-x.x.x/sql/pgpool-recovery/
改变相应的目录,并执行"make install"。
% cd pgpool-II-x.x.x/sql/pgpool-recovery/ % make install
然后安装 SQL 函数。
% cd pgpool-II-x.x.x/sql/pgpool-recovery/ % psql -f pgpool-recovery.sql template1
我们必须在数据库实例目录($PGDATA)中部署一些数据同步脚本和一个远程启动脚本。在pgpool-II-x.x.x/sample 目录中可找到一些示例脚本文件。
本节说明如何通过基于时间点的恢复(Point In Time Recovery,PITR)执行在线恢复。PITR 在 PostgreSQL 8.2 以及后续版本可用。注意所有的涉及的 PostgreSQL 服务器都需要支持 PITR。
在第一阶段,需要一个脚本从主节点获取一个备份库,然后把它拷贝到恢复目标节点中去。该脚本可命名为如"copy-base-backup"。下面是个示例:
#! /bin/sh
DATA=$1
RECOVERY_TARGET=$2
RECOVERY_DATA=$3
psql -c "select pg_start_backup('pgpool-recovery')" postgres
echo "restore_command = 'scp $HOSTNAME:/data/archive_log/%f %p'" > /data/recovery.conf
tar -C /data -zcf pgsql.tar.gz pgsql
psql -c 'select pg_stop_backup()' postgres
scp pgsql.tar.gz $RECOVERY_TARGET:$RECOVERY_DATA
该脚本把主数据库设成backup模式,生成如下的 recovery.conf:
restore_command = 'scp master:/data/archive_log/%f %p'
执行备份,接着把主数据库不再设成备份模式,然后拷贝备份库到选择的目标节点。
该过程的第二阶段是一个脚本进行强制 XLOG 文件转换。该脚本此处命名为"pgpool_recovery_pitr"。它强制执行事务日志的一个转换。为此,pg_switch_xlog可能会被用到。然后它可能在转换执行完前返回,这样可能会导致在线恢复过程的失败。Pgpool-II提供了一个更加安全的称之为"pgpool_switch_xlog"的函数,该函数等待一直到事务日志转换实际被完成后。pgpool_switch_xlog 在安装 C 函数小节过程执行时被安装。
下面是示例脚本。
#! /bin/sh
# Online recovery 2nd stage script
#
datadir=$1 # master dabatase cluster
DEST=$2 # hostname of the DB node to be recovered
DESTDIR=$3 # database cluster of the DB node to be recovered
port=5432 # PostgreSQL port number
archdir=/data/archive_log # archive log directory
# Force to flush current value of sequences to xlog
psql -p $port -t -c 'SELECT datname FROM pg_database WHERE NOT datistemplate AND datallowconn' template1|
while read i
do
if [ "$i" != "" ];then
psql -p $port -c "SELECT setval(oid, nextval(oid)) FROM pg_class WHERE relkind = 'S'" $i
fi
done
psql -p $port -c "SELECT pgpool_switch_xlog('$archdir')" template1
该序列注入(flushing of sequences)仅在复制模式下有效:在该情况下,序列不得不在所有节点上具有同一个起点。在主/备模式下并不可用。脚本中的循环强制 PostgreSQL 发出所有数据库中序列生成器的当前值到事务日志中,这样它就传播到恢复的目标节点中去。
我们部署这些脚本到 $PGDATA 目录中去。
最后,我们修改pgpool.conf。
recovery_1st_stage_command = 'copy-base-backup' recovery_2nd_stage_command = 'pgpool_recovery_pitr'
我们已完成通过PITR进行在线恢复的准备工作。
pgpool_remote_start
该脚本启动远程主机的 postmaster 进程。pgpool-II 以如下方式执行。
% pgpool_remote_start remote_host remote_datadir remote_host: Hostname of a recovery target. remote_datadir: Database cluster path of a recovery target.
在该示例脚本中,我们通过 ssh 启动 postmaster 进程。所以如果你想要它能够运行,你需要提供不需要密码输入的 ssh 连接。
如果你使用PITR进行恢复,你需要部署一个库备份。PostgreSQL 将自动启动一个 PITR 恢复,然后它开始接受连接。
#! /bin/sh DEST=$1 DESTDIR=$2 PGCTL=/usr/local/pgsql/bin/pg_ctl # Deploy a base backup ssh -T $DEST 'cd /data/;le config-file指定 pgpool.conf -a hba_file
--hba-file hba_file指定 pool_hba.conf -F pcp_config_file
--pcp-password-file指定 pcp.conf 需要指出的是,一些配置项并不能通过重新加载来改变。新的修改后的配置将在新会话上生效。
SHOW 命令
概述
pgpool-II 通过 SHOW 命令提供一些信息。SHOW 是一个真实的 SQL 语句, 但是如果该命令查询 pgpool-II 信息的话,pgpool-II 解释了该命令。可选项如下:
注意:术语 'pool' 指的是一个 pgpool 进程所拥有的 PostgreSQL 会话池,并非指所有的 pgpool 所拥有的会话。
SQL语句中的 "pool_status" 在以前的版本中已经存在,但是其它可选项在 3.0 中才出现。
"SHOW pool_status" 返回配置参数列表,包含参数的 name, value, 和 description。下面是返回结果的一个摘录:
benchs2=# show pool_status;
item | value | description
-------------------------------+---------------------------------+------------------------------------------------------------------
listen_addresses | 127.0.0.1 | host name(s) or IP address(es) to listen to
port | 9999 | pgpool accepting port number
socket_dir | /tmp | pgpool socket directory
num_init_children | 5 | # of children initially pre-forked
child_life_time | 300 | if idle for this seconds, child exits
"SHOW pool_nodes" 返回所有配置节点的列表.它显示了节点的 id, hostname, port, status, 以及权重 weight (仅在使用负载均衡模式时有意义)。status 列可能的值可在 pcp_node_info reference 里获得解释。
benchs2=# show pool_nodes; id | hostname | port | status | lb_weight ------+-------------+------+--------+----------- 0 | 127.0.0.1 | 5432 | 2 | 0.5 1 | 192.168.1.7 | 5432 | 3 | 0.5 (2 lignes)
"SHOW pool_processes" 返回 pgpool-II 所有进程的信息,这些进程正等待连接或在处理一个连接。
结果有 6 列:
结果将一直返回 num_init_children 行。
benchs2=# show pool_processes; pool_pid | start_time | database | username | create_time | pool_counter ----------+---------------------+----------+-----------+---------------------+-------------- 8465 | 2010-08-14 08:35:40 | | | | 8466 | 2010-08-14 08:35:40 | benchs | guillaume | 2010-08-14 08:35:43 | 1 8467 | 2010-08-14 08:35:40 | | | | 8468 | 2010-08-14 08:35:40 | | | | 8469 | 2010-08-14 08:35:40 | | | | (5 lines)
"SHOW pool_pools" 返回 pgpool-II 所处理的连接池列表,包含它们的 name, value, 和 description,下面是结果的一个摘录:
共 11 列:
结果将一直返回num_init_children*max_pool 行.
pool_pid | start_time | pool_id | backend_id | database | username | create_time | majorversion | minorversion | pool_counter | pool_backendpid | pool_connected ----------+---------------------+---------+------------+----------+-----------+---------------------+--------------+--------------+--------------+-----------------+---------------- 8465 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8465 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 0 | 0 | benchs | guillaume | 2010-08-14 08:35:43 | 3 | 0 | 1 | 8473 | 1 8466 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8466 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8467 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8468 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 0 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 1 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 2 | 0 | | | | | | | | 8469 | 2010-08-14 08:35:40 | 3 | 0 | | | | | | | | (20 lines)
"SHOW pool_version" 将显示包含 pgpool-II 版本号的一个字符串。下面是一个示例:
benchs2=# show pool_version;
pool_version
------------------------
3.0-dev (umiyameboshi)
(1 line)
pgpool-II,在复制模式下在给客户端提供服务的同时,能够同步一个数据库并关联(attach)一个节点,我们称这项特性为"在线恢复"。
在执行在线恢复之前,一个恢复的目标节点必须处于 detached 状态。如果你想动态的增加一个 PostgreSQL server,则在pgpool.conf中增加'backend_hostname'及其相关的参数并重新加载该配置文件。 pgpool-II 把该新的节点注册为 detached 节点。
注意:停止 master 节点(第一个启动和运行的节点)上的autovacuum。如果Autovacuum运行的话,它可能会改变数据的内容并可能造成在线恢复后的不一致性。这仅适用于使用简单的复制机制的恢复,例如下文将会讨论的 rsync 方式,而对使用 PostgreSQL 的PITR机制进行在线恢复的并不适用。
若目标 PostgreSQL 服务器已经启动开,你需要关闭它。
pgpool-II 以两个阶段来执行在线恢复。当一个恢复节点同步数据库时,客户端可能需要等待几秒到几分钟不等的时间来连接 pgpool-II。下面是这些步骤:
数据同步的第一个步称之为"第一阶段"。 数据在第一阶段中被同步,在第一阶段中,数据能够被并行的从任意表更新或获取。
你可以指定第一阶段中执行的脚本。pgpool-II传递三个参数到该脚本中。
数据同步在称之为"第二阶段"中完成。在进入第二阶段前,pgpool-II 等待所有的客户端断开连接。它阻塞所有新来的连接直到第二阶段完成。当所有的连接被中断后,pgpool-II合并在第一和第二阶段中更新的数据。这是同步的最终数据。
注意:关于在线恢复有一个限制。如果 pgpool-II 本身安装在多个主机上,在线恢复则不能正确的工作,这是因为 pgpool-II需要在在线恢复的第二阶段中断所有客户端连接。如果存在多个 pgpool-II 主机,只有一个主机能收到在线恢复命令,然后阻塞连接。
为在线恢复在pgpool.conf中设置如下参数:
你需要为在线恢复在所有的后端节点中的"template1"数据库中安装c语言函数。源代码在pgpool-II的压缩包中。
pgpool-II-x.x.x/sql/pgpool-recovery/
改变相应的目录,并执行"make install"。
% cd pgpool-II-x.x.x/sql/pgpool-recovery/ % make install
然后安装 SQL 函数。
% cd pgpool-II-x.x.x/sql/pgpool-recovery/ % psql -f pgpool-recovery.sql template1
我们必须在数据库实例目录($PGDATA)中部署一些数据同步脚本和一个远程启动脚本。在pgpool-II-x.x.x/sample 目录中可找到一些示例脚本文件。
本节说明如何通过基于时间点的恢复(Point In Time Recovery,PITR)执行在线恢复。PITR 在 PostgreSQL 8.2 以及后续版本可用。注意所有的涉及的 PostgreSQL 服务器都需要支持 PITR。
在第一阶段,需要一个脚本从主节点获取一个备份库,然后把它拷贝到恢复目标节点中去。该脚本可命名为如"copy-base-backup"。下面是个示例:
#! /bin/sh
DATA=$1
RECOVERY_TARGET=$2
RECOVERY_DATA=$3
psql -c "select pg_start_backup('pgpool-recovery')" postgres
echo "restore_command = 'scp $HOSTNAME:/data/archive_log/%f %p'" > /data/recovery.conf
tar -C /data -zcf pgsql.tar.gz pgsql
psql -c 'select pg_stop_backup()' postgres
scp pgsql.tar.gz $RECOVERY_TARGET:$RECOVERY_DATA
该脚本把主数据库设成backup模式,生成如下的 recovery.conf:
restore_command = 'scp master:/data/archive_log/%f %p'
执行备份,接着把主数据库不再设成备份模式,然后拷贝备份库到选择的目标节点。
该过程的第二阶段是一个脚本进行强制 XLOG 文件转换。该脚本此处命名为"pgpool_recovery_pitr"。它强制执行事务日志的一个转换。为此,pg_switch_xlog可能会被用到。然后它可能在转换执行完前返回,这样可能会导致在线恢复过程的失败。Pgpool-II提供了一个更加安全的称之为"pgpool_switch_xlog"的函数,该函数等待一直到事务日志转换实际被完成后。pgpool_switch_xlog 在安装 C 函数小节过程执行时被安装。
下面是示例脚本。
#! /bin/sh
# Online recovery 2nd stage script
#
datadir=$1 # master dabatase cluster
DEST=$2 # hostname of the DB node to be recovered
DESTDIR=$3 # database cluster of the DB node to be recovered
port=5432 # PostgreSQL port number
archdir=/data/archive_log # archive log directory
# Force to flush current value of sequences to xlog
psql -p $port -t -c 'SELECT datname FROM pg_database WHERE NOT datistemplate AND datallowconn' template1|
while read i
do
if [ "$i" != "" ];then
psql -p $port -c "SELECT setval(oid, nextval(oid)) FROM pg_class WHERE relkind = 'S'" $i
fi
done
psql -p $port -c "SELECT pgpool_switch_xlog('$archdir')" template1
该序列注入(flushing of sequences)仅在复制模式下有效:在该情况下,序列不得不在所有节点上具有同一个起点。在主/备模式下并不可用。脚本中的循环强制 PostgreSQL 发出所有数据库中序列生成器的当前值到事务日志中,这样它就传播到恢复的目标节点中去。
我们部署这些脚本到 $PGDATA 目录中去。
最后,我们修改pgpool.conf。
recovery_1st_stage_command = 'copy-base-backup' recovery_2nd_stage_command = 'pgpool_recovery_pitr'
我们已完成通过PITR进行在线恢复的准备工作。
pgpool_remote_start
该脚本启动远程主机的 postmaster 进程。pgpool-II 以如下方式执行。
% pgpool_remote_start remote_host remote_datadir remote_host: Hostname of a recovery target. remote_datadir: Database cluster path of a recovery target.
在该示例脚本中,我们通过 ssh 启动 postmaster 进程。所以如果你想要它能够运行,你需要提供不需要密码输入的 ssh 连接。
如果你使用PITR进行恢复,你需要部署一个库备份。PostgreSQL 将自动启动一个 PITR 恢复,然后它开始接受连接。
#! /bin/sh DEST=$1 DESTDIR=$2 PGCTL=/usr/local/pgsql/bin/pg_ctl # Deploy a base backup ssh -T $DEST 'cd /data/;le config-file指定 pgpool.conf -a hba_file
--hba-file hba_file指定 pool_hba.conf -F pcp_config_file
--pcp-password-file指定 pcp.conf 需要指出的是,一些配置项并不能通过重新加载来改变。新的修改后的配置将在新会话上生效。
SHOW 命令
概述
pgpool-II 通过 SHOW 命令提供一些信息。SHOW 是一个真实的 SQL 语句, 但是如果该命令查询 pgpool-II 信息的话,pgpool-II 解释了该命令。可选项如下:
注意:术语 'pool' 指的是一个 pgpool 进程所拥有的 PostgreSQL 会话池,并非指所有的 pgpool 所拥有的会话。
SQL语句中的 "pool_status" 在以前的版本中已经存在,但是其它可选项在 3.0 中才出现。
"SHOW pool_status" 返回配置参数列表,包含参数的 name, value, 和 description。下面是返回结果的一个摘录:
benchs2=# show pool_status;
item | value | description
-------------------------------+---------------------------------+------------------------------------------------------------------
listen_addresses | 127.0.0.1 | host name(s) or IP address(es) to listen to
port | 9999 | pgpool accepting port number
socket_dir | /tmp | pgpool socket directory
num_init_children | 5 | # of children initially pre-forked
child_life_time | 300 | if idle for this seconds, child exits
"SHOW pool_nodes" 返回所有配置节点的列表.它显示了节点的 id, hostname, port, status, 以及权重 weight (仅在使用负载均衡模式时有意义)。status 列可能的值可在 pcp_node_info reference 里获得解释。
benchs2=# show pool_nodes; id | hostname | port | status | lb_weight ------+-------------+------+--------+----------- 0 | 127.0.0.1 | 5432 | 2 | 0.5 1 | 192.168.1.7 | 5432 | 3 | 0.5 (2 lignes)
"SHOW pool_processes" 返回 pgpool-II 所有进程的信息,这些进程正等待连接或在处理一个连接。
结果有 6 列:
结果将一直返回 num_init_children 行。
benchs2=# show pool_processes; pool_pid | start_time | database | username | create_time | pool_counter ----------+---------------------+----------+-----------+---------------------+-------------- 8465 | 2010-08-14 08:35:40 | | | | 8466 | 2010-08-14 08:35:40 | benchs | guillaume | 2010-08-14 08:35:43 | 1 8467 | 2010-08-14 08:35:40 | | | | 8468 | 2010-08-14 08:35:40 | | | | 8469 | 2010-08-14 08:35:40 | | | | (5 lines)
"SHOW pool_pools" 返回 pgpool-II 所处理的连接池列表,包含它们的 name, value, 和 description,下面是结果的一个摘录:
共 11 列: