时间:2021-07-01 10:21:17 帮助过:48人阅读
mysql的锁是面试中很高频问题,也是我们在日常开发中经常会遇到但是我们并没有注意到的地方。我把我自己理解的锁通过本篇博文分享出来,由于锁需要结合事务来理解,本文只介绍锁的基本概念,同样为了理解事务会更加深刻,先介绍了InnoDB的一些基础概念,也是记录自己的学习,欢迎大家一起探讨交流。
下一篇:mysql的事务与mvcc
按照锁的粒度来分
表锁和行锁的区别
mysql的表级锁有两种:元数据锁和表锁。
表锁的两种形式:
表共享读锁
表排它写锁
手动加表锁
lock table tableName read;
查看表锁情况
show open tables;
删除表锁
unlock tables;
元数据锁:
mysql的行级锁是有存储引擎实现的,mysql现在默认的数据引擎为Innodb。本文主要介绍InnoDB的行锁;
InnoDB的行锁是给索引项加锁实现的,也就意味着只有使用索引检索的数据才能使用行锁,否则将使用表锁。
对于InnoDB来说,会自动给增删改语句添加排它锁,X锁。对于普通的查询语句不会添加任何锁。
InnoDB同样也实现了表级锁,也就是意向锁。意向锁是mysql内部使用的,不需要用户去干预。
意向和行锁可以共存,意向锁的作用是为了提升全表更新数据时的性能提升,否则在更新全表时要检索哪些数据行上有行锁。
顾名思义,主要是在记录之间添加锁,不允许往间隙插入数据。比如id为 2 4,那此时使用间隙锁就会锁2 3 4 这三个,稍后在介绍事务的时候也会再次介绍间隙锁,间隙锁的主要作用就是为了解决幻读问题。此处先了解一下。
mysql的死锁和我们代码中死锁理论是一样的,不同的是,mysql指的是两个不同的连接互相等待对方释放锁,才能释放自己持有的资源,所以造成了死锁。mysql中也有对死锁的优化。我们稍后再具体说。
接下来我们开始介绍事务,上面只是简单介绍了一下锁的基本概念,锁还有一部分内容需要结合事务来理解,所以稍后还有锁的介绍。
在我们介绍事务之前,我们先聊一下InnoDB的架构,事务中的一些部分会涉及到这部分的内容。
系统表空间
用户表空间
InnoDB数据落盘有图可以看出来是通过两种方式来实现的
通过两种方式来落盘,也可以理解为持久化到磁盘上。是为了保证数库发生突然宕机,造成数据丢失。
脏页落盘会产生IO并且是随机写入,耗时比较长。频繁进行磁盘IO对性能损耗是非常大。并且数据的安全性得不到保障。如果在脏页数据还没来得及落盘或者落盘过程出现宕机,那么数据就会丢失。
鉴于以上情况,mysql用双保险完成数据的安全性,脏页落盘是一种,另一种就是预写redo 日志,首先我们要知道redo 持久化到磁盘是顺序写入,顺序写入的速度要比随机写入要快,此时有朋友就会问,那脏页落盘为什么不采用顺序写入呢但?
顺序写入速度快的同时是会产生磁盘碎片的,磁盘碎片会大大浪费磁盘资源。
redo 日志持久化的时机是在事务提交时写入到磁盘的redo file中,此时脏页数据并不一定完成了落盘,脏页落盘是由checkPoint检查点机制控制的,我们这里不展开多说。
数据库发生宕机的情况:
有的朋友还会说,那redo log file的数据岂不是无限大?
ib_logfile0,ib_logfile1 这是rodo log 在我们磁盘上的命名,可以看到有两个文件,采用的循环写入的方式,如果1满了就写入2,2满了写入1,这样循环。
redo 日志持久化到磁盘也是可以配置的,通过InnoDB的innodb_push_log_at_trx_commit来设置
默认值为1,一般也建议设置为1,会保证数据的安全性,并且只有为1的时候才会保证事务的一致性。
下一篇:mysql的事务和mvcc
MySql锁与InnoDB引擎
标签:tab 问题 mit 没有 内存 重启 默认值 索引数据 查询