mysql锁相关知识点总结
1.mysql server分为3层:服务层、核心层(查询缓存、分析器、优化器、执行器)、存储层。Mysql在5.5之前默认使用MyISAM存储引擎,之后使用InnoDB
1.MySQL事务包含四个特性,号称ACID四大天王。
原子性(Atomicity):语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的;实现主要基于undo log日志实现的。
持久性(Durability:保证事务提交后不会因为宕机等原因导致数据丢失;实现主要基于redo log日志。
隔离性(Isolation):保证事务执行尽可能不受其他事务影响;InnoDB默认的隔离级别是RR,RR的实现主要基于锁机制、数据的隐藏列、undo log和类next-key lock机制。
一致性(Consistency):事务追求的最终目标,一致性的实现既需要数据库层面的保障,也需要应用层面的保障。
2.隔离级别
select @@tx_isolation;
select @@transaction_isolation;
隔离级别 | 脏读 | 不可重复读 | 幻读 |
READ UNCOMMITTED(读未提交) | 可能 | 可能 | 可能 |
READ COMMITTED(读已提交) | 不可能 | 可能 | 可能 |
REPEATABLE READ(可重复读) | 不可能 | 不可能 | 可能 |
SERIALIZABLE(序列化) | 不可能 | 不可能 | 不可能 |
MVVC (多版本并发控制) 的方式,一行实际上会有多个trx_id不同(插入版本号和删除版本号)的记录
对于一个快照来说,它能够读到那些版本数据,要遵循以下规则:
1、当前事务内的更新,可以读到;
2、版本未提交,不能读到;
3、版本已提交,但是却在快照创建后提交的,不能读到;
4、版本已提交,且是在快照创建前提交的,可以读到;
利用上面的规则,再返回去套用到读提交和可重复读的那读已提交和可重复读,两者主要的区别就是在快照的创建上,可重复读仅在事务开始是创建一次,而读提交每次执行语句的时候都要重新创建一次。
2.autocommit
①无论为ON还是OFF,都会在执行sql语句时自动开启事务;②为ON时,执行sql后会自动提交(除非使用BEGIN显式开启了一个事务);③为OFF时,需要用户手动提交
3.InnoDB行锁是通过给索引上的索引项加锁来实现的。只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。
只要事务 未commit 或者 未rollback,会一直持有对索引项和行记录的锁
4.触发加锁的操作
①排他锁:INSERT、UPDATE、DELETE、SELECT * FOR UPDATE
②共享锁:SELECT * LOCK IN SHARE MODE
5.查看sql语句的执行计划
EXPLAIN SELECT ******;
结果中最关键的两列:
①type,性能从好到差排序如下,system(一般不会出现) > const(主键or唯一索引精确匹配) > eq_ref(主键or唯一索引精确匹配) > ref(非唯一索引精确匹配) > range(索引范围查询) > index(全遍历索引树) > all(全遍历数据表)
②key,就是这次查询使用的索引
如果需要干预最终选择使用的索引,可以加上FORCE INDEX(索引名)子句
6.调试语句
①查看当前事务:SELECT * FROM information_schema.INNODB_TRX;
②查看当前活跃连接正在执行的语句:SELECT * FROM information_schema.PROCESSLIST;
③查看等锁最大超时时间:SHOW VARIABLES LIKE ‘innodb_lock_wait_timeout’;
④查看autocommit模式:SHOW VARIABLES LIKE ‘autocommit’;
7.行锁的分类
记录锁(Record Lock)、间隙锁(Gap Lock)、临键锁(Next-Key Lock)
9.MySQL 8.0新特性 – nowait以及skip locked
10.元数据锁(MDL)
MDL不需要主动加锁,每当我们访问一个数据表的时候,会自动被加上,作用是防止在我们进行表的操作的时候,进行了表结构的变更。在5.5这个版本中被引入了Mysql中:
当对一个表进行增删改查的时候,加MDL的读锁
当进行一个表的结构变更的时候,加MDL的写锁