目录:
1. 前言。
2. 并发控制。
3. 事务。
4. 多版本并发控制。
5. 存储引擎。
此篇文章主要是归纳了在使用MySQL两年多时间中了解到的点。仅供参考,若有说错或者有补充欢迎评论。
MySQL的并发控制是比较复杂的,资历不深。这里就简单聊聊MySQL控制并发读写。
1、读写锁
1.1 读锁(共享锁):读锁是共享的,多个客户端同时读取同一个资源,相互间是没有干扰的。
1.2 写锁(排他锁):写锁具有排他性,当一个资源被写锁占用时候,mysql会阻塞其他的写锁或读锁。
* 写锁的优先级高于读锁,所以写锁可以插队。
2、锁粒度
2.1 表锁:锁定整表,当进行一个写操作时候需要申请获得写锁。阻塞其他读写锁。一般由存储引擎管理实现,但是有些时候mysql自己会使用表锁。比如 ALTER TABLE (版本5.6之后好像不会锁表,可以去mysql官网细看)。
2.2 行锁:锁定影响的行。缺点也很明显,开销远大于表锁。
事务可以由四点来表述:
1. 原子性:在事务中的操作只有两种结果。第一全部成功;第二全部失败(回滚)。
2. 一致性:这一点很像原子性,从一个一致性的状态切换到另一个一致性的状态。
3. 隔离性:一个事务在最终提交前对于其他事务是“不可见的”。
4. 持久性:事务提交后永久保存。(我在想 要是还没进行刷盘,突然断电。哈哈哈!)
上面第三点提到的隔离性在MySQL中由隔离级别来细说:
3.1 未提交读
这种级别应该很少用到。因为一个事务可以读取其他事务没有提交的数据,常常产生“脏读”。
3.2 提交读(不可重复读)
定义:一个事务开始时候能看的数据一定是其他事务提交了的。解决了“脏读”。
保证了读到的任何数据都是提交的数据,避免读到中间的未提交的数据。但是不保证事务重新读的时候能读到相同的数据,因为在每次数据读完之后其他事务可以修改刚才读到的数据。
3.3 可重复读
定义:保证同一个事务过程读不同时间读取同一个数据是一致的。解决了“脏读”。
我在想假如一个事务读取范围内的数据增加了尼?另一个事务插入了新的数据怎么办?原来这叫“幻读”,听说MVCC会解决这个问题。
* 该隔离级别是MySQL默认的事务隔离级别。
3.4 可串行化
这个是最高的隔离级别了,会在事务读取的每一行都加上锁。优缺点都很明显,数据一致性高,并发低。
特性总结如下表:
隔离级别 是否会脏读 是否会不可重复读 是否会幻读 是否会加锁读
未提交读 是 是 是 否
提交读 否 是 是 否
可重复读 否 否 是 否
可串行化 否 否 否 是
更改MySQl隔离级别: set transaction isolation level + 隔离级别(英文名自行查)
我太难了,看不懂。 过几年再说.....
这一节我打算说下我常用的俩个:innoDB、tokuDB。
1. innoDB
特性:数据和索引单独存放、支持上诉四个隔离级别(默认可重复读)、通过间歇锁解决幻读(不仅锁定事务中读取的行,还会锁定索引中的间隙,防止幻影行插入)。
注意:innoDB是基于聚族索引建立的,默认主键似乎不能更改。所以innoDB就算你不见主键也会自动建一个隐形的。其他二级索引都会包含主键列(B-tree),索引主键列尽量小些。
2. tokuDB
特性:支持全事务等等巴拉巴拉。
我喜欢他的点:
2.1 允许直接给表增加索引而不影响更新语句(insert, update 等)的执行。通过 CREATE INDEX方法,不要用ALTER TABLE。
2.2 可以在轻微阻塞更新或查询语句的情况下, 允许实现以下操作
增删列
增加 char, varchar, varbinary 和 int 类型的列
命名列, 不支持字段类型: TIME、ENUM、BLOB、 TINYBLOB、 MEDIUMBLOB、LONGBLOB。
2.3 数据压缩,支持多种压缩级别。作为日志表存储是真好!
总的来说,就是真男人,快!!!