☰
Pigsty pg_exporters 角色实战:用本地 Exporter 监控远程 PostgreSQL(Remote Monitoring 全指南)
2026/10/3 2:03:38 网站建设 项目流程
  • 数据库
  • 运维
  • 云原生
  • 高可用
  • 监控

【免费下载链接】pigsty

Enterprise-Grade OSS PostgreSQL Distribution with HA, PITR, IaC, Monitor, 12 kernel forks and 575 PG extensions. Best-of-breed products integrated as a platform. Self-host Postgres like a Pro!

项目地址:https://gitcode.com/GitHub_Trending/pi/pigsty
点击查看免费下载

本指南以 Pigsty 仓库中的 roles/pg_exporters/README.md 为骨架,结合 pgsql-monitor.yml、roles/pg_exporters/tasks 源码与 conf/demo/remote.yml 真实配置,系统讲解如何在不向目标主机部署任何 Agent 的前提下,把 AWS/Azure/GCP/阿里云 RDS 等非 Pigsty 托管的远程 PostgreSQL 实例纳入 Pigsty 统一监控体系。读完本文,你将掌握pg_exporters的架构原理、清单配置语法、连接串生成规则、远程端 SQL/HBA 准备以及维多利亚指标(VictoriaMetrics)与 Grafana 注册的完整链路。

一、角色概览:什么是 pg_exporters

pg_exporters是 Pigsty 中负责远程 PostgreSQL 监控的 Ansible Role。它的核心思想是:不在远程 PostgreSQL 所在主机上安装任何采集组件,而是在infra 节点(监控节点)本地部署pg_exporter,通过数据库协议直连远端实例拉取指标,再接入本地监控栈。

从 roles/pg_exporters/meta/main.yml 可以看到,该角色在 Ansible Galaxy 中的定位是deploy multiple pg_exporters(部署多个 pg_exporter),支持 EL/Ubuntu/Debian 全系列平台。与本地监控角色 pg_monitor 和基础设施监控角色 infra 互为补充。

典型适用场景

  • 监控云上 RDS 实例:AWS RDS、Azure Database、GCP Cloud SQL、阿里云 RDS/PolarDB 等托管数据库;
  • 监控 Pigsty 之外的 PostgreSQL 集群:例如既有存量数据库、异构环境中的 PostgreSQL;
  • 集中式监控:目标主机不允许安装 Agent(安全性、合规性或托管平台限制),只需一个可被 infra 节点访问的数据库端口即可。

一个重要边界

该角色只采集 PostgreSQL 本身的指标。远程实例的 Node、pgBouncer、Patroni、HAProxy 指标均不可用,日志采集同样不支持——这些依赖本机 Agent 的组件天然无法通过远程方式获得。

二、架构与数据流

pgsql-monitor.yml(Playbook 文件)是该功能唯一的入口,其内部头注释绘制了清晰的拓扑:

------ infra ------ | | | victoria | v---- pg-foo-1 ----v | ^ | metrics | ^ | | pg_exporter <-|------------|---- postgres | | (port: 20001) | | 10.10.10.10:5432 | | ^ | ^------------------^ | pg_exporter <-|------------|---- postgres | | (port: 20002) | | 10.10.10.11:5433 | ------------------- ^------------------^

数据流分三段:

  1. 采集:infra 节点上每个pg_exporter进程通过 PostgreSQL 协议连接远端实例(默认端口 5432,可配置),执行预定义的采集 SQL;
  2. 暴露:pg_exporter在本地监听一个独占端口(如 20001、20002),以 Prometheus 文本格式暴露/metrics端点;
  3. 汇聚与展示:本地 VictoriaMetrics 按端口抓取这些指标,同时 Grafana 注册对应的 PostgreSQL 数据源,最终呈现监控面板。

从 roles/pg_exporters/tasks/main.yml 看,角色内部按三条流水线工作:

  • pg_exporter.yml:为每个条目渲染采集器配置、环境变量、systemd 单元并启动服务;
  • add_metrics:把每个pg_cluster写入/infra/targets/pgrds/<cluster>.yml,作为 VictoriaMetrics 的抓取目标;
  • add_ds:为每个pg_databases中声明的数据库生成并注册 Grafana PostgreSQL 数据源。

三、快速上手:Playbook 与 Tags

角色提供了清晰的标签(Tags)层级,便于精细控制执行范围:

pg_exporters # 设置远程 pg_exporter 实例 ├── pg_register # 注册到监控系统 │ ├── add_metrics # 注册到 Victoria Metrics │ └── add_ds # 注册到 Grafana 数据源

常用命令示例(在仓库根目录执行):

# 设置所有远程 exporter ./pgsql-monitor.yml -t pg_exporters # 仅注册到监控(不重建 exporter) ./pgsql-monitor.yml -t pg_register # 仅操作指定集群 ./pgsql-monitor.yml -e clsname=pg-foo

Playbook 本身(pgsql-monitor.yml)定义如下:

- name: PGSQL MONITOR become: true hosts: infra gather_facts: no ignore_errors: true vars: { clsname: '' } # 指定时仅处理单个集群 roles: - { role: node_id , tags: id } # 获取节点身份(始终执行) - { role: pg_exporters , tags: exporter } # 设置 exporters

注意hosts: infra:所有pg_exporter都部署在infra 节点上,且clsname变量可在命令行通过-e覆盖,实现"只初始化某个远程集群"的增量运维。ignore_errors: true保证了单个实例配置失败不会中断整批部署,配合wait_for轮询端口上线,具备一定的容错能力。

四、核心配置:pg_exporters 清单定义

pg_exporters是一个以本地端口为键(key)、以远程实例描述为值(value)的字典,定义在 infra 组变量中。每个条目把"一个本地端口"映射到"一个远程实例":

pg_exporters: <local_port>: pg_cluster: <cluster_name> # 必填:集群名称 pg_seq: <sequence_number> # 必填:实例序号 pg_host: <remote_ip> # 必填:远程 PostgreSQL IP 或域名 pg_port: 5432 # 可选:PostgreSQL 端口,默认 5432 pg_dbsu: postgres # 可选:数据库超级用户 pg_monitor_username: dbuser_monitor # 可选:监控用户 pg_monitor_password: DBUser.Monitor # 可选:监控密码 pg_exporter_url: '' # 可选:覆盖连接 URL pg_exporter_config: pg_exporter.yml # 可选:采集器配置文件名 pg_databases: [] # 可选:注册 Grafana 数据源的数据库列表

字段的取值优先级从 tasks/main.yml 的实现可以明确看出:条目级 > 主机级(hostvars)> 全局默认值。例如pg_port的解析逻辑是:

"{% if 'pg_port' in item.value %}{{ item.value.pg_port }} {% elif 'pg_port' in hostvars[inventory_hostname] %}{{ hostvars[inventory_hostname].pg_port }} {% else %}5432{% endif %}"

pg_monitor_username与pg_monitor_password同样遵循该三级回退规则(默认dbuser_monitor/DBUser.Monitor)。因此你既可以全局统一定义监控账号,也可以为个别实例单独覆盖——这是连接云上不同 RDS 账号时的关键能力。

生产级示例:监控阿里云 PolarDB 与 RDS

conf/demo/remote.yml 提供了完整的实战配置,涵盖域名主机、自定义端口、独立账号、数据库白名单与 Grafana 数据源:

infra: hosts: { 10.10.10.10: { infra_seq: 1 } } vars: pg_exporters: 20001: { pg_cluster: pg-foo, pg_seq: 1, pg_host: 10.10.10.10 } 20002: { pg_cluster: pg-bar, pg_seq: 1, pg_host: 10.10.10.11 , pg_port: 5432 } 20003: { pg_cluster: pg-bar, pg_seq: 2, pg_host: 10.10.10.12 , pg_exporter_url: 'postgres://dbuser_monitor:DBUser.Monitor@10.10.10.12:5432/postgres?sslmode=disable' } 20004: { pg_cluster: pg-bar, pg_seq: 3, pg_host: 10.10.10.13 , pg_monitor_username: dbuser_monitor, pg_monitor_password: DBUser.Monitor } 20011: pg_cluster: pg-polar # RDS 集群名(身份标识) pg_seq: 1 # RDS 实例序号 pg_host: pxx.polardbpg.rds.aliyuncs.com # RDS 域名地址 pg_port: 1921 # RDS 端口 pg_exporter_include_database: 'test' # 仅监控该数据库列表 pg_monitor_username: dbuser_monitor # 覆盖默认监控用户 pg_monitor_password: DBUser_Monitor # 覆盖默认监控密码 pg_databases: [{ name: test }] # 注册到 Grafana 数据源的数据库 20014: pg_cluster: pg-rds pg_seq: 1 pg_host: pgm-xx.pg.rds.aliyuncs.com pg_port: 5432 pg_exporter_auto_discovery: true # 开启自动发现 pg_exporter_include_database: 'rds' pg_monitor_username: dbuser_monitor pg_monitor_password: DBUser_Monitor pg_databases: [ { name: rds } ]

