Mysql 逻辑架构
- 读写锁
读锁(共享锁):读锁时共享的,不互相阻塞的,多个用户可以在同一时刻同时读取同一个资源,而互不干扰。
写锁(排它锁):写锁是排它的,一个写锁会阻塞其他写锁和读锁,保证在给定时间内只能有一个用户写入,并防止其他用户读取正在写入的同一资源。 - 锁粒度
表锁:mysql最基本的锁策略,开销最小的策略。即锁定整张表,写锁比读锁有更高的优先级,写锁请 求会被加入到读锁队列之前,从而阻塞其他锁。服务器层可以实现控制表锁,alter table语句时服务器层就会给整张表加上表锁,忽略引擎层的锁机制。
行级锁:最大程度的支持并发处理,同时也带来最大的锁开销。不需要对整张表锁定,而只是锁定对应的行。行级锁只在存储引擎层实现。服务器层完全不了解引擎层的锁实现。 - 事务(ACID)
原子性(automicity):一个事物是一个不可分割的最小执行单元,事务内的任务要么全部执行成功提交,要么全部失败回滚,不可能只执行其中一部分。
一致性(consistency):数据库总是从一个一致性状态转换到另一个一致性状态。
隔离性(isolation):一般情况下,一个事务所做的修改在最终提交之前,对于其它事务是不可见的。
持久性(durability):一旦事务提交,其所做的修改就会永久保存到数据库中,要保证即使系统崩溃修改的数据也不会丢失。 - 隔离级别
未提交读(read uncommitted):一个事物中所做的修改,及时没有提交,对其他事务也是可见的。事务可以读取未提交的数据,就会产生脏读。实际情况中几乎不会使用。
提交读(read committed):大多数数据库的默认隔离级别。一个事务开始时只能看见已提交的事务所做的修改,及满足隔离性的基本定义。也叫作不可重复读,应为执行两个同样的查询,可能会得到不一样的结果。
可重复读(repeatable read):mysql的默认事务隔离级别。该级别保证在同一个事务中多次读取同样记录的结果是一致的。但还是无法解决幻读问题,幻读是指,当前的某个事务在读取某个范围的记录数据时,另外一个事务又在该范围内插入了新的记录数据,导致当前事务再次读取该范围记录时,就会产生幻行。mvcc解决换行问题。
可串行化(serializable):最高隔离级别,强制事务串行执行,避免幻读问题。即对读取的每一行数据都加锁,从而导致大量超时及锁竞争。一般也很难使用到。
- 死锁
死锁是指两个或者多个事务在同一个资源上互相占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。占用对方的需要资源,又依赖对方释放自己所需资源才能完成整个事务。
死锁检测机制和死锁超时机制用于处理死锁问题。
InnoDB目前处理死锁的方法是将持有最少行级排它锁的事务进行回滚。 - 事务日志
- 多版本并发控制
行级锁的变种,在很多情况下避免了加锁操作,因此开销更低。
举例: