1.行锁:索引加锁算法
2.意向锁数据库
3.间隙锁并发
4.MVCC机制mvc
InnoDB的设计是为了在处理大数据量的时候获得最好的性能。InnoDB存储引擎维护了一个它本身的缓冲区,用来存储数据和索引。InnoDB将表和索引存储在一个表空间中,这个表空间可能由不一样的文件组成。而MyISAM存储引擎的表中每一个表都存在一个独立的文件里面。性能
InnoDB事务模型是将传统的两阶段封锁协议同多版本数据库特性相结合。它采用加行级锁和查询不加锁。大数据
InnoDB行锁是经过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不一样,后者是经过在数据块中对相应数据行加锁来实现的。优化
InnoDB这种行锁实现特色意味着:只有经过索引条件检索数据,InnoDB才使用行级锁,不然,InnoDB将使用表锁。spa
很显然,在使用范围条件检索并锁定记录时,InnoDB这种加锁机制会阻塞符合条件范围内键值的并发插入,这每每会形成严重的锁等待。所以,在实际应用开发中,尤为是并发插入比较多的应用,咱们要尽可能优化业务逻辑,尽可能使用相等条件来访问更新数据,避免使用范围条件。设计
InnoDB支持多种上锁粒度,它容许同时加行锁和表锁。为了支持多粒度锁,引入了一个新的锁,意向锁。意向锁是加在表上的锁。意向锁就是代表某个事务以后要对这个表上的某个行加该类型的锁。索引
共享意向锁IS,代表事务T将要在表T的某些行上加S锁。
排他意向锁IX,代表事务T将要在表T的某些行上加X锁
意向锁协议是:
在某个事务请求行上的S锁以前,它必须先获得该行所在表的IS锁或更强的锁。
在某个事务请求行上的X锁以前,它必须先获得该行所在表的IX锁。
这个规则致使了下面的异常:若是你更新了某个表里面的行,使用SELECT将能够看见最新更新的行和老版本的行。若是其它事务同时更新相同的表,那么你就可能看到根本不可能在数据库中存在的状态。
若是在某人的REPEATABLE READ隔离级别下的话,全部同一事物的全部一致性读都是读的第一次查询时创建的快照。若是想获得最新的快照的话,那么须要提交当前的事务,而后再开始新的查询。
注意:DROP TABLE 和ALTER TABLE语句不使用一致性读。由于DROP TABLE的话,MYSQL不能使用已经删除了的表。而ALTER TABLE的时候,MYSQL是将原来的表复制一份,而后删除掉原来的表。
当咱们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的 索引项加锁;对于键值在条件范围内但并不存在的记录,叫作“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁 (Next-Key锁)
在行级锁中,InnoDB使用一种称为next-key locking的算法。当检索表的一个索引的时候,它对遇到的索引记录加S或X锁。所以行级锁其实是索引记录锁。
InnoDB在索引记录上加锁的时候也影响了索引记录前的‘gap’。若是一个用户拥有索引上某个记录R的S或X锁,另外一个用户不能立刻在记录R前插入一个新的索引记录。这样就能够避免幻象的出现。
Next-key lock是Record lock与Gap lock相结合后的锁。Next-key首先会使用Gap lock锁定范围,而后使用Record lock锁定具体的行。这是REPEATABLE-READ隔离级别的默认处理方式。
再也不单纯的使用行锁来进行数据库的并发控制,取而代之的是,把数据库的行锁与行的多个版本结合起来,只须要很小的开销,就能够实现非锁定读,从而大大提升数据库系统的并发性能。
为了实现mvcc, innodb对每一行都加上了两个隐含的列,其中一列存储行被更新的”时间”,另一列存储行被删除的”时间”. 可是innodb存储的并非绝对的时间,而是与时间对应的数据库系统的版本号。
每当一个事务开始的时候,innodb都会给这个事务分配一个递增的版本号,因此版本号也能够被认为是事务号.对于每个”查询”语句,innodb都会把这个查询语句的版本号同这个查询语句遇到的行的版本号进行对比,而后结合不一样的事务隔离等级,来决定是否返回该行.
在读取数据时,innodb几乎不用获取任何锁,在每一个查询经过版本检查,只获取须要的数据版本,提升系统并发度
缺点:为了实现多版本,innodb必须对每行增长相应字段来存储版本信息,同时须要维护每一行的版本信息,并且
在检索行的时候,须要进行版本的比较,于是减低了查询效率;innodb还须要按期清理再也不须要的行版本,及时回收
空间,这也增长开销;
MySQL加锁处理分析:http://hedengcheng.com/?p=771