数据库锁机制简单来讲就是数据库为了保证数据的一致性而使各类共享资源在被并发访问时,使得访问有序所设计的一种规则数据库
锁机制是针对存储引擎的,不一样的引擎有不一样的优化设计并发
MySQL有三种类型的锁定机制:行级锁定、页级锁定、表级锁定高并发
MySQL的InnoDB和MyISAM储存引擎最大的区别就是:事务的支持、行级锁的支持性能
在上面咱们有讲到MySQL有三种锁机制,下面对其进行详细的说明:学习
行级锁定优化
对一条数据进行锁定,锁定粒度最小,正是由于如此可以使得程序能够尽量大的并发访问数据库,提高高并发系统的总体性能有优势就有缺点,虽然在并发处理能力上有较大的优点,可是行级锁的粒度最小,每次获取锁和释放锁都须要额外的消耗,此外行级锁有死锁隐患spa
页级锁定设计
页级锁定是MySQL中比较特殊的一种锁定机制,锁定粒度介于行级锁定和表级锁定,也有死锁隐患blog
表级锁定索引
直接将整个表锁定,是MySQL中最大粒度的锁定机制,最大的特色是实现逻辑很是简单,带来的系统负面影响最小,获取与释放锁速度都很快,但因为锁定的粒度最大,处理并发需求很弱,但能够消除死锁隐患
可概括为:
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的几率最高,并发度最低;
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的几率最低,并发度也最高;
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度通常。
MySQL的表级锁有两种模式:表共享读锁、表独占写锁
查看表级锁定争用状态变量: show status like 'table%';
table_locks_immediate:产生表级锁定的次数;
table_locks_waited:出现表级锁定争用而发生等待的次数;
手动增长表锁 : lock table 表名称 read(write),表名称2 read(write),其余;
查询表锁状况:show open tables;
删除表锁:unlock tables;
仍是讲解一下:
首先咱们在第一个链接里面 使用 lock table oyherTest read; 给otherTest表上了一个读锁
而后咱们再当前会话进行查询,能够发现咱们能够查询到数据
在当前链接,当咱们想往表中更改数据的时候,发现报错了,若是其余链接想更改数据,会处于等待状态
当咱们使用 unlock tables; 释放全部锁的时候,其余的链接对该表的更改会生效
你们都知道,咱们当前使用的MySQL的默认储存引擎就是InnoDB,下面对其的锁机制进行学习
共享锁:容许一个事务去读一行,阻止其余事务来获取相同数据集的,是一个排它锁
排它锁:容许得到该锁的事务更新数据,阻止其余事务获取相同数据集的共享读锁和排他写锁
对于update、delete、insert语句,InnoDB会自动给涉及数据集加排它锁
对于普通select语句,InnoDB不会加任何锁,事务能够经过如下语句显示给记录集加共享锁或排它锁
共享锁:select * from table_name where ... lock in share mode;
排它锁:select * from table_name where ... for update;
InnoDB行锁是用过给索引项加锁来实现的,所以InoDB这种行锁实现的特色就意味着,只有经过索引条件检索数据,InnoDB才会使用行级锁,不然,InnoDB将会使用表锁;
InnoDb的行级锁一样分为两种类型:共享锁、排它锁
而在锁定机制的实现过程当中为了让行级锁和表级锁共存,InnoDB使用了意向锁,也就有了意向共享/排他锁
InnoDb的锁定是经过在指向数据记录的第一个索引键以前和最后一个索引键以后的区间上标记锁定信息,因此select 查询过程当中经过范围查询的话,就会锁定整个范围内全部的索引键值,即便这个键值并不存在
Innodb所使用的行级锁定争用状态查看:show status like 'innodb_row_lock%';
Innodb_row_lock_current_waits:当前正在等待锁定的数量;
Innodb_row_lock_time:从系统启动到如今锁定总时间长度;
Innodb_row_lock_time_avg:每次等待所花平均时间;
Innodb_row_lock_time_max:从系统启动到如今等待最常的一次所花的时间;
lnnodb_row_lock_waits:系统启动后到如今总共等待的次数;
行锁的基本演示:
在有索引的状况下,是行级锁定
咱们依次设置关闭自动提交,这时会话一的链接会得到锁
而后咱们在更改表中的数据,在未commit以前,咱们在会话二中也对同一行数据进行更改,会处于阻塞状态
会话一commit提交后释放锁,此时处于阻塞状态的会话二也相继完成更改,最后提交
在无索引的状况下升级为表锁
在自动提交关闭的状况下继续演示,咱们不是用索引更改一条数据
在还没有提交的状况下,咱们经过会话二,对表中的其余行数据进行更改,会处于阻塞状态
当会话一提交完成后,会话二相继完成更改操做
至于死锁的话,我就口头表述一下:
在自动提交关闭的状况下,会话一使用索引对表中的一行数据进行了更改,此时为行级锁定,
会话二此时也经过索引对另外一条数据发生了更改操做,也是行级锁定
在上面的环境下,会话一相对会话二所操做的数据进行更改,会话二也想对会话一所操做的数据进行更改