该示例中pg_exporters也定义在infra.vars下,pg_host直接使用云厂商域名(如pgm-xx.pg.rds.aliyuncs.com),端口可以是非 5432(如 PolarDB 的 1921),并通过pg_monitor_username/pg_monitor_password为每个实例提供独立凭据,贴近真实混合云场景。

五、Exporter 参数与默认值

每个 exporter 实例还受以下全局/条目级参数控制(默认值见 defaults/main.yml):

变量默认值说明
pg_exporter_configpg_exporter.yml采集器配置文件;使用其他文件名时从files/目录拷贝
pg_exporter_cache_ttls1,10,60,300采集器 TTL 分级(秒),逗号分隔的四个阶段
pg_exporter_port9630pg_exporter 监听端口(条目级场景下被字典键覆盖)
pg_exporter_paramssslmode=disableDSN 附加连接参数
pg_exporter_url''显式覆盖自动生成的连接串
pg_exporter_auto_discoverytrue是否启用数据库自动发现
pg_exporter_exclude_databasetemplate0,template1,postgres自动发现时不监控的数据库 CSV
pg_exporter_include_database''自动发现时只监控的数据库 CSV
pg_exporter_connect_timeout200连接超时(毫秒)
pg_exporter_options''追加传给 pg_exporter 的额外启动参数

值得关注的是pg_exporter_cache_ttls:采集 SQL 按开销被划分为四个 TTL 档位(快/中/慢/最慢),例如基础信息用快速档(1 秒级),库大小统计用慢速档(60 秒级)。在 tasks/pg_exporter.yml 中它被解析为四个整数注入模板:

ttl_fast: "{{ pg_exporter_cache_ttls.split(',')[0]|int }}" ttl_norm: "{{ pg_exporter_cache_ttls.split(',')[1]|int }}" ttl_slow: "{{ pg_exporter_cache_ttls.split(',')[2]|int }}" ttl_slowest: "{{ pg_exporter_cache_ttls.split(',')[3]|int }}"

六、连接 URL 的生成规则与覆盖

未显式指定pg_exporter_url时,连接串由 templates/pg_exporter.env 自动拼装:

postgres://<pg_monitor_username>:<pg_monitor_password>@<pg_host>:<pg_port>/postgres?<pg_exporter_params>

例如默认参数下即为postgres://dbuser_monitor:DBUser.Monitor@<pg_host>:5432/postgres?sslmode=disable。该模板在渲染时的完整逻辑是:

{% if pg_exporter_url != '' %} # OVERWRITE by pg_exporter_url PG_EXPORTER_URL='{{ pg_exporter_url }}' {% else %} PG_EXPORTER_URL='postgres://{{ pg_monitor_username }}:{{ pg_monitor_password }}@{{ pg_host }}:{{ pg_port }}/postgres{% if pg_exporter_params != '' %}?{{ pg_exporter_params }}{% endif %}' {% endif %}

当需要强制 SSL(如云 RDS 强制要求加密连接)或目标实例对账号/库有特殊要求时,可用pg_exporter_url整体覆盖:

pg_exporters: 20001: pg_cluster: pg-rds pg_seq: 1 pg_host: rds.example.com pg_exporter_url: 'postgres://monitor:password@rds.example.com:5432/postgres?sslmode=require'

模板还会根据pg_exporter_auto_discovery布尔值生成PG_EXPORTER_AUTO_DISCOVERY=true/false,并写入PG_EXPORTER_EXCLUDE_DATABASE、PG_EXPORTER_INCLUDE_DATABASE、PG_EXPORTER_CONFIG、PG_EXPORTER_TELEMETRY_PATH(默认/metrics)、PG_EXPORTER_DISABLE_CACHE=false与PG_EXPORTER_CONNECT_TIMEOUT等环境变量,最终通过 systemd 的EnvironmentFile注入进程。

七、远程 PostgreSQL 端准备

在开始监控前,需要让远端实例接受 infra 节点的连接并授予监控权限。

1. 创建监控用户并授权

在目标 PostgreSQL 上执行(参考 pgsql-monitor.yml 注释):

-- 创建监控用户 CREATE USER dbuser_monitor PASSWORD 'DBUser.Monitor'; COMMENT ON ROLE dbuser_monitor IS 'system monitor user'; -- 授予监控权限(PolarDB for PostgreSQL 等定制内核可能不提供 pg_monitor 角色) GRANT pg_monitor TO dbuser_monitor; -- 创建必需的扩展(用于 pg_stat_statements 指标采集) CREATE EXTENSION IF NOT EXISTS "pg_stat_statements" WITH SCHEMA "monitor";

