mysql 锁及数据一致性总结
简介
本文将从以下几方面展开介绍
1、msyql 锁的类型:行锁,表锁,页锁,乐观锁,悲观锁等
2、mysql 脏读、不可重复读、幻读的概念及如何避免
3、mysql 如何保证数据一致性,以及 mysql 和 redis 的数据一致性如何保证?
mysql 锁
在本节,我们针对不同粒度的锁进行介绍:行锁、页锁,表锁,介绍 mysql 不同引擎使用的粒度锁及优劣,最后,针对 innodb 中的锁进行更为详细的讲述。
粒度锁:行锁、表锁、页锁
首先,我们来看下 mysql 不同的粒度锁之间的优劣,页锁其实处于行锁和表锁之间。innodb 支持行锁和表锁,但默认是行锁。
InnoDB 锁模式
InnoDB 实现了两种类型的行锁:行锁是加在索引上的,只有通过索引条件检索数据,才会使用行锁
共享锁(S):共享锁又称读锁,简称 S 锁,共享锁是多个事务对同一数据可以共享一把锁,只能读不能修改
排他锁(X):排他锁又称写锁,简称 X 锁,不能与其他事务共享(包含读锁和写锁),但是获取到排他锁的事务时可以对数据进行读取和修改
我们都知道,innodb 支持行锁和表锁,因此,为了允许这两种锁共存,还有两种意向锁(Intention Locks),这两种意向锁都是表锁:
意向共享锁(IS):事务打算加 S 锁时,必须先取得该表的 IS 锁
意向排他锁(IX):事务打算加 X 锁时,必须先取得该表的 IX 锁
InnoDB 加锁方法
意向锁是 InnoDB 自动加的, 不需用户干预。
对于 UPDATE、 DELETE 和 INSERT 语句, InnoDB 会自动给涉及数据集加排他锁(X);
对于普通 SELECT 语句,InnoDB 不会加任何锁;
事务可以通过以下语句显式给记录集加共享锁或排他锁:
共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。 其他 session 仍然可以查询记录,并也可以对该记录加 share mode 的共享锁。但是如果当前事务需要对该记录进行更新操作,则很有可能造成死锁。排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE。其他 session 可以查询该记录,但是不能对该记录加共享锁或排他锁,而是等待获得锁
InnoDB 间隙锁
当我们使用范围条件查询时,InnoDB 会给符合条件的数据索引加锁,对于符合条件范围内,但数据还不存在的间隙,InnoDB 也会加锁,就是所谓的间隙锁(Next-key 锁),因此,在并发插入时,我们尽量要用等于来更新数据,避免使用范围条件。而 InnoDB 使用间隙锁的目的,也是为了防止幻读。
乐观锁和悲观锁
乐观锁:认为每次去 select 数据时,都认为不会修改,所以不会上锁,但在更新的时候回去判断是否有人更新数据,可以用版本号等机制控制;
悲观锁:认为肯定会发生冲突,认为每次去获取数据时别人都会修改,因此每次拿数据时都会上锁。而上文提到的行锁、表锁、页锁都是悲观锁的不同实现。
脏读、不可重复读、幻读
本节我们针对数据库中脏读、不可重复读、幻读进行详细的介绍,并介绍数据库是如何解决这几个问题。
数据库事务 ACID
我们首先来了解数据库事务的四大特性,简称 ACID,分别是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
原子性:事务包含的数据库操作,要么全部成功,要么失败了全部回滚
一致性:一个事务执行前后必须一致,比如转账:A+B 的钱总共 1000,在 A 向 B 转账 100 后,两个人加起来的钱还应该是 1000
隔离性:一个事务为提交时,结果对其他事务是否可见,级别一般包含:读未提交、读提交、可重复读、串行化访问
持久性:事务一旦提交,在数据库中永久生效,即使数据库故障也不会丢失
脏读、不可重复读、幻读
接下来我们了解这三种由于并发访问,从而导致的数据库读取问题
脏读:读取未提交数据,eg:A 事务在获取数据时,B 事务已经更改了数据,但事务未完成,在 A 获取数据后,B 事务失败回滚,因此 A 事务获取到的数据是错误的。
不可重复读:前后多次读取的数据不一致,eg:A 事务开始时获取数据,然后 B 事务修改了数据(针对 update 操作),A 再次获取数据,前后获取的数据不一致。
幻读:前后多次读取的数据量不一致,eg:A 事务开始时获取数据,然后 B 事务 insert 了数据(针对 insert 或 delete 操作),A 再次获取,发现获取的数据量比上次要多。
数据库隔离级别
mysql 数据库隔离级别分为四种,默认为可重复读,能够解决脏读、不可重复读的问题。
如何保证数据一致性
mysql 日志:binlog、relog、unlog
可以到参考链接 3 中学习
参考链接
1、漫谈 MySQL 的锁机制:https://developer.aliyun.com/article/686688
2、MySQL 锁总结:https://zhuanlan.zhihu.com/p/29150809
3、mysql 日志:https://www.toutiao.com/article/7146212778104160802/?wid=1678002274213
版权声明: 本文为 InfoQ 作者【阿呆】的原创文章。
原文链接:【http://xie.infoq.cn/article/d4194f80bbda8a795debaa661】。文章转载请联系作者。
评论