十4、MySQL中的锁机制 - 系统的撸一遍MySQL

以前在上文已经记录过锁的简单应用今天更深刻的了解一下MySQL中的锁。php

锁的类型

锁类型 存储引擎 特色
表级锁 MyISAM、MEMORY、InnoDB(非默认) 开销小,加锁快,不会死锁,颗粒大,并发低。
行级锁 InnoDB 开销大,加锁慢,会死锁,颗粒小,并发高。
页面锁 BDB 介于以上两种之间,会死锁。

MyISAM中的表级锁

锁的模式

表级锁支持两种模式,共享读锁和独占写锁。sql

共享读锁

READ锁定后,当前线程不能够写入,其余线程写入会被阻塞到解锁后执行,查询不受影响。并发

独占写锁

WRITE锁定后,当前线程能够插入查询,其余进行插入查询会被阻塞到解锁后执行。spa

查看表等待数量.net

//查看表等待次数
show status like 'table%';

通常会体如今 table_locks_waited中,若是比较高说明发生大量锁等待。线程

锁的用法

MySQL执行读写操做会自动进行锁定,通常不须要显示指定。code

锁的使用方法能够参考:锁的简单应用blog

LOCK TABLES table_name READ LOCAL;

LOCAL表示容许获取读锁的时候在表结尾进行并发插入。索引

MySQL能够经过 concurrent_insert 来控制并发插入。进程

concurrent_insert 为 0 的时候不容许并发插入。

concurrent_insert 为1 的时候,若是表中不存在空洞能够在结尾插入。

concurrent_insert 为 2 的时候,是否有空洞都容许结尾插入。

锁的调度

若是加锁的时候已经被其余线程锁定,则会阻塞到其余线程解锁。

若是两个进程同时进行读锁和写锁的请求,那么写锁会优先执行,哪怕读锁先到。

咱们能够经过 low-priorty-updates 参数来设置优先级别。

SET LOW_PRIORITY_UPDATES=1;
SET LOW_PRIORITY_INSERT=1;
SET LOW_PRIORITY_DELETE=1;

经过设置来下降写的优先级。

同时还能够经过设置 max_write_lock_count 来实现锁等待超过必定数量后读优先,用于避免大量写操做致使查询阻塞。

InnoDB中的行几锁和事务

事务的ACID原则

原子性

事务做为一个单独的处理单元具备原子性,要么所有执行,要么所有不执行

一致性

事务的开始和结束都保持一致状态,事务结束的时候必须保证数据是正确的。

隔离性

并发事务的状况下,不容许互相影响,每一个事务必须是隔离开的。

持久性

事务一旦提交便永久生效。

并发事务出现的问题

更新丢失

两个并发事务A和B,A和B同时读取了数据,A修改数据提交后,B页修改数据进行提交,会覆盖A种修改的数据。

脏读

两个并发事务A和B,A读取并修改了数据可是没有提交,B此时读取了A修改后的数据并提交,此时A回滚了数据,那么B提交的数据会成为脏数据。

不可重复读

一个事务读取数据后,再次读取数据(同一条数据)发现两次数据不一致。

幻读

一个事务读取数据后,再次读取数据(相同条件读取的数据),发现其余事务插入了知足条件的新数据。

事务的4种隔离机制

未提交读

经过排他锁避免更新丢失。

这个级别的事务能够读取到其余事务的未提交数据,因此会产生脏读。

已提交读

经过排他锁和共享空间锁来避免更新丢失和脏读。

这个级别的事务能够读取到其余事务已经提交的数据,因此屡次读取会出现“不可重复读”。

可重复读

经过排他锁和共享空间锁来避免更新丢失和脏读,在进行读锁的时候禁止写锁执行,写锁的时候禁止任何锁执行,用于避免重复读。

可序列化

最为严格的隔离机制,经过串行的方式保证事务一个一个执行。

//查看隔离级别
select @@global.tx_isolation,@@tx_isolation;

查看InnoDB锁状态

show status like 'innodb_row_lock%';

经过查看返回结果中 锁等待次数和平均等待时间来判断当前锁情况,若是比较高说明当前锁竞争严重,能够经过查看 schema.innodb_locks来进一步查询。

InnoDB的行锁

共享锁(S):对一行数据开启共享锁,会阻止其余数据对这行数据开启排他锁。

排他锁(X):得到排他锁的数据能够写数据,其余数据不能够得到共享锁或排他锁。

为了兼容表级锁,实现了如下两种锁。

意向共享锁(IS):事务获得共享锁以前先取得该锁。

意向排他锁(IX):事务获得排他锁以前先取得该锁。

加锁的模式

InnoDB种不须要显式的加锁,会在执行语句时候自动加锁解锁。

InnoDB行锁经过给索引上的索引项加锁,没有索引会加载汇集索引上。

三种索引方式

一、Record lock:直接对索引项加锁

二、Gap lock:对索引项第一条和最后一条的位置加锁(GAP锁)用于防止幻读(RC、RR隔离级别)。

三、Next-key lock:二者结合

InnoDB加锁若是使用索引(非主键),会同时给索引项和汇集索引项加锁。

范围查询的时候会锁住范围内的全部索引项。

注意:若是检索数据没有经过索引条件检索(全表扫描),那么将对表中全部数据加锁。

相关文章
相关标签/搜索