需要说明的是:GRANT pg_monitor是 PostgreSQL 10+ 内置的监控预定义角色,能覆盖绝大多数监控视图的只读权限;但部分云厂商定制内核(如 PolarDB)并不提供该角色,此时需要手动授予所需视图/函数的 SELECT 权限。

2. 配置 HBA(host-based authentication)

确保远端 PostgreSQL 的pg_hba.conf放行来自 infra 节点的连接,并使用强认证方式:

# pg_hba.conf host all dbuser_monitor <infra_ip>/32 scram-sha-256

若 infra 与 RDS 之间存在 VPN/VPC 对等,请以实际可达地址为准;scram-sha-256优于md5,是较新的 PostgreSQL 默认推荐认证方式。

八、服务命名与 systemd 单元

每个 exporter 对应一个唯一的 systemd 服务,命名规则为:

pg_exporter_<cluster>-<seq>

例如:

  • pg_exporter_pg-foo-1(监听 20001)
  • pg_exporter_pg-foo-2(监听 20002)

该命名在 tasks/main.yml 中显式构造:pg_exporter_unit: "pg_exporter_{{ item.value.pg_cluster }}-{{ item.value.pg_seq|string }}",并用于配置文件、环境变量文件与服务的统一命名。

systemd 单元模板(templates/pg_exporter.svc)体现了 Pigsty 对采集器资源的克制管理:

[Unit] Description= PG Exporter @ {{ pg_exporter_port }} for {{ pg_cluster }}-{{ pg_seq }}@{{ pg_host }}:{{ pg_port }} After=network.target [Service] EnvironmentFile=-/etc/default/{{ pg_exporter_unit }} User={{ pg_dbsu }} ExecStart=/usr/bin/pg_exporter $PG_EXPORTER_OPTS ExecReload=/usr/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=5 CPUQuota=10% #MemoryMax=200M [Install] WantedBy=multi-user.target

要点解读:

  • 以postgres(pg_dbsu)身份运行,配置目录/etc/pg_exporter权限为0750,环境文件权限0600,避免监控凭据泄露;
  • 默认通过PG_EXPORTER_OPTS指定--web.listen-address=:<port> --log.level=info(若设置pg_exporter_options则整体替换);
  • CPUQuota=10%限定 CPU 占用上限,防止采集对监控节点造成冲击;
  • 进程异常退出时Restart=on-failure自动拉起,ExecReload支持 SIGHUP 平滑重载配置。

部署任务(tasks/pg_exporter.yml)执行顺序为:创建/etc/pg_exporter目录 → 渲染或拷贝pg_exporter.yml采集配置 → 渲染pg_exporter.env环境文件 → 渲染 systemd 单元 →systemctl daemon-reload并重启服务 →wait_for等待本地端口在线(超时 10 秒)。

九、注册到监控栈:VictoriaMetrics 与 Grafana

1. 注册为 VictoriaMetrics 抓取目标(add_metrics)

tasks/main.yml 第二部分会按集群聚合所有条目,在 infra 节点生成/infra/targets/pgrds/<cluster>.yml:

# PGRDS: remote postgres service for pg-foo - labels: { cls: pg-foo, ins: pg-foo-1, ip: 10.10.10.10 } targets: [ 10.10.10.10:20001 ] - labels: { cls: pg-foo, ins: pg-foo-2, ip: 10.10.10.11 } targets: [ 10.10.10.10:20002 ]

每个 target 带有cls(集群)、ins(实例)、ip(远端地址)标签,与 Pigsty 本地监控的标签体系保持一致,从而复用现有的pgsql系列 Grafana 面板与告警规则。文件属主victoria:infra、权限0640。

2. 注册 Grafana PostgreSQL 数据源(add_ds)

当条目声明了pg_databases(如[{ name: test }])时,角色会为每个数据库在全部 infra 节点上注册一个 Grafana 数据源,数据源名称格式为<cluster>-<seq>.<database>(如pg-polar-1.test)。

数据源 JSON 由 tasks/register_grafana_db.yml 生成,关键字段包括:type: postgres、access: proxy、url: <pg_host>:<pg_port>、监控账号与密码,以及连接池与sslmode: require等jsonData。随后通过 Grafana HTTP API 完成 upsert:

