Skip to content

TiDB 高可用问题处理

TiDB 集群的高可用性是确保业务连续性的关键。本文将详细介绍 TiDB 高可用问题的处理方法,包括故障检测、主从切换、故障恢复和常见问题排查。

高可用架构

1. 组件冗余设计

TiDB 集群通过组件冗余实现高可用性:

  • TiDB 服务器:无状态设计,可水平扩展,单个节点故障不影响集群
  • TiKV 服务器:基于 Raft 协议,每个 Region 有多个副本,默认 3 副本
  • PD 服务器:基于 Raft 协议,通常部署 3 或 5 个节点,保证元数据高可用
  • TiFlash 服务器:可配置多个副本,支持实时备份和读取

2. 故障自动恢复机制

  • TiKV 副本自动修复:当 TiKV 节点故障时,PD 会自动调度新的副本
  • TiDB 自动重启:可通过系统服务管理工具实现自动重启
  • PD Leader 自动选举:当 PD Leader 故障时,会自动选举新的 Leader
  • TiKV Leader 自动迁移:当 TiKV Leader 故障时,会自动选举新的 Leader

故障检测

1. 组件状态监控

  • TiDB 状态:通过 HTTP API /statustiup cluster display cluster-name 查看
  • TiKV 状态:通过 PD API /pd/api/v1/storestiup ctl pd -u pd-url store 查看
  • PD 状态:通过 PD API /pd/api/v1/memberstiup ctl pd -u pd-url member 查看
  • 监控告警:通过 Prometheus 和 Grafana 监控组件状态,设置告警规则

2. 故障类型识别

故障类型表现症状影响范围恢复时间
TiDB 节点故障连接中断、查询失败单个节点秒级
TiKV 节点故障部分 Region 不可用、查询延迟增加节点上的所有 Region分钟级
PD 节点故障调度停止、元数据更新失败集群整体秒级(Leader 切换)
网络分区集群分裂、数据不一致风险跨区域依赖网络恢复时间

主从切换

1. TiDB 节点切换

TiDB 是无状态节点,切换过程简单:

bash
# 停止故障 TiDB 节点
tiup cluster stop <cluster-name> -N <tidb-ip:4000>

# 启动新的 TiDB 节点
tiup cluster start <cluster-name> -N <new-tidb-ip:4000>

# 验证新节点状态
tiup cluster display <cluster-name> | grep tidb

2. TiKV 节点切换

TiKV 节点切换涉及 Region 迁移:

bash
# 标记故障 TiKV 节点为下线
tiup ctl pd -u <pd-url> store <store-id> delete

# 等待 PD 调度新副本
# 可通过以下命令查看调度进度
tiup ctl pd -u <pd-url> operator show

# 当所有 Region 迁移完成后,移除故障节点
tiup cluster scale-in <cluster-name> -N <tikv-ip:20160>

# 添加新的 TiKV 节点
tiup cluster scale-out <cluster-name> <new-tikv-topology.yaml>

3. PD 节点切换

PD 节点切换涉及 Leader 选举:

bash
# 查看当前 PD Leader
tiup ctl pd -u <pd-url> member

# 停止故障 PD 节点
tiup cluster stop <cluster-name> -N <pd-ip:2379>

# 等待 PD 自动选举新 Leader(通常几秒内完成)
tiup ctl pd -u <pd-url> member

# 移除故障 PD 节点
tiup cluster scale-in <cluster-name> -N <pd-ip:2379>

# 添加新的 PD 节点
tiup cluster scale-out <cluster-name> <new-pd-topology.yaml>

故障恢复

1. TiDB 节点恢复

bash
# 检查 TiDB 节点状态
systemctl status tidb-server

# 查看 TiDB 日志
tail -f /tidb-deploy/tidb-4000/log/tidb.log

# 重启 TiDB 服务
systemctl restart tidb-server

# 或使用 TiUP 重启
tiup cluster restart <cluster-name> -N <tidb-ip:4000>

2. TiKV 节点恢复

bash
# 检查 TiKV 节点状态
systemctl status tikv-server

# 查看 TiKV 日志
tail -f /tidb-deploy/tikv-20160/log/tikv.log

