
Silvia Botros Jeremy Tinley
《高性能 MySQL》一直是 MySQL 领域的经典之作,影响了一代又一代的 DBA 和技术人员,从第3 版出版到第 4 版出版过去了近十年,MySQL 也从 5.5 版本更新到了 8.0 版本。第 4 版中增加了大量对 MySQL 5.7 和 8.0 版本新特性的介绍,删除了一些在新版本中已经废弃或者不再常用的功能,还增加了对云数据库的介绍,减少了在官方文档中已有的基础使用和配置相关的内容。这些年,MySQL 经过在大量大规模互联网场景中的应用验证,使得本书在继续关注高性能之外,还用了较多的篇幅来介绍如何实现 MySQL 的大规模可扩展应用和合规性问题,这是相比第 3 版最大的不同,也是本书封面上所写的“经过大规模运维验证的策略”的体现。本书适合数据库管理员(DBA)阅读,也适合系统运维和开发人员参考学习。不管你是数据库新手还是专家,相信都能从本书中有所收获。
分表如何设计主键问题 因为当一个叶子节点存满后,此时又新增一个新的值,也要插入到这个节点中,那么该节点中的最后一个数据只能往后面的节点移动,而后面的节点又需要继续往后面移动,最终才能给新增的值腾出位置 因为这个过程索引树的结构正在发生变更,所以会加锁防止其他事务读到不对的数据,而挪动数据、加锁阻塞都需要时间,因此树分裂会导致索引性能下降 但如果选择按需递增的字段就不会有这个问题,毕竟每次新增的值,都会直接放入到最后面去插入,并不会导致树结构发生分裂 主键生成的常见思路:UUID、数据库自增和雪花算法 UUID 的弊端有两个 过长 UUID 不是递增的 引发页分裂,页分裂还会造成一个问题,就是逻辑上相邻的两个页,在真实存储的磁盘上,它们可能离得很远,这样就无法利用局部性原理 无法利用顺序读特性 自增主键其实还有一个好处,就是数据会有更大的概率按照主键的大小排序,两条主键相近的记录,在磁盘上位置也是相近的,那么可以预计,在范围查询的时候,我们能够充分利用到磁盘的顺序读特性 数据库步长自增 举个例子,经过分库分表之后我有十个表,那么我可以让每个表按照步长来生成自增 ID。比如说第一个表就是生成 1、11、21、31 这种 ID,第二个表就是生成 2、12、22、32 这种 ID 这种方案非常简单,而且我们本身在应用层并不需要做任何事情,只是需要在创建表的时候指定好步长就可以了。ID 虽然不是全局递增的,但是在一个表内部,他肯定是递增的,这个方案的性能取决于数据库的性能,应用层上面也不需要关注 雪花算法 雪花算法保证 ID 唯一性的理由也很充分了 时间戳是递增的,不同时刻产生的 ID 肯定是不同的 机器 ID 是不同的,同一时刻不同机器的 ID 肯定是不同的 同一时刻同一机器上,可以轻易控制序列号 雪花算法采用 64 位来表示一个 ID,其中 1 比特保留,41 比特表示时间戳,10 比特作为机器 ID,12 比特作为序列号 调整分段: 大多数情况下,如果自己设计一个类似的算法,那么每个字段的含义、长度都是可以灵活控制的。比如说时间戳 41 比特可以改的更短或者更长,比如说 39 比特也能表示十几年,其实也够用 机器 ID 虽然明面上是机器 ID,但是实际上并不是指物理机器,准确说是算法实例。例如,一台机器部署两个进程,每个进程的 ID 是不同的;又或者进一步切割,机器 ID 前半部分表示机器,后半部分可以表示这个机器上用于产生 ID 的进程、线程或者协程。甚至机器 ID 也并不一定非得表示机器,也可以引入一些特定的业务含义。而序列号也是可以考虑加长或者缩短的 雪花算法可以算是一种思想,借助时间戳和分段,我们可以自由切割 ID 的不同比特位,赋予其不同的含义,灵活设计自己的 ID 算法 序列号耗尽 但是这里还有一个问题,就是不管你怎么设计雪花算法,你的序列号长度都有可能不够。比如说前面标准的是 12 比特,那么有没有可能并发非常高,以至于 12 比特在某一个特定的时刻机器上的比特全都用完了呢 一般来说可以考虑加长序列号的长度,比如说缩减时间戳,然后挪给序列号 ID。当然也可以更加简单粗暴地将 64 位的 ID 改成 96 位的 ID,那么序列号 ID 就可以有三四十位,即便是国际大厂也不可能用完了。不过,彻底的兜底方案还是要有的。我们可以考虑引入类似限流的做法,在当前时刻的 ID 已经耗尽之后,可以让业务方等一下。我们的时间戳一般都是毫秒数,那么业务方最多就会等一毫秒 业务方等待算是一个比较危险的方案,因为这可能导致大量业务方阻塞住,导致线程耗尽或者协程耗尽之类的问题。不过如果是偶发性的序列号不够,那么问题不大,因为阻塞的业务方很快就能拿到 ID 那么如果序列号耗尽不是一个偶发性的问题,是长期的问题,那么还是要考虑从业务角度切割,不同业务使用不同的 ID 生成,就不要共享了。又或者,逼不得已还是用 96 或者128 位的,一了百了 数据堆积 在低频场景下,很容易出现序列号几乎没有增长,从而导致数据在经过分库分表之后只落到某一张表里面的情况。为了解决这种问题,可以考虑这么做,序列号部分不再是从 0 开始增长,而是从一个随机数开始增长。还有一个策略就是序列号从上一时刻的序列号开始增长,但是如果上一时刻序列号已经很大了,那么就可以退化为从 0 开始增长。这样的话要比随机数更可控一点,并且性能也要更好一点 一般来说,这个问题只在利用 ID 进行哈希的分库分表里面有解决的意义。在利用 ID 进行范围分库分表的情况下,很显然某一段时间内产生的 ID 都会落到同一张表里面。不过这也是我们的使用范围分库分表预期的行为,不需要解决。 主键内嵌分库分表大多数时候,我们会面临一个问题,就是分库分表的键和主键并不是同一个。比如说在 C 端的订单分库分表,我们可以采用买家 ID 来进行分库分表。但是一些业务场景,比如说查看订单详情,可能是根据主键又或者是根据订单 SN 来查找的 那么我们可以考虑借鉴雪花算法的设计,将主键生成策略和分库分表键结合在一起,也就是说在主键内部嵌入分库分表键。例如,我们可以这样设计订单 ID 的生成策略,在这里我们假设分库分表用的是买家 ID 的后四位。第一段依旧是采用时间戳,但是第二段我们就换成了这个买家后四位,第三段我们采用随机数 普遍情况下,我们都是用买家 ID 来查询对应的订单信息。在别的场景下,比如说我们只有一个订单 ID,这种时候我们可以取出订单 ID 里嵌入进去的买家 ID 后四位,来判断数据存储在哪个库、哪个表。类似的设计还有答题记录按照答题者 ID 来分库分表,但是答题记录 ID 本身可以嵌入这个答题者 ID 中用于分库分表的部分 这一类解决方案,核心就是不拘泥于雪花算法每一段的含义。比如说第二段可以使用具备业务含义的 ID,第三段可以自增,也可以随机。只要我们最终能够保证 ID 生成是全局递增的,并且是独一无二的就可以
整体上写得不错,适合MySQL进阶,标记下个人认为值得学习/有所启发的知识点: 1. Performance Schema的作用,启停和原理; 2. 操作系统和硬件优化:RAID控制器为何能提高写操作I/O,事务系统采用write-ahead logging策略的原因,vmstat/dstat/collectl命令; 3. 优化服务器设置:最小化MySQL配置项,thread_cache_size/skip_name_resolve/innodb_old_blocks_time等配置的作用,推荐生产环境使用innodb_dedicated_server参数组; 4. 后台开发人员重点关注:第六章schema设计与管理,第七章创建高性能索引,第八章查询性能优化; 5. 复制:优先考虑基于行的复制(避免重放故障),优先启用GTID特性执行主从备份,注意启停super_read_only防止误写; 6. 备份与恢复:物理备份工具(Percona XtraBackup),逻辑备份首选(mydumper/myloader),优先考虑物理备份; 7. 扩展MySQL:Vitess,ProxySQL; 8. 推荐补充读物:《SRE: Google运维解密》,《Google SRE工作手册》,《性能之巅:系统、企业与云可观测性》; 当然,也存在不足/待补充的地方,比如,缺少MySQL锁机制,事务二阶段提交,MVCC原理等知识点的讲解。
从23年开始读的这本书,到26年读完。大约过了2年半(警觉) 开始只看了索引以及查询优化。其他的章节都没看懂。所以并不适合新手看。(嗯?如何定义新手呢?) 不过这本书开启了我的mysql优化启蒙之路。
大体上还是推荐阅读,特别是相对于第三版本书更新了很多新版本的内容以及涉及到云和云原生相关的知识。有几点不好的地方,一是有些地方翻译的很生硬,二是翻到最后都没有看到参考链接在哪里可以看到,我从原文补充到评论里不少
写的不好,知识点总是断断续续,很不专业,读起来也很晦涩
刚出版就上架了?不得不说,微信读书有点东西。。。《高性能MySQL》第四版相对于第三版在减少内容的同时竟然保存了所有精华,实在令人感动,本书深入浅出、详略得当,每一句话都值得细细品读,配合官方文档学习效果更棒!数据库基础的学习,看这本书结合官方文档,对于大多数DBA已足够,对于开发者应付日常工作完全绰绰有余。
翻译过来的,感觉有的地方翻译的不到位。而且感觉这本书对开发的帮助不是特别大,或许对运维/DBA有帮助吧,像MVCC、ACID、锁等等讲的不是特别深入。新手小白,或者只工作几年的同学来讲,还是可以读一读的。
非常棒的MySQL学习书籍,虽然说现在pgsql占用率越来越高,但是现在仍然有很多的项目使用MySQL,这本书非常适合进阶,没想到第四版这么快就出来了,基于MySQL8.0的,项目中有数据库需求的可以读一下
翻译真差劲,读起来很拗口,还不如不翻译误人子弟
书里提到的面很宽,比较着重于性能检测方面。另外感觉作者像是 Percona 的布道者似的,从头到尾都在宣传这个软件。