|
| 1 | +# 第1章:解决 MySQL 问题的传统方法 |
| 2 | + |
| 3 | +## 1.1 解决 MySQL 问题的现状 |
| 4 | + |
| 5 | +解决与 MySQL 使用相关的问题通常比较简单,涉及收集信息和应用逻辑推理,这些问题通常是可以解决的。然而,解决 MySQL 本身的固有问题则要复杂得多。幸运的是,MySQL 用户足智多谋,已经设计了各种解决方案,例如实施线程池来缓解可扩展性挑战。 |
| 6 | + |
| 7 | +要有效解决 MySQL 的各种问题,仅仅依靠外围的修复和补丁是不够的。必须深入问题的核心本质,全面解决这些问题才能取得有意义的进展。例如,MySQL Group Replication 一直在不稳定性方面挣扎。尽管有强大的开发努力,但持续的挑战在于采用正确的问题解决方法,导致难以减少缺陷。 |
| 8 | + |
| 9 | +## 1.2 MySQL 问题是如何解决的? |
| 10 | + |
| 11 | +以下列出了一些经典问题,以及在实际 MySQL 使用场景中的典型解决方案。 |
| 12 | + |
| 13 | +### 1.2.1 解决 MySQL 5.7 中的可扩展性问题 |
| 14 | + |
| 15 | +下图展示了在特定配置下 MySQL 5.7.39 中 TPC-C 吞吐量与并发度之间的关系。这包括将事务隔离级别设置为读已提交(Read Committed),并调整 *innodb_spin_wait_delay* 参数以缓解吞吐量下降。 |
| 16 | + |
| 17 | +<img src="media/image-20240829080057376.png" alt="image-20240829080057376" style="zoom:150%;" /> |
| 18 | + |
| 19 | +图 1-1. 在 BenchmarkSQL 测试期间 MySQL 5.7.39 的可扩展性问题。 |
| 20 | + |
| 21 | +从图中可以明显看出,可扩展性问题显著限制了 MySQL 吞吐量的增长。例如,在 100 并发之后,吞吐量开始下降。由于 MySQL 历史上的可扩展性挑战,Percona 甚至开源了一个线程池来解决这些问题。下图展示了配置 Percona 线程池后 TPC-C 吞吐量与并发度之间的关系。 |
| 22 | + |
| 23 | +<img src="media/image-20240829080659528.png" alt="image-20240829080659528" style="zoom:150%;" /> |
| 24 | + |
| 25 | +图 1-2. Percona 线程池缓解了 MySQL 5.7.39 的可扩展性问题。 |
| 26 | + |
| 27 | +对于 MySQL 5.7.39,线程池有效地缓解了吞吐量下降,尽管由于固有的开销成本,它也略微降低了峰值吞吐量。在比较低并发级别的性能时,这种开销变得更加明显。 |
| 28 | + |
| 29 | +随着 MySQL 8.0 版本改进了可扩展性,线程池在缓解吞吐量下降方面的效果也随之减弱。后续章节将提供实际案例来证实这一观察结果。 |
| 30 | + |
| 31 | +### 1.2.2 提升 MySQL 中的 Join 性能 |
| 32 | + |
| 33 | +由于 MySQL 5.7 中缺乏哈希连接(hash join)支持,以下统计 SQL 查询执行时间为 3.82 秒。 |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | +图 1-3. MySQL 5.7 中的非哈希连接性能。 |
| 38 | + |
| 39 | +在 MySQL 8.0 中,执行计划中引入了哈希连接,提高了连接性能。对于前面提到的相同 SQL 查询,通过注释指定哈希连接将执行时间缩短到仅 1.22 秒,相比之前观察到的 3.82 秒有了显著改进。 |
| 40 | + |
| 41 | + |
| 42 | + |
| 43 | +图 1-4. MySQL 8.0 中的哈希连接性能。 |
| 44 | + |
| 45 | +这说明了 MySQL 8.0 中引入的连接执行改进,突出了其关键进步之一。 |
| 46 | + |
| 47 | +### 1.2.3 MySQL 半同步复制在大规模部署中的挑战 |
| 48 | + |
| 49 | +自 Paxos 协议引入以来,越来越多的数据库采用状态机复制来构建高可用集群。 |
| 50 | + |
| 51 | +Paxos 协议依赖于基于集合论的多数派机制来达成共识。例如,在一个包含 3 个 MySQL 节点的集群中,2 个节点可以形成多数派。如果这 2 个节点达成共识,系统就可以持续运行。理论上,遵守这种多数派机制应该可以防止在任何异常情况下出现分歧或脑裂问题。 |
| 52 | + |
| 53 | +Raft 是另一个广泛使用的协议,本质上是 Paxos 协议的简化版本。以下部分描述了 Meta 使用 Raft 协议实现 MySQL 高可用性的方案 [38],该方案简化了传统的高可用性流程。 |
| 54 | + |
| 55 | +<img src="media/91bc13de07d658b009ae498b5afa4ac1.gif" style="zoom: 50%;" /> |
| 56 | + |
| 57 | +图 1-5. Meta 使用 Raft 的原因。 |
| 58 | + |
| 59 | +Meta 的案例研究表明,基于 Raft 协议的新解决方案简化了高可用性挑战。Raft 通常被视为 Paxos 协议的精简版本。同样,基于 Paxos 协议的 Group Replication 解决方案,如果实现正确,也可以提供一个优雅的解决方案。 |
| 60 | + |
| 61 | +### 1.2.4 多数派机制的性能及其准确性 |
| 62 | + |
| 63 | +在事务隔离级别设置为读已提交的情况下,基于 Group Replication 在各种网络延迟条件下进行了模拟。 |
| 64 | + |
| 65 | +Group Replication 的部署设置如下:在机器 A 上,部署了两个 MySQL 实例——一个作为主节点,另一个作为从节点。这两个实例形成多数派,并通过 localhost 通信。机器 B 承载第三个实例,部署为集群的成员,网络延迟为 X 毫秒。 |
| 66 | + |
| 67 | + |
| 68 | + |
| 69 | +图 1-6. 多数派机制性能测试的部署图。 |
| 70 | + |
| 71 | +理论上,在多数派机制下,一个 3 节点的集群只需要 2 个节点的响应就可以向客户端提供结果。按照这个逻辑,本地 SysBench 测试应该表现出非常高的效率。 |
| 72 | + |
| 73 | +已经对机器 B 在同一数据中心内以及跨数据中心延迟为 10ms、100ms 和 1000ms 的场景下进行了随时间变化的吞吐量比较。具体结果如下图所示。 |
| 74 | + |
| 75 | +<img src="media/image-20240829081015123.png" alt="image-20240829081015123" style="zoom:150%;" /> |
| 76 | + |
| 77 | +图 1-7. 默认多领导者 Paxos 算法的性能测试结果。 |
| 78 | + |
| 79 | +从图中可以明显看出,在 Group Replication 的默认模式下,跨数据中心的吞吐量与理论预期有很大偏差。例如,在网络延迟为 10ms 的场景中,集群的吞吐量降至原来水平的五分之一。为了解决这一差异,从 MySQL 8.0.27 开始,引入了 *group_replication_paxos_single_leader* 选项。启用此选项将使用单领导者 Paxos 算法而不是默认的多领导者 Paxos 算法。 |
| 80 | + |
| 81 | +将 Group Replication 配置为使用单领导者 Paxos 算法后,使用 SysBench 测试工具在相同条件下进行了测试。测试结果如下。 |
| 82 | + |
| 83 | +<img src="media/image-20240829081049988.png" alt="image-20240829081049988" style="zoom:150%;" /> |
| 84 | + |
| 85 | +图 1-8. 单领导者 Paxos 算法的性能测试结果。 |
| 86 | + |
| 87 | +从图中可以明显看出,单领导者模式的结果明显优于之前的结果。然而,缺点是单领导者模式只能在 MySQL 的单主模式下运行,其应用范围有限,无法应用于需要读写操作强一致性的场景。 |
| 88 | + |
| 89 | +对底层 Paxos 算法的这种修改真的是最优解决方案吗?这将在接下来的章节中深入探讨。 |
| 90 | + |
| 91 | +### 1.2.5 Group Replication:本地主机部署报告不可达 |
| 92 | + |
| 93 | +在同一台机器上部署两个节点的 Group Replication,这些节点之间通过 localhost 通信,理论上在正常条件下不应遇到与网络相关的抖动、丢包或对等节点不可达的问题。 |
| 94 | + |
| 95 | + |
| 96 | + |
| 97 | +图 1-9. Performance Schema 显示的本地主机部署关系。 |
| 98 | + |
| 99 | +在使用 BenchmarkSQL 进行 TPC-C 数据加载测试的正常压力下,MySQL 错误日志显示主节点和从节点多次报告对方不可达。 |
| 100 | + |
| 101 | +以下是 MySQL 主节点错误日志的部分截图: |
| 102 | + |
| 103 | + |
| 104 | + |
| 105 | +图 1-10. MySQL 主节点错误日志的部分截图。 |
| 106 | + |
| 107 | +以下是 MySQL 从节点错误日志的部分截图: |
| 108 | + |
| 109 | + |
| 110 | + |
| 111 | +图 1-11. MySQL 从节点错误日志的部分截图。 |
| 112 | + |
| 113 | +从这些日志中,可以明显看到指示"已变得不可达(has become unreachable)"的警告。在正常条件下,像这样在本地主机场景中频繁出现"不可达"报告是意料之外的。将 Group Replication 延迟问题处理归咎于网络并非最佳做法。未来的章节将探讨对网络探测机制的增强,以解决这些误报问题。 |
| 114 | + |
| 115 | +## 1.3 总结 |
| 116 | + |
| 117 | +本章分析了用户如何解决 MySQL 问题。MySQL 8.0 在改进方面取得了长足进步,特别是在缓解可扩展性问题和引入对哈希连接的支持方面,这是一个积极的发展。然而,仍然存在许多未解决的问题,既有长期存在的问题,也有新出现的问题。有效解决 MySQL 问题需要对问题和相关理论有透彻的理解;否则,理解可能不完整。 |
| 118 | + |
| 119 | +下一章将通过各种案例研究展示解决晦涩的 MySQL 问题所面临的巨大挑战。需要广泛的知识基础和大量的逻辑推理才能找出这些问题的根本原因。 |
| 120 | + |
| 121 | +[下一页](Chapter2_zh.md) |
0 commit comments