162 张表,一张都不多余
PmaControl 不是一个简单的仪表盘。它是一个分布式系统,实时采集、存储、转换和展示来自数百台 MariaDB / MySQL 服务器的指标。内部数据库包含 162 张表 — 每张表在数据管道中都有精确的角色。
本文详细介绍其内部架构:四个主要组件(Aspirateur、Listener、Dot3、Schema),端到端的数据流,负责编排一切的 cron 任务,以及调试或扩展系统时需要了解的关键表。
四大支柱
Aspirateur:数据采集器
Aspirateur 是从每台受监控服务器获取指标的组件。其运作方式简单但高效:
- 它通过 SSH(隧道)连接到服务器,然后建立本地 MySQL 连接
- 它执行一系列查询:
SHOW GLOBAL STATUS、SHOW GLOBAL VARIABLES、SHOW SLAVE STATUS、SHOW PROCESSLIST、performance_schema查询等 - 它将结果写入 PmaControl 数据库的
ts_value_*(时间序列)表中
ts_ 前缀随处可见:它代表 time series(时间序列)。每个指标都带有时间戳和源服务器标识符进行存储。
Aspirateur → SSH 隧道 → 本地 MySQL
→ SHOW GLOBAL STATUS
→ SHOW SLAVE STATUS
→ performance_schema 查询
→ INSERT INTO ts_value_general_int (...)
→ INSERT INTO ts_value_general_json (...)
Aspirateur 不做任何处理。它只负责采集和写入。这是一个基本设计原则:将采集与处理分离,使它们可以独立扩展。
Listener:后处理引擎
Listener 是 PmaControl 的大脑。它监控时间序列表,并在新数据到达时触发操作。其机制依赖一张枢纽表:listener_main。
listener_main 表包含:
| 列 | 角色 |
|---|---|
ts_file |
数据源文件 |
ts_max_date |
最后处理的时间戳 |
ts_date_by_server |
每台服务器的最后时间戳 |
Listener 在一个持续循环中运行。每次迭代时,它将记录的 ts_max_date 与 ts_value_* 表中最新的时间戳进行比较。如果检测到差异,说明 Aspirateur 已写入新数据 — Listener 随即触发后处理链:
Listener 循环:
1. 检查 ts_max_date 与实际 max(timestamp)
2. 如果有变化 → 触发管道:
a. updateDatabase() — 更新服务器元数据
b. afterUpdateVariable() — 触发条件规则
c. Digest::integrate() — 聚合 performance_schema 指标
d. Alias::updateAlias() — 刷新 DNS 别名
updateDatabase() 同步基本信息:服务器版本、复制状态、数据库大小、活跃连接数。
afterUpdateVariable() 是规则引擎。它将新值与配置的阈值进行比较,必要时生成告警。例如,如果 Seconds_Behind_Master 超过 60,则创建一个 Warning 告警。
Digest::integrate() 处理 performance_schema 数据。它聚合查询统计信息(执行时间、扫描行数、频率)并存储到 PmaControl 的 digest 表中。这为性能仪表盘提供数据。
Alias::updateAlias() 维护 alias_dns 表,该表将友好名称映射到实际 IP 地址。这是最大的表之一:110 万行,85 MB 数据。别名在整个界面中使用,显示可读名称而非 IP 地址。
Dot3:实时拓扑
Dot3 是拓扑映射组件。它分析服务器之间的复制关系,并生成 DOT 格式(Graphviz)的有向图。
流程如下:
- Dot3 读取每台服务器的复制元数据(主从关系、GTID、通道)
- 它构建一个依赖图:谁是谁的主库,谁是谁的从库
- 它生成带有集群(相关服务器组)的可视化表示
涉及的表:
dot3_graph:完整的 DOT 图,可直接渲染dot3_cluster:服务器集群(一个集群 = 一个复制组)
Dot3 特别适用于检测损坏的拓扑:一个从库指向不存在的服务器、意外的环形复制回路,或一台本应属于某个集群却被隔离的服务器。
Schema:结构导出
Schema 组件导出每个受监控数据库的完整结构。对于每台服务器,它创建一个文件树:
data/model/<server_id>/databases/<db_name>/
├── schema/
│ └── tables/
│ ├── users.sql
│ ├── orders.sql
│ └── ...
├── routines/
│ ├── calculate_total.sql
│ └── ...
├── events/
│ ├── daily_cleanup.sql
│ └── ...
└── triggers/
├── before_insert_users.sql
└── ...
每个文件包含对应的 CREATE TABLE、CREATE PROCEDURE、CREATE EVENT 或 CREATE TRIGGER。这使得:
- 在 Git 中对结构进行版本控制(两次导出之间的 diff)
- 比较生产环境和预发布环境的结构
- 检测 Schema 漂移(在生产环境手动添加的索引、未经迁移修改的列)
Glial CLI
PmaControl 基于 Glial 框架构建,该框架提供标准化的命令行接口:
./glial <controller> <action> [params]
具体示例:
# 检查守护进程状态
./glial agent check_daemon
# 强制执行一次采集周期
./glial control service
# 导出服务器的 Schema
./glial schema export 42
# 重新生成拓扑
./glial dot3 generate
CLI 既用于手动操作(调试、维护),也被 cron 任务用于自动编排。
Cron 任务:编排引擎
三个关键的 cron 任务保持 PmaControl 运行:
1. ./glial agent check_daemon — 每分钟
这是最频繁的 cron 任务。它检查所有代理进程是否存活,必要时重启它们。一个死掉的代理意味着数据缺口 — 这个 cron 确保采集连续性。
* * * * * cd /srv/www/pmacontrol && ./glial agent check_daemon >> /tmp/pmacontrol_agent.log 2>&1
如果一个代理在 3 次尝试后仍无响应,将发送 Telegram 告警。
2. ./glial control service — 每 4 小时
这个 cron 执行繁重的维护任务:
- 重新计算每日聚合
- 清理过期数据(可配置的保留策略)
- 重新生成 Dot3 拓扑
- 同步服务器元数据
- 表间一致性检查
4 小时是数据新鲜度和负载之间的良好折中:这些操作开销较大,不需要实时执行。
0 */4 * * * cd /srv/www/pmacontrol && ./glial control service >> /tmp/pmacontrol_control.log 2>&1
3. ./monitor_mysql.sh — 每分钟
这个脚本是 Aspirateur 的入口点。它触发一个完整的采集周期:
* * * * * cd /srv/www/pmacontrol && ./monitor_mysql.sh >> /tmp/pmacontrol_monitor.log 2>&1
该脚本处理并行化:如果你监控 200 台服务器,它不会逐一联系它们。它将工作分配到并行批次中,工作线程数可配置。
关键表
以下是理解或调试 PmaControl 需要了解的最重要的表:
mysql_server
核心表。每行代表一个受监控的实例 — 不仅仅是 MariaDB / MySQL 服务器,还包括:
- MariaDB / MySQL 服务器(主要用例)
- 代理:MaxScale、ProxySQL、HAProxy
- VIP(虚拟 IP)
is_proxy 和 is_vip 列区分类型:
is_proxy |
is_vip |
类型 |
|---|---|---|
| 0 | 0 | 普通 MariaDB / MySQL 服务器 |
| 1 | 0 | 代理(MaxScale、ProxySQL、HAProxy) |
| 0 | 1 | VIP(虚拟 IP) |
-- 仅 MariaDB/MySQL 服务器
SELECT id, ip, port, name, display_name, id_environment
FROM mysql_server
WHERE is_deleted = 0 AND is_proxy = 0 AND is_vip = 0;
-- 代理(MaxScale、ProxySQL、HAProxy)
SELECT id, ip, port, name, display_name
FROM mysql_server
WHERE is_deleted = 0 AND is_proxy = 1;
-- VIP
SELECT id, ip, port, name, display_name
FROM mysql_server
WHERE is_deleted = 0 AND is_vip = 1;
代理和 VIP 与 MySQL 服务器存储在同一张表中,以简化 JOIN 和拓扑。Dot3 使用它们来绘制网络层之间的连接(VIP → 代理 → 主库 → 从库)。timeout 列是动态计算的:代理 11 秒(因为它们对检查的响应较慢),普通服务器 1 秒。
专用表补充代理特定的详细信息:
maxscale_server/maxscale_server__mysql_server— MaxScale 配置及其后端proxysql_server— ProxySQL 配置haproxy_main/haproxy_main_input/haproxy_main_output/link__haproxy_main_output__mysql_server— HAProxy 配置(监听器、前端、后端)vip_server— VIP 详情
ts_variable
指标字典。每个采集的变量(例如 Threads_connected、Innodb_buffer_pool_pages_data)在此表中都有一条记录及其数字标识符。
SELECT id, name, source
FROM ts_variable
WHERE name LIKE 'Innodb%';
ts_value_general_int
数值指标的主存储。这是最大的表 — 每秒接收数千次插入,在最大的 PmaControl 部署中每天可达数十亿行。
SELECT server_id, variable_id, value, timestamp
FROM ts_value_general_int
WHERE server_id = 42
AND variable_id = 107 -- Threads_connected
AND timestamp > NOW() - INTERVAL 1 HOUR;
此表按天分区,以便快速清理旧数据(ALTER TABLE ... DROP PARTITION)。
ts_value_general_json
用于无法用整数表示的复杂指标:SHOW PROCESSLIST 结果、performance_schema 表(查询摘要、锁、表 I/O)、SHOW ENGINE INNODB STATUS 等。JSON 格式允许存储任意结构。复制指标(SHOW SLAVE STATUS)有其专用表(ts_value_slave_*)。
alias_dns
DNS 别名表 — 110 万行,85 MB。它将 IP 地址映射到可读名称,在整个界面中使用。
SELECT ip, alias, source, updated_at
FROM alias_dns
WHERE ip = '10.0.1.42';
dot3_graph 和 dot3_cluster
拓扑表。dot3_graph 包含完整的 DOT 图,dot3_cluster 包含逻辑服务器组。
完整数据流
让我们回顾一个指标从源到屏幕的旅程:
| 步骤 | 组件 | 操作 |
|---|---|---|
| 1 | CRON monitor_mysql.sh(每分钟) |
启动 Aspirateur |
| 2 | ASPIRATEUR | SSH 隧道 → MySQL → SHOW GLOBAL STATUS |
写入 ts_value_general_int / ts_value_general_json |
||
| 3 | LISTENER(检测到 ts_max_date 变化) |
updateDatabase() — 更新服务器元数据 |
afterUpdateVariable() — 阈值超标时告警 |
||
Digest::integrate() — 聚合 performance_schema |
||
Alias::updateAlias() — 刷新 alias_dns |
||
| 4 | DOT3(约每 3 秒循环) | 实时重新生成复制拓扑 |
| 5 | CRON control service(每 4 小时) |
每日清理和聚合 |
| 6 | WEB 界面 | 读取聚合表 → 仪表盘、图表、拓扑 |
容量规划
对于典型的 100 台 MariaDB / MySQL 服务器部署:
- PmaControl 数据库:约 15 GB 数据(以
ts_value_*表为主) - CPU:2-4 核即可(Listener 消耗最大)
- RAM:最低 4 GB,建议 8 GB(用于 PmaControl 数据库自身的 buffer pool)
- 磁盘:必须使用 SSD — 时间序列表产生大量随机 I/O
ts_value_* 表推荐使用 RocksDB(通过 MyRocks)作为存储引擎:更好的压缩、更好的顺序写入性能,以及原生的按天分区。
调试指南
当出现问题时,以下是检查清单:
- 代理是否在运行?
./glial agent check_daemon— 如果代理死了,它管理的服务器将不再采集数据 - Listener 是否在运行? 检查
listener_main中的ts_max_date— 如果不再推进,说明 Listener 卡住了 - cron 任务是否在执行? 检查
/tmp/pmacontrol_*.log中是否有错误 - SSH 连接是否正常? 使用配置的密钥手动测试
ssh -p <port> <user>@<host> - PmaControl 数据库是否健康? 检查 PmaControl 数据库自身的磁盘空间、锁、慢查询
总结
PmaControl 的架构遵循经典的 ETL(提取-转换-加载)模型,适配于监控场景:
- 提取(Extract):Aspirateur 只采集不处理
- 转换(Transform):Listener 应用规则并聚合
- 加载(Load):仪表盘读取转换后的数据
162 张表不是偶然的复杂性 — 它们反映了从每台 MariaDB / MySQL 服务器采集的数据的丰富性。理解这套架构对于任何想要调试采集问题、为 PmaControl 扩展新指标类型或优化监控系统自身性能的人来说都至关重要。
评论 (0)
暂无评论。
发表评论