读书笔记之-《高性能MySQL》

原文链接: http://blog.51cto.com/sbp810050504/2428524

数据库相关的知识,看了《高性能MySQL》和《数据库系统实现》两本。两本书综合看效果更好。 《高性能MySQL》从使用的角度入手,《数据库系统实现》从原理的角度入手。以前学习数据库相关的知识时有个执念,一定要弄明白它是怎么实现的,就直接买了一个《MySQL内核:Innodb存储引擎》,结果看不懂,束之高阁。

数据库的知识,个人觉得如下的顺序比较合理。

硬盘

《数据库系统实现》在第二章就单独用一章的篇幅讲解磁盘的存储原理。这是因为计算机内置组件中具备持久存储能力的只有硬盘,软件屈从于硬件。因此理解磁盘的存储特点才能理解软件设计背后的逻辑。磁盘存储有如下的特点:

  1. 特性A:相比CPU的延迟,磁盘延迟非常非常大。 在《性能之巅》中有做过对比,对于3.3GHz的CPU, 一个指令周期为0.3ns;机械硬盘一次I/O的延迟为1~10ms。这个差距有多大,如果一个CPU指令周期为1s, 那么机械硬盘一次I/O的延迟为1~12个月。真是等到花儿都谢了。

  2. 特性B:磁盘是块设备,每次写入都是按块来的。通常一个块为512byte。即使用硬盘,得注意不能用轮船只运输一个土豆到美国

  3. 特性C:顺序IO的性能远远高于随机IO的性能。因为顺序IO避免了寻道时间和旋转延迟。

上述的特性不仅影响了数据库的设计,更是深刻影响了操作系统的设计,例如page cache

读写

数据库的操作基本上就是更高阶的读写: select 和 delete/update 是我们使用数据库频率最高的操作了。 所以,数据库解决的核心问题就是如何组织数据实现高性能的读写。

###事务
高性能没法忽略掉并发,在并发读写场景下,就会出现数据一致性的问题。所以事务就用来解决数据一致性的问题了。

默认每条SQL语句都是一个事务, 可以手动设置提交点改变这一规则

在MySQL中,事务的隔离级别有4种。这4种其实不用死记硬背,可以从应用场景推导出来。

未提交读

事物A修改了记录a, 没有提交;事务B读取表,读取到了该事务。 这就是未提交读。 如果我们自己设计数据库,在原数据上修改字段,如果没有其他手段的控制,并发情况下就会出现这种情况。由于读取到了脏数据,也称为脏读。这里我们也可以将事务换一个熟悉的概念:线程来理解

提交读

针对上面未提交读的问题,如果将改动保存在事务的作用域内部,那么未提交的数据就不会影响其他事务。 这种隔离级别就是提交读。也叫不可重复读。因为失误内部两次执行可能得到不一样的结果。

可重复读

提交读面临的不可重复读的问题,在可重复读隔离级别下可以避免。它能保证一个事务多次读取同一条记录不会改变。当然,如果事务内部改变了该记录,另说。这个级别带来的另一个问题就是[幻读]。 这个很好理解: 2个事务。事务A 读取记录不存在就写入;事务B写入记录。 事务A有可能出现写入失败的情况。

可序列化

将事务顺序执行。性能最低的做法。

索引

通常查询数据有两种典型的场景: 等值查询区间查询。 即select * from table where field=a 或者 select * from table where field between a and b。 如果没有索引,唯一的做法就是全表扫描。这是一种大海捞针的做法。 程序员一般关注两个点: 问题在哪和怎么优化。 对于等值查询,最好的优化方式就是hash了。对于区间查询,不是hash算法的用武之地,因为它有个隐藏的逻辑: 排序。 通常,具备排序功能的数据结构有: 排序后的数组,链表。 跳跃表。AVL树,红黑树,B树,B+树。

为什么选择B+树?

  1. 硬盘是块设备。使用B+树,可以通过在同一个块中容纳N个元素,从而控制B树的层级不超过3层。减小IO的次数。
  2. B+树叶子节点是链表。方便磁盘顺序IO的操作。

性能

性能就是响应时间。 性能问题的排查思路是top-down的方式:

  1. CPU,内存,网络,IO, 硬盘是否OK?
  2. 不OK只有3种情况: 余量不足 或者 配置不合理 或者 出故障了。
  3. 索引优化, 表结构优化,查询优化 其头并进。

性能问题需要更多是操作系统相关的知识。

复制

这个是MySQL的杀手锏。如果没有复制功能,MySQL不可能这么流行。 复制引申出来的特性: 读写分离,负载均衡,高可用,故障切换, 备份, 测试升级。都是滥大街的概念。

复制的实现方式:基于行的复制和基于日志的复制。

可扩展性

可扩展性就是通过增加资源来提升系统容量的能力。比如MySQL通过读写分离,每新增一个Slave节点,数据库层面的读并发能力有所提升。当然由于系统分层,每个层级都支持可扩展性,整个系统才具备可扩展性。

数据库层级的扩展常用策略就是分库分表这些策略了。

另外,可扩展性跟系统性能是两回事。 比如Hive性能较低,但是不影响其可扩展性。

高可用

高可用本质上就是更少的宕机时间。 如果从计算机的视角来看待人,人的可用性一般只有50%,按每天8小时工作制,人的可用性只有33%。

利用top-down的思路, 实现高可用,只有两种办法: 提升平均失效时间间隔, 简而言之,就是让系统两次宕机中间的时间间隔越长越好;降低平均恢复时间, 简而言之,就是出了故障修复时间越短越好。 所以,高可用更多的是架构层面的东西, 比如MySQL的互为主备,负载均衡。

备份

备份是个容易被忽略的话题。属于那种平时不待见,关键时刻需要扛雷。 备份的作用基本有三个: 灾难恢复,审计,测试。

《高性能MySQL》是一本兼顾深度和广度的书,没有那么多的原理性细节,适合开发阅读。如果想更深入学习,估计《数据库系统实现》是一本比较适合的书。

你可能感兴趣的:(读书笔记之-《高性能MySQL》)