MySQL数据库——多事务并发访问锁
多用户共享资源,出现并发访问的时候,需要合理控制资源的访问规则。锁就是用来实现这些访问规则的重要数据结构。
根据加锁的范围,锁可以大致分成全局锁、表级锁、行锁。
(1)全局锁就是对整个数据库实例加锁。
业务的更新不只是增删改数据DML,还有可能是加字段等修改表结构的操作DDL。
全局读锁,使用Flush tables with read LOCK,做全库逻辑备份,即把整个库的每个表都select出来存成文本。这样在备份过程中整个库完全处于只读的状态,这样业务就得停摆,而且备份期间从库不能执行主库同步的binlog,会导致主从延迟。
场景:用户购买一个课程,业务逻辑就要扣掉他的余额,然后往已购课程里面加上一门课。
顺序:先备份账户余额,然后用户购买,然后备份已购课程。会发现钱没少,课多了。
也就是说,不加锁的话,备份系统得到的不是一个逻辑时间点,这个视图是逻辑不一致的。
官方自带的逻辑备份工具是mysqldump,当mysqldump使用参数-single-transaction的时候,导数据之前就会启动一个事务,确保拿到一致性视图。由于MVCC的支持,这个过程数据可以正常更新。但是这个一致性读的前提是引擎支持隔离级别(暗戳戳说MyISAM不行)
(2)表级锁(一般不支持行锁的才会想用这种)(意向共享锁和意向排他锁)
一种是表锁,一种是元数据锁。
a、表锁的语法:lock tables ...read/write。可以用unlock tables主动释放锁,也可以在客户端断开的时候自动释放。
除了会限制别的线程的读写之外,也限定了本线程接下来的操作对象。
例如:线程A执行了lock tables t1 read, t2 write;
其他线程写t1、读写t2的语句都会被阻塞。
同时,线程A执行unlock tables之前,也只能执行读t1、读写t2的操作。不允许写t1,也不能访问其他表。
锁住整个表还是不好用的,影响面太大了。
b、元数据锁MDL。MDL的作用是保证读写的正确性,不需要显示使用,访问表的时候会被自动加上。
对一个表做增删改查操作的时候,加MDL读锁。对表做结构变更操作的时候,加MDL写锁。
事务中的MDL锁,在语句执行开始时申请,但是语句结束之后并不会马上释放,而会等到整个事务提交之后再释放。
(3)行锁(共享锁和排他锁)
行锁是在引擎层由各个引擎自己实现的。
不是所有的引擎都支持行锁,比如MyISAM就不支持。不支持行锁就只能用表锁,表锁的话,同一张表在任何时刻都只能有一个更新在执行,会影响业务并发度。
如果使用了行锁,可以在一个表设置很多锁,并通过减少锁冲突来提高业务并发度。
行锁是针对数据表中记录得锁。比如锁定一行,只有在事务A操作完成后事务B才能执行。
两阶段锁:有两个事务都要执行update操作,只有事务Acommit之后事务B才能执行操作。
因为在InnoDB事务中,行锁是在需要的时候加上的,等待事务结束才能释放。这就是两阶段锁协议。
如果事务需要锁很多行,要把最可能造成锁冲突,最可能影响并发度的锁尽量往后放。
当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源的时候,就会导致几个线程都无限等待,即死锁。
解决方案:直接进入等待,直到超时。这个超时时间通过innodb_lock_wait_timeout来设置。也可以主动发起死锁检测,发现死锁就主动回滚死锁链的事务,执行其他事务。将参数innodb_deadlock_detect设置成on就表示开启这个逻辑。
锁的算法。
(1)Record Lock。记录锁,单个行记录上的锁。
(2)Gap Lock。间隙锁,锁定一个范围,两边都是开区间。可重复读及以上支持间隙锁。
如果可重复读修改了innodb_locks_for_binlog=0,那么隔离级别就退化到读提交。
(3)Next-key Lock。记录锁+间隙锁。锁定一个范围,并且锁住记录本身,左开右闭。
(4)Insert Intention Lock。插入操作的时候,插入意向锁。
(5)AUTO-INC Lock。插入操作的时候,自增锁。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
2021-03-08 常见排序
2021-03-08 模板元编程和constexpr的关系