别再凭峰值拍脑袋:用 gcache-inspector 为 Galera/PXC 精确规划写集缓存

2026-08-19 49 预计阅读时间: 1 分钟
来源: percona.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

Galera Cluster 和 Percona XtraDB Cluster(PXC)通常按高峰期写入量估算 gcache.size。这个方法能给出起点,却容易忽略写集大小分布、突发事务以及节点实际能保留的序列号范围。结果往往是:配置看起来足够,维护稍微超时,节点仍然无法进行增量状态传输(IST),只能执行耗时更长的全量状态传输(SST)。

gcache-inspector 的价值在于把猜测变成检查:分析已有 gcache 中的写集,观察缓存覆盖范围和写集特征,再据此决定容量与维护窗口。

gcache 真正要覆盖的是维护窗口

节点短暂离开集群后,如果缺失的写集仍然保存在其他节点的 gcache 中,就有机会通过 IST 追平;如果所需写集已经被覆盖,只能走 SST。后者通常需要复制更多数据,也会给仍在提供服务的节点增加磁盘、网络和计算压力。

因此,容量规划的核心问题不是“数据库每小时写入多少业务数据”,而是:

在节点离线的最长时间内,供体节点需要保留多少 Galera 写集字节?

可以先用下面的近似公式建立预算:

目标 gcache 容量
  = 峰值写集字节速率 × 最长离线秒数 × 安全系数

例如,峰值写集速率为 18 MiB/s,计划允许节点离线 30 分钟,安全系数取 1.5:

18 MiB/s × 1800 s × 1.5 ≈ 48.6 GiB

这只是预算,不是最终答案。平均吞吐会掩盖短时尖峰,大事务也可能显著改变写集分布。gcache-inspector 应当用于核对缓存里实际存在的内容,而不是仅凭业务表增长量推导。

先采集运行状态,再检查 gcache 副本

在调整配置前,可以从每个节点采集 Galera 状态。以下脚本可直接改造;先设置数据库连接参数,再运行:

#!/usr/bin/env bash
set -euo pipefail

MYSQL_HOST=${MYSQL_HOST:-127.0.0.1}
MYSQL_PORT=${MYSQL_PORT:-3306}
MYSQL_USER=${MYSQL_USER:-root}

mysql \
  --host="$MYSQL_HOST" \
  --port="$MYSQL_PORT" \
  --user="$MYSQL_USER" \
  --password \
  --batch --skip-column-names \
  --execute="
    SHOW GLOBAL STATUS
    WHERE Variable_name IN (
      'wsrep_cluster_size',
      'wsrep_cluster_status',
      'wsrep_local_state_comment',
      'wsrep_ready',
      'wsrep_last_committed',
      'wsrep_local_cached_downto',
      'wsrep_replicated',
      'wsrep_replicated_bytes',
      'wsrep_received',
      'wsrep_received_bytes'
    )
    ORDER BY Variable_name;
  "

其中,wsrep_last_committedwsrep_local_cached_downto 可以帮助理解当前节点大致覆盖的序列号区间;字节计数器则适合按固定间隔采样,计算复制流量速率。不同 Galera/PXC 版本暴露的状态变量可能不同,脚本没有返回某一项时,应先运行 SHOW GLOBAL STATUS LIKE 'wsrep%'; 核对。

检查 gcache 时,不要默认分析工具可以安全读取一个正在被数据库持续修改的文件。更稳妥的做法是使用停机节点上的文件、快照或副本,除非当前工具版本明确说明支持在线读取。

下面给出一个可改造的检查流程。gcache 文件路径和 CLI 参数可能随安装方式、工具版本而变化,因此先查看帮助,不要直接套用未经确认的参数:

#!/usr/bin/env bash
set -euo pipefail

INSPECTOR=${INSPECTOR:-gcache-inspector}
GCACHE_FILE=${GCACHE_FILE:-/var/lib/mysql/galera.cache}
WORK_DIR=${WORK_DIR:-/srv/gcache-analysis}

command -v "$INSPECTOR" >/dev/null || {
  echo "找不到 $INSPECTOR,请先安装并把它加入 PATH" >&2
  exit 1
}

mkdir -p "$WORK_DIR"

# 先确认当前版本支持的参数和输入格式。
"$INSPECTOR" --help

