这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
集群配置
根据需求场景选择合适的实例与集群类型,配置出满足需求的 PostgreSQL 数据库集群。
Pigsty 是一个“配置驱动”的 PostgreSQL 平台:所有行为都来自 ~/pigsty/conf/*.yml 清单与 PGSQL 参数 的组合。
只要写好配置,你就能在几分钟内复刻出一套包含实例、用户、数据库、访问控制、扩展与调优策略的定制集群。
配置入口
- 准备清单:复制
pigsty/conf/*.yml 模板或从零开始编写 Ansible Inventory,将集群分组(all.children.<cls>.hosts)与全局变量(all.vars)写入同一个文件。 - 定义参数:在
vars 区块中覆盖需要的 PGSQL 参数。全局 → 集群 → 主机的覆盖顺序决定了最终值。 - 应用配置:运行
./configure -c <conf> 或 bin/pgsql-add <cls> 等剧本让配置落地。Pigsty 会根据参数生成 Patroni/pgbouncer/pgbackrest 等服务所需的配置文件。
Pigsty 默认的 Demo 清单 conf/pgsql.yml 就是一份最小化示例:一个 pg-meta 集群、全局 pg_version: 18、少量业务用户与数据库定义。你可以在此基础上扩展更多集群。
关注点与文档索引
Pigsty 的 PostgreSQL 配置可以从以下几个维度组合,后续文档会逐一展开“如何配置”:
- 集群实例:通过
pg_cluster / pg_role / pg_seq / pg_upstream 定义实例拓扑(单机、主从、备份集群、延迟集群、Citus 等)。 - 内核版本:使用
pg_version、pg_mode、pg_packages、pg_extensions、pg_conf 等参数挑选核心版本、风味和调优模板。 - 用户/角色:在
pg_default_roles 与 pg_users 中声明系统角色、业务账号、密码策略以及连接池属性。 - 数据库对象:借助
pg_databases、baseline、schemas、extensions、pool_* 字段按需创建数据库并自动接入 pgbouncer/Grafana。 - 访问控制 (HBA):利用
pg_default_hba_rules 与 pg_hba_rules 维护主机级认证策略,保证不同角色/网络的访问边界。 - 权限模型 (ACL):通过
pg_default_privileges、pg_default_roles、pg_revoke_public 等参数收敛对象权限,开箱即用地提供分层角色体系。
理解这些参数之后,你就可以针对任意业务需求写出“配置即基础设施”的声明式清单,Pigsty 会负责执行并确保幂等。
一个典型示例
下面的片段展示了如何在同一个配置文件中同时控制实例拓扑、内核版本、扩展、用户以及数据库:
all:
children:
pg-analytics:
hosts:
10.10.10.11: { pg_seq: 1, pg_role: primary }
10.10.10.12: { pg_seq: 2, pg_role: replica, pg_offline_query: true }
vars:
pg_cluster: pg-analytics
pg_conf: olap.yml
pg_extensions: [ postgis, timescaledb, pgvector ]
pg_databases:
- { name: bi, owner: dbuser_bi, schemas: [mart], extensions: [timescaledb], pool_mode: session }
pg_users:
- { name: dbuser_bi, password: DBUser.BI, roles: [dbrole_admin], pgbouncer: true }
vars:
pg_version: 17
pg_packages: [ pgsql-main pgsql-common ]
pg_hba_rules:
- { user: dbuser_bi, db: bi, addr: intra, auth: ssl, title: 'BI 只允许内网 SSL 访问' }
pg-analytics 集群包含一个主库和一个离线副本。- 全局指定
pg_version: 17 与一套扩展示例,并加载 olap.yml 调优。 - 在
pg_databases 与 pg_users 中声明业务对象,自动生成 schema/extension 与连接池条目。 - 附加的
pg_hba_rules 限制了访问来源与认证方式。
修改并应用这份清单即可得到一套定制化的 PostgreSQL 集群,而无需手工逐项配置。
1 - 集群实例
根据需求场景选择合适的实例与集群类型,配置出满足需求的 PostgreSQL 数据库集群。
根据需求场景选择合适的实例与集群类型,配置出满足需求的 PostgreSQL 数据库集群。
您可以定义不同类型的实例和集群,下面是 Pigsty 中常见的几种 PostgreSQL 实例/集群类型:
读写主库
我们从最简单的情况开始:由一个主库(Primary)组成的单实例集群:
pg-test:
hosts:
10.10.10.11: { pg_seq: 1, pg_role: primary }
vars:
pg_cluster: pg-test
这段配置言简意赅,自我描述,仅由 身份参数 构成,请注意 Ansible Group 分组名应当与 pg_cluster 保持一致。
使用以下命令创建该集群:
Demo展示,开发测试,承载临时需求,进行无关紧要的计算分析任务时,使用单一数据库实例可能并没有太大问题。但这样的单机集群没有 高可用,当出现硬件故障时,您需要使用 PITR 或其他恢复手段来确保集群的 RTO / RPO。为此,您可以考虑为集群添加若干个 只读从库
只读从库
要添加一台只读从库(Replica)实例,您可以在 pg-test 中添加一个新节点,并将其 pg_role 设置为replica。
pg-test:
hosts:
10.10.10.11: { pg_seq: 1, pg_role: primary }
10.10.10.12: { pg_seq: 2, pg_role: replica } # <--- 新添加的从库
vars:
pg_cluster: pg-test
如果整个集群不存在,您可以直接 创建 这个完整的集群。 如果集群主库已经初始化好了,那么您可以向现有集群 添加 一个从库:
bin/pgsql-add pg-test # 一次性初始化整个集群
bin/pgsql-add pg-test 10.10.10.12 # 添加从库到现有的集群
当集群主库出现故障时,只读实例(Replica)可以在高可用系统的帮助下接管主库的工作。除此之外,只读实例还可以用于执行只读查询:许多业务的读请求要比写请求多很多,而大部分只读查询负载都可以由从库实例承担。
离线从库
离线实例(Offline)是专门用于服务慢查询、ETL、OLAP流量和交互式查询等的专用只读从库。慢查询/长事务对在线业务的性能与稳定性有不利影响,因此最好将它们与在线业务隔离开来。
要添加离线实例,请为其分配一个新实例,并将 pg_role 设置为offline。
pg-test:
hosts:
10.10.10.11: { pg_seq: 1, pg_role: primary }
10.10.10.12: { pg_seq: 2, pg_role: replica }
10.10.10.13: { pg_seq: 3, pg_role: offline } # <--- 新添加的离线从库
vars:
pg_cluster: pg-test
专用离线实例的工作方式与常见的从库实例类似,但它在 pg-test-replica 服务中用作备份服务器。 也就是说,只有当所有replica实例都宕机时,离线和主实例才会提供此项只读服务。
许多情况下,数据库资源有限,单独使用一台服务器作为离线实例是不经济的做法。作为折中,您可以选择一台现有的从库实例,打上 pg_offline_query 标记,将其标记为一台可以承载"离线查询"的实例。在这种情况下,这台只读从库会同时承担在线只读请求与离线类查询。您可以使用 pg_default_hba_rules 和 pg_hba_rules 对离线实例进行额外的访问控制。
同步备库
当启用同步备库(Sync Standby)时,PostgreSQL 将选择一个从库作为同步备库,其他所有从库作为候选者。 主数据库会等待备库实例刷新到磁盘,然后才确认提交,备库实例始终拥有最新的数据,没有复制延迟,主从切换至同步备库不会有数据丢失。
PostgreSQL 默认使用异步流复制,这可能会有小的复制延迟(10KB / 10ms 数量级)。当主库失败时,可能会有一个小的数据丢失窗口(可以使用 pg_rpo 来控制),但对于大多数场景来说,这是可以接受的。
但在某些关键场景中(例如,金融交易),数据丢失是完全不可接受的,或者,读取复制延迟是不可接受的。在这种情况下,您可以使用同步提交来解决这个问题。 要启用同步备库模式,您可以简单地使用 pg_conf 中的crit.yml模板。
pg-test:
hosts:
10.10.10.11: { pg_seq: 1, pg_role: primary }
10.10.10.12: { pg_seq: 2, pg_role: replica }
10.10.10.13: { pg_seq: 3, pg_role: replica }
vars:
pg_cluster: pg-test
pg_conf: crit.yml # <--- 使用 crit 模板
要在现有集群上启用同步备库,请 配置集群 并启用 synchronous_mode:
$ pg edit-config pg-test # 在管理员节点以管理员用户身份运行
+++
-synchronous_mode: false # <--- 旧值
+synchronous_mode: true # <--- 新值
synchronous_mode_strict: false
应用这些更改?[y/N]: y
在这种情况下,PostgreSQL 配置项 synchronous_standby_names 由 Patroni 自动管理。
一台从库将被选拔为同步从库,它的 application_name 将被写入 PostgreSQL 主库配置文件中并应用生效。
法定人数提交
法定人数提交(Quorum Commit)提供了比同步备库更强大的控制能力:特别是当您有多个从库时,您可以设定提交成功的标准,实现更高/更低的一致性级别(以及可用性之间的权衡)。
如果想要最少两个从库来确认提交,可以通过 Patroni 配置集群,调整参数 synchronous_node_count 并应用生效
synchronous_mode: true # 确保同步提交已经启用
synchronous_node_count: 2 # 指定“至少”有多少个从库提交成功,才算提交成功
如果你想要使用更多的同步从库,修改 synchronous_node_count 的取值即可。当集群的规模发生变化时,您应当确保这里的配置仍然是有效的,以避免服务不可用。
在这种情况下,PostgreSQL 配置项 synchronous_standby_names 由 Patroni 自动管理。
synchronous_standby_names = '2 ("pg-test-3","pg-test-2")'
示例:使用多个同步从库
$ pg edit-config pg-test
---
+synchronous_node_count: 2
Apply these changes? [y/N]: y
应用配置后,出现两个同步备库。
+ Cluster: pg-test (7080814403632534854) +---------+----+-----------+-----------------+
| Member | Host | Role | State | TL | Lag in MB | Tags |
+-----------+-------------+--------------+---------+----+-----------+-----------------+
| pg-test-1 | 10.10.10.10 | Leader | running | 1 | | clonefrom: true |
| pg-test-2 | 10.10.10.11 | Sync Standby | running | 1 | 0 | clonefrom: true |
| pg-test-3 | 10.10.10.12 | Sync Standby | running | 1 | 0 | clonefrom: true |
+-----------+-------------+--------------+---------+----+-----------+-----------------+
另一种情景是,使用 任意n个 从库来确认提交。在这种情况下,配置的方式略有不同,例如,假设我们只需要任意一个从库确认提交:
synchronous_mode: quorum # 使用法定人数提交
postgresql:
parameters: # 修改 PostgreSQL 的配置参数 synchronous_standby_names ,使用 `ANY n ()` 语法
synchronous_standby_names: 'ANY 1 (*)' # 你可以指定具体的从库列表,或直接使用 * 通配所有从库。
示例:启用ANY法定人数提交
$ pg edit-config pg-test
+ synchronous_standby_names: 'ANY 1 (*)' # 在 ANY 模式下,需要使用此参数
- synchronous_node_count: 2 # 在 ANY 模式下, 不需要使用此参数
Apply these changes? [y/N]: y
应用后,配置生效,所有备库在 Patroni 中变为普通的 replica。但是在 pg_stat_replication 中可以看到 sync_state 会变为 quorum。
备份集群
您可以克隆现有的集群,并创建一个备份集群(Standby Cluster),用于数据迁移、水平拆分、多区域部署,或灾难恢复。
在正常情况下,备份集群将追随上游集群并保持内容同步,您可以将备份集群提升,作为真正地独立集群。
备份集群的定义方式与正常集群的定义基本相同,除了在主库上额外定义了 pg_upstream 参数,备份集群的主库被称为 备份集群领导者 (Standby Leader)。
例如,下面定义了一个pg-test集群,以及其备份集群pg-test2,其配置清单可能如下所示:
# pg-test 是原始集群
pg-test:
hosts:
10.10.10.11: { pg_seq: 1, pg_role: primary }
vars: { pg_cluster: pg-test }
# pg-test2 是 pg-test 的备份集群
pg-test2:
hosts:
10.10.10.12: { pg_seq: 1, pg_role: primary , pg_upstream: 10.10.10.11 } # <--- pg_upstream 在这里定义
10.10.10.13: { pg_seq: 2, pg_role: replica }
vars: { pg_cluster: pg-test2 }
而 pg-test2 集群的主节点 pg-test2-1 将是 pg-test 的下游从库,并在pg-test2集群中充当备份集群领导者(Standby Leader)。
只需确保备份集群的主节点上配置了 pg_upstream 参数,以便自动从原始上游拉取备份。
bin/pgsql-add pg-test # 创建原始集群
bin/pgsql-add pg-test2 # 创建备份集群
示例:更改复制上游
如有必要(例如,上游发生主从切换/故障转移),您可以通过 配置集群 更改备份集群的复制上游。
要这样做,只需将standby_cluster.host更改为新的上游IP地址并应用。
$ pg edit-config pg-test2
standby_cluster:
create_replica_methods:
- basebackup
- host: 10.10.10.13 # <--- 旧的上游
+ host: 10.10.10.12 # <--- 新的上游
port: 5432
Apply these changes? [y/N]: y
示例:提升备份集群
你可以随时将备份集群提升为独立集群,这样该集群就可以独立承载写入请求,并与原集群分叉。
为此,你必须 配置 该集群并完全擦除standby_cluster部分,然后应用。
$ pg edit-config pg-test2
-standby_cluster:
- create_replica_methods:
- - basebackup
- host: 10.10.10.11
- port: 5432
Apply these changes? [y/N]: y
示例:级联复制
如果您在一台从库上指定了 pg_upstream,而不是主库。那么可以配置集群的 级联复制(Cascade Replication)
在配置级联复制时,您必须使用集群中某一个实例的IP地址作为参数的值,否则初始化会报错。该从库从特定的实例进行流复制,而不是主库。
这台充当 WAL 中继器的实例被称为 桥接实例(Bridge Instance)。使用桥接实例可以分担主库发送 WAL 的负担,当您有几十台从库时,使用桥接实例级联复制是一个不错的注意。
pg-test:
hosts: # pg-test-1 ---> pg-test-2 ---> pg-test-3
10.10.10.11: { pg_seq: 1, pg_role: primary }
10.10.10.12: { pg_seq: 2, pg_role: replica } # <--- 桥接实例
10.10.10.13: { pg_seq: 3, pg_role: replica, pg_upstream: 10.10.10.12 }
# ^--- 从 pg-test-2 (桥接)复制,而不是从 pg-test-1 (主节点)
vars: { pg_cluster: pg-test }
延迟集群
延迟集群(Delayed Cluster)是一种特殊类型的 备份集群,用于尽快恢复"意外删除"的数据。
例如,如果你希望有一个名为 pg-testdelay 的集群,其数据内容与一小时前的 pg-test 集群相同:
# pg-test 是原始集群
pg-test:
hosts:
10.10.10.11: { pg_seq: 1, pg_role: primary }
vars: { pg_cluster: pg-test }
# pg-testdelay 是 pg-test 的延迟集群
pg-testdelay:
hosts:
10.10.10.12: { pg_seq: 1, pg_role: primary , pg_upstream: 10.10.10.11, pg_delay: 1d }
10.10.10.13: { pg_seq: 2, pg_role: replica }
vars: { pg_cluster: pg-testdelay }
你还可以在现有的 备份集群 上 配置 一个"复制延迟"。
$ pg edit-config pg-testdelay
standby_cluster:
create_replica_methods:
- basebackup
host: 10.10.10.11
port: 5432
+ recovery_min_apply_delay: 1h # <--- 在此处添加延迟时长,例如1小时
Apply these changes? [y/N]: y
当某些元组和表格被意外删除时,你可以通过修改此参数的方式,将此延迟集群推进到适当的时间点,并从中读取数据,快速修复原始集群。
延迟集群需要额外的资源,但比起 PITR 要快得多,并且对系统的影响也小得多,对于非常关键的集群,可以考虑搭建延迟集群。
Citus集群
Pigsty 原生支持 Citus。可以参考 files/pigsty/citus.yml 与 prod.yml 作为样例。
要定义一个 citus 集群,您需要指定以下参数:
此外,还需要额外的 hba 规则,允许从本地和其他数据节点进行 SSL 访问。如下所示:
all:
children:
pg-citus0: # citus 0号分片
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars: { pg_cluster: pg-citus0 , pg_group: 0 }
pg-citus1: # citus 1号分片
hosts: { 10.10.10.11: { pg_seq: 1, pg_role: primary } }
vars: { pg_cluster: pg-citus1 , pg_group: 1 }
pg-citus2: # citus 2号分片
hosts: { 10.10.10.12: { pg_seq: 1, pg_role: primary } }
vars: { pg_cluster: pg-citus2 , pg_group: 2 }
pg-citus3: # citus 3号分片
hosts:
10.10.10.13: { pg_seq: 1, pg_role: primary }
10.10.10.14: { pg_seq: 2, pg_role: replica }
vars: { pg_cluster: pg-citus3 , pg_group: 3 }
vars: # 所有 Citus 集群的全局参数
pg_mode: citus # pgsql 集群模式需要设置为: citus
pg_shard: pg-citus # citus 水平分片名称: pg-citus
pg_primary_db: meta # citus 数据库名称:meta
pg_dbsu_password: DBUser.Postgres # 如果使用 dbsu ,那么需要为其配置一个密码
pg_users: [ { name: dbuser_meta ,password: DBUser.Meta ,pgbouncer: true ,roles: [ dbrole_admin ] } ]
pg_databases: [ { name: meta ,extensions: [ { name: citus }, { name: postgis }, { name: timescaledb } ] } ]
pg_hba_rules:
- { user: 'all' ,db: all ,addr: 127.0.0.1/32 ,auth: ssl ,title: 'all user ssl access from localhost' }
- { user: 'all' ,db: all ,addr: intra ,auth: ssl ,title: 'all user ssl access from intranet' }
在协调者节点上,您可以创建分布式表和引用表,并从任何数据节点查询它们。从 11.2 开始,任何 Citus 数据库节点都可以扮演协调者的角色了。
SELECT create_distributed_table('pgbench_accounts', 'aid'); SELECT truncate_local_data_after_distributing_table($$public.pgbench_accounts$$);
SELECT create_reference_table('pgbench_branches') ; SELECT truncate_local_data_after_distributing_table($$public.pgbench_branches$$);
SELECT create_reference_table('pgbench_history') ; SELECT truncate_local_data_after_distributing_table($$public.pgbench_history$$);
SELECT create_reference_table('pgbench_tellers') ; SELECT truncate_local_data_after_distributing_table($$public.pgbench_tellers$$);
2 - 内核版本
如何选择合适的 PostgreSQL 内核与大版本。
在 Pigsty 中选择"内核"意味着确定 PostgreSQL 大版本、模式/发行版、需要安装的包以及要加载的调优模板。
Pigsty 从 PostgreSQL 10 起提供支持,当前版本默认打包了 13 - 18 的核心软件,并在 17/18 上提供完整扩展集合。下方内容展示如何通过配置文件完成这些选择。
大版本与软件包
pg_version:指定 PostgreSQL 主版本(默认 18)。Pigsty 会根据版本自动映射到正确的包名前缀。pg_packages:定义需要安装的核心包集合,支持使用 包别名(默认 pgsql-main pgsql-common,包含内核 + patroni/pgbouncer/pgbackrest 等常用工具)。pg_extensions:额外需要安装的扩展包列表,同样支持别名;缺省为空表示只装核心依赖。
all:
vars:
pg_version: 18
pg_packages: [ pgsql-main pgsql-common ]
pg_extensions: [ postgis, timescaledb, pgvector, pgml ]
效果:Ansible 在安装阶段会拉取与 pg_version=18 对应的包,将扩展预装到系统中,随后数据库初始化脚本即可直接 CREATE EXTENSION。
Pigsty 的离线仓库中不同版本的扩展支持范围不同:12/13 只提供核心与一级扩展,15/17/18 则涵盖全部扩展。若某扩展未预打包,可通过 repo_packages_extra 追加。
内核模式(pg_mode)
pg_mode 控制要部署的内核“风味”,默认 pgsql 表示标准 PostgreSQL。Pigsty 目前支持以下模式:
| 模式 | 场景 |
|---|
pgsql | 标准 PostgreSQL,高可用 + 复制 |
citus | Citus 分布式集群,需要额外的 pg_shard / pg_group |
gpsql | Greenplum / MatrixDB |
mssql | Babelfish for PostgreSQL |
mysql | OpenGauss/HaloDB 兼容 MySQL 协议 |
polar | 阿里 PolarDB(基于 pg polar 发行) |
ivory | IvorySQL(Oracle 兼容语法) |
oriole | OrioleDB 存储引擎 |
oracle | PostgreSQL + ora 兼容(pg_mode: oracle) |
选择模式后,Pigsty 会自动加载对应的模板、依赖包与 Patroni 配置。以部署 Citus 为例:
all:
children:
pg-citus0:
hosts: { 10.10.10.11: { pg_seq: 1, pg_role: primary } }
vars: { pg_cluster: pg-citus0, pg_group: 0 }
pg-citus1:
hosts: { 10.10.10.12: { pg_seq: 1, pg_role: primary } }
vars: { pg_cluster: pg-citus1, pg_group: 1 }
vars:
pg_mode: citus
pg_shard: pg-citus
patroni_citus_db: meta
效果:所有成员会安装 Citus 相关包,Patroni 以分片模式写入 etcd,并自动在 meta 数据库内 CREATE EXTENSION citus。
扩展与预置对象
除了系统包,你还可以通过以下参数控制数据库启动后自动加载的组件:
pg_libs:写入 shared_preload_libraries 的列表。例如 pg_libs: 'timescaledb, pg_stat_statements, auto_explain'。pg_default_extensions / pg_default_schemas:控制初始化脚本对 template1 与 postgres 预创建的 schema、扩展。pg_parameters:为所有实例附加 ALTER SYSTEM SET(写入 postgresql.auto.conf)。
示例:启用 TimescaleDB、pgvector 并自定义一些系统参数。
pg-analytics:
vars:
pg_cluster: pg-analytics
pg_libs: 'timescaledb, pg_stat_statements, pgml'
pg_default_extensions:
- { name: timescaledb }
- { name: pgvector }
pg_parameters:
timescaledb.max_background_workers: 8
shared_preload_libraries: "'timescaledb,pg_stat_statements,pgml'"
效果:初始化时 template1 会创建扩展、Patroni 的 postgresql.conf 注入对应参数,所有业务库继承这些设置。
调优模板 (pg_conf)
pg_conf 指向 roles/pgsql/templates/*.yml 中的 Patroni 模板。Pigsty内置四套通用模板:
| 模板 | 适用场景 |
|---|
oltp.yml | 默认模板,面向 4–128 核的 TP 负载 |
olap.yml | 针对分析场景优化 |
crit.yml | 强调同步提交/最小延迟,适合金融等零丢失场景 |
tiny.yml | 轻量机 / 边缘场景 / 资源受限环境 |
你可以直接替换模板或自定义一个 YAML 文件放在 templates/ 下,然后在集群 vars 里指定。
pg-ledger:
hosts: { 10.10.10.21: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-ledger
pg_conf: crit.yml
pg_parameters:
synchronous_commit: 'remote_apply'
max_wal_senders: 16
wal_keep_size: '2GB'
效果:拷贝 crit.yml 作为 Patroni 配置,叠加 pg_parameters 写入 postgresql.auto.conf,使实例立即以同步提交模式运行。
组合实例:一个完整示例
pg-rag:
hosts:
10.10.10.31: { pg_seq: 1, pg_role: primary }
10.10.10.32: { pg_seq: 2, pg_role: replica }
vars:
pg_cluster: pg-rag
pg_version: 18
pg_mode: pgsql
pg_conf: olap.yml
pg_packages: [ pgsql-main pgsql-common ]
pg_extensions: [ pgvector, pgml, postgis ]
pg_libs: 'pg_stat_statements, pgvector, pgml'
pg_parameters:
max_parallel_workers: 8
shared_buffers: '32GB'
- 第一台主库 + 一台 replica,使用
olap.yml 调优。 - 安装 PG18 + RAG 常用扩展,自动在系统级加载
pgvector/pgml。 - Patroni/pgbouncer/pgbackrest 由 Pigsty 生成,无需手工干预。
根据业务需要替换上述参数即可完成内核层的全部定制。
3 - 别名翻译
Pigsty 提供软件包别名翻译机制,可以屏蔽底层操作系统的二进制包细节差异,让安装更简易。
PostgreSQL 在不同操作系统上的软件包命名规则存在显著差异:
- EL 系统(RHEL/Rocky/Alma/…)使用
pgvector_17,postgis36_17* 这样的格式 - Debian/Ubuntu 系统使用
postgresql-17-pgvector,postgresql-17-postgis-3 这样的格式
这种差异给用户带来了额外的认知负担:您需要记住不同系统的包名规则,还要处理 PostgreSQL 版本号嵌入的问题。
软件包别名
Pigsty 通过 软件包别名(Package Alias) 机制解决了这个问题:您只需使用统一的别名,Pigsty 会处理好所有细节:
# 使用别名 —— 简单、统一、跨平台
pg_extensions: [ postgis, pgvector, timescaledb ]
# 等效于 EL9 + PG17 上的实际包名
pg_extensions: [ postgis36_17*, pgvector_17*, timescaledb-tsl_17* ]
# 等效于 Ubuntu 24 + PG17 上的实际包名
pg_extensions: [ postgresql-17-postgis-3, postgresql-17-pgvector, postgresql-17-timescaledb-tsl ]
别名翻译
别名还可以将一组软件包归类为一个整体,例如 Pigsty 默认安装的软件包 —— pg_packages 的默认值是:
pg_packages: # pg packages to be installed, alias can be used
- pgsql-main pgsql-common
Pigsty 将查询当前的操作系统别名清单(假设为 el10.x86_64),将其翻译为 PGSQL 内核,扩展,以及工具包:
pgsql-main: "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit pg_repack_$v* wal2json_$v* pgvector_$v*"
pgsql-common: "patroni patroni-etcd pgbouncer pgbackrest pg_exporter pgbackrest_exporter vip-manager"
接下来,Pigsty 又进一步通过当前指定的 PG 大版本(假设 pg_version = 18 ),将 pgsql-main 翻译为:
pg18-main: "postgresql18 postgresql18-server postgresql18-libs postgresql18-contrib postgresql18-plperl postgresql18-plpython3 postgresql18-pltcl postgresql18-llvmjit pg_repack_18* wal2json_18* pgvector_18*"
通过这种方式,Pigsty 屏蔽了软件包的复杂性,让用户可以简单的指定自己想要的功能组件。
哪些变量可以使用别名?
您可以在以下四个参数中使用包别名,别名会根据翻译流程自动转换为实际的软件包名称:
别名列表
你可以在 Pigsty 项目源代码的 roles/node_id/vars/ 目录下,找到各操作系统与架构对应的别名映射文件:
工作原理
别名翻译流程
用户配置别名 --> 检测操作系统 --> 查找别名映射表 ---> 替换$v占位符 ---> 安装实际软件包
↓ ↓ ↓ ↓
postgis el9.x86_64 postgis36_$v* postgis36_17*
postgis u24.x86_64 postgresql-$v-postgis-3 postgresql-17-postgis-3
版本占位符
Pigsty 的别名系统使用 $v 作为 PostgreSQL 版本号的占位符。当您使用 pg_version 指定了 PostgreSQL 版本后,所有别名中的 $v 都会被替换为实际版本号。
例如,当 pg_version: 17 时:
| 别名定义 (EL) | 展开结果 |
|---|
postgresql$v* | postgresql17* |
pgvector_$v* | pgvector_17* |
timescaledb-tsl_$v* | timescaledb-tsl_17* |
| 别名定义 (Debian/Ubuntu) | 展开结果 |
|---|
postgresql-$v | postgresql-17 |
postgresql-$v-pgvector | postgresql-17-pgvector |
postgresql-$v-timescaledb-tsl | postgresql-17-timescaledb-tsl |
通配符匹配
在 EL 系统上,许多别名使用 * 通配符来匹配相关的子包。例如:
postgis36_17* 会匹配 postgis36_17、postgis36_17-client、postgis36_17-utils 等postgresql17* 会匹配 postgresql17、postgresql17-server、postgresql17-libs、postgresql17-contrib 等
这种设计确保您无需逐一列出每个子包,一个别名即可安装完整的扩展。
4 - 用户/角色
如何通过配置来定制所需 PostgreSQL 用户与角色?
在本文中,“用户”(User) 指的是使用 SQL 命令 CREATE USER/ROLE 创建的,数据库集簇内的逻辑对象。
在 PostgreSQL 中,用户直接隶属于数据库集簇而非某个具体的数据库。因此在创建业务数据库和业务用户时,应当遵循"先用户,后数据库"的原则。
Pigsty 通过两个配置参数定义数据库集群中的角色与用户:
前者用于定义整套环境中共用的角色与用户,后者定义单个集群中特有的业务角色与用户。二者形式相同,均为用户定义对象的数组。
用户/角色按数组顺序逐一创建,因此后定义的用户可以属于先定义的角色。
默认情况下,所有带有 pgbouncer: true 标记的用户都会被添加到 Pgbouncer 连接池用户列表中。
定义用户
下面是 Pigsty 演示环境中默认集群 pg-meta 中的业务用户定义:
pg-meta:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta
pg_users:
- {name: dbuser_meta ,password: DBUser.Meta ,pgbouncer: true ,roles: [dbrole_admin] ,comment: pigsty admin user }
- {name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer for meta database }
- {name: dbuser_grafana ,password: DBUser.Grafana ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for grafana database }
- {name: dbuser_bytebase ,password: DBUser.Bytebase ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for bytebase database }
- {name: dbuser_kong ,password: DBUser.Kong ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for kong api gateway }
- {name: dbuser_gitea ,password: DBUser.Gitea ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for gitea service }
- {name: dbuser_wiki ,password: DBUser.Wiki ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for wiki.js service }
- {name: dbuser_noco ,password: DBUser.Noco ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for nocodb service }
- {name: dbuser_remove ,state: absent } # 使用 state: absent 删除用户
每个用户/角色定义都是一个复杂对象,可能包括以下字段,除了 name 字段外,其他字段均为可选字段:
- name: dbuser_meta # 必选,`name` 是用户定义的唯一必选字段
state: create # 可选,用户状态:create(创建,默认)、absent(删除)
password: DBUser.Meta # 可选,密码,可以是 scram-sha-256 哈希字符串或明文
login: true # 可选,默认为 true,是否可以登录
superuser: false # 可选,默认为 false,是否是超级用户
createdb: false # 可选,默认为 false,是否可以创建数据库
createrole: false # 可选,默认为 false,是否可以创建角色
inherit: true # 可选,默认为 true,是否自动继承所属角色权限
replication: false # 可选,默认为 false,是否可以发起流复制连接
bypassrls: false # 可选,默认为 false,是否可以绕过行级安全
connlimit: -1 # 可选,用户连接数限制,默认 -1 不限制
expire_in: 3650 # 可选,从创建时起 N 天后过期(优先级比 expire_at 高)
expire_at: '2030-12-31' # 可选,过期日期,使用 YYYY-MM-DD 格式(优先级没 expire_in 高)
comment: pigsty admin user # 可选,用户备注信息
roles: [dbrole_admin] # 可选,所属角色数组
parameters: # 可选,角色级配置参数
search_path: public
pgbouncer: true # 可选,是否加入连接池用户列表,默认 false
pool_mode: transaction # 可选,用户级别的池化模式,默认 transaction
pool_connlimit: -1 # 可选,用户级别的连接池最大连接数,默认 -1 不限制
参数总览
所有参数中唯一 必选 的字段是 name,它应该是当前 PostgreSQL 集群中有效且唯一的用户名,其他参数都有合理的默认值,均为可选项。
参数详情
name
字符串,必选参数,表示用户的名称,在一个数据库集群内必须唯一。
用户名必须是有效的 PostgreSQL 标识符,必须匹配正则表达式 ^[a-z_][a-z0-9_]{0,62}$:
以小写字母或下划线开头,只能包含小写字母、数字、下划线,最长 63 个字符。
- name: dbuser_app # 标准命名
- name: app_readonly # 下划线分隔
- name: _internal # 下划线开头(用于内部角色)
state
枚举值,用于指定要对用户执行的操作,可以是 create 或 absent,默认值为 create。
| 状态 | 说明 |
|---|
create | 默认,创建用户,如果已存在则更新属性 |
absent | 删除用户,使用 DROP ROLE |
- name: dbuser_app # state 默认为 create
- name: dbuser_old
state: absent # 删除用户
以下系统用户无法通过 state: absent 删除,这是为了防止误删关键系统用户导致集群故障:
password
字符串,可变参数,用于设置用户密码,不指定则用户无法使用密码登录。
密码可以是以下格式之一:
| 格式 | 示例 | 说明 |
|---|
| 明文密码 | DBUser.Meta | 不推荐,会被记录到配置文件和日志 |
| SCRAM-SHA-256 | SCRAM-SHA-256$4096:xxx$yyy:zzz | 推荐,PostgreSQL 10+ 默认认证方式 |
| MD5 哈希 | md5... | 兼容旧版本,不推荐新项目使用 |
# 明文密码(不推荐,会被记录到配置和日志中)
- name: dbuser_app
password: MySecretPassword
# SCRAM-SHA-256 哈希(推荐)
- name: dbuser_app
password: 'SCRAM-SHA-256$4096:xxx$yyy:zzz'
设置密码时,Pigsty 会临时屏蔽当前会话的日志记录以避免密码泄露:
SET log_statement TO 'none';
ALTER USER "dbuser_app" PASSWORD 'xxx';
SET log_statement TO DEFAULT;
如果你不希望在配置文件中记录明文密码,可以使用 SCRAM-SHA-256 哈希字符串代替明文密码。生成 SCRAM-SHA-256 哈希的方法:
# 使用 PostgreSQL 生成(需要先连接到数据库,数据库有 pgcrypto 扩展)
psql -c "SELECT encode(digest('password' || 'username', 'sha256'), 'hex')"
字符串,可变参数,用于设置用户的备注信息,如果不指定,默认值为 business user {name}。
用户备注信息通过 COMMENT ON ROLE 语句设置,支持中文和特殊字符(Pigsty 会自动转义单引号)。
- name: dbuser_app
comment: '业务应用主账号'
COMMENT ON ROLE "dbuser_app" IS '业务应用主账号';
login
布尔值,可变参数,用于控制用户是否可以登录,默认值为 true。
设置为 false 则创建的是无法登陆的 角色(Role)而非用户(User),通常用于权限分组。
在 PostgreSQL 中,CREATE USER 等价于 CREATE ROLE ... LOGIN。
# 创建可登录用户
- name: dbuser_app
login: true
# 创建角色(不可登录,用于权限分组)
- name: dbrole_custom
login: false
comment: 自定义权限角色
CREATE USER "dbuser_app" LOGIN;
CREATE USER "dbrole_custom" NOLOGIN;
superuser
布尔值,可变参数,用于指定用户是否为超级用户,默认值为 false。
超级用户拥有数据库的全部权限,可以绕过所有权限检查。
- name: dbuser_admin
superuser: true # 危险:拥有全部权限
ALTER USER "dbuser_admin" SUPERUSER;
Pigsty 已经提供了默认的超级用户 pg_admin_username (dbuser_dba)
除非绝对必要,否则不应创建额外的超级用户。
createdb
布尔值,可变参数,用于指定用户是否可以创建数据库,默认值为 false。
- name: dbuser_dev
createdb: true # 允许创建数据库
ALTER USER "dbuser_dev" CREATEDB;
一些应用软件可能会要求自己创建数据库,例如 Gitea,Odoo 等,因此您可能需要为这些应用的管理员用户启用 CREATEDB 权限。
createrole
布尔值,可变参数,用于指定用户是否可以创建其他角色,默认值为 false。
拥有 CREATEROLE 权限的用户可以创建、修改、删除其他非超级用户角色。
- name: dbuser_admin
createrole: true # 允许管理其他角色
ALTER USER "dbuser_admin" CREATEROLE;
inherit
布尔值,可变参数,用于控制用户是否自动继承所属角色的权限,默认值为 true。
设置为 false 时,用户需要通过 SET ROLE 显式切换角色才能使用所属角色的权限。
# 自动继承角色权限(默认)
- name: dbuser_app
inherit: true
roles: [dbrole_readwrite]
# 需要显式切换角色
- name: dbuser_special
inherit: false
roles: [dbrole_admin]
ALTER USER "dbuser_special" NOINHERIT;
-- 用户需要执行 SET ROLE dbrole_admin 才能获得该角色权限(必要但不充分)
replication
布尔值,可变参数,用于指定用户是否可以发起流复制连接,默认值为 false。
通常只有复制用户(如 replicator)需要此权限。普通业务用户不应该拥有此权限,除非这是一个逻辑解码订阅者。
- name: replicator
replication: true # 允许流复制连接
roles: [pg_monitor, dbrole_readonly]
ALTER USER "replicator" REPLICATION;
bypassrls
布尔值,可变参数,用于指定用户是否可以绕过行级安全(RLS)策略,默认值为 false。
启用此权限后,用户可以访问所有行,即使表上定义了行级安全策略。此权限通常只授予管理员用户。
- name: dbuser_myappadmin
bypassrls: true # 绕过行级安全策略
ALTER USER "dbuser_myappadmin" BYPASSRLS;
connlimit
整数,可变参数,用于限制用户的最大并发连接数,默认值为 -1,表示不限制。
设置为正整数时,会限制该用户同时建立的最大数据库连接数。此限制不影响超级用户。
- name: dbuser_app
connlimit: 100 # 最多 100 个并发连接
- name: dbuser_batch
connlimit: 10 # 批处理用户限制连接数
ALTER USER "dbuser_app" CONNECTION LIMIT 100;
expire_in
整数,可变参数,用于指定用户从当前日期起多少天后过期。
此参数优先级高于 expire_at,如果同时指定两者,只有 expire_in 生效。
每次执行剧本时会根据当前日期重新计算过期时间,适合用于临时用户或需要定期续期的场景。
- name: temp_user
expire_in: 30 # 30 天后过期
- name: contractor_user
expire_in: 90 # 90 天后过期
执行时会计算实际过期日期并生成对应的 SQL:
-- expire_in: 30, 假设当前日期为 2025-01-01
ALTER USER "temp_user" VALID UNTIL '2025-01-31';
expire_at
字符串,可变参数,用于指定用户的过期日期,格式为 YYYY-MM-DD 或特殊值 infinity。
此参数优先级低于 expire_in。使用 infinity 表示用户永不过期。
- name: contractor_user
expire_at: '2024-12-31' # 指定日期过期
- name: permanent_user
expire_at: 'infinity' # 永不过期
ALTER USER "contractor_user" VALID UNTIL '2024-12-31';
ALTER USER "permanent_user" VALID UNTIL 'infinity';
roles
数组,增量参数,用于定义用户所属的角色。数组元素可以是字符串或对象。
简单格式使用字符串直接指定角色名:
- name: dbuser_app
roles:
- dbrole_readwrite
- pg_read_all_data
GRANT "dbrole_readwrite" TO "dbuser_app";
GRANT "pg_read_all_data" TO "dbuser_app";
完整格式使用对象定义,支持更精细的角色成员关系控制:
- name: dbuser_app
roles:
- dbrole_readwrite # 简单字符串:GRANT 角色
- { name: dbrole_admin, admin: true } # 带 ADMIN OPTION
- { name: pg_monitor, set: false } # PG16+: 不允许 SET ROLE
- { name: pg_signal_backend, inherit: false } # PG16+: 不自动继承权限
- { name: old_role, state: absent } # 撤销角色成员关系
对象格式参数说明:
| 参数 | 类型 | 说明 |
|---|
name | string | 角色名称(必选) |
state | enum | grant(默认)或 absent/revoke:控制授予或撤销 |
admin | bool | true:WITH ADMIN OPTION,false:REVOKE ADMIN |
set | bool | PG16+:true:WITH SET TRUE,false:REVOKE SET |
inherit | bool | PG16+:true:WITH INHERIT TRUE,false:REVOKE INHERIT |
PostgreSQL 16+ 新特性:
PostgreSQL 16 引入了更细粒度的角色成员关系控制:
- ADMIN OPTION:允许将角色授予其他用户
- SET OPTION:允许使用
SET ROLE 切换到该角色 - INHERIT OPTION:是否自动继承该角色的权限
# PostgreSQL 16+ 完整示例
- name: dbuser_app
roles:
# 普通成员关系
- dbrole_readwrite
# 可以将 dbrole_admin 授予其他用户
- { name: dbrole_admin, admin: true }
# 不能 SET ROLE 到 pg_monitor(只能通过继承使用权限)
- { name: pg_monitor, set: false }
# 不自动继承 pg_execute_server_program 的权限(需要显式 SET ROLE)
- { name: pg_execute_server_program, inherit: false }
# 撤销 old_role 的成员关系
- { name: old_role, state: absent }
set 和 inherit 选项仅在 PostgreSQL 16+ 中有效,在早期版本会被忽略并在生成的 SQL 中添加警告注释。
parameters
对象,可变参数,用于设置角色级别的配置参数。参数通过 ALTER ROLE ... SET 设置,会对该用户的所有会话生效。
- name: dbuser_analyst
parameters:
work_mem: '256MB'
statement_timeout: '5min'
search_path: 'analytics,public'
log_statement: 'all'
ALTER USER "dbuser_analyst" SET "work_mem" = '256MB';
ALTER USER "dbuser_analyst" SET "statement_timeout" = '5min';
ALTER USER "dbuser_analyst" SET "search_path" = 'analytics,public';
ALTER USER "dbuser_analyst" SET "log_statement" = 'all';
使用特殊值 DEFAULT(大小写不敏感)可以将参数重置为 PostgreSQL 默认值:
- name: dbuser_app
parameters:
work_mem: DEFAULT # 重置为默认值
statement_timeout: '30s' # 设置新值
ALTER USER "dbuser_app" SET "work_mem" = DEFAULT;
ALTER USER "dbuser_app" SET "statement_timeout" = '30s';
常用角色级参数:
| 参数 | 说明 | 示例值 |
|---|
work_mem | 查询工作内存 | '64MB' |
statement_timeout | 语句超时时间 | '30s' |
lock_timeout | 锁等待超时 | '10s' |
idle_in_transaction_session_timeout | 空闲事务超时 | '10min' |
search_path | Schema 搜索路径 | 'app,public' |
log_statement | 日志记录级别 | 'ddl' |
temp_file_limit | 临时文件大小限制 | '10GB' |
您可以从数据库的 pg_db_role_setting 系统视图查询用户级别的参数设置。
pgbouncer
布尔值,可变参数,用于控制是否将用户添加到 Pgbouncer 连接池用户列表,默认值为 false。
对于需要通过连接池访问数据库的生产用户,必须显式设置 pgbouncer: true。
默认为 false 是为了避免意外将内部用户暴露给连接池。
# 生产用户:需要连接池
- name: dbuser_app
password: DBUser.App
pgbouncer: true
# 内部用户:不需要连接池
- name: dbuser_internal
password: DBUser.Internal
pgbouncer: false # 默认值,可省略
设置 pgbouncer: true 的用户会被添加到 /etc/pgbouncer/userlist.txt 文件中。
pool_mode
枚举值,可变参数,用于设置用户级别的池化模式,可选值为 transaction、session 或 statement,默认值为 transaction。
| 模式 | 说明 | 适用场景 |
|---|
transaction | 事务结束后归还连接 | 大多数 OLTP 应用,默认推荐 |
session | 会话结束后归还连接 | 需要会话状态的应用(如 SET 命令) |
statement | 每条语句后归还连接 | 简单无状态查询,极致复用 |
# DBA 用户使用 session 模式(可能需要 SET 命令等会话状态)
- name: dbuser_dba
pgbouncer: true
pool_mode: session
# 普通业务用户使用 transaction 模式
- name: dbuser_app
pgbouncer: true
pool_mode: transaction
用户级别的连接池参数通过 /etc/pgbouncer/useropts.txt 文件配置:
dbuser_dba = pool_mode=session max_user_connections=16
dbuser_monitor = pool_mode=session max_user_connections=8
pool_connlimit
整数,可变参数,用于设置用户级别的连接池最大连接数,默认值为 -1,表示不限制。
- name: dbuser_app
pgbouncer: true
pool_connlimit: 50 # 此用户最多使用 50 个连接池连接
ACL 系统
Pigsty 提供了一套内置的、开箱即用的访问控制 / ACL 系统,您只需将以下四个默认角色分配给业务用户即可轻松使用:
| 角色 | 权限说明 | 典型使用场景 |
|---|
dbrole_readwrite | 全局读写访问 | 主属业务的生产账号 |
dbrole_readonly | 全局只读访问 | 其他业务的只读访问 |
dbrole_admin | 拥有 DDL 权限 | 业务管理员,需要建表的场景 |
dbrole_offline | 受限只读访问(仅离线实例) | 个人用户,ETL/分析任务 |
# 典型业务用户配置
pg_users:
- name: dbuser_app
password: DBUser.App
pgbouncer: true
roles: [dbrole_readwrite] # 生产账号,读写权限
- name: dbuser_readonly
password: DBUser.Readonly
pgbouncer: true
roles: [dbrole_readonly] # 只读账号
- name: dbuser_admin
password: DBUser.Admin
pgbouncer: true
roles: [dbrole_admin] # 管理员,可执行 DDL
- name: dbuser_etl
password: DBUser.ETL
roles: [dbrole_offline] # 离线分析账号
如果您希望重新设计您自己的 ACL 系统,可以考虑定制以下参数和模板:
Pgbouncer 用户
默认情况下启用 Pgbouncer 作为连接池中间件。Pigsty 默认将 pg_users 中显式带有 pgbouncer: true 标志的所有用户添加到 Pgbouncer 用户列表中。
Pgbouncer 连接池中的用户在 /etc/pgbouncer/userlist.txt 中列出:
"postgres" ""
"dbuser_wiki" "SCRAM-SHA-256$4096:+77dyhrPeFDT/TptHs7/7Q==$KeatuohpKIYzHPCt/tqBu85vI11o9mar/by0hHYM2W8=:X9gig4JtjoS8Y/o1vQsIX/gY1Fns8ynTXkbWOjUfbRQ="
"dbuser_view" "SCRAM-SHA-256$4096:DFoZHU/DXsHL8MJ8regdEw==$gx9sUGgpVpdSM4o6A2R9PKAUkAsRPLhLoBDLBUYtKS0=:MujSgKe6rxcIUMv4GnyXJmV0YNbf39uFRZv724+X1FE="
"dbuser_monitor" "SCRAM-SHA-256$4096:fwU97ZMO/KR0ScHO5+UuBg==$CrNsmGrx1DkIGrtrD1Wjexb/aygzqQdirTO1oBZROPY=:L8+dJ+fqlMQh7y4PmVR/gbAOvYWOr+KINjeMZ8LlFww="
"dbuser_meta" "SCRAM-SHA-256$4096:leB2RQPcw1OIiRnPnOMUEg==$eyC+NIMKeoTxshJu314+BmbMFpCcspzI3UFZ1RYfNyU=:fJgXcykVPvOfro2MWNkl5q38oz21nSl1dTtM65uYR1Q="
用户级别的连接池参数使用另一个单独的文件 /etc/pgbouncer/useropts.txt 进行维护:
dbuser_dba = pool_mode=session max_user_connections=16
dbuser_monitor = pool_mode=session max_user_connections=8
当您 创建用户 时,Pgbouncer 的用户列表定义文件将会被刷新,并通过在线重载配置的方式生效,不会影响现有的连接。
Pgbouncer 使用和 PostgreSQL 相同的 dbsu 运行,默认为 postgres 操作系统用户。您可以使用 pgb 别名,使用 dbsu 访问 Pgbouncer 管理功能。
pgbouncer_auth_query 参数允许您使用动态查询来完成连接池用户认证,当您不想手动管理连接池中的用户时,这是一种便捷的方案。
相关资源
关于用户管理操作,请参考 用户管理 一节。
关于用户的访问权限,请参考 ACL:角色权限 一节。
5 - 数据库
如何通过配置来定制所需 PostgreSQL 数据库?
在本文中,“数据库”(Database) 指的是使用 SQL 命令 CREATE DATABASE 创建的,数据库集簇内的逻辑对象。
一组 PostgreSQL 服务器可以同时服务于多个 数据库 (Database)。在 Pigsty 中,你可以在集群配置中 定义 好所需的数据库。
Pigsty会对默认模板数据库template1进行修改与定制,创建默认模式,安装默认扩展,配置默认权限,新创建的数据库默认会从template1继承这些设置。
您也可以通过 template 参数指定其他模板数据库,实现瞬间 数据库克隆。
默认情况下,所有业务数据库都会被 1:1 添加到 Pgbouncer 连接池 中;pg_exporter 默认会通过 自动发现 机制查找所有业务数据库并进行库内对象监控。
所有数据库也会添加到所有 INFRA节点 上的 Grafana 中,
注册为 PostgreSQL 数据源供 PGCAT 监控面板使用。
定义数据库
业务数据库定义在数据库集群参数 pg_databases 中,这是一个数据库定义构成的对象数组。
在集群初始化时,数组内的数据库按照 定义顺序 依次创建,因此后面定义的数据库可以使用先前定义的数据库作为模板。
下面是 Pigsty 演示环境中默认集群 pg-meta 中的数据库定义:
pg-meta:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta
pg_databases:
- { name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty] ,extensions: [{name: postgis, schema: public}, {name: timescaledb}]}
- { name: grafana ,owner: dbuser_grafana ,revokeconn: true ,comment: grafana primary database }
- { name: bytebase ,owner: dbuser_bytebase ,revokeconn: true ,comment: bytebase primary database }
- { name: kong ,owner: dbuser_kong ,revokeconn: true ,comment: kong the api gateway database }
- { name: gitea ,owner: dbuser_gitea ,revokeconn: true ,comment: gitea meta database }
- { name: wiki ,owner: dbuser_wiki ,revokeconn: true ,comment: wiki meta database }
- { name: noco ,owner: dbuser_noco ,revokeconn: true ,comment: nocodb database }
每个数据库定义都是一个复杂对象,可能包括以下字段,除了 name 字段外,其他字段均为可选字段:
- name: meta # 必选,`name` 是数据库定义的唯一必选字段
state: create # 可选,数据库状态:create(创建,默认)、absent(删除)、recreate(重建)
baseline: cmdb.sql # 可选,数据库 sql 的基线定义文件路径(ansible 搜索路径中的相对路径,如 files/)
pgbouncer: true # 可选,是否将此数据库添加到 pgbouncer 数据库列表?默认为 true
schemas: [pigsty] # 可选,要创建的附加模式,由模式名称字符串组成的数组
extensions: # 可选,要安装的附加扩展: 扩展对象的数组
- { name: postgis , schema: public } # 可以指定将扩展安装到某个模式中,也可以不指定(不指定则安装到 search_path 首位模式中)
- { name: timescaledb } # 例如有的扩展会创建并使用固定的模式,就不需要指定模式。
comment: pigsty meta database # 可选,数据库的说明与备注信息
owner: postgres # 可选,数据库所有者,不指定则为当前用户
template: template1 # 可选,要使用的模板,默认为 template1,目标必须是一个模板数据库
strategy: FILE_COPY # 可选,克隆策略:FILE_COPY 或 WAL_LOG(PG15+),不指定使用 PG 默认
encoding: UTF8 # 可选,不指定则继承模板/集群配置(UTF8)
locale: C # 可选,不指定则继承模板/集群配置(C)
lc_collate: C # 可选,不指定则继承模板/集群配置(C)
lc_ctype: C # 可选,不指定则继承模板/集群配置(C)
locale_provider: libc # 可选,本地化提供者:libc、icu、builtin(PG15+)
icu_locale: en-US # 可选,ICU 本地化规则(PG15+)
icu_rules: '' # 可选,ICU 排序规则(PG16+)
builtin_locale: C.UTF-8 # 可选,内置本地化提供者规则(PG17+)
tablespace: pg_default # 可选,默认表空间,默认为 'pg_default'
is_template: false # 可选,是否标记为模板数据库,允许任何有 CREATEDB 权限的用户克隆
allowconn: true # 可选,是否允许连接,默认为 true。显式设置 false 将完全禁止连接到此数据库
revokeconn: false # 可选,撤销公共连接权限。默认为 false,设置为 true 时,属主和管理员之外用户的 CONNECT 权限会被回收
register_datasource: true # 可选,是否将此数据库注册到 grafana 数据源?默认为 true,显式设置为 false 会跳过注册
connlimit: -1 # 可选,数据库连接限制,默认为 -1 ,不限制,设置为正整数则会限制连接数。
parameters: # 可选,数据库级参数,通过 ALTER DATABASE SET 设置
work_mem: '64MB'
statement_timeout: '30s'
pool_auth_user: dbuser_meta # 可选,连接到此 pgbouncer 数据库的所有连接都将使用此用户进行验证(启用 pgbouncer_auth_query 才有用)
pool_mode: transaction # 可选,数据库级别的 pgbouncer 池化模式,默认为 transaction
pool_size: 64 # 可选,数据库级别的 pgbouncer 默认池子大小,默认为 64
pool_reserve: 32 # 可选,数据库级别的 pgbouncer 池子保留空间,默认为 32,当默认池子不够用时,最多再申请这么多条突发连接。
pool_size_min: 0 # 可选,数据库级别的 pgbouncer 池的最小大小,默认为 0
pool_connlimit: 100 # 可选,数据库级别的最大数据库连接数,默认为 100
参数总览
所有参数中唯一 必选 的字段是 name,它应该是当前 PostgreSQL 集群中有效且唯一的数据库名称,其他参数都有合理的默认值,均为可选项。
带有 “不可变” 标记的参数仅在数据库创建时生效,创建后无法修改,若需更改则必须删除并重建数据库。
参数详情
name
字符串,必选参数,表示数据库的名称,在一个数据库集群内集群内必须唯一。
数据库名称必须是有效的 PostgreSQL 标识符,长度不超过 63 个字符,不得使用 SQL 关键字,
形式上以字母或下划线开头,后续字符可以是字母、数字或下划线,不能包含空格或特殊字符。
形式应当满足正则表达式:^[A-Za-z_][A-Za-z0-9_$]{0,62}$
- name: myapp # 简单命名
- name: my_application # 下划线分隔
- name: app_v2 # 包含版本号
state
枚举值,用于指定要对数据库执行的操作,可以是 create、absent 或 recreate,默认值为 create。
| 状态 | 说明 |
|---|
create | 默认,创建或修改数据库,如果已经存在,则将可变参数调整到描述的状态 |
absent | 删除数据库,使用 DROP DATABASE WITH (FORCE) |
recreate | 先删除再创建,用于重置数据库 |
- name: myapp # state 默认为 create
- name: olddb
state: absent # 删除数据库
- name: testdb
state: recreate # 重建数据库
owner
字符串,指定数据库的属主用户,默认不指定,不指定则为数据库 pg_dbsu,即 postgres 用户。
要指定数据库的 owner,被指定的用户必须已存在。修改 owner 会执行:旧 Owner 在数据库上的权限不会被撤回。
数据库属主具有对数据库的完全控制权限,包括创建模式、表、扩展等对象的权限,对于多租户场景尤为有用。
ALTER DATABASE "myapp" OWNER TO "new_owner";
GRANT ALL PRIVILEGES ON DATABASE "myapp" TO "new_owner";
字符串,用于设置数据库的备注信息,如果不指定,默认值为 business database {name}。
数据库备注信息通过 COMMENT ON DATABASE 语句设置,支持中文和特殊字符(Pigsty 会自动转义单引号)。
备注信息会存储在系统目录 pg_database.datacl 中,可以通过 \l+ 命令查看。
COMMENT ON DATABASE "myapp" IS '我的应用主数据库';
- name: myapp
comment: 我的应用主数据库
template
字符串,不可变参数,用于指定创建数据库时使用的模板数据库,默认值为 template1。
PostgreSQL 的 CREATE DATABASE 本质上是对模板数据库进行复制,新数据库会继承模板中的所有对象、扩展、模式、权限设置等。
Pigsty 会在集群初始化阶段对 template1 进行定制配置,因此新建数据库默认会继承这些设置。
| 模板 | 说明 |
|---|
template1 | 默认模板,包含 Pigsty 预配置的扩展、模式和权限设置 |
template0 | 干净模板,使用不同于集群默认的本地化提供者时,必须使用此模板 |
| 自定义数据库 | 可以使用已有数据库作为模板进行克隆 |
使用 icu 或 builtin 本地化提供者时,必须指定 template: template0,因为 template1 已有本地化设置无法覆盖。
使用其他
- name: myapp_icu
template: template0 # 使用 ICU 时必须指定 template0
locale_provider: icu
icu_locale: zh-Hans
使用 template0 时,监控所需的扩展与 Schema,以及角色的默认权限都不再自动创建,这允许你从一个完全干净的模板开始定制数据库。
strategy
枚举值,不可变参数,用于指定从模板克隆数据库的策略,可选值为 FILE_COPY 或 WAL_LOG,此参数在 PostgreSQL 15 及以上版本可用。
| 策略 | 说明 | 适用场景 |
|---|
FILE_COPY | 直接复制数据文件,PG15+ 默认 | 大模板,通用场景 |
WAL_LOG | 通过 WAL 日志记录复制 | 小模板,不阻塞模板上的连接 |
WAL_LOG 策略的优势是复制过程中不会阻塞模板数据库上的连接,但对于较大的模板效率不如 FILE_COPY。
在 PostgreSQL 14 及更早版本中,此参数会被忽略。
- name: cloned_db
template: source_db
strategy: WAL_LOG # 使用 WAL 日志方式克隆
encoding
字符串,不可变参数,用于指定数据库的字符编码,如果不指定则继承模板数据库的编码设置,通常为 UTF8。
如果没有特殊原因,强烈建议使用 UTF8 编码。字符编码在数据库创建后无法修改,如需更改必须重建数据库。
- name: legacy_db
template: template0 # 指定非默认编码时使用 template0
encoding: LATIN1
locale
字符串,不可变参数,用于指定数据库的本地化规则,相当于同时设置 lc_collate 和 lc_ctype,如果不指定则继承模板数据库的设置,通常为 C。
本地化规则决定了字符串的排序顺序和字符分类行为。使用 C 或 POSIX 可获得最佳性能和跨平台一致性,
使用特定语言的本地化规则(如 zh_CN.UTF-8)可以获得符合该语言习惯的排序结果。
- name: chinese_db
template: template0
locale: zh_CN.UTF-8 # 中文本地化
encoding: UTF8
lc_collate
字符串,不可变参数,用于指定字符串的排序规则,如果不指定则继承模板数据库的设置,通常为 C。
排序规则决定了 ORDER BY 和比较操作的结果。常用值包括:C(字节序,最快)、C.UTF-8、en_US.UTF-8、zh_CN.UTF-8。
此参数在数据库创建后无法修改。
- name: myapp
template: template0
lc_collate: en_US.UTF-8 # 英文排序规则
lc_ctype: en_US.UTF-8
lc_ctype
字符串,不可变参数,用于指定字符分类规则,决定字符的大小写、数字、字母等分类,如果不指定则继承模板数据库的设置,通常为 C。
字符分类规则影响 upper()、lower()、正则表达式中的 \w 等函数的行为。此参数在数据库创建后无法修改。
locale_provider
枚举值,不可变参数,用于指定本地化的实现提供者,可选值为 libc、icu 或 builtin,此参数在 PostgreSQL 15 及以上版本可用,默认值为 libc。
| 提供者 | 版本 | 说明 |
|---|
libc | - | 使用操作系统 C 库,传统默认方式,行为因系统而异 |
icu | PG15+ | 使用 ICU 库,跨平台一致,支持更多语言 |
builtin | PG17+ | PostgreSQL 内置实现,最高效,仅支持 C/C.UTF-8 |
使用 icu 或 builtin 提供者时,必须指定 template: template0,并配合相应的 icu_locale 或 builtin_locale 参数。
- name: fast_db
template: template0
locale_provider: builtin # 使用内置提供者,最高效
builtin_locale: C.UTF-8
icu_locale
字符串,不可变参数,用于指定 ICU 本地化规则标识符,此参数在 PostgreSQL 15 及以上版本、且 locale_provider 为 icu 时可用。
ICU 本地化标识符遵循 BCP 47 标准,常用值包括:
| 值 | 说明 |
|---|
en-US | 美式英语 |
en-GB | 英式英语 |
zh-Hans | 简体中文 |
zh-Hant | 繁体中文 |
ja-JP | 日语 |
ko-KR | 韩语 |
- name: chinese_app
template: template0
locale_provider: icu
icu_locale: zh-Hans # 简体中文 ICU 排序
encoding: UTF8
icu_rules
字符串,不可变参数,用于自定义 ICU 排序规则,此参数在 PostgreSQL 16 及以上版本可用。
ICU 规则允许对默认排序行为进行微调,使用 ICU 排序规则语法。
- name: custom_sort_db
template: template0
locale_provider: icu
icu_locale: en-US
icu_rules: '&V << w <<< W' # 自定义 V/W 排序顺序
builtin_locale
字符串,不可变参数,用于指定内置本地化提供者的规则,此参数在 PostgreSQL 17 及以上版本、且 locale_provider 为 builtin 时可用,可选值为 C 或 C.UTF-8。
builtin 提供者是 PostgreSQL 17 新增的内置本地化实现,比 libc 更快,且行为跨平台完全一致。
适合只需要 C 或 C.UTF-8 排序规则的场景。
- name: fast_db
template: template0
locale_provider: builtin
builtin_locale: C.UTF-8 # 内置 UTF-8 支持
encoding: UTF8
tablespace
字符串,可变参数,用于指定数据库的默认表空间,默认值为 pg_default。
修改现有数据库的表空间会触发数据物理迁移,PostgreSQL 会将数据库中的所有对象移动到新表空间,对于大数据库可能需要较长时间,慎用。
- name: archive_db
tablespace: slow_hdd # 归档数据使用慢速存储
ALTER DATABASE "archive_db" SET TABLESPACE "slow_hdd";
is_template
布尔值,可变参数,用于指定是否将数据库标记为模板数据库,默认值为 false。
设置为 true 后,任何拥有 CREATEDB 权限的用户都可以使用此数据库作为模板克隆新数据库。
模板数据库通常用于预装标准模式、扩展和数据,方便快速创建具有相同配置的新数据库。
- name: app_template
is_template: true # 标记为模板,允许普通用户克隆
schemas: [core, api]
extensions: [postgis, pg_trgm]
删除标记为 is_template: true 的数据库时,Pigsty 会先执行 ALTER DATABASE ... IS_TEMPLATE false 取消模板标记,然后再删除。
allowconn
布尔值,可变参数,用于控制是否允许连接到此数据库,默认值为 true。
设置为 false 会在数据库层面完全禁止连接,任何用户(包括超级用户)都无法连接到此数据库。
此参数通常用于维护或归档用途。
- name: archive_db
allowconn: false # 禁止任何连接
ALTER DATABASE "archive_db" ALLOW_CONNECTIONS false;
revokeconn
布尔值,可变参数,用于控制是否回收 PUBLIC 角色的 CONNECT 权限,默认值为 false。
设置为 true 时,Pigsty 会执行以下权限变更:
- 回收 PUBLIC 的 CONNECT 权限,普通用户将无法连接
- 授予复制用户(
replicator)和监控用户(dbuser_monitor)连接权限 - 授予管理员用户(
dbuser_dba)和数据库属主连接权限,并附带 WITH GRANT OPTION
设置为 false 时,会恢复 PUBLIC 的 CONNECT 权限。
- name: secure_db
owner: dbuser_secure
revokeconn: true # 回收公共连接权限,只有指定用户可连接
connlimit
整数,可变参数,用于限制数据库的最大并发连接数,默认值为 -1,表示不限制。
设置为正整数时,会限制同时连接到此数据库的最大会话数。此限制不影响超级用户。
- name: limited_db
connlimit: 50 # 最多允许 50 个并发连接
ALTER DATABASE "limited_db" CONNECTION LIMIT 50;
baseline
字符串,一次性参数,用于指定数据库创建后要执行的 SQL 基线文件路径。
基线文件通常包含表结构定义、初始数据、存储过程等,用于初始化新数据库。
路径是相对于 Ansible 搜索路径的相对路径,通常放在 files/ 目录下。
基线文件仅在首次创建数据库时执行;如果数据库已存在则跳过。使用 state: recreate 重建数据库时会重新执行基线文件。
- name: myapp
baseline: myapp_schema.sql # 会查找 files/myapp_schema.sql
schemas
数组,可变参数(支持增删),用于定义要在数据库中创建或删除的模式。数组元素可以是字符串或对象。
简单格式使用字符串直接指定模式名,仅支持创建操作:
schemas:
- app
- api
- core
完整格式使用对象定义,支持指定模式属主和删除操作:
schemas:
- name: app # 模式名(必选)
owner: dbuser_app # 模式属主(可选),生成 AUTHORIZATION 子句
- name: deprecated
state: absent # 删除模式(使用 CASCADE)
创建模式时使用 IF NOT EXISTS,已存在则跳过;删除模式时使用 CASCADE,会同时删除模式内的所有对象。
CREATE SCHEMA IF NOT EXISTS "app" AUTHORIZATION "dbuser_app";
DROP SCHEMA IF EXISTS "deprecated" CASCADE;
extensions
数组,可变参数(支持增删),用于定义要在数据库中安装或卸载的扩展。数组元素可以是字符串或对象。
简单格式使用字符串直接指定扩展名,仅支持安装操作:
extensions:
- postgis
- pg_trgm
- vector
完整格式使用对象定义,支持指定安装模式、版本和卸载操作:
extensions:
- name: vector # 扩展名(必选)
schema: public # 安装到指定模式(可选)
version: '0.5.1' # 指定版本(可选)
- name: old_extension
state: absent # 卸载扩展(使用 CASCADE)
安装扩展时使用 CASCADE,如果已存在则会报错但跳过,同时自动安装依赖扩展;卸载扩展时使用 CASCADE,会同时删除依赖此扩展的对象。
CREATE EXTENSION IF NOT EXISTS "vector" WITH SCHEMA "public" VERSION '0.5.1' CASCADE;
DROP EXTENSION IF EXISTS "old_extension" CASCADE;
parameters
对象,可变参数,用于设置数据库级别的配置参数。参数通过 ALTER DATABASE ... SET 设置,会对连接到此数据库的所有会话生效。
- name: analytics
parameters:
work_mem: '256MB'
maintenance_work_mem: '512MB'
statement_timeout: '5min'
search_path: 'analytics,public'
使用特殊值 DEFAULT(大小写不敏感)可以将参数重置为 PostgreSQL 默认值:
parameters:
work_mem: DEFAULT # 重置为默认值
statement_timeout: '30s' # 设置新值
ALTER DATABASE "myapp" SET "work_mem" = DEFAULT;
ALTER DATABASE "myapp" SET "statement_timeout" = '30s';
pgbouncer
布尔值,可变参数,用于控制是否将数据库添加到 Pgbouncer 连接池列表,默认值为 true。
设置为 false 时,数据库不会出现在 Pgbouncer 的数据库列表中,客户端无法通过连接池访问此数据库。
适用于内部管理数据库或需要直连的特殊场景。
- name: internal_db
pgbouncer: false # 不通过连接池访问
pool_mode
枚举值,可变参数,用于设置此数据库在 Pgbouncer 中的池化模式,可选值为 transaction、session 或 statement,默认值为 transaction。
| 模式 | 说明 | 适用场景 |
|---|
transaction | 事务结束后归还连接 | 大多数 OLTP 应用,默认推荐 |
session | 会话结束后归还连接 | 需要会话级状态的应用 |
statement | 每条语句后归还连接 | 简单无状态查询,极致复用 |
- name: session_app
pool_mode: session # 使用会话级池化
pool_size
整数,可变参数,用于设置此数据库在 Pgbouncer 中的默认连接池大小,默认值为 64。
连接池大小决定了 Pgbouncer 为此数据库预留的后端连接数量。根据应用负载调整此值。
- name: high_load_db
pool_size: 128 # 高负载应用使用更大的池
pool_size_min
整数,可变参数,用于设置此数据库在 Pgbouncer 中的最小连接池大小,默认值为 0。
设置大于 0 的值会让 Pgbouncer 预先创建指定数量的后端连接,用于连接预热,减少首次请求的延迟。
- name: latency_sensitive
pool_size_min: 10 # 预热 10 个连接
pool_reserve
整数,可变参数,用于设置此数据库在 Pgbouncer 中的保留连接数,默认值为 32。
当默认池不够用时,Pgbouncer 最多可以额外申请 pool_reserve 个连接来处理突发流量。
- name: bursty_db
pool_size: 64
pool_reserve: 64 # 允许突发到 128 个连接
pool_connlimit
整数,可变参数,用于设置通过 Pgbouncer 连接池访问此数据库的最大连接数,默认值为 100。
此限制是 Pgbouncer 层面的限制,与数据库本身的 connlimit 参数独立。
- name: limited_pool_db
pool_connlimit: 50 # 连接池最多 50 个连接
pool_auth_user
字符串,可变参数,用于指定 Pgbouncer 认证查询使用的用户。
此参数需要配合 pgbouncer_auth_query 参数启用才生效。
设置后,所有通过 Pgbouncer 连接到此数据库的请求都会使用指定用户执行认证查询来验证密码。
- name: myapp
pool_auth_user: dbuser_monitor # 使用监控用户执行认证查询
register_datasource
布尔值,可变参数,用于控制是否将此数据库注册到 Grafana 作为 PostgreSQL 数据源,默认值为 true。
设置为 false 可以跳过 Grafana 数据源注册。适用于临时数据库、测试数据库,或不希望在监控系统中出现的内部数据库。
- name: temp_db
register_datasource: false # 不注册到 Grafana
模板继承
许多参数如果不显式指定,会从模板数据库继承。默认模板是 template1,其编码设置由集群初始化参数决定:
新创建的数据库默认会从 template1 数据库 Fork 出来,这个模版数据库会在 PG_PROVISION 阶段进行定制修改:
配置好扩展、模式以及默认权限,因此新创建的数据库也会继承这些配置,除非您显式使用一个其他的数据库作为模板。
深度定制
Pigsty 提供了丰富的定制参数与配置旋钮,如果你想定制模板数据库,请参考以下资源:
如果上面这些配置仍然无法满足您的需求,您可以使用 pg_init 指定自定义的集群初始化脚本进行定制:
本地化提供者
PostgreSQL 15+ 引入了 locale_provider 参数,支持不同的本地化实现。这些属性只能在数据库创建时指定,之后无法修改。
Pigsty 在 configure 配置向导中会根据 PG 与操作系统版本,优先使用 PG 内置的 C.UTF-8/C 本地化提供者。
数据库在默认情况下继承集群的本地化设置。如果您要为数据库指定一个不同于集群默认的本地化提供者,则必须使用 template0 作为模板数据库。
使用 ICU 提供者(PG15+):
- name: myapp_icu
template: template0 # ICU 必须使用 template0
locale_provider: icu
icu_locale: en-US # ICU 本地化规则
encoding: UTF8
使用内置提供者(PG17+):
- name: myapp_builtin
template: template0
locale_provider: builtin
builtin_locale: C.UTF-8 # 内置本地化规则
encoding: UTF8
提供者对比:libc(传统方式,依赖操作系统)、icu(PG15+,跨平台一致,功能丰富)、builtin(PG17+,最高效的 C/C.UTF-8 排序)。
连接池
Pgbouncer 连接池可以优化短连接性能,降低并发征用,以避免过高的连接数冲垮数据库,并在数据库迁移时提供额外的灵活处理空间。
Pigsty 会默认为 PostgreSQL 实例 1:1 配置启用一个连接池,
使用和 PostgreSQL 同样的 pg_dbsu 运行,默认为 postgres 操作系统用户。
连接池与数据库使用 /var/run/postgresql Unix Socket 通信。
Pigsty 默认将 pg_databases 中的所有数据库都添加到 pgbouncer 的数据库列表中。
您可以通过在数据库定义中显式设置 pgbouncer: false 来禁用特定数据库的 pgbouncer 连接池支持。
pgbouncer 数据库列表与其配置参数在 /etc/pgbouncer/database.txt 中定义。
meta = host=/var/run/postgresql mode=session
grafana = host=/var/run/postgresql mode=transaction
bytebase = host=/var/run/postgresql auth_user=dbuser_meta
kong = host=/var/run/postgresql pool_size=32 reserve_pool=64
gitea = host=/var/run/postgresql min_pool_size=10
wiki = host=/var/run/postgresql
noco = host=/var/run/postgresql
mongo = host=/var/run/postgresql
当您 创建数据库时,Pgbouncer 的数据库列表定义文件将会被刷新,并通过在线重载配置的方式生效,正常不会影响现有的连接。
6 - HBA 规则
Pigsty 中 PostgreSQL 与 Pgbouncer 的 HBA(Host-Based Authentication)规则配置详解。
概述
HBA(Host-Based Authentication)控制"谁可以从哪里、以什么方式连接到数据库"。
Pigsty 通过 pg_default_hba_rules 与 pg_hba_rules 让 HBA 规则也能以声明式配置形式管理。
Pigsty 在集群初始化或 HBA 刷新时渲染以下配置文件:
| 配置文件 | 路径 | 说明 |
|---|
| PostgreSQL HBA | /pg/data/pg_hba.conf | PostgreSQL 服务器的 HBA 规则 |
| Pgbouncer HBA | /etc/pgbouncer/pgb_hba.conf | 连接池 Pgbouncer 的 HBA 规则 |
HBA 规则由以下参数控制:
规则支持以下特性:
- 按角色过滤:规则支持
role 字段,根据实例的 pg_role 自动筛选生效 - 按顺序排序:规则支持
order 字段,控制规则在最终配置文件中的位置 - 两种写法:支持别名形式(简化语法)和原始形式(直接 HBA 文本)
刷新 HBA
修改配置后,需要重新渲染配置文件并让服务重载:
bin/pgsql-hba <cls> # 刷新整个集群的 HBA 规则(推荐)
bin/pgsql-hba <cls> <ip>... # 刷新集群中指定实例的 HBA 规则
脚本内部执行以下剧本命令:
./pgsql.yml -l <cls> -t pg_hba,pg_reload,pgbouncer_hba,pgbouncer_reload -e pg_reload=true
仅刷新 PostgreSQL:./pgsql.yml -l <cls> -t pg_hba,pg_reload -e pg_reload=true
仅刷新 Pgbouncer:./pgsql.yml -l <cls> -t pgbouncer_hba,pgbouncer_reload
不要直接编辑配置文件
不要直接编辑 /pg/data/pg_hba.conf 或 /etc/pgbouncer/pgb_hba.conf,下次执行 playbook 时会被覆盖。
所有变更应在 pigsty.yml 中进行,然后执行 bin/pgsql-hba 刷新。
参数详解
pg_default_hba_rules
PostgreSQL 全局默认 HBA 规则列表,通常定义在 all.vars 中,为所有 PostgreSQL 集群提供基础访问控制。
pg_default_hba_rules:
- {user: '${dbsu}' ,db: all ,addr: local ,auth: ident ,title: 'dbsu access via local os user ident' ,order: 100}
- {user: '${dbsu}' ,db: replication ,addr: local ,auth: ident ,title: 'dbsu replication from local os ident' ,order: 150}
- {user: '${repl}' ,db: replication ,addr: localhost ,auth: pwd ,title: 'replicator replication from localhost',order: 200}
- {user: '${repl}' ,db: replication ,addr: intra ,auth: pwd ,title: 'replicator replication from intranet' ,order: 250}
- {user: '${repl}' ,db: postgres ,addr: intra ,auth: pwd ,title: 'replicator postgres db from intranet' ,order: 300}
- {user: '${monitor}' ,db: all ,addr: localhost ,auth: pwd ,title: 'monitor from localhost with password' ,order: 350}
- {user: '${monitor}' ,db: all ,addr: infra ,auth: pwd ,title: 'monitor from infra host with password',order: 400}
- {user: '${admin}' ,db: all ,addr: infra ,auth: ssl ,title: 'admin @ infra nodes with pwd & ssl' ,order: 450}
- {user: '${admin}' ,db: all ,addr: world ,auth: ssl ,title: 'admin @ everywhere with ssl & pwd' ,order: 500}
- {user: '+dbrole_readonly',db: all ,addr: localhost ,auth: pwd ,title: 'pgbouncer read/write via local socket',order: 550}
- {user: '+dbrole_readonly',db: all ,addr: intra ,auth: pwd ,title: 'read/write biz user via password' ,order: 600}
- {user: '+dbrole_offline' ,db: all ,addr: intra ,auth: pwd ,title: 'allow etl offline tasks from intranet',order: 650}
pg_hba_rules
PostgreSQL 集群/实例级 HBA 追加规则,可在集群或实例级别覆盖,与默认规则合并后按 order 排序。
- 类型:
rule[],层级:全局/集群/实例 (G/C/I),默认值:[]
pg_hba_rules:
- {user: app_user, db: app_db, addr: intra, auth: pwd, title: 'app user access'}
pgb_default_hba_rules
Pgbouncer 全局默认 HBA 规则列表,通常定义在 all.vars 中。
pgb_default_hba_rules:
- {user: '${dbsu}' ,db: pgbouncer ,addr: local ,auth: peer ,title: 'dbsu local admin access with os ident',order: 100}
- {user: 'all' ,db: all ,addr: localhost ,auth: pwd ,title: 'allow all user local access with pwd' ,order: 150}
- {user: '${monitor}' ,db: pgbouncer ,addr: intra ,auth: pwd ,title: 'monitor access via intranet with pwd' ,order: 200}
- {user: '${monitor}' ,db: all ,addr: world ,auth: deny ,title: 'reject all other monitor access addr' ,order: 250}
- {user: '${admin}' ,db: all ,addr: intra ,auth: pwd ,title: 'admin access via intranet with pwd' ,order: 300}
- {user: '${admin}' ,db: all ,addr: world ,auth: deny ,title: 'reject all other admin access addr' ,order: 350}
- {user: 'all' ,db: all ,addr: intra ,auth: pwd ,title: 'allow all user intra access with pwd' ,order: 400}
pgb_hba_rules
Pgbouncer 集群/实例级 HBA 追加规则。
- 类型:
rule[],层级:全局/集群/实例 (G/C/I),默认值:[]
注意:Pgbouncer HBA 不支持 db: replication。
规则字段
每条 HBA 规则是一个 YAML 字典,支持以下字段:
| 字段 | 类型 | 必需 | 默认值 | 说明 |
|---|
user | string | 否 | all | 用户名,支持 all、变量占位符、+rolename 等 |
db | string | 否 | all | 数据库名,支持 all、replication、具体库名 |
addr | string | 是* | - | 地址别名或 CIDR,见 地址别名 |
auth | string | 否 | pwd | 认证方式别名,见 认证方式 |
title | string | 否 | - | 规则说明/注释,会渲染为配置文件中的注释 |
role | string | 否 | common | 实例角色过滤,见 角色过滤 |
order | int | 否 | 1000 | 排序权重,数字小的排前面,见 排序机制 |
rules | list | 是* | - | 原始 HBA 文本行列表,与 addr 二选一 |
addr 和 rules 必须指定其一。使用 rules 时可以直接写原始 HBA 格式。
地址别名
Pigsty 提供地址别名,简化 HBA 规则编写:
| 别名 | 展开为 | 说明 |
|---|
local | Unix socket | 本地 Unix 套接字连接 |
localhost | Unix socket + 127.0.0.1/32 + ::1/128 | 本地回环地址 |
admin | ${admin_ip}/32 | 管理员 IP 地址 |
infra | 所有 infra 组节点 IP | 基础设施节点列表 |
cluster | 当前集群所有成员 IP | 同一集群内的所有实例 |
intra / intranet | 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 | 内网 CIDR 网段 |
world / all | 0.0.0.0/0 + ::/0 | 任意地址(IPv4 + IPv6) |
<CIDR> | 直接使用 | 如 192.168.1.0/24、10.1.1.100/32 |
内网 CIDR 可通过 node_firewall_intranet 参数自定义:
node_firewall_intranet:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
认证方式
Pigsty 提供认证方式别名,简化配置:
| 别名 | 实际方式 | 连接类型 | 说明 |
|---|
pwd | scram-sha-256 或 md5 | host | 根据 pg_pwd_enc 自动选择 |
ssl | scram-sha-256 或 md5 | hostssl | 强制 SSL + 密码 |
ssl-sha | scram-sha-256 | hostssl | 强制 SSL + SCRAM-SHA-256 |
ssl-md5 | md5 | hostssl | 强制 SSL + MD5 |
cert | cert | hostssl | 客户端证书认证 |
trust | trust | host | 无条件信任(危险) |
deny / reject | reject | host | 拒绝连接 |
ident | ident | host | OS 用户映射(PostgreSQL) |
peer | peer | local | OS 用户映射(Pgbouncer/本地) |
pg_pwd_enc 默认为 scram-sha-256,可设为 md5 以兼容老客户端。
用户变量
HBA 规则支持以下用户占位符,渲染时自动替换为实际用户名:
| 占位符 | 默认值 | 对应参数 |
|---|
${dbsu} | postgres | pg_dbsu |
${repl} | replicator | pg_replication_username |
${monitor} | dbuser_monitor | pg_monitor_username |
${admin} | dbuser_dba | pg_admin_username |
角色过滤
HBA 规则的 role 字段控制规则在哪些实例上生效:
| 角色 | 说明 |
|---|
common | 默认值,所有实例都生效 |
primary | 仅主库实例生效 |
replica | 仅从库实例生效 |
offline | 仅离线实例生效(pg_role: offline 或 pg_offline_query: true) |
standby | 备库实例 |
delayed | 延迟从库实例 |
角色过滤基于实例的 pg_role 变量进行匹配,不匹配的规则会被注释掉(以 # 开头)。
pg_hba_rules:
# 仅在主库生效:写入用户只能连主库
- {user: writer, db: all, addr: intra, auth: pwd, role: primary, title: 'writer only on primary'}
# 仅在离线实例生效:ETL 任务专用网络
- {user: '+dbrole_offline', db: all, addr: '172.20.0.0/16', auth: ssl, role: offline, title: 'offline dedicated'}
排序机制
PostgreSQL HBA 是 首条匹配生效,规则顺序至关重要。Pigsty 通过 order 字段控制规则渲染顺序。
Order 区间约定
| 区间 | 用途 |
|---|
0 - 99 | 用户高优先规则(在所有默认规则之前) |
100 - 650 | 默认规则区(间隔 50,便于插入) |
1000+ | 用户规则默认值(不填 order 时追加到最后) |
PostgreSQL 默认规则 Order 分配
| Order | 规则说明 |
|---|
| 100 | dbsu local ident |
| 150 | dbsu replication local |
| 200 | replicator localhost |
| 250 | replicator intra replication |
| 300 | replicator intra postgres |
| 350 | monitor localhost |
| 400 | monitor infra |
| 450 | admin infra ssl |
| 500 | admin world ssl |
| 550 | dbrole_readonly localhost |
| 600 | dbrole_readonly intra |
| 650 | dbrole_offline intra |
Pgbouncer 默认规则 Order 分配
| Order | 规则说明 |
|---|
| 100 | dbsu local peer |
| 150 | all localhost pwd |
| 200 | monitor pgbouncer intra |
| 250 | monitor world deny |
| 300 | admin intra pwd |
| 350 | admin world deny |
| 400 | all intra pwd |
写法示例
别名形式:使用 Pigsty 提供的简化语法
pg_hba_rules:
- title: allow grafana view access
role: primary
user: dbuser_view
db: meta
addr: infra
auth: ssl
渲染结果:
# allow grafana view access [primary]
hostssl meta dbuser_view 10.10.10.10/32 scram-sha-256
原始形式:直接使用 PostgreSQL HBA 语法
pg_hba_rules:
- title: allow intranet password access
role: common
rules:
- host all all 10.0.0.0/8 scram-sha-256
- host all all 172.16.0.0/12 scram-sha-256
- host all all 192.168.0.0/16 scram-sha-256
渲染结果:
# allow intranet password access [common]
host all all 10.0.0.0/8 scram-sha-256
host all all 172.16.0.0/12 scram-sha-256
host all all 192.168.0.0/16 scram-sha-256
常见配置场景
黑名单 IP:使用 order: 0 确保最先匹配
pg_hba_rules:
- {user: all, db: all, addr: '10.1.1.100/32', auth: deny, order: 0, title: 'block bad ip'}
白名单应用服务器:高优先级允许特定 IP
pg_hba_rules:
- {user: app_user, db: app_db, addr: '192.168.1.10/32', auth: ssl, order: 50, title: 'app server'}
管理员强制证书:覆盖默认的 SSL 密码认证
pg_hba_rules:
- {user: '${admin}', db: all, addr: world, auth: cert, order: 10, title: 'admin cert only'}
离线实例专用网络:仅在 offline 实例生效
pg_hba_rules:
- {user: '+dbrole_offline', db: all, addr: '172.20.0.0/16', auth: ssl-sha, role: offline, title: 'etl network'}
按数据库限制访问:敏感库仅允许特定网段
pg_hba_rules:
- {user: fin_user, db: finance_db, addr: '10.20.0.0/16', auth: ssl, title: 'finance only'}
- {user: hr_user, db: hr_db, addr: '10.30.0.0/16', auth: ssl, title: 'hr only'}
Pgbouncer 专用规则:注意不支持 db: replication
pgb_hba_rules:
- {user: '+dbrole_readwrite', db: all, addr: world, auth: ssl, title: 'app via pgbouncer'}
完整集群示例
pg-prod:
hosts:
10.10.10.11: {pg_seq: 1, pg_role: primary}
10.10.10.12: {pg_seq: 2, pg_role: replica}
10.10.10.13: {pg_seq: 3, pg_role: offline}
vars:
pg_cluster: pg-prod
pg_hba_rules:
# 黑名单:已知恶意 IP(最高优先级)
- {user: all, db: all, addr: '10.1.1.100/32', auth: deny, order: 0, title: 'blacklist'}
# 应用服务器白名单(高优先级)
- {user: app_user, db: app_db, addr: '192.168.1.0/24', auth: ssl, order: 50, title: 'app servers'}
# ETL 任务:仅离线实例
- {user: etl_user, db: all, addr: '172.20.0.0/16', auth: pwd, role: offline, title: 'etl tasks'}
# 集群内监控访问
- {user: '${monitor}', db: all, addr: cluster, auth: pwd, order: 380, title: 'cluster monitor'}
pgb_hba_rules:
# 应用通过连接池
- {user: '+dbrole_readwrite', db: all, addr: '192.168.1.0/24', auth: ssl, title: 'app via pgbouncer'}
验证与排查
查看当前 HBA 规则
psql -c "TABLE pg_hba_file_rules" # 通过 SQL 查看(推荐)
cat /pg/data/pg_hba.conf # 查看 PostgreSQL HBA 文件
cat /etc/pgbouncer/pgb_hba.conf # 查看 Pgbouncer HBA 文件
grep '^#' /pg/data/pg_hba.conf | head -20 # 查看规则标题(验证 order)
测试连接认证
psql -h <host> -p 5432 -U <user> -d <db> -c "SELECT 1"
常见问题排查
| 错误信息 | 可能原因 | 解决方案 |
|---|
no pg_hba.conf entry for host... | 没有匹配的 HBA 规则 | 添加对应规则并刷新 |
password authentication failed | 密码错误或加密方式不兼容 | 检查密码和 pg_pwd_enc |
| 规则不生效 | 未刷新或 order 被覆盖 | 执行 bin/pgsql-hba 并检查顺序 |
注意事项
- 顺序敏感:PostgreSQL HBA 首条匹配生效,善用
order 字段 - 角色匹配:确保
role 字段与目标实例的 pg_role 一致 - 地址格式:CIDR 必须正确,如
10.0.0.0/8 而非 10.0.0.0/255.0.0.0 - Pgbouncer 限制:不支持
db: replication - SSL 前提:使用
ssl、cert 认证前确保 SSL 已正确配置 - 测试优先:修改 HBA 前建议先在测试环境验证
- 扩缩容刷新:使用
addr: cluster 的规则在集群成员变化后需要刷新
相关文档
7 - 参数配置
如何配置集群、实例、用户和数据库级别的 PostgreSQL 参数
PostgreSQL 参数可以在多个层级进行配置,不同层级的参数设置具有不同的作用范围和优先级。
Pigsty 支持在四个层级配置 PostgreSQL 参数,从全局到局部依次为:
| 层级 | 作用范围 | 配置方式 | 存储位置 |
|---|
| 集群级 | 整个集群所有实例 | Patroni DCS / 调优模板 | etcd + postgresql.conf |
| 实例级 | 单个 PostgreSQL 实例 | pg_parameters / ALTER SYSTEM | postgresql.auto.conf |
| 数据库级 | 特定数据库的所有会话 | pg_databases[].parameters | pg_db_role_setting |
| 用户级 | 特定用户的所有会话 | pg_users[].parameters | pg_db_role_setting |
参数优先级从低到高:集群级 < 实例级 < 数据库级 < 用户级 < 会话级(SET 命令)。
高优先级的设置会覆盖低优先级的设置。
关于 PostgreSQL 参数的完整说明,请参阅 PostgreSQL 官方文档:服务器配置。
集群级参数
集群级参数是整个 PostgreSQL 集群共享的配置,所有实例(主库和从库)都会使用相同的参数值。
在 Pigsty 中,集群级参数通过 Patroni 管理,存储在分布式配置存储(DCS,默认为 etcd)中。
Pigsty 提供了四种预置的 Patroni 参数优化模板,针对不同的使用场景进行了优化,通过 pg_conf 参数指定:
调优模板文件位于 Pigsty 安装目录的 roles/pgsql/templates/ 目录下,包含了根据硬件规格自动计算的参数值。
这些模板会在集群初始化时渲染为 Patroni 配置文件 /etc/patroni/patroni.yml。更多详情请参阅 场景模板。
在集群创建前,您可以通过调整这些 Patroni 配置模板来修改集群的 初始化参数。
一旦集群初始化完成,后续的参数修改应通过 Patroni 的 配置管理 机制进行。
Patroni DCS 配置
Patroni 将集群配置存储在 DCS(分布式配置存储,默认为 etcd)中,确保集群所有成员使用一致的配置。
配置存储结构:
/pigsty/ # 命名空间(patroni_namespace)
└── pg-meta/ # 集群名称(pg_cluster)
├── config # 集群配置(所有成员共享)
├── leader # 当前主库信息
├── members/ # 成员注册信息
│ ├── pg-meta-1
│ └── pg-meta-2
└── ...
配置渲染流程:
- 初始化阶段:调优模板(如
oltp.yml)通过 Jinja2 渲染为 /etc/patroni/patroni.yml - 启动阶段:Patroni 读取本地配置,将 PostgreSQL 参数写入 DCS
- 运行阶段:Patroni 定期从 DCS 同步配置到本地 PostgreSQL
本地缓存机制:
每个 Patroni 实例会在本地缓存 DCS 配置,位于 /pg/conf/<instance>.yml:
- 启动时:从 DCS 加载配置,缓存到本地
- 运行时:定期同步 DCS 配置到本地缓存
- DCS 不可用时:使用本地缓存继续运行(但无法进行主从切换)
配置文件层次
Patroni 会将 DCS 中的配置渲染到本地 PostgreSQL 配置文件,形成以下层次结构:
/pg/data/
├── postgresql.conf # 主配置文件(由 Patroni 动态管理)
├── postgresql.base.conf # 基础配置(通过 include 指令加载)
├── postgresql.auto.conf # 实例级覆盖配置(ALTER SYSTEM 写入)
├── pg_hba.conf # 客户端认证配置
└── pg_ident.conf # 用户映射配置
配置加载顺序(优先级从低到高):
postgresql.conf:Patroni 动态生成,包含 DCS 中的集群参数postgresql.base.conf:通过 include 指令加载,包含静态基础配置postgresql.auto.conf:PostgreSQL 自动加载,用于实例级参数覆盖
由于 postgresql.auto.conf 最后加载,其中的参数会覆盖前面文件中的同名参数。
实例级参数
实例级参数仅对单个 PostgreSQL 实例生效,用于覆盖集群级配置或设置实例特定的参数。
实例级参数会写入 postgresql.auto.conf 文件,由于该文件最后加载,可以覆盖集群级的任何参数。
这是一项非常有用的技术:您可以为特定实例设置不同于集群的参数值,例如:
- 为从库设置
hot_standby_feedback = on - 为特定实例调整
work_mem 或 maintenance_work_mem - 为延迟从库设置
recovery_min_apply_delay
使用 pg_parameters
在 Pigsty 配置中,使用 pg_parameters 参数定义实例级配置:
pg-meta:
hosts:
10.10.10.10:
pg_seq: 1
pg_role: primary
pg_parameters: # 实例级参数
log_statement: all # 仅此实例记录所有 SQL
vars:
pg_cluster: pg-meta
pg_parameters: # 集群默认的实例参数
log_timezone: Asia/Shanghai
log_min_duration_statement: 1000
使用 ./pgsql.yml -l <cls> -t pg_param 子任务,可以将参数配置应用生效,这些参数会被渲染到 postgresql.auto.conf 文件中。
参数覆盖层次
pg_parameters 可以在 Ansible 配置的不同层次定义,优先级从低到高:
all:
vars:
pg_parameters: # 全局默认
log_statement: none
children:
pg-meta:
vars:
pg_parameters: # 集群级覆盖
log_statement: ddl
hosts:
10.10.10.10:
pg_parameters: # 实例级覆盖(最高优先级)
log_statement: all
使用 ALTER SYSTEM
除了通过配置文件,还可以在运行时使用 SQL 命令 ALTER SYSTEM 修改实例级参数:
-- 设置参数
ALTER SYSTEM SET work_mem = '256MB';
ALTER SYSTEM SET log_min_duration_statement = 1000;
-- 重置为默认值
ALTER SYSTEM RESET work_mem;
ALTER SYSTEM RESET ALL; -- 重置所有 ALTER SYSTEM 设置
-- 重新加载配置使其生效
SELECT pg_reload_conf();
ALTER SYSTEM 会将参数写入 postgresql.auto.conf 文件。
注意:在 Pigsty 管理的集群中,postgresql.auto.conf 由 Ansible 通过 pg_parameters 管理。
手动使用 ALTER SYSTEM 修改的参数可能会在下次执行 playbook 时被覆盖。
建议通过修改 pigsty.yml 中的 pg_parameters 来管理实例级参数。
列表类型参数
PostgreSQL 中有一类特殊的参数接受逗号分隔的列表值。在 YAML 配置文件中配置这类参数时,
整个值必须用引号包裹,否则 YAML 解析器会将其解释为数组而导致错误:
# ✓ 正确:用引号包裹整个值
pg_parameters:
shared_preload_libraries: 'timescaledb, pg_stat_statements'
search_path: '"$user", public, app'
# ✗ 错误:不加引号会导致 YAML 解析错误
pg_parameters:
shared_preload_libraries: timescaledb, pg_stat_statements # YAML 会解析为数组!
Pigsty 会自动识别以下列表类型参数,在渲染到配置文件时不添加外层引号:
| 参数 | 说明 | 示例值 |
|---|
shared_preload_libraries | 预加载共享库 | 'timescaledb, pg_stat_statements' |
search_path | Schema 搜索路径 | '"$user", public, app' |
local_preload_libraries | 本地预加载库 | 'auto_explain' |
session_preload_libraries | 会话预加载库 | 'pg_hint_plan' |
log_destination | 日志输出目标 | 'csvlog, stderr' |
unix_socket_directories | Unix Socket 目录 | '/var/run/postgresql, /tmp' |
temp_tablespaces | 临时表空间 | 'ssd_space, hdd_space' |
debug_io_direct | 直接 I/O 模式(PG16+) | 'data, wal' |
渲染示例:
# pigsty.yml 配置(YAML 中需要引号)
pg_parameters:
shared_preload_libraries: 'timescaledb, pg_stat_statements'
search_path: '"$user", public, app'
work_mem: 64MB
# 渲染后的 postgresql.auto.conf(列表参数无外层引号)
shared_preload_libraries = timescaledb, pg_stat_statements
search_path = "$user", public, app
work_mem = '64MB'
数据库级参数
数据库级参数针对特定数据库生效,连接到该数据库的所有会话都会应用这些参数设置。
通过 ALTER DATABASE ... SET 实现,存储在系统表 pg_db_role_setting 中。
配置方式
在 pg_databases 中使用 parameters 字段定义:
pg_databases:
- name: analytics
owner: dbuser_analyst
parameters:
work_mem: 256MB # 分析库需要更多内存
maintenance_work_mem: 1GB # 大表维护操作
statement_timeout: 10min # 允许长查询
search_path: '"$user", public, mart' # 列表参数需要引号
与实例级参数相同,列表类型参数值在 YAML 中需要用引号包裹。
参数渲染规则
数据库级参数通过 ALTER DATABASE ... SET 语句设置。Pigsty 会根据参数类型自动选择正确的语法:
列表类型参数(search_path、temp_tablespaces、local_preload_libraries、session_preload_libraries、log_destination)不加外层引号:
ALTER DATABASE "analytics" SET "search_path" = "$user", public, mart;
标量参数 使用引号包裹值:
ALTER DATABASE "analytics" SET "work_mem" = '256MB';
ALTER DATABASE "analytics" SET "statement_timeout" = '10min';
注意:虽然 log_destination 在数据库级参数白名单中,但由于其 context 为 sighup,
实际上无法在数据库级别生效。此参数应在实例级(pg_parameters)配置。
查看数据库参数
-- 查看特定数据库的参数设置
SELECT datname, unnest(setconfig) AS setting
FROM pg_db_role_setting drs
JOIN pg_database d ON d.oid = drs.setdatabase
WHERE drs.setrole = 0 AND datname = 'analytics';
手动管理
-- 设置参数
ALTER DATABASE analytics SET work_mem = '256MB';
ALTER DATABASE analytics SET search_path = "$user", public, myschema;
-- 重置参数
ALTER DATABASE analytics RESET work_mem;
ALTER DATABASE analytics RESET ALL;
用户级参数
用户级参数针对特定数据库用户生效,该用户的所有会话都会应用这些参数设置。
通过 ALTER USER ... SET 实现,同样存储在系统表 pg_db_role_setting 中。
配置方式
在 pg_users 或 pg_default_roles 中使用 parameters 字段定义:
pg_users:
- name: dbuser_analyst
password: DBUser.Analyst
parameters:
work_mem: 256MB # 分析查询需要更多内存
statement_timeout: 5min # 允许较长的查询时间
search_path: '"$user", public, analytics' # 列表参数需要引号
log_statement: all # 记录所有 SQL
参数渲染规则
用户级参数的渲染规则与数据库级参数相同:
列表类型参数(search_path、temp_tablespaces、local_preload_libraries、session_preload_libraries)不加外层引号:
ALTER USER "dbuser_analyst" SET "search_path" = "$user", public, analytics;
标量参数 使用引号包裹:
ALTER USER "dbuser_analyst" SET "work_mem" = '256MB';
ALTER USER "dbuser_analyst" SET "statement_timeout" = '5min';
特殊值 DEFAULT
使用 DEFAULT(大小写不敏感)可以将参数重置为 PostgreSQL 默认值:
parameters:
work_mem: DEFAULT # 重置为默认值
statement_timeout: 30s # 设置具体值
ALTER USER "dbuser_app" SET "work_mem" = DEFAULT;
ALTER USER "dbuser_app" SET "statement_timeout" = '30s';
查看用户参数
-- 查看特定用户的参数设置
SELECT rolname, unnest(setconfig) AS setting
FROM pg_db_role_setting drs
JOIN pg_roles r ON r.oid = drs.setrole
WHERE rolname = 'dbuser_analyst';
手动管理
-- 设置参数
ALTER USER dbuser_app SET work_mem = '128MB';
ALTER USER dbuser_app SET search_path = "$user", public, myschema;
-- 重置参数
ALTER USER dbuser_app RESET work_mem;
ALTER USER dbuser_app RESET ALL;
参数优先级
当同一参数在多个层级设置时,PostgreSQL 按以下优先级应用(从低到高):
postgresql.conf ← 集群级参数(Patroni DCS)
↓
postgresql.auto.conf ← 实例级参数(pg_parameters / ALTER SYSTEM)
↓
数据库级 ← ALTER DATABASE SET
↓
用户级 ← ALTER USER SET
↓
会话级 ← SET 命令
关于数据库级与用户级的优先级:
当用户连接到特定数据库时,如果同一参数在数据库级和用户级都有设置,
PostgreSQL 会使用 用户级参数,因为用户级优先级更高。
示例场景:
# 数据库级:analytics 数据库 work_mem = 256MB
pg_databases:
- name: analytics
parameters:
work_mem: 256MB
# 用户级:analyst 用户 work_mem = 512MB
pg_users:
- name: analyst
parameters:
work_mem: 512MB
- 当
analyst 用户连接到 analytics 数据库时:work_mem = 512MB(用户级优先) - 当其他用户连接到
analytics 数据库时:work_mem = 256MB(数据库级生效) - 当
analyst 用户连接到其他数据库时:work_mem = 512MB(用户级生效)
8 - 访问控制
Pigsty 提供的默认角色系统与权限模型
访问控制由“角色体系 + 权限模板 + HBA”共同决定。本节聚焦于如何通过配置参数声明角色与对象权限。
Pigsty 预置了一套精简的 ACL 模型,全部通过以下参数描述:
pg_default_roles:系统角色与系统用户。pg_users:业务用户与角色。pg_default_privileges:管理员/属主新建对象时的默认权限。pg_revoke_public、pg_default_schemas、pg_default_extensions:控制 template1 的默认行为。
理解这些参数后,你就可以写出完全可复现的权限配置。
默认角色体系(pg_default_roles)
默认包含 4 个业务角色 + 4 个系统用户:
| 名称 | 类型 | 说明 |
|---|
dbrole_readonly | NOLOGIN | 所有业务共用,拥有 SELECT/USAGE |
dbrole_readwrite | NOLOGIN | 继承只读角色,并拥有 INSERT/UPDATE/DELETE |
dbrole_admin | NOLOGIN | 继承 pg_monitor + 读写角色,可建对象和触发器 |
dbrole_offline | NOLOGIN | 受限只读角色,仅允许访问离线实例 |
postgres | 用户 | 系统超级用户,与 pg_dbsu 同名 |
replicator | 用户 | 用于流复制与备份,继承监控与只读权限 |
dbuser_dba | 用户 | 主要管理员账号,同时同步到 pgbouncer |
dbuser_monitor | 用户 | 监控账号,具备 pg_monitor 权限,默认记录慢 SQL |
这些定义位于 pg_default_roles,理论上可以自定义,但若要替换名称,必须同步更新 HBA/ACL/脚本中的引用。
示例:为离线任务额外加一个 dbrole_etl:
pg_default_roles:
- { name: dbrole_etl, login: false, roles: [dbrole_offline], comment: 'etl read-only role' }
- { name: dbrole_admin, login: false, roles: [pg_monitor, dbrole_readwrite, dbrole_etl] }
效果:所有继承 dbrole_admin 的用户自动拥有 dbrole_etl 权限,可访问 offline 实例并执行 ETL。
默认用户与凭据参数
系统用户的用户名/密码由以下参数控制:
| 参数 | 默认值 | 作用 |
|---|
pg_dbsu | postgres | 数据库/系统超级用户 |
pg_dbsu_password | 空字符串 | dbsu 密码(默认不启用) |
pg_replication_username | replicator | 复制用户名称 |
pg_replication_password | DBUser.Replicator | 复制用户密码 |
pg_admin_username | dbuser_dba | 管理员用户名 |
pg_admin_password | DBUser.DBA | 管理员密码 |
pg_monitor_username | dbuser_monitor | 监控用户 |
pg_monitor_password | DBUser.Monitor | 监控用户密码 |
如果修改这些参数,请同步在 pg_default_roles 中更新对应用户的定义,以避免角色属性不一致。
业务角色与授权(pg_users)
业务用户通过 pg_users 声明(详细字段见 用户配置),其中 roles 字段控制授予的业务角色。
示例:创建只读/读写用户各一名:
pg_users:
- { name: app_reader, password: DBUser.Reader, roles: [dbrole_readonly], pgbouncer: true }
- { name: app_writer, password: DBUser.Writer, roles: [dbrole_readwrite], pgbouncer: true }
通过继承 dbrole_* 来控制访问权限,无需为每个库单独 GRANT。配合 pg_hba_rules 即可区分访问来源。
若需要更细粒度的 ACL,可在 baseline SQL 中或后续剧本里使用标准 GRANT/REVOKE。Pigsty 不会阻止你额外授予权限。
默认权限模板(pg_default_privileges)
pg_default_privileges 会在 postgres、dbuser_dba、dbrole_admin(业务管理员 SET ROLE 后)上设置 DEFAULT PRIVILEGE。默认模板如下:
pg_default_privileges:
- GRANT USAGE ON SCHEMAS TO dbrole_readonly
- GRANT SELECT ON TABLES TO dbrole_readonly
- GRANT SELECT ON SEQUENCES TO dbrole_readonly
- GRANT EXECUTE ON FUNCTIONS TO dbrole_readonly
- GRANT USAGE ON SCHEMAS TO dbrole_offline
- GRANT SELECT ON TABLES TO dbrole_offline
- GRANT SELECT ON SEQUENCES TO dbrole_offline
- GRANT EXECUTE ON FUNCTIONS TO dbrole_offline
- GRANT INSERT ON TABLES TO dbrole_readwrite
- GRANT UPDATE ON TABLES TO dbrole_readwrite
- GRANT DELETE ON TABLES TO dbrole_readwrite
- GRANT USAGE ON SEQUENCES TO dbrole_readwrite
- GRANT UPDATE ON SEQUENCES TO dbrole_readwrite
- GRANT TRUNCATE ON TABLES TO dbrole_admin
- GRANT REFERENCES ON TABLES TO dbrole_admin
- GRANT TRIGGER ON TABLES TO dbrole_admin
- GRANT CREATE ON SCHEMAS TO dbrole_admin
只要对象由上述管理员创建,就会自动携带对应权限,无需人为执行 GRANT。若业务需要自定义模板,直接替换该数组即可。
额外提示:
pg_revoke_public 默认为 true,意味着自动撤销 PUBLIC 在数据库和 public schema 上的 CREATE 权限。pg_default_schemas 和 pg_default_extensions 控制在 template1/postgres 中预创建的 schema/扩展,通常用于监控对象(monitor schema、pg_stat_statements 等)。
常见配置场景
为合作方提供只读账号
pg_users:
- name: partner_ro
password: Partner.Read
roles: [dbrole_readonly]
pg_hba_rules:
- { user: partner_ro, db: analytics, addr: 203.0.113.0/24, auth: ssl }
效果:合作方账号登录后只具备默认只读权限,并且只能通过 TLS 从指定网段访问 analytics 库。
为业务管理员赋予 DDL 能力
pg_users:
- name: app_admin
password: DBUser.AppAdmin
roles: [dbrole_admin]
业务管理员通过 SET ROLE dbrole_admin 或直接以 app_admin 登录,即可继承默认的 DDL 权限模板。
自定义默认权限
pg_default_privileges:
- GRANT INSERT,UPDATE,DELETE ON TABLES TO dbrole_admin
- GRANT SELECT,UPDATE ON SEQUENCES TO dbrole_admin
- GRANT SELECT ON TABLES TO reporting_group
替换默认模板后,所有由管理员创建的对象都会携带新的权限定义,避免逐对象授权。
与其他组件的协同
- HBA 规则:使用
pg_hba_rules 将角色与来源进行绑定(例如只让 dbrole_offline 访问离线实例)。 - Pgbouncer:
pgbouncer: true 的用户会被写入 userlist.txt,pool_mode/pool_connlimit 可以控制连接池层面的配额。 - Grafana/监控:
dbuser_monitor 的权限来自 pg_default_roles,如果你新增监控用户,记得赋予 pg_monitor + monitor schema 的访问权。
通过这些参数,可以让权限体系与代码一起版本化,真正做到“配置即策略”。