# 检查磁盘状态
df -h /tidb-data

# 重启 TiKV 服务
systemctl restart tikv-server

# 或使用 TiUP 重启
tiup cluster restart <cluster-name> -N <tikv-ip:20160>

# 检查节点是否重新加入集群
tiup ctl pd -u <pd-url> store <store-id>

3. PD 节点恢复

bash
# 检查 PD 节点状态
systemctl status pd-server

# 查看 PD 日志
tail -f /tidb-deploy/pd-2379/log/pd.log

# 重启 PD 服务
systemctl restart pd-server

# 或使用 TiUP 重启
tiup cluster restart <cluster-name> -N <pd-ip:2379>

# 检查节点是否重新加入集群
tiup ctl pd -u <pd-url> member

数据一致性保证

1. Raft 协议保证

TiKV 使用 Raft 协议保证数据一致性:

  • 写入操作需要大多数副本确认才能返回成功
  • 读取操作默认从 Leader 读取,确保最新数据
  • 支持线性一致性读取,可通过 tidb_read_consistency = "linearizable" 配置

2. 数据一致性检查

bash
# 使用 tiup ctl pd 检查 Region 健康状态
tiup ctl pd -u <pd-url> region check

# 使用 tikv-ctl 检查 Raft 状态
tiup ctl tikv --host <tikv-ip:20160> raft region <region-id>

# 执行一致性检查 SQL
SELECT * FROM mysql.tidb WHERE variable_name = 'cluster_version';

3. 数据修复

bash
# 修复 Region 副本
tiup ctl pd -u <pd-url> scheduler add replicate

# 检查并修复不一致的副本
tiup cluster check <cluster-name> --cluster

常见高可用问题排查

1. TiDB 连接失败

问题描述:客户端无法连接到 TiDB 服务器

排查步骤

  1. 检查 TiDB 进程是否运行:ps aux | grep tidb-server
  2. 检查 TiDB 监听端口:netstat -tuln | grep 4000
  3. 检查防火墙规则:iptables -L -n | grep 4000
  4. 检查 TiDB 日志中的错误信息
  5. 检查负载均衡配置(如果使用了负载均衡)

解决方案

  • 重启 TiDB 服务
  • 调整 TiDB 配置参数 max_connections
  • 检查网络连接和防火墙规则

2. TiKV 节点频繁上下线

问题描述:TiKV 节点频繁从集群中下线后又重新上线

排查步骤

  1. 检查 TiKV 日志中的心跳超时信息
  2. 检查网络延迟:ping tikv-ip -c 10
  3. 检查 TiKV 节点资源使用情况:topfree -hiostat -x
  4. 检查 PD 配置中的心跳超时时间:tiup ctl pd -u pd-url config show | grep heartbeat

解决方案

  • 优化网络连接,降低延迟
  • 增加 TiKV 节点资源
  • 调整 PD 配置 pd-server.heartbeat-intervalpd-server.heartbeat-timeout

3. PD Leader 频繁切换

问题描述:PD Leader 频繁更换,影响集群稳定性

排查步骤

  1. 检查 PD 日志中的 Leader 选举信息
  2. 检查 PD 节点之间的网络延迟
  3. 检查 PD 节点资源使用情况
  4. 检查 PD 配置中的选举超时时间

解决方案

  • 优化网络连接,确保 PD 节点之间延迟 `< 10ms
  • 增加 PD 节点资源
  • 调整 PD 配置 election-timeouttick-interval
  • 确保 PD 节点时间同步

4. Region 不可用

问题描述:部分 Region 处于不可用状态,导致查询失败

排查步骤

  1. 查看不可用 Region:tiup ctl pd -u <pd-url> region check miss-peer`
  2. 检查相关 TiKV 节点状态:tiup ctl pd -u pd-url store
  3. 查看 PD 调度操作:tiup ctl pd -u pd-url operator show
  4. 检查 TiKV 日志中的 Raft 错误信息

解决方案

  • 修复或替换故障的 TiKV 节点
  • 手动添加缺失的副本:tiup ctl pd -u pd-url operator add add-peer region-id store-id
  • 调整 PD 调度参数,加速副本修复

5. 网络分区问题

