1、锁mysql
1)锁是数据库系统区别于文件系统的一个关键特性,数据库使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。算法
2)每一种数据库实现锁的方式都不一样。sql
共享锁:容许事务读一行数据。当一个事务得到行h的共享锁,那么另外的事务也能够当即得到行h的共享锁,这种状况叫锁兼容数据库
排他锁:容许事务删除或更新一行数据。在上面的状况中,若是有事务想要获取行h的排他锁,则必须等待事务释放行h上的共享锁。这种状况叫锁不兼容服务器
为支持在不一样粒度上进行加锁操做,InnoDB存储引擎还支持一种额外的锁方式:意向锁,InnoDB支持两种意向锁:架构
意向共享锁:事务想要获取表中某几行的共享锁并发
意向排他锁:事务想要获取表中某几行的排他锁ide
查看当前事务中锁的状况,可以使用如下三张表(MySQL 5.7中已经不提倡使用,这几种表已经deprecated):性能
l INFORMATION_SCHEMA.INNODB_TRXspa
l INFORMATION_SCHEMA.LOCKS
l INNODB_LOCK_WAITS
1、一致性的非锁定读操做(重点)
指InnoDB存储引擎经过行多版本控制的方式来读取当前执行时间数据库中行的数据。若是读取的行正在执行DELETE、UPDATE操做,这时读取操做不会所以而会等待行上锁的释放,相反,InnoDB存储引擎会去读取行的一个快照数据
快照数据实际上是当前行数据以前的历史版本,可能有多个版本,一个行可能有不止一个快照数据,咱们称这种技术为行多版本技术,由此带来的并发控制,称为多版本并发控制(MVCC)。
在Read Committed的事务隔离级别下,对于快照数据,非一致性读老是读取被锁定行的最新一份快照数据。
在Repeatable Read的事务隔离级别(InnoDB的默认隔离级别)下,则老是读取事务开始时的行数据版本。
2、SELECT…FOR UPDATE,SELECT…LOCK IN SHARE MODE
InnoDB对SELECT支持两种锁定:
SELECT…FOR UPDATE:对读取的行记录加一个排他锁,其余任何锁都会被阻塞
SELECT…LOCK IN SHARE MODE:对读取的行记录加一个共享锁。其余事务能够向锁定的记录加共享锁,可是对于加排他锁,则会阻塞。
对于非一致性读锁定读,即便读取的行已经被使用SELECT…FOR UDPADE,也是能够进行读取的。
3、外键和锁
对于一个外键,若是没有显示地对这个列加索引,InnoDB存储引擎自动对其加一个索引。
对父表的SELECT操做,不是使用一致性非锁定的方式,由于这样会发生数据不一致的问题,所以这时使用的是SELECT…LOCK IN SHARE MODE方式。主动对父表加一个S锁,若是这时父表上已经加了排他锁,那么子表上的操做会阻塞。
4、锁的算法(重点)
InnoDB中有三种行锁的算法:
Record Lock:单个行记录上的锁
Gap Lock:间隙锁,锁定一个范围,但不包括记录自己
Next-Key Lock:Gap Lock+Record Lock,锁定一个范围,而且锁定记录自己。
实验:演示Next-Key Lock算法:
1)创建表:
2)插入数据
这里插入了6条数据。
3)打开两个会话:A(左)和B
可看到会话B阻塞住了,由于这是使用的Next-Key Lock算法下,锁定的是(-无穷, 8)数值区间的全部数值。可是插入9是能够的,由于9不在这个范围,对于单值得索引查询,不须要Gap Lock,只须要加一个Record Lock便可。
注意:InnoDB在REPEATABLE READ模式下,Next-Key Lock是默认的行记录锁定算法
5、锁问题
1)丢失更新:多用户计算机系统中,各个用户将远程数据库服务器中的同一行数据读到本地内存中,当各个用户在本地更新并提交数据库后,可能会出现有些用户的更新操做丢失的状况
解决办法:须要将事务变成串行操做,而不是并发操做.
2)脏读:首先有两个概念:脏页指在缓冲池中已经修改的页,但尚未刷新到磁盘,即数据库实例内存中的页和磁盘的页中的数据是不一致的。而脏数据是指缓冲池中被修改的数据,而且尚未提交。
脏读指的是在不一样事务下,能够读到另外事务未提交的数据,便可读到脏数据。
解决办法:发生脏读的条件是事务的隔离级别为READ UNCOMMITTED。
3)不可重复读:指一个事务内屡次读同一个数据,在这个事务尚未结束前,另外事务也访问该同一数据。那么在第一个事务的两次读数据之间,因为第二个事务的更改,第一个事务两次读到的数据可能不同。
不可重读读和脏读的区别是:脏读是读到未提交的数据,而不可重复读读到的确实是已提交的数据,但违反了数据库事务的一致性要求。不可重复读又称为幻象问题,InnoDB存储引擎使用Next-Key Lock避免不可重复读问题。
六、阻塞
一个事务中的锁须要等待另外一个事务中的锁释放它的资源
2、索引、事务
索引
一个较为容易误解的问题是:B+树索引能找到的只是被查找数据行所在的页,而后数据库经过把页读入内存,再在内存中进行查找,最后获得查找的数据。查找方式通常为二分查找。
索引的使用:
一、对高选择性字段并从表中取出不多一部分行时,对这个字段添加B+树索引是很是必要的;
二、对于联合索引,对联合字段的查找,然而此时若对非第一列进行查找,效率较低,由于B+树中以联合字段的形式进行排序;能够对第二字段进行排序,这样可避免再一次的排序。
事务:
InnoDB存储引擎的事务彻底符合ACID(原子性、一致性、隔离性、持久性)
日志的实现主要靠redo(重作)、undo记录
一、事务控制语句:
Ø START TRANSACTION | BEGIN
Ø COMMIT
Ø ROLLBACK
Ø SAVEPOINT identifier
Ø RELEASE SAVEPOINT identifier
Ø ROLLBACK TO [SAVEPOINT] identifier
Ø SET TRACSACTION
二、隐式提交的SQL语句
Ø DDL语句
Ø 用来隐式地修改mysql架构的操做
Ø 管理语句
三、事务隔离级别
Ø READ UNCOMMITEED:读不可提交,在另外一个事务没有提交的状况下,也能读取,可能会出现脏读状况
Ø READ COMMITTED:不可重复读,在事务还未提交的状况下,另外一事务改变一个数据并提交后,本事务在未提交的状况下能读取变动后的数据。这种状况就是幻读。因此该种隔离级别会出现幻读现象。
Ø REPEATABLE READ:可重复读,可避免脏读以及幻读现象,在本事务未提交的状况下不会读到不一样的数据。
Ø SERIALIZATION:序列化,没有并发,虽能避免脏读、幻读等状况,但性能较低
四、很差的事务习惯
1)在循环中提交;
2)使用自动提交;
3)使用自动回滚。