1.1.大多数基于网络的客户端/服务器工具或服务器都有类似的服务
1.1.1.连接处理
1.1.2.身份验证
1.1.3.确保安全性
1.2.核心层
1.2.1.查询解析、分析、优化、以及所有的内置函数
1.2.2.跨存储引擎的功能
1.2.2.1.存储过程
1.2.2.2.触发器
1.2.2.3.视图
1.3.存储引擎层
1.3.1.存储引擎负责MySQL中数据的存储和提取
1.3.2.和GNU/Linux下的各种文件系统一样,每种存储引擎都有其优势和劣势
1.3.3.优化器并不关心表使用的是什么存储引擎,但存储引擎对于查询优化是有影响的
2.查询缓存2.1.qurycach
2.2.随着并发性的增加,查询缓存成为一个让人诟病的瓶颈
2.3.MySQL5.7.20版本开始,查询缓存已经被官方标注为被弃用的特性
2.4.在8.0版本中被完全移除
2.5.缓存被频繁请求的结果集依然是一个很好的实践
2.5.1.一个流行的设计模式是在mmcachd或Rdis中缓存数据
3.并发控制3.1.只要有多个查询需要同时修改数据,就会产生并发控制问题
3.2.并发控制的级别
3.2.1.服务器级别
3.2.2.存储引擎级别
3.3.读写锁
3.3.1.从电子表格中读取数据不会有什么麻烦,即使很多人同时读取也不会有问题
3.3.2.读锁(radlock)
3.3.2.1.共享锁(shardlock)
3.3.2.2.资源上的读锁是共享的,或者说是相互不阻塞的
3.3.3.写锁(writlock)
3.3.3.1.排他锁(xclusivlock)
3.3.3.2.写锁则是排他的,也就是说,一个写锁既会阻塞读锁也会阻塞其他的写锁
3.3.3.3.只有这样才能确保在特定的时间点只有一个客户端能执行写入,并防止其他客户端读取正在写入的资源
3.3.3.3.1.这是出于安全策略的考虑
3.3.4.处理并发读/写访问的系统通常实现一个由两种锁类型组成的锁系统
3.3.5.在实际的数据库系统中,每时每刻都在发生锁定
3.3.6.如果数据库服务器以可接受的方式执行,锁的管理速度足够快,那么不会引起客户端的感知
3.3.7.锁是数据库实现一致性保证的方法
3.4.锁的粒度
3.4.1.一种提高共享资源并发性的方式就是让锁定对象更有选择性
3.4.2.尽量只锁定包含需要修改的部分数据,而不是所有的资源
3.4.3.只对需要修改的数据片段进行精确的锁定
3.4.4.让锁定的数据量最小化,理论上就能保证在给定资源上同时进行更改操作,只要被修改的数据彼此不冲突即可
3.4.5.如果系统花费大量的时间来管理锁,而不是存取数据,那么系统的性能可能会受影响
3.5.锁策略
3.5.1.锁定策略是锁开销和数据安全性之间的平衡,这种平衡会影响性能
3.5.2.表锁(tabllock)
3.5.2.1.MySQL中最基本也是开销最小的锁策略
3.5.2.2.它会锁定整张表
3.5.2.2.1.只有没有人执行写操作时,其他读取的客户端才能获得读锁,读锁之间不会相互阻塞
3.5.2.3.写锁队列和读锁队列是分开的,但写锁队列的优先级绝对高于读队列
3.5.3.行级锁(rowlock)
3.5.3.1.行级锁是在存储引擎而不是服务器中实现的
3.5.3.2.可以最大程度地支持并发处理(也带来了最大的锁开销)
3.5.3.3.允许多人同时编辑不同的行,而不会阻塞彼此
3.5.3.4.一般都是在表中施加行级锁(rowlvllock),为了在锁比较多的情况下尽可能地提供更好的性能,锁的实现方式非常复杂
3.5.3.5.服务器可以执行更多的并发写操作
3.5.3.6.代价是需要承担更多开销
3.5.3.6.1.跟踪谁拥有这些行级锁
3.5.3.6.2.已经锁定了多长时间
3.5.3.6.3.行级锁的类型
3.5.3.6.4.何时该清理不再需要的行级锁
4.事务4.1.事务就是一组SQL语句,作为一个工作单元以原子方式进行处理
4.2.作为事务的一组语句,要么全部执行成功,要么全部执行失败
4.3.存在高度复杂且缓慢的两阶段提交系统的典型原因
4.3.1.为了应对各种失败场景
4.3.1.1.连接可能会断开
4.3.1.2.会超时
4.3.1.3.数据库服务器在操作执行过程中会崩溃
4.4.ACID
4.4.1.原子性(atomicity)
4.4.1.1.一个事务必须被视为一个不可分割的工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚
4.4.2.一致性(consistncy)
4.4.2.1.数据库总是从一个一致性状态转换到下一个一致性状态
4.4.3.隔离性(isolation)
4.4.3.1.一个事务所做的修改在最终提交以前,对其他事务是不可见的,这就是隔离性带来的结果
4.4.4.持久性(durability)
4.4.4.1.一旦提交,事务所做的修改就会被永久保存到数据库中
4.4.4.2.不可能有%的持久性保障
4.4.4.3.如果数据库本身就能做到真正的持久性,那么备份又怎么能增加持久性?
4.4.5.ACID事务和InnoDB引擎提供的保证是MySQL中最强大、最成熟的特性之一
4.4.6.除非系统通过严格的ACID测试,否则空谈事务的概念是不够的
4.5.隔离级别
4.5.1.READUNCOMMITTED(未提交读)
4.5.1.1.在事务中可以查看其他事务中还没有提交的修改
4.5.1.2.从性能上来说,READUNCOMMITTED不会比其他级别好太多,却缺乏其他级别的很多好处
4.5.1.3.在实际应用中一般很少使用
4.5.1.4.读取未提交的数据,也称为脏读(dirtyrad)
4.5.2.READCOMMITTED(提交读)
4.5.2.1.大多数数据库系统的默认隔离级别是READCOMMITTED
4.5.2.1.1.MySQL不是
4.5.2.2.一个事务可以看到其他事务在它开始之后提交的修改
4.5.2.3.在该事务提交之前,其所做的任何修改对其他事务都是不可见的
4.5.2.4.允许不可重复读(nonrpatablrad)
4.5.2.4.1.这意味着同一事务中两次执行相同语句,可能会看到不同的数据结果
4.5.3.REPEATABLEREAD(可重复读)
4.5.3.1.MySQL默认的事务隔离级别
4.5.3.2.保证了在同一个事务中多次读取相同行数据的结果是一样的
4.5.3.3.无法解决另外一个幻读(phantomrad)
4.5.3.4.幻读指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(phantomrow)
4.5.3.5.InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC,MultivrsionConcurrncyControl)解决了幻读的问题
4.5.4.SERIALIZABLE(可串行化)
4.5.4.1.最高的隔离级别
4.5.4.2.通过强制事务按序执行,使不同事务之间不可能产生冲突,从而解决了幻读问题
4.5.4.3.实际应用中很少用到这个隔离级别,除非需要严格确保数据安全且可以接受并发性能下降的结果
4.5.5.隔离级别之间的利与弊
5.死锁5.1.两个或多个事务相互持有和请求相同资源上的锁,产生了循环依赖
5.2.InnoDB存储引擎,检测到循环依赖后会立即返回一个错误信息
5.2.1.死锁将表现为非常缓慢的查询
5.3.一旦发生死锁,如果不回滚其中一个事务(部分或全部),就无法打破死锁
5.4.InnoDB目前处理死锁的方式是将持有最少行级排他锁的事务回滚
5.4.1.这是一种最容易回滚的近似算法
5.5.死锁的产生有双重原因
5.5.1.真正的数据冲突,这种情况通常很难避免
5.5.2.完全是由于存储引擎的实现方式导致的