共计 1280 个字符,预计需要花费 4 分钟才能阅读完成。
MySQL 的中的全局锁、表级锁、行锁
学习极客工夫 - 林晓彬老师 -MySQL 实战 45 讲 学习整顿
???? 全局锁
对整个数据库实例加锁。通过应用 Flush tables with read lock (FTWRL)
办法,让整个数据库处于只读的状态,尔后的数据库的更新语句(增删改)、数据定义语句(建表、批改表构造)和更新类事务的提交语句会被阻塞
锁定整个数据库,那么全局锁的一个显著的应用场景就是做全库逻辑备份;还有另外一个形式应用set global readonly=true
让全库进入只读的状态,这两种形式有个最大的区别是:
异样解决上,如果客户端产生异样断开,MySQL 会主动开释全局锁,让整个库回到失常的状态;将整个库设置为 readonly 之后,异样断开后,数据库还是会始终放弃 readonly 状态,导致数据库长时间处于不可写状态。
???? 表级锁
MySQL 有两种表级锁:表锁和元数据锁(meta data lock (MDL))
表锁语法 lock tables ...read/write
,解锁unlock talbes
。在客户端断开的时候会主动开释。表锁除了会限度别的线程读写外,也限定了本线程接下来的操作对象,例如:线程 A 执行lock tables t1 read,t2 write
, 其余线程写 t1 读 t2 写都会被阻塞,在unlock tables
之前,A 线程也只能读 t1, 写 t2
元数据锁在拜访一个表的时候回主动加上,保障在拜访数据的时候,表的构造不能批改
???? 行锁
MySQL 的行锁是在各个存储引擎中本人实现,InnoDB 中就反对行锁,MyISAM 引擎就不反对行锁
行锁就是锁住表中一行记录的锁,当 A 在对这行数据进行解决,B 也想解决这条数据,就须要等到 A 处理完毕之后,B 能力持续
两阶段锁协定
在 InnoDB 事务中,行锁是在须要的时候才被加上,但并不是不须要了就会立即开释,而是要期待以后事务完结后才会开释。
所以在如果事务中须要锁住多个行,把最可能造成并发的行尽量往后放。
举个????:
一个购票的零碎的买票业务大略是:
- 顾客 A 购票,A 余额扣除票价
- 影院 B 账户余额减少电影票价
- 记录交易日志
这条业务下,并发的点在于影院 B 增加收入,如果每个客户依照 1、2、3 的业务程序去购票,那么并发的点 2 持有锁的工夫会很长;如果批改为 3、1、2 解决完并发的点之后,就会开释行级锁,缩小了事物之间的锁的等待时间。
死锁和死锁检测
不同线程之间相互持有对方的锁,A 等 B 开释锁,B 等 A 开释锁,那么就会造成死锁
解决死锁的策略:
- 一种策略是,间接进入期待,直到超时。这个超时工夫能够通过参数 innodb_lock_wait_timeout 来设置
- 发动死锁检测,发现死锁后,被动回滚死锁链条中的某一个事务,让其余事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,示意开启这个逻辑,
这里须要留神:
(1)拜访的行上有行锁才会去做死锁检测
(2)并不是每次死锁检测都都要扫所有事务。比方某个时刻,事务期待状态是这样的:
B 在等 A,D 在等 C,当初来了一个 E,发现 E 须要等 D,那么 E 就判断跟 D、C 是否会造成死锁,这个检测不必管 B 和 A