curl -X DELETE "http://127.0.0.1:{{ gf_port }}/ui/api/datasources/name/{{ ds_name }}" -u "{{ gf_user }}:{{ gf_pass }}" curl -X POST "http://127.0.0.1:{{ gf_port }}/ui/api/datasources/" -u "{{ gf_user }}:{{ gf_pass }}" -H 'Content-Type: application/json' -d @/infra/datasources/{{ ds_name }}.json

该任务delegate_to每个 infra 节点并ignore_errors: true,即使 Grafana API 暂不可用也不会中断整体流程。pg_databases条目还支持register_datasource: false显式跳过注册。

十、采集器配置深度解析

默认采集配置由 templates/pg_exporter.yml 渲染(源文件是 2500+ 行的采集器定义,兼容 PostgreSQL 10~19+ 与 pgbouncer)。它本质上是"采集指标定义文件",每个 metric 块由 SQL 查询 + 指标元数据构成,例如基础状态采集(区分主库与备库,分别执行):

pg_primary_only: name: pg desc: PostgreSQL basic information (on primary) query: |- SELECT extract(EPOCH FROM CURRENT_TIMESTAMP) AS timestamp, extract(EPOCH FROM now() - pg_postmaster_start_time()) AS uptime, pg_current_wal_lsn() - '0/0' AS lsn, ... pg_is_in_recovery() AS is_in_recovery; tags: [ cluster, primary ] ttl: {{ ttl_fast }} min_version: 100000 fatal: true metrics: - timestamp: { usage: GAUGE , description: current database timestamp in unix epoch } - uptime: { usage: GAUGE , description: seconds since postmaster start } - lsn: { usage: COUNTER , description: log sequence number, current write location } ...

几个值得注意的设计:

  • 版本自适应:min_version/max_version字段让同一个指标名在不同 PG 大版本上执行不同的查询(如pg_meta_13/pg_meta_10、pg_repl_12/pg_repl_10、pg_slot_17/pg_slot_10等),兼容性由配置层解决;
  • TTL 分级:ttl: {{ ttl_fast/norm/slow/slowest }}控制各类指标刷新频率,开销大的查询(如pg_size遍历目录)使用慢档;
  • 指标类型:usage字段区分GAUGE、COUNTER、LABEL,其中LABEL用于把集群元数据(如cluster_name、version)作为标签注入序列;
  • 内置跳过项:pg_origin默认skip: true,需要额外授权才启用;pg_stat_statements相关指标依赖监控 schema 中创建该扩展。

由于采集 SQL 全部在远端执行,远程监控获得的指标覆盖面与本地监控的pg_exporter一致,这是远程方案信息密度不减的关键原因。

十一、能力边界与限制

远程监控与本地监控的能力对比如下(摘自 README):

功能本地监控远程监控
PostgreSQL 指标✓✓
Node 指标✓✗
pgBouncer 指标✓✗
Patroni 指标✓✗
HAProxy 指标✓✗
日志采集✓✗

决策建议:对于仍可安装 Agent 的自主部署 PostgreSQL,优先使用本地 pg_monitor 获得完整观测;pg_exporters适用于无法部署 Agent、但开放数据库端口的托管实例,作为统一可观测性拼图上的最后一环。

十二、参考

  • 角色文档:roles/pg_exporters/README.md
  • 默认变量:roles/pg_exporters/defaults/main.yml
  • 任务实现:roles/pg_exporters/tasks/main.yml、roles/pg_exporters/tasks/pg_exporter.yml、roles/pg_exporters/tasks/register_grafana_db.yml
  • 模板:roles/pg_exporters/templates/pg_exporter.env、roles/pg_exporters/templates/pg_exporter.svc、roles/pg_exporters/templates/pg_exporter.yml
  • Playbook:pgsql-monitor.yml
  • 配置示例:conf/demo/remote.yml
  • 关联角色:本地监控 pg_monitor 与基础设施监控 infra
  • 数据库
  • 运维
  • 云原生
  • 高可用
  • 监控

【免费下载链接】pigsty

Enterprise-Grade OSS PostgreSQL Distribution with HA, PITR, IaC, Monitor, 12 kernel forks and 575 PG extensions. Best-of-breed products integrated as a platform. Self-host Postgres like a Pro!

项目地址:https://gitcode.com/GitHub_Trending/pi/pigsty
点击查看免费下载

相关推荐

上一篇:终极指南:如何用Arduino HID库从零打造专业级USB输入设备
下一篇:为什么顶级iOS应用都在用OBShapedButton?非矩形按钮技术深度解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询