Percona XtraDB Cluster (PXC) 面试题
30 道题- 分类
- 数据库
- 子分类
- mysql
- 题目数
- 30 道
1 PXC 的架构与 Galera 同步复制原理
答案:
PXC 基于 Galera Replication 插件实现多主同步复制,集群中每个节点均可读写,事务在提交前通过写集合(Write-Set)在所有节点间进行认证,确保数据强一致性。
[分层展开]
- 多主架构:每个节点拥有完整数据副本,任意节点可接受读写请求,无需主从切换
- 同步复制:事务在源节点执行到 commit 阶段时,将写集合广播至集群内所有节点进行认证,认证通过后源节点提交,其余节点异步 apply
- 虚拟同步:Galera 的同步指认证阶段的同步(certification-based replication),非 2PC 意义上的同步提交,实际 apply 与应用 relay log 类似
- 数据路径:客户端 -> MySQL Server 层 -> InnoDB 事务 -> wsrep API -> Galera Replication Plugin -> gcomm 后端(Group Communication)-> 网络广播
- 认证机制:每个写集合携带全局事务 ID(Global Transaction ID, GTID),各节点在 certification index 中检查冲突,无冲突则 apply,有冲突则回滚本地事务
+------------------+ Write-Set +------------------+
| Node 1 (PXC) | <---------------------> | Node 2 (PXC) |
| MySQL + Galera | | MySQL + Galera |
| + wsrep Provider| | + wsrep Provider|
+--------+---------+ +--------+---------+
| |
| Group Communication (gcomm) |
+--------------------------------------------+
|
+------------------+
| Node 3 (PXC) |
| MySQL + Galera |
| + wsrep Provider|
+------------------+
核心组件:
| 组件 | 作用 |
|---|---|
| wsrep API | MySQL/Galera 接口层,拦截事务并提取写集合 |
| Galera Replication Plugin | 写集合认证、复制、apply |
| gcomm / gcs | Group Communication System,组成员通信与消息排序 |
| gcache | 写集合缓存,用于 IST 增量同步 |
2 PXC 的流控(Flow Control)机制
答案:
PXC 流控通过调节各节点的写入速率,防止慢节点因 apply 速度跟不上而被写集合队列淹没,避免队列过长导致事务延迟急剧上升或节点从集群中被驱逐。
[分层展开]
- 触发条件:节点 receive queue 中等待 apply 的写集合数量超过
gcs.fc_limit(默认 16),或队列大小超过gcs.fc_factor(默认 1.0)倍的平均队列 - 流控信号:触发流控的节点向集群广播 FC_PAUSE 消息,集群内所有节点暂停发送新事务,直到 FC_RESUME 消息到达
- 关键参数:
wsrep_slave_threads:apply 线程数,增大可加快 apply 速度,降低流控频率gcs.fc_limit:流控队列阈值,调大可容忍更大延迟但可能增加 apply 积压gcs.fc_factor:动态流控因子,控制流控灵敏度gcs.fc_master_slave:启用后仅主节点(写入节点)响应流控
- 监控指标:
wsrep_flow_control_paused_ns反映流控暂停累计时间,wsrep_flow_control_recv记录接收到的流控事件数
-- 查看流控状态
SHOW STATUS LIKE 'wsrep_flow_control%';
-- 查看接收队列长度
SHOW STATUS LIKE 'wsrep_local_recv_queue%';
-- 调整流控参数(运行时)
SET GLOBAL wsrep_slave_threads = 4;
优化方向:提高磁盘 I/O 性能、增加 wsrep_slave_threads、升级硬件以降低 apply 延迟、使用更低延迟的网络。
3 PXC 的节点状态与集群视图
答案:
PXC 节点在生命周期中经历多个状态转换,通过 wsrep_local_state_comment 和 wsrep_cluster_status 反映当前节点及集群的整体健康状态。
[分层展开]
节点状态(wsrep_local_state_comment):
| 状态 | 值 | 说明 |
|---|---|---|
| Joining | 1 | 节点正在加入集群,处于 SST/IST 阶段 |
| Donor/Desynced | 2 | 节点作为 SST 数据源,不接受客户端请求 |
| Joined | 3 | 节点已完成数据同步,但尚未完成最终校验 |
| Synced | 4 | 节点完全正常运行,可接受读写 |
集群状态(wsrep_cluster_status):
| 状态 | 说明 |
|---|---|
| Primary | 集群正常,存在仲裁多数派(quorum) |
| Non-Primary | 集群分裂或节点数不足,无法形成仲裁,拒绝所有写操作 |
关键监控变量:
-- 查看节点完整 wsrep 状态
SHOW GLOBAL STATUS LIKE 'wsrep%';
-- 关键字段
-- wsrep_cluster_state_uuid : 集群唯一标识
-- wsrep_cluster_size : 集群当前节点数
-- wsrep_cluster_status : Primary / Non-Primary
-- wsrep_local_state_comment : Synced / Donor / Joining
-- wsrep_ready : ON 表示节点可接受查询
-- wsrep_connected : ON 表示与集群通信正常
集群视图(Cluster View):每一次成员变更(节点加入或离开)都会生成新的视图 ID(view ID),所有节点对该视图达成一致后,事务可以继续在新视图下进行。
4 PXC 的 SST(State Snapshot Transfer)vs IST(Incremental State Transfer)
答案:
SST 是节点的全量数据同步方式,将 Donor 节点的完整数据快照传输给 Joiner;IST 是增量同步方式,仅传输 Joiner 缺失的那部分写集合缓存数据。
[分层展开]
对比:
| 维度 | SST | IST |
|---|---|---|
| 数据量 | 全量数据集 | 仅缺失的增量写集合 |
| 适用场景 | 新节点加入、数据差异过大 | 节点短暂断开后重连 |
| 触发条件 | gcache 中无 Joiner 缺失的 seqno | gcache 中存在 Joiner 缺失的全部 seqno |
| 性能影响 | 大,Donor 进入 Desynced 状态 | 小,增量数据量通常有限 |
| 传输方式 | xtrabackup / mysqldump / rsync | 直接从 gcache 环形缓冲区读取 |
| 耗时 | 分钟至小时级(取决于数据量) | 秒至分钟级 |
| Donor 负载 | 高,需全量导出 | 低,仅需读取 gcache |
SST 方法:
| 方法 | 特点 |
|---|---|
| xtrabackup | 物理备份,速度快,Donor 端非阻塞,推荐 |
| xtrabackup-v2 | xtrabackup 的增强版,支持 GTID |
| mysqldump | 逻辑备份,速度慢,Donor 端阻塞,仅适合小型库 |
| rsync | 直接文件复制,最快但要求同版本二进制 |
| clone | MySQL 8.0 clone 插件,物理克隆,速度快 |
# my.cnf 配置 SST
[mysqld]
wsrep_sst_method = xtrabackup-v2
wsrep_sst_auth = "sstuser:sstpassword"
适用场景:IST 优先,SST 作为 IST 不可用时的回退方案。生产环境配置 gcache.size 足够大以覆盖绝大多数节点重连场景。
5 PXC 的 gcache 机制与作用
答案:
gcache 是 PXC 节点内存中的写集合环形缓冲区,缓存最近写入的写集合数据,用于 IST 增量同步,避免短时断开后的全量 SST。
[分层展开]
- 结构:gcache 由固定大小的环形缓冲区(ring buffer)构成,文件映射形式存储在磁盘上
- 核心参数:
gcache.size:gcache 总大小,决定可缓存多少写集合gcache.page_size:page 文件大小,gcache 溢出到磁盘时的分页单元gcache.keep_pages_size:可保留在内存中的 page 总量
- 淘汰策略:新写集合写入时,最旧的写集合被覆盖,循环使用缓冲空间
- IST 依赖:Joiner 所需的 seqno 必须在 gcache 范围内,否则回退到 SST
- 大小估算:
# gcache.size = (每小时写入量 × 最大允许停机时间) / 压缩比
# 示例:100GB/h 写入,允许停机 2h,压缩比 3:1
# gcache.size ≈ 200GB / 3 ≈ 67GB
[mysqld]
wsrep_provider_options = "gcache.size=2G;gcache.page_size=128M"
调优建议:生产环境 gcache.size 设置为覆盖至少 2-4 小时写入量,使用 SSD 存储 gcache.page 文件以降低磁盘 I/O 瓶颈。
6 PXC 的写集合(Write-Set)认证与复制
答案:
PXC 在事务提交前,将事务所涉及的行级变更封装为写集合,广播至集群中所有节点进行冲突检测(certification),认证通过后源节点提交,其余节点异步 apply。
[分层展开]
- 写集合生成:wsrep API 拦截 InnoDB 事务的变更操作,提取每行的主键、旧值(before image)和新值(after image),构成写集合
- 广播与排序:gcomm 层使用基于全局序列号(seqno)的全序广播(total order broadcast)协议,确保所有节点以相同顺序接收写集合
- 认证过程:
- 目标节点将写集合中的主键与 certification index 中已认证但尚未 apply 的事务进行比对
- 若存在冲突(主键重合且写集合不兼容),目标事务被回滚并返回死锁错误
- 若无冲突,写集合插入 certification index,事务 apply 后从 index 中移除
- 冲突处理:客户端收到
ERROR 1213 (40001): Deadlock found when trying to get lock,业务层必须实现重试逻辑 - 乐观复制:先执行后认证(commit 前认证),区别于悲观锁的预检测机制
事务执行流程:
1. BEGIN
2. 执行 DML 语句(本地执行,InnoDB 写 undo/redo log)
3. COMMIT -> wsrep 拦截,提取写集合
4. 写集合广播至集群所有节点
5. 各节点并行认证(certification)
6. 认证通过 -> 源节点 commit + 其余节点 apply
7. 认证失败 -> 源节点 rollback + 返回死锁错误
适用场景:高冲突工作负载(如热点行更新)应谨慎评估 PXC 适用性,必要时将热点数据路由到同一节点写入。
7 PXC 在 Kubernetes 上的部署架构(Percona Operator)
答案:
Percona Operator for MySQL 将 PXC 部署为 Kubernetes StatefulSet,每个 Pod 包含 PXC 实例容器、ProxySQL/HAProxy sidecar、备份 sidecar 和 PMM 监控 agent,通过 CR 声明式管理集群生命周期。
[分层展开]
- Operator 架构:PerconaXtraDBCluster CRD -> Operator Controller -> StatefulSet / Service / ConfigMap / Secret / PVC
- 核心容器:
pxc:Percona XtraDB Cluster 主容器proxysql或haproxy:负载均衡 sidecar,提供集群入口backup:备份 sidecar,通过 xtrabackup 定期备份到 S3 兼容存储pmm-client:Percona Monitoring and Management agent
- 服务发现:Operator 自动创建 Headless Service 用于节点间通信,ClusterIP Service 供客户端连接
- 存储:每节点绑定独立的 PVC(PersistentVolumeClaim),StatefulSet 保证 Pod 重建后数据不丢
# PerconaXtraDBCluster CR 示例
apiVersion: pxc.percona.com/v1
kind: PerconaXtraDBCluster
metadata:
name: cluster1
spec:
crVersion: 1.15.0
pxc:
size: 3
image: percona/percona-xtradb-cluster:8.0
volumeSpec:
persistentVolumeClaim:
resources:
requests:
storage: 100Gi
proxysql:
size: 3
image: percona/percona-xtradb-cluster-operator:1.15.0-proxysql
backup:
image: percona/percona-xtradb-cluster-operator:1.15.0-pxc8.0-backup
storages:
s3-us-east:
type: s3
s3:
bucket: pxc-backups
region: us-east-1
节点流量路由:
Service (ClusterIP)
|
+------------+-----------+
| | |
ProxySQL-0 ProxySQL-1 ProxySQL-2
| | |
PXC Pod-0 PXC Pod-1 PXC Pod-2
(Writer) (Reader) (Reader)
\ | /
Galera Group Communication
8 PXC 的备份与恢复策略
答案:
PXC 备份以 xtrabackup 物理热备份为主,Percona Operator 内置定时备份调度并上传至 S3 兼容对象存储;恢复时从 S3 拉取备份,通过 SST 机制重建集群节点。
[分层展开]
备份方案:
| 工具 | 类型 | 特点 | 适用场景 |
|---|---|---|---|
| xtrabackup | 物理热备份 | 非阻塞、压缩、增量备份支持 | 生产首选 |
| mysqldump | 逻辑备份 | 阻塞、输出 SQL 文本、速度慢 | 小型库或逻辑迁移 |
| mysqlbackup | MySQL Enterprise | 物理备份、加密 | 企业版环境 |
| S3 对象存储 | 远程存储 | Operator 自动上传,支持定时调度 | K8s 环境 |
Operator 备份配置:
spec:
backup:
image: percona/percona-xtradb-cluster-operator:1.15.0-pxc8.0-backup
schedule:
- name: daily-backup
schedule: "0 2 * * *"
keep: 7
storageName: s3-us-east
storages:
s3-us-east:
type: s3
s3:
bucket: pxc-backups
region: us-east-1
恢复流程:
# 1. 从 S3 下载最新备份
# 2. 准备备份(apply-log)
xtrabackup --prepare --target-dir=/backup/
# 3. 启动新节点(自动触发 SST 加入集群)
# 4. 或通过 Operator 从备份恢复:
kubectl apply -f restore.yaml
# restore.yaml
apiVersion: pxc.percona.com/v1
kind: PerconaXtraDBClusterRestore
metadata:
name: restore-daily
spec:
pxcCluster: cluster1
backupName: daily-backup
RPO/RTO:定时备份频率决定 RPO(建议每日全备 + 每小时增量),SST 恢复时间决定 RTO(取决于数据量)。
9 PXC 的监控指标与 Prometheus 集成
答案:
PXC 原生暴露 Prometheus metrics 端点,通过 Percona Monitoring and Management(PMM)或直接 Prometheus 采集 wsrep 状态、MySQL 性能指标和 Galera 复制指标。
[分层展开]
核心监控指标分类:
| 类别 | 指标 | 说明 |
|---|---|---|
| 集群健康 | wsrep_cluster_size | 集群节点数 |
| 集群健康 | wsrep_cluster_status | Primary / Non-Primary |
| 节点状态 | wsrep_local_state | 4=Synced, 3=Joined, 2=Donor, 1=Joining |
| 节点状态 | wsrep_ready | 是否可接受查询 |
| 流控 | wsrep_flow_control_paused_ns | 累计流控暂停纳秒数 |
| 流控 | wsrep_flow_control_recv | 接收到的流控事件数 |
| 复制延迟 | wsrep_local_recv_queue | 本地接收队列大小 |
| 复制延迟 | wsrep_local_recv_queue_avg | 平均接收队列大小 |
| 复制延迟 | wsrep_apply_window | 认证与 apply 的时间窗口 |
| 冲突 | wsrep_local_bf_aborts | 本地因冲突被回滚的事务数 |
| 冲突 | wsrep_local_cert_failures | 本地认证失败次数 |
| 流量 | wsrep_received_bytes | 接收的 wsrep 数据量 |
| 流量 | wsrep_replicated_bytes | 发送的 wsrep 数据量 |
Prometheus 集成:
# ServiceMonitor 示例
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: pxc-monitor
spec:
selector:
matchLabels:
app.kubernetes.io/name: percona-xtradb-cluster
endpoints:
- port: metrics
interval: 30s
告警规则示例:
groups:
- name: pxc_alerts
rules:
- alert: PXCNodeNotSynced
expr: mysql_global_status_wsrep_local_state != 4
for: 2m
annotations:
summary: "PXC 节点 XQOPEN $labels.pod XQCLOSE 状态异常"
- alert: PXCClusterNonPrimary
expr: mysql_global_status_wsrep_cluster_status != 0
for: 1m
annotations:
summary: "PXC 集群进入 Non-Primary 状态"
- alert: PXCFlowControlPaused
expr: rate(mysql_global_status_wsrep_flow_control_paused_ns[5m]) > 0.1
for: 5m
annotations:
summary: "PXC 流控暂停比例过高"
10 PXC 与 ProxySQL 的集成
答案:
ProxySQL 作为 PXC 集群的智能负载均衡层,提供读写分离、连接池、查询路由、故障隔离和查询缓存能力,避免应用直接感知集群拓扑变化。
[分层展开]
- 读写分离:ProxySQL 通过
mysql_query_rules将读写请求分别路由到 Writer 组和 Reader 组 - 故障检测:ProxySQL 定期执行
mysql-monitor_galera_healthcheck脚本检测节点状态,自动将故障节点从路由表移除 - 连接池:ProxySQL 维护与后端 PXC 节点的连接池,减少连接开销,支持连接复用
- 查询缓存:对高频只读查询在 ProxySQL 层缓存结果
ProxySQL 核心配置表:
-- 定义后端 PXC 节点
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight, max_connections)
VALUES (10, 'pxc-node-0.pxc', 3306, 1, 1000),
(10, 'pxc-node-1.pxc', 3306, 1, 1000),
(10, 'pxc-node-2.pxc', 3306, 1, 1000);
-- 读写分离规则
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES (1, 1, '^SELECT.*', 10, 1), -- 读请求路由至 Reader 组
(2, 1, '^INSERT|^UPDATE|^DELETE', 10, 1); -- 写请求路由至 Writer 组
-- Galera 健康检查用户
SET mysql-monitor_username = 'monitor';
SET mysql-monitor_password = 'monitor_password';
SET mysql-monitor_galera_healthcheck = 1;
-- 加载配置到运行时
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL QUERY RULES TO DISK;
Percona Operator 集成:Operator 自动管理 ProxySQL 配置,节点变更时自动更新 mysql_servers 表,无需手动维护。
11 PXC 的 HAProxy vs ProxySQL 负载均衡对比
答案:
HAProxy 是 L4/L7 高性能反向代理,适合简单 TCP 负载均衡场景;ProxySQL 是数据库专用代理,提供查询路由、读写分离、连接缓存等数据库层智能。
[分层展开]
| 维度 | HAProxy | ProxySQL |
|---|---|---|
| 层级 | L4(TCP)/ L7(HTTP) | L7(MySQL Protocol) |
| 读写分离 | 需监听不同端口或健康检查脚本 | 原生支持,基于查询规则 |
| 连接池 | 不支持(TCP 透传) | 支持,可大幅降低后端起连压力 |
| 查询缓存 | 不支持 | 支持,可缓存高频只读查询 |
| 查询路由 | 仅支持端口/地址级路由 | 支持按 SQL 模式、用户、schema 匹配路由 |
| 延迟开销 | 极低(TCP 转发) | 略高(需解析 MySQL 协议) |
| 故障检测 | 基础 TCP 检查 | Galera 专用健康检查,感知节点状态 |
| 配置复杂度 | 低 | 中,管理表较多 |
| 适用场景 | 高吞吐、简单负载均衡 | 复杂路由、读写分离、连接池需求 |
选择建议:
- 高并发简单负载均衡场景:HAProxy
- 需要读写分离、连接池、查询路由:ProxySQL
- 同集群混合部署:HAProxy 作为外部入口,ProxySQL 作为内部智能路由
HAProxy 配置示例:
frontend pxc_frontend
bind *:3306
default_backend pxc_backend
backend pxc_backend
balance roundrobin
option httpchk GET /check
server pxc-node-0 pxc-node-0.svc:3306 check port 9200 inter 2s
server pxc-node-1 pxc-node-1.svc:3306 check port 9200 inter 2s
server pxc-node-2 pxc-node-2.svc:3306 check port 9200 inter 2s
12 PXC 的脑裂(Split-Brain)处理机制
答案:
PXC 基于权重仲裁(Weighted Quorum)防止脑裂:当集群分裂时,仅大多数节点分区可继续操作(Primary),少数分区自动降级为 Non-Primary 并拒绝所有写入。
[分层展开]
- 仲裁规则:每个节点拥有一个投票权重(pc.weight,默认 1),分区中权重之和 > 集群总权重的 50% 时该分区保持 Primary
- Non-Primary 行为:降级分区中的节点主动拒绝客户端写请求,返回
ERROR 1047 (08S01): Unknown command,确保数据一致性 - 网络分区恢复:分区恢复后,少数分区节点自动从多数分区获取增量数据(IST 优先)或全量数据(SST),重新加入集群
- 权重配置策略:
- 单数据中心 3 节点:各节点权重相等(1,1,1),任一节点可与其余构成多数
- 跨数据中心:主数据中心节点分配较高权重,确保主数据中心在分区中获取 Primary
# 在 my.cnf 中配置节点权重
[mysqld]
wsrep_provider_options = "pc.weight=2"
仲裁计算示例:
| 场景 | 节点数 | 总权重 | 多数要求 | 分区 A 权重 | 分区 B 权重 | 结果 |
|---|---|---|---|---|---|---|
| 3 节点等权 | 3 | 3 | >1.5 | 2 | 1 | A=Primary, B=Non-Primary |
| 5 节点等权 | 5 | 5 | >2.5 | 3 | 2 | A=Primary, B=Non-Primary |
| 跨 DC,4 节点 | 4 | 6 | >3 | 4 (DC1) | 2 (DC2) | DC1=Primary, DC2=Non-Primary |
13 PXC 的最小集群节点数与仲裁机制
答案:
PXC 最小部署为 3 个节点以保证高可用,两节点集群存在脑裂风险;仲裁机制通过节点投票确保仅多数派分区可为 Primary。
[分层展开]
- 最小节点数:奇数个节点(3、5、7 等)是最佳实践,避免平票问题
- 2 节点风险:任一节点故障导致剩余节点无法形成多数(50% 不构成多数),整个集群进入 Non-Primary
- 4 节点:可容忍 1 节点故障(3/4 > 50%),但无法容忍 2 节点同时故障(2/4 = 50%)
- 5 节点:可容忍 2 节点故障(3/5 > 50%)
- 仲裁机制(PC:Primary Component):
- 集群启动时运行 PC bootstrap 协议,确定主组件
- 主组件运行期间通过 weight-based quorum 维护
- 当主组件中节点故障导致权重不足,整个组件降级
-- 查看当前集群 views 和仲裁状态
SHOW STATUS LIKE 'wsrep_cluster_size';
SHOW STATUS LIKE 'wsrep_cluster_status';
SHOW STATUS LIKE 'wsrep_provider_name';
SHOW STATUS LIKE 'wsrep_provider_vendor';
Garbd 仲裁守护进程:可在独立轻量节点运行 garbd(Galera Arbitrator Daemon),仅参与投票不存储数据,避免 2 节点集群的平票问题,或为偶数节点集群提供"决胜票"。
# 启动 garbd
garbd --group=pxc_cluster --address="gcomm://10.0.0.1,10.0.0.2" \
--option="pc.weight=1"
14 PXC 的 2PC(两阶段提交)支持
答案:
PXC 通过 Galera 对 XA 事务的有限支持实现分布式两阶段提交,允许跨多个存储引擎执行原子事务,但受限于 Galera 的乐观复制模型,XA 事务在 PXC 中存在严格约束。
[分层展开]
- XA 事务流程:XA START -> DML 操作 -> XA END -> XA PREPARE -> XA COMMIT / XA ROLLBACK
- 约束:
- XA 事务跨越的存储引擎必须都支持 XA(InnoDB 原生支持)
- XA PREPARE 阶段引入额外写入放大(每个分支产生独立写集合)
- 认证发生在 XA COMMIT 阶段,而非 XA PREPARE
- 仅支持同一节点内跨引擎 XA,不支持跨节点分布式事务
- 写入放大:XA 事务在 prepare 阶段在每个参与节点产生写集合,导致 2 倍以上的网络开销
-- XA 事务示例
XA START 'xid1';
INSERT INTO orders VALUES (1, 'order_data');
INSERT INTO orders_archive VALUES (1, 'order_data');
XA END 'xid1';
XA PREPARE 'xid1';
XA COMMIT 'xid1';
适用场景:单节点内需要保证跨表原子操作的场景。跨节点分布式事务应使用应用层 Saga 模式或两阶段提交协调器,而非直接依赖 PXC 的 XA 支持。
15 PXC 的 DDL 复制方式(TOI/RSU)
答案:
PXC 提供两种 DDL 执行模式:TOI(Total Order Isolation)以全局顺序在所有节点同步执行 DDL,保证一致性;RSU(Rolling Schema Upgrade)仅在本地节点执行 DDL,适合在线 schema 变更。
[分层展开]
| 维度 | TOI(Total Order Isolation) | RSU(Rolling Schema Upgrade) |
|---|---|---|
| 执行范围 | 全局所有节点同步执行 | 仅本地节点执行 |
| 一致性 | DDL 执行期间阻塞所有 DML | DDL 执行期间本节点仍可执行 DML |
| 可用性 | DDL 期间集群全局暂停写入 | DDL 期间仅本节点写入暂停 |
| 适用场景 | 小表、快速 DDL | 大表在线 DDL、滚动升级 |
| 风险 | 长时间 DDL 导致集群全局不可写 | DDL 期间其他节点的 DML 可能产生冲突 |
| 控制方式 | 默认模式,wsrep_OSU_method=TOI | 需显式设置 wsrep_OSU_method=RSU |
操作示例:
-- TOI 模式(默认)
ALTER TABLE large_table ADD COLUMN new_col INT;
-- 全局所有节点同时执行,阻塞 DML 直到完成
-- RSU 模式
SET GLOBAL wsrep_OSU_method = 'RSU';
ALTER TABLE large_table ADD COLUMN new_col INT;
SET GLOBAL wsrep_OSU_method = 'TOI';
-- 仅本地节点执行,执行完成后逐节点重复操作
-- 检查当前模式
SHOW VARIABLES LIKE 'wsrep_OSU_method';
最佳实践:
- 小表 DDL(<1s):直接使用 TOI
- 大表 DDL:逐节点 RSU + 工具辅助(pt-online-schema-change、gh-ost)
- pt-online-schema-change 与 PXC 兼容,自动处理 TOI/RSU 切换
16 PXC 的 4 节点以上拓扑设计
答案:
4 节点以上 PXC 部署用于读扩展和跨机房容灾,关键设计包括写入节点收敛、读负载均衡策略、跨区域延迟控制和仲裁票数分配。
[分层展开]
拓扑模型:
+----------+ +----------+
| PXC-1 | | PXC-2 |
| (DC1-R1) | | (DC1-R2) |
+----+-----+ +-----+----+
| |
| Galera Replication |
+----------+----------+----------+----------+
| | | | |
+----+----+ +---+----+ +---+----+ +---+----+
| PXC-3 | | PXC-4 | | PXC-5 | | PXC-6 |
| DC2-R1 | | DC2-R2 | | DC3-R1 | | DC3-R2 |
+---------+ +--------+ +--------+ +--------+
设计要点:
| 维度 | 策略 |
|---|---|
| 写入目标 | 单一节点写入(通过 ProxySQL 规则),避免多节点写入导致的冲突概率上升 |
| 读取负载 | 读请求均匀分布至所有节点,线性扩展读吞吐 |
| 仲裁权重 | 不同 DC 分配差异化权重,确保主 DC 在网络分区时获取 Primary |
| 跨区域延迟 | 节点间 RTT 控制在 10ms 以内,超过此值考虑分段仲裁配置 |
| 节点数量 | 推荐 3/5/7 奇数节点,偶数节点需配合 garbd 消除平票 |
段仲裁(Segment):
# DC1 节点
wsrep_provider_options = "gmcast.segment=1;pc.weight=2"
# DC2 节点
wsrep_provider_options = "gmcast.segment=2;pc.weight=1"
# DC3 节点
wsrep_provider_options = "gmcast.segment=3;pc.weight=1"
Segment 配置使 Donor 选择优先在本地段进行,降低跨 DC SST 流量。
17 PXC 的跨数据中心部署方案
答案:
PXC 跨数据中心部署通过 Segmented Group Communication 和权重仲裁实现地理分布高可用,节点按物理位置分组为 Segment,SST/IST 优先在同 Segment 内完成。
[分层展开]
部署架构:
ProxySQL VIP
|
+----------+----------+
| |
+-------+--------+ +-------+--------+
| Data Center 1 | | Data Center 2 |
| (Primary Site) | | (Disaster Rec.) |
+-----------------+ +-----------------+
| PXC-1 (w=2,s=1) | | PXC-3 (w=1,s=2) |
| PXC-2 (w=2,s=1) | | PXC-4 (w=1,s=2) |
+-----------------+ +-----------------+
| |
+---- WAN Link -------+
配置策略:
| 配置项 | 主 DC(DC1) | 备 DC(DC2) |
|---|---|---|
gmcast.segment | 1 | 2 |
pc.weight | 2 | 1 |
gcache.size | 4h 写入量 | 4h 写入量 |
evs.inactive_check_period | PT0.5S | PT0.5S |
evs.suspect_timeout | PT5S | PT5S |
evs.inactive_timeout | PT15S | PT15S |
关键考量:
- 跨 DC 延迟(RTT)< 5ms 时可作为同步集群运行
- 延迟 5-30ms 时需调整超时参数并接受性能折损
- 延迟 > 30ms 不建议跨 DC 同步复制,改用异步复制方案
- 备 DC 节点权重低于主 DC,确保网络分区时主 DC 成为 Primary
客户端路由:通过 Geo-DNS 或 GSLB 将客户端路由至最近 ProxySQL 端点,本地读取,写入路由至主 DC。
18 PXC 的性能优化与参数调优
答案:
PXC 性能优化围绕减少写集合大小、降低流控频率、优化网络传输和协调 InnoDB 与 Galera 参数展开。
[分层展开]
核心参数调优:
| 参数 | 建议值 | 作用 |
|---|---|---|
wsrep_slave_threads | CPU 核心数 × 2 | 提高 apply 并发度 |
innodb_flush_log_at_trx_commit | 2 | 降低磁盘 I/O,容忍 1s 数据丢失 |
innodb_autoinc_lock_mode | 2 | 跨节点 auto_inc 兼容,避免自增锁冲突 |
binlog_format | ROW | Galera 要求,写集合依赖行格式 |
wsrep_provider_options | 见下 | 多项组合调优 |
innodb_buffer_pool_size | 物理内存 70-80% | 缓存热数据 |
Provider Options 调优:
[mysqld]
wsrep_provider_options = "
gcache.size=4G;
gcs.fc_limit=32;
gcs.fc_factor=0.8;
gcs.max_packet_size=64500;
evs.inactive_check_period=PT1S;
evs.suspect_timeout=PT10S;
evs.inactive_timeout=PT30S;
evs.keepalive_period=PT3S
"
写入优化:
- 批量插入使用 INSERT INTO … VALUES (…), (…), (…),减少写集合数量
- 避免大事务,拆分超过 10 万行的批量操作
- 降低
wsrep_max_ws_size防止超大写集合导致内存溢出
网络优化:
# 增大网络缓冲区
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
冲突规避:将相同行的写入路由至同一节点,降低跨节点冲突概率。
19 PXC 的故障恢复流程
答案:
PXC 节点故障恢复分为节点自动重加入、集群整体重启和灾难恢复三种场景,核心流程依赖 Galera 的 IST/SST 机制和 PC bootstrap 协议。
[分层展开]
场景一:单节点故障 - 自动重加入
1. 节点故障(崩溃、网络断开)
2. 其余节点维持 Primary,集群正常运行
3. 故障节点恢复,检测到 gcache 覆盖的 seqno 范围
4. 优先 IST:从集群节点拉取增量事务
5. 否则 SST:从 Donor 节点拉取全量快照
6. 节点状态 Joining -> Joined -> Synced
场景二:集群整体停机 - Bootstrap
# 1. 确认最后运行的节点(拥有最高 seqno)
# 在每个节点上执行
mysqld --wsrep-recover
# 2. 查看最后一个节点输出的 seqno(grastate.dat 或错误日志):
cat /var/lib/mysql/grastate.dat
# seqno: 12345
# 3. 以 bootstrap 模式启动 seqno 最高的节点(设为 safe_to_bootstrap: 1)
# 在 grastate.dat 中设置后再启动,或直接:
mysqld --wsrep-new-cluster
# 4. 其余节点正常启动,自动加入集群
systemctl start mysql
场景三:灾难恢复 - S3 备份恢复
# 1. 从 S3 拉取最新备份
aws s3 cp s3://pxc-backups/latest/ /backup/
# 2. 准备备份
xtrabackup --prepare --target-dir=/backup/
# 3. 初始化节点数据目录
rm -rf /var/lib/mysql/*
xtrabackup --copy-back --target-dir=/backup/
# 4. 创建 grastate.dat
echo "safe_to_bootstrap: 1" > /var/lib/mysql/grastate.dat
# 5. 启动 bootstrap 节点
mysqld --wsrep-new-cluster
# 6. 其余节点从备份节点的 SST 恢复
故障恢复 SLA 评估:
| 故障类型 | RTO | 恢复方式 |
|---|---|---|
| 单节点 crash | 数秒 ~ 数分钟 | IST 自动恢复 |
| 单节点长时间离线 | 分钟 ~ 小时 | SST 自动恢复 |
| 集群全停 | 数分钟 | 手动 bootstrap |
| 数据中心故障 | 数分钟 ~ 小时 | 手动 bootstrap + S3 恢复 |
20 PXC 与 Group Replication(InnoDB Cluster)对比
答案:
PXC 基于 Galera(Percona 分支)实现多主同步复制,Group Replication 是 MySQL 原生插件基于 Paxos 协议的单主/多主同步方案;二者均支持多主写入,但在性能特性、冲突检测和生态工具上有显著差异。
[分层展开]
| 维度 | PXC | Group Replication / InnoDB Cluster |
|---|---|---|
| 复制协议 | Galera(virtually synchronous) | Paxos(Group Communication System) |
| 多主写入 | 原生支持,所有节点等权 | 支持多主模式,配置复杂 |
| 冲突检测 | 乐观认证(certification) | 乐观认证(certification) |
| SST/IST | 原生支持 | 仅支持 MySQL Clone 插件 |
| 流控 | 基于队列长度的 f-low control | 基于事务延迟的 flow control |
| 写集合 | 基于行的 write-set | 基于行的 certification info |
| 最小节点数 | 3(推荐) | 3(单主模式 1 也可) |
| 异步从库 | 支持异步 slave 挂载 | 支持(Group Replication + Async) |
| MySQL 版本 | Percona Server(MySQL 分支) | MySQL 5.7.17+ / 8.0+ |
| DDL 复制 | TOI / RSU 两种模式 | 仅支持原子 DDL(8.0+) |
| 运维工具 | Percona Toolkit, PMM, Operator | MySQL Shell, MySQL Router |
| K8s Operator | Percona Operator for MySQL | MySQL Operator for Kubernetes |
选择依据:
| 场景 | 推荐方案 |
|---|---|
| 多活写入、对等节点 | PXC |
| MySQL 官方支持、单主场景 | Group Replication |
| 需要 ProxySQL 读写分离 | PXC |
| 需要 MySQL Router 原生路由 | InnoDB Cluster |
| K8s 部署、备份调度集成 | PXC(Percona Operator 更成熟) |
21 PXC 的备份工具(xtrabackup vs mysqldump)
答案:
xtrabackup 是 Percona 开发的物理热备份工具,非阻塞、支持增量备份和压缩,是 PXC 生产环境首选;mysqldump 是 MySQL 原生逻辑备份工具,输出 SQL 文本,适合小型库和逻辑迁移。
[分层展开]
| 维度 | xtrabackup | mysqldump |
|---|---|---|
| 备份类型 | 物理(数据文件 + redo log) | 逻辑(SQL 语句) |
| 阻塞性 | 非阻塞(短暂 FTWRL 或 backup lock) | 阻塞(读锁,–single-transaction 可缓解) |
| 速度 | 快(直接拷贝文件) | 慢(逐行转 SQL) |
| 增量备份 | 支持(基于 LSN) | 不支持 |
| 压缩 | 原生支持(–compress) | 需通过 pipe 到 gzip |
| 输出格式 | 二进制文件 | 可读 SQL 文本 |
| 恢复灵活性 | 必须恢复到相同版本/架构 | 可跨版本、跨引擎 |
| PXC SST 集成 | 原生(xtrabackup-v2) | 支持(mysqldump SST) |
| 数据量级 | TB 级 | 建议 50GB 以下 |
xtrabackup 使用示例:
# 全量备份
xtrabackup --backup --target-dir=/backup/full --user=root --password=xxx
# 增量备份(基于上一次全量/增量)
xtrabackup --backup --target-dir=/backup/inc1 \
--incremental-basedir=/backup/full \
--user=root --password=xxx
# 准备备份(apply-log)
xtrabackup --prepare --apply-log-only --target-dir=/backup/full
xtrabackup --prepare --apply-log-only --target-dir=/backup/full \
--incremental-dir=/backup/inc1
# 恢复
xtrabackup --copy-back --target-dir=/backup/full
mysqldump 使用示例:
# 单事务备份(PXC 专用参数)
mysqldump --single-transaction \
--skip-lock-tables \
--all-databases \
--routines --triggers --events \
> /backup/dump.sql
选择依据:生产环境全量 + 增量策略使用 xtrabackup;小型测试环境、跨版本数据迁移使用 mysqldump。
22 PXC 的 SSL/TLS 加密配置
答案:
PXC 支持三层 SSL/TLS 加密:Galera 节点间通信加密(gcomm)、SST 传输加密和 MySQL 客户端连接加密,生产环境应按要求启用全部三层。
[分层展开]
加密层级:
| 层级 | 配置项 | 范围 |
|---|---|---|
| Galera 通信 | socket.ssl_key / socket.ssl_cert / socket.ssl_ca | 节点间 gcomm 加密 |
| SST 传输 | sst 选项 + xtrabackup SSL | SST 数据传输加密 |
| 客户端连接 | MySQL SSL(常规配置) | 应用连接加密 |
Galera 节点间加密:
[mysqld]
wsrep_provider_options = "
socket.ssl_key=/etc/mysql/certs/server-key.pem;
socket.ssl_cert=/etc/mysql/certs/server-cert.pem;
socket.ssl_ca=/etc/mysql/certs/ca-cert.pem;
socket.ssl_cipher=AES128-SHA256
"
SST 加密:
[mysqld]
wsrep_sst_method = xtrabackup-v2
wsrep_sst_auth = "sstuser:sstpassword"
[sst]
encrypt = 4 # xtrabackup 加密算法(AES256)
ssl-mode = VERIFY_CA
ssl-ca = /etc/mysql/certs/ca-cert.pem
ssl-cert = /etc/mysql/certs/server-cert.pem
ssl-key = /etc/mysql/certs/server-key.pem
客户端连接加密:
[mysqld]
ssl-ca = /etc/mysql/certs/ca-cert.pem
ssl-cert = /etc/mysql/certs/server-cert.pem
ssl-key = /etc/mysql/certs/server-key.pem
require_secure_transport = ON
证书生成:
# 生成 CA
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca-cert.pem
# 生成 Server 证书
openssl req -newkey rsa:2048 -days 3650 -nodes \
-keyout server-key.pem -out server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 3650 \
-CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 \
-out server-cert.pem
Percona Operator 配置:
spec:
pxc:
sslSecretName: pxc-ssl
sslInternalSecretName: pxc-ssl-internal
23 PXC 的异步从库(Async Slave)挂载
答案:
PXC 节点可作为传统异步复制的主库,挂载异步 Slave 实现跨区域灾备或只读扩展,通过 wsrep 的 log_slave_updates 和 GTID 实现平滑切换。
[分层展开]
架构:
+--------+ +--------+ +--------+
| PXC-1 | <-> | PXC-2 | <-> | PXC-3 |
|Master | |Master | |Master |
+---+----+ +--------+ +--------+
| 异步复制
v
+--------+
| Async |
| Slave |
+--------+
配置步骤:
-- 1. 在 PXC 节点上启用 binlog(主库)
-- my.cnf
-- [mysqld]
-- log_bin = mysql-bin
-- log_slave_updates = ON
-- binlog_format = ROW
-- gtid_mode = ON
-- enforce_gtid_consistency = ON
-- 2. 创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- 3. 在 Slave 上配置复制
CHANGE MASTER TO
MASTER_HOST = 'pxc-node-1',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'repl_password',
MASTER_AUTO_POSITION = 1;
START SLAVE;
-- 4. 验证
SHOW SLAVE STATUS\G
PXC 主库切换:当异步复制的主 PXC 节点故障时,Slave 通过 GTID 自动连接到另一 PXC 节点,确保复制连续性。
适用场景:
- 跨数据中心灾备(远距离、高延迟不适合同步方案)
- 报表/分析只读实例(与 OLTP 集群隔离)
- 零停机迁移的过渡方案
注意事项:异步从库的数据一致性为最终一致性,延迟取决于网络和主库写入量。
24 PXC 的 wsrep_provider 参数详解
答案:
wsrep_provider_options 是 PXC 的核心配置项,控制 Galera Replication Plugin 的行为,涵盖通信、缓存、流控、认证和驱逐策略。
[分层展开]
核心参数分类:
通信参数(gcomm / gcs):
| 参数 | 默认值 | 说明 |
|---|---|---|
gcs.fc_limit | 16 | 流控队列阈值,超过则暂停发送 |
gcs.fc_factor | 1.0 | 动态流控灵敏度因子 |
gcs.max_packet_size | 64500 | 最大网络包大小(bytes) |
gcs.max_throttle | 0.005 | 最大节流间隔(秒) |
缓存参数(gcache):
| 参数 | 默认值 | 说明 |
|---|---|---|
gcache.size | 128M | gcache 环形缓冲区大小 |
gcache.page_size | 128M | 磁盘 page 文件大小 |
gcache.keep_pages_size | 0 | 保留在内存中的 page 总量 |
驱逐与超时(evs):
| 参数 | 默认值 | 说明 |
|---|---|---|
evs.inactive_check_period | PT0.5S | 节点活跃检查间隔 |
evs.suspect_timeout | PT5S | 节点可疑超时(标记为 suspect) |
evs.inactive_timeout | PT15S | 节点非活跃超时(驱逐) |
evs.keepalive_period | PT1S | 心跳间隔 |
仲裁参数(pc):
| 参数 | 默认值 | 说明 |
|---|---|---|
pc.weight | 1 | 节点仲裁权重 |
pc.ignore_sb | false | 是否忽略脑裂 |
pc.ignore_quorum | false | 是否忽略仲裁要求 |
生产环境推荐配置:
[mysqld]
wsrep_provider_options = "
gcache.size=4G;
gcache.page_size=256M;
gcs.fc_limit=32;
gcs.fc_factor=0.8;
gcs.max_packet_size=64500;
evs.inactive_check_period=PT1S;
evs.suspect_timeout=PT10S;
evs.inactive_timeout=PT30S;
evs.keepalive_period=PT3S;
pc.weight=1;
gmcast.segment=1
"
25 PXC 的 K8s 升级策略(滚动升级 vs 全量替换)
答案:
Percona Operator 支持两种升级策略:Smart Update(类似滚动升级)和传统的全量替换重建;Smart Update 逐节点升级并利用 IST 恢复,避免 SST 重建,是生产环境推荐方式。
[分层展开]
升级策略对比:
| 维度 | Smart Update(滚动升级) | 全量替换 |
|---|---|---|
| 过程 | 逐 Pod 升级,等待节点 Synced 后再升级下一个 | 直接重建所有 Pod,并行 SST |
| 数据同步 | 优先 IST,减少数据拷贝 | 每组 Pod 可能触发 SST |
| 可用性 | 全程可读写(至少保持 quorum) | 短暂不可用 |
| 耗时 | 较长(逐节点迁回) | 较短(并行重建) |
| 网络流量 | 低(IST 增量数据) | 高(SST 全量快照) |
| 风险 | 低,可回滚 | 中,数据丢失风险 |
| 适用 PXC 版本 | 8.0.x 间小版本 | 跨大版本(5.7 -> 8.0) |
Operator 升级配置:
spec:
crVersion: 1.15.0
upgradeOptions:
versionServiceEndpoint: https://check.percona.com
apply: disabled # disabled / recommended / latest / 8.0.35-27.1
schedule: "0 4 * * *" # 定时升级窗口
版本兼容性矩阵:
| 升级路径 | 方式 | 备注 |
|---|---|---|
| PXC 8.0.32 -> 8.0.35 | Smart Update | 小版本,IST 可用 |
| PXC 5.7 -> 8.0 | 全量替换 / 迁移 | 跨大版本,需 xtrabackup 兼容检查 |
| Operator 1.13 -> 1.15 | Smart Update | Operator 自身升级不影响数据面 |
升级检查清单:
# 1. 确认当前集群状态
kubectl get pxc -o yaml
# 2. 检查节点状态
kubectl exec -it cluster1-pxc-0 -- mysql -e "SHOW STATUS LIKE 'wsrep%'"
# 3. 确认备份可用(升级前必做备份)
kubectl get pxc-backup
# 4. 设置 apply 策略
# spec.upgradeOptions.apply = recommended
# 5. 监控升级过程
kubectl logs -f deployment/percona-xtradb-cluster-operator
kubectl get pods -w
26 PXC 的存储选型(Local PV vs Ceph RBD vs NFS)
答案:
PXC 对存储延迟极度敏感,Local PV 提供最低延迟和最高 IOPS,是生产环境首选;Ceph RBD 提供可移植性和动态供给;NFS 延迟高,不推荐用于 PXC 数据卷。
[分层展开]
| 维度 | Local PV | Ceph RBD | NFS |
|---|---|---|---|
| 延迟 | <1ms(本地磁盘) | 1-5ms(网络 + 副本) | 5-20ms(协议开销) |
| IOPS | 磁盘原生 IOPS | 受网络和副本数影响 | 最低 |
| 数据持久性 | 单副本,本地磁盘故障数据丢失 | 多副本(3x),高持久性 | 依赖 NFS 后端 |
| Pod 可移植性 | 绑死节点,无法漂移 | 可漂移到任意节点 | 可漂移到任意节点 |
| 动态供给(CSI) | 支持(LocalPV CSI) | 支持(RBD CSI) | 支持(NFS CSI) |
| SST 性能 | 最优(本地 I/O) | 良好 | 较差 |
| 运维复杂度 | 低 | 中(需维护 Ceph 集群) | 低 |
| PXC 兼容性 | 测试充分,官方推荐 | 测试充分 | 不推荐 |
| 备份 | 需额外备份工具 | 可利用 RBD 快照 | 可利用存储快照 |
选型建议:
- 单集群、高性能场景:Local PV + Operator 定期备份到 S3
- 多云/混合云、需要 Pod 漂移:Ceph RBD
- 开发测试环境:NFS(仅限非性能敏感场景)
Local PV 配置示例:
spec:
pxc:
volumeSpec:
persistentVolumeClaim:
storageClassName: local-ssd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
Ceph RBD 配置示例:
spec:
pxc:
volumeSpec:
persistentVolumeClaim:
storageClassName: ceph-rbd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
27 PXC 对 K8s PodDisruptionBudget 的配置
答案:
Percona Operator 自动为 PXC 创建 PodDisruptionBudget(PDB),确保在自愿性中断(节点维护、集群缩容)期间始终保留仲裁所需的节点数,防止集群进入 Non-Primary 状态。
[分层展开]
PDB 原理:
- PDB 定义了同时不可用的最小或最大 Pod 数,K8s 调度器在驱逐 Pod 时尊重 PDB 约束
- 自愿性中断受 PDB 约束(drain、Deployment 滚动更新),非自愿中断(节点宕机)不受约束
默认 PDB 配置:
# Operator 自动生成的 PDB
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: cluster1-pxc
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: percona-xtradb-cluster
app.kubernetes.io/instance: cluster1
3 节点集群 PDB 分析:
| maxUnavailable | 可容忍中断 | 风险 |
|---|---|---|
| 1 | 可安全驱逐 1 个 Pod | 驱逐期间若有节点同时故障,可能丢失 quorum |
| 2 | 可同时驱逐 2 个 Pod | 仅剩 1 节点,集群进入 Non-Primary |
| 0 | 不允许任何驱逐 | 无法执行节点维护 |
5 节点集群 PDB:
spec:
maxUnavailable: 2 # 可同时中断 2 个 Pod,仍保有 3 节点 quorum
节点维护操作流程:
# 1. 确认集群状态
kubectl exec cluster1-pxc-0 -- mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
# 2. 检查 PDB 状态
kubectl get pdb cluster1-pxc
# 3. 执行节点 drain(受 PDB 保护)
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
# 4. 观察 Pod 驱逐过程
kubectl get pods -w
# 5. 维护完成后 uncordon 节点
kubectl uncordon node-1
注意事项:PDB 仅约束自愿性中断,不防止非自愿故障,因此 PDB 设置不能替代最小节点数设计和仲裁规划。
28 PXC 与 Vitess 的对比
答案:
PXC 是基于 Galera 的多主同步复制 MySQL 集群方案,面向强一致性和低延迟读写的 OLTP 场景;Vitess 是 MySQL 的水平分片中间件,面向超大规模数据集和高吞吐的互联网场景。
[分层展开]
| 维度 | PXC | Vitess |
|---|---|---|
| 数据模型 | 单一数据副本集,每个节点全量数据 | 分片模型,每分片独立 MySQL 实例 |
| 扩展方式 | 垂直扩展(读节点横向扩展) | 水平分片,数据按 shard key 分布 |
| 写入扩展 | 受 Galera 认证限制,写入不线性扩展 | 线性写入扩展,各分片独立写入 |
| 一致性 | 强一致性(同步复制 + 认证) | 分片内强一致,跨分片最终一致 |
| 跨分片事务 | 不支持(单集群内所有数据本地) | 支持有限的 2PC 跨分片事务 |
| SQL 兼容性 | 完整 MySQL SQL 支持 | 有限(无 JOIN 跨分片、有限子查询等) |
| 运维复杂度 | 低-中(Galera 集群管理) | 高(Vttablet/Vtgate/topology 等多组件) |
| 数据量上限 | TB 级(单节点存储上限) | PB 级(水平分片无理论上限) |
| 适用场景 | 金融、交易、配置管理等强一致 OLTP | 社交媒体、IoT、日志等超大规模场景 |
| 节点拓扑感知 | Galera Segment 跨 DC 支持 | 原生多 DC 拓扑感知路由 |
| K8s 支持 | Percona Operator(成熟) | Vitess Operator / Helm(成熟) |
选择依据:
| 场景特征 | 推荐方案 |
|---|---|
| 单数据集 < 5TB,需要完整 SQL 支持 | PXC |
| 数据量 > 10TB,可接受分片限制 | Vitess |
| 强一致性 + 低延迟 | PXC |
| 极高写入吞吐 + 可接受最终一致 | Vitess |
| 多活写入、无单点故障 | PXC |
| 全球部署、超大规模用户 | Vitess |
29 PXC 的容器化最佳实践
答案:
PXC 容器化部署需关注资源隔离、存储持久化、网络优化、配置管理和生命周期钩子,通过 Percona Operator 实现声明式管理,确保生产级可用性。
[分层展开]
1. 资源配置:
spec:
pxc:
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "8Gi"
cpu: "4"
2. 存储配置:
- 使用 SSD 或 NVMe 存储类,禁止使用 NFS 或网络文件系统
- PVC 大小预留 30% 余量用于 tmpdir 和 binlog
3. Pod 反亲和性:
spec:
pxc:
affinity:
antiAffinityTopologyKey: kubernetes.io/hostname # 每个物理节点最多 1 个 PXC Pod
4. 网络调优:
# sysctl 参数(通过 initContainer 设置)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
5. 安全配置:
spec:
pxc:
# 非 root 运行
runAsUser: 1001
runAsGroup: 1001
# 启用 SSL
sslSecretName: pxc-ssl
sslInternalSecretName: pxc-ssl-internal
6. 就绪与存活探针:
# Operator 自动配置的探针逻辑
# 就绪探针:wsrep_ready=ON AND wsrep_local_state=4
# 存活探针:mysqld 进程存活
# 启动探针:允许 SST 期间的较长启动时间
spec:
pxc:
readinessDelaySec: 15
livenessDelaySec: 60
7. 备份验证:
spec:
backup:
schedule:
- name: daily-backup
schedule: "0 2 * * *"
keep: 7
# 定期验证备份可用性
# 通过 restore job 验证
8. 监控集成:
spec:
pmm:
enabled: true
image: percona/pmm-client:2
serverHost: monitoring-service
禁止事项:
- 禁止在同一个 K8s Node 上部署多个 PXC Pod(通过 PodAntiAffinity 实施)
- 禁止使用
emptyDir作为数据卷 - 禁止未经备份验证直接升级 Operator 版本
- 禁止在生产环境使用默认密码
30 PXC 的常见问题与故障排查
答案:
PXC 常见问题包括节点无法加入集群、SST 失败、流控频繁、认证冲突、gcache 溢出和集群 Non-Primary,通过 wsrep 状态变量和错误日志定位根因。
[分层展开]
问题一:节点无法加入集群(Joining 状态卡住)
-- 排查步骤
-- 1. 检查网络连通性
-- 2. 检查 wsrep_cluster_address 配置
-- 3. 检查 SST 用户权限
-- 4. 查看错误日志
SHOW STATUS LIKE 'wsrep_local_state_comment';
-- 长时间显示 Joining -> 检查 SST 日志
典型原因与解决:
| 现象 | 根因 | 解决方案 |
|---|---|---|
| Joining 卡住 | SST 用户权限不足 | GRANT ALL ON . TO ‘sstuser’@’%’ |
| Joining 卡住 | 防火墙拦截端口 4444/4567/4568 | 开放 Galera 所需端口 |
| Joining 卡住 | Donor 节点 gcache 不足 | 增大 gcache.size 或强制 SST |
| Joining 失败 | 数据目录非空 | 清空数据目录后重启 |
问题二:SST 失败
# 检查 SST 日志
grep -i sst /var/log/mysql/error.log
# 常见原因
# - xtrabackup 版本不匹配
# - Donor 磁盘空间不足
# - SST 用户认证失败
# 手动触发 SST
rm -f /var/lib/mysql/grastate.dat
systemctl restart mysql
问题三:频繁流控
-- 诊断
SHOW STATUS LIKE 'wsrep_flow_control%';
SHOW STATUS LIKE 'wsrep_local_recv_queue%';
-- 优化
SET GLOBAL wsrep_slave_threads = 8;
问题四:认证冲突(死锁错误 1213)
-- 监控冲突
SHOW STATUS LIKE 'wsrep_local_bf_aborts';
SHOW STATUS LIKE 'wsrep_local_cert_failures';
-- 应对
-- 1. 应用层实现重试逻辑
-- 2. 将热点数据写入路由至同一节点
-- 3. 排查是否有跨节点并发更新同一行
问题五:gcache 溢出导致 SST
-- 检查 gcache 使用率
-- gcache 溢出表现为 IST 不可用,节点回退至 SST
-- 增加 gcache 大小
-- wsrep_provider_options = "gcache.size=8G"
问题六:集群 Non-Primary
# 根因定位
# 1. 确认存活节点数
mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
# 2. 检查网络分区
# 3. 检查是否所有节点同时崩溃
# 恢复步骤
# 确认 safe_to_bootstrap 节点
cat /var/lib/mysql/grastate.dat
# 将 seqno 最高的节点设为 safe_to_bootstrap: 1
# Bootstrap 集群
mysqld --wsrep-new-cluster
# 其余节点正常启动
systemctl start mysql
问题七:PXC 所需端口
| 端口 | 协议 | 用途 |
|---|---|---|
| 3306 | TCP | MySQL 客户端连接 |
| 4444 | TCP | SST 数据传输 |
| 4567 | TCP/UDP | Galera 组通信(gcomm) |
| 4568 | TCP | IST 增量数据传输 |
故障排查工具速查:
-- 综合健康检查
SHOW GLOBAL STATUS LIKE 'wsrep%';
-- 集群基本信息
SELECT * FROM performance_schema.replication_group_members; -- Group Replication
-- PXC 无对应表,使用 SHOW STATUS
-- 检查 InnoDB 状态(冲突检测日志)
SHOW ENGINE INNODB STATUS\G