问题描述:集群因网络分区而分裂,出现多个 Leader

排查步骤

  1. 检查网络连接状态
  2. 查看 PD 日志中的网络分区告警
  3. 检查集群状态:tiup cluster display cluster-name

解决方案

  • 修复网络连接问题
  • 等待集群自动恢复
  • 如无法自动恢复,可能需要手动介入,联系 TiDB 支持团队

高可用最佳实践

1. 部署建议

  • 跨可用区部署:将 TiKV 副本分布在不同可用区,提高容灾能力
  • 合理的副本数:根据业务需求和成本考虑,设置合适的副本数(通常 3-5 副本)
  • 足够的资源冗余:确保每个节点有足够的资源,避免因资源不足导致故障
  • 定期备份:即使有高可用机制,也应定期进行数据备份

2. 监控告警

  • 关键指标监控:监控组件状态、资源使用率、Raft 状态等关键指标
  • 合理的告警规则:设置合适的告警阈值和持续时间,避免告警风暴
  • 多渠道告警通知:配置邮件、短信、企业微信等多种告警渠道
  • 定期告警演练:确保告警通知能够及时送达相关人员

3. 日常维护

  • 定期检查集群状态:使用 tiup cluster check cluster-name 定期检查集群健康状态
  • 定期更新版本:及时更新到稳定版本,获取最新的 bug 修复和功能改进
  • 定期演练故障恢复:模拟各种故障场景,测试恢复流程
  • 文档化故障处理流程:制定详细的故障处理文档,确保团队成员熟悉流程

4. 容量规划

  • 提前规划容量:根据业务增长趋势,提前规划集群容量
  • 合理的扩展策略:制定清晰的扩展策略,包括垂直扩展和水平扩展
  • 监控容量使用情况:定期监控集群容量使用情况,及时进行扩展

常见问题(FAQ)

Q1: TiDB 集群最少需要部署多少个节点?

A1: TiDB 集群的最小部署建议:

  • TiDB 节点:至少 2 个,实现负载均衡和高可用
  • TiKV 节点:至少 3 个,实现 3 副本冗余
  • PD 节点:至少 3 个,实现高可用
  • 监控节点:至少 1 个

Q2: 如何判断 TiKV 节点是否正常?

A2: 可以通过以下方式判断:

  1. 查看 TiKV 进程状态:ps aux | grep tikv-server
  2. 查看 TiKV 日志:tail -f /tidb-deploy/tikv-20160/log/tikv.log,检查是否有 ERROR 级别的日志
  3. 通过 PD 查看 TiKV 状态:tiup ctl pd -u pd-url store store-id,检查状态是否为 "Up"
  4. 查看监控指标:检查 TiKV 的 CPU、内存、磁盘 I/O 等指标是否正常

Q3: PD Leader 故障后,集群需要多长时间恢复?

A3: PD Leader 故障后,通常在几秒内就会选举出新的 Leader。选举时间取决于 PD 配置中的 election-timeout 参数,默认是 3 秒。在选举期间,集群的调度功能会暂时停止,但不影响已有的查询和写入操作。

Q4: 如何处理 TiKV 磁盘满的问题?

A4: 处理 TiKV 磁盘满的问题步骤:

  1. 立即停止写入操作,避免情况恶化
  2. 清理 TiKV 节点上的临时文件和日志文件
  3. 检查是否有大量的过期数据,考虑执行数据清理
  4. 考虑添加新的 TiKV 节点,进行水平扩展
  5. 调整 TiKV 配置,设置合理的磁盘使用阈值

Q5: 如何验证 TiDB 集群的高可用性?

A5: 可以通过以下方式验证:

  1. 故障注入测试:故意停止某个组件,观察集群是否能正常工作
  2. 性能测试:在故障场景下进行性能测试,确保性能满足要求
  3. 数据一致性测试:在故障场景下写入数据,然后验证数据一致性
  4. 恢复时间测试:记录故障发生到集群恢复的时间,验证是否符合 SLA 要求
  5. 压力测试:在高负载下进行故障测试,验证集群的稳定性

通过定期的验证测试,可以确保 TiDB 集群在实际故障发生时能够提供预期的高可用性。