# 建议从已停止的节点、存储快照或一致性副本中取得文件。
# 如果源文件仍在写入,不应把普通 cp 当成一致性快照。
cp --reflink=auto "$GCACHE_FILE" "$WORK_DIR/galera.cache.copy"

echo "待分析副本:$WORK_DIR/galera.cache.copy"
echo "请根据上方 --help 给出的语法检查该副本。"

分析报告时,重点关注工具当前版本能够提供的这些维度:

  • gcache 实际覆盖的序列号范围;
  • 写集大小的平均值、分位数和最大值;
  • 是否存在少量超大写集拉高容量需求;
  • 在高峰时段,缓存可覆盖多少分钟的复制流量;
  • 维护窗口结束时,是否仍保有节点恢复所需的最早写集。

不要只看平均写集大小。容量规划更应该参考高分位值、最坏维护时长,以及业务是否会周期性执行批量更新或大事务。

用一个可运行的计算器形成容量下限

下面的 Python 脚本根据观测到的写集速率、离线时间和安全系数计算建议下限。它不代替 gcache-inspector,但适合把检查结果转化为配置预算。

保存为 size_gcache.py

#!/usr/bin/env python3
import argparse

MIB = 1024 ** 2
GIB = 1024 ** 3

parser = argparse.ArgumentParser(
    description="Estimate a Galera gcache capacity floor"
)
parser.add_argument(
    "--rate-mib-s",
    type=float,
    required=True,
    help="Observed peak or high-percentile writeset rate in MiB/s",
)
parser.add_argument(
    "--offline-minutes",
    type=float,
    required=True,
    help="Maximum planned node downtime in minutes",
)
parser.add_argument(
    "--safety-factor",
    type=float,
    default=1.5,
    help="Headroom multiplier; default: 1.5",
)
args = parser.parse_args()

if args.rate_mib_s <= 0 or args.offline_minutes <= 0:
    parser.error("rate and offline duration must be positive")
if args.safety_factor < 1:
    parser.error("safety factor should be at least 1")

required_bytes = (
    args.rate_mib_s
    * MIB
    * args.offline_minutes
    * 60
    * args.safety_factor
)

print(f"Estimated capacity floor: {required_bytes / GIB:.2f} GiB")
print("Round up, then verify disk space and test an actual IST scenario.")

运行示例:

python3 size_gcache.py \
  --rate-mib-s 18 \
  --offline-minutes 30 \
  --safety-factor 1.5

预期结果约为:

Estimated capacity floor: 47.46 GiB
Round up, then verify disk space and test an actual IST scenario.

这里应输入高峰值或较高分位的写集字节速率,而不是数据库文件的增长速度。实际环境还应把维护超时、流量突增和观测误差算进安全余量。

修改配置时别覆盖其他 wsrep_provider_options

得到目标容量后,可以在 MySQL 配置中设置 gcache。例如:

[mysqld]
wsrep_provider_options="gcache.size=50G;gcache.recover=yes"

应用前要检查现有的 wsrep_provider_options。这个配置项可能已经包含其他 Galera 参数,直接替换整行会意外删除它们。应把新的键值合并进去,并在与当前 PXC/Galera 版本兼容的前提下使用 gcache.recover

还要确认以下边界:

  • 数据目录或 gcache 所在文件系统有足够空间;
  • 扩大 gcache 不会挤压数据库数据、临时文件和日志空间;
  • 每个潜在供体节点都具有合理的缓存容量,而不是只调整一个节点;
  • 维护测试确实触发 IST,并记录离线时长、追赶时间和资源占用;
  • SST 流程仍然可用,因为再大的 gcache 也不能保证覆盖无限离线时间。

建议的落地顺序

先连续采样 wsrep_replicated_byteswsrep_received_bytes,覆盖正常高峰、批处理和备份时段;随后用 gcache-inspector 检查一致性副本,核对写集范围与大小分布。基于高分位速率和最长维护窗口计算容量,再留出可解释的安全系数。

配置上线后,安排一次受控节点重启或维护演练,确认节点通过 IST 返回集群。真正可靠的 gcache 规划,不是得到一个看起来足够大的数字,而是证明它能够覆盖你的维护窗口,同时不会把磁盘空间变成新的故障源。


相关推荐