Mysql实战学习笔记四:锁

全局锁

全局锁就是对整个数据库实例进行加锁。命令为Flush Tables with read lock。执行后整个库处于只读状态,数据增删改语句,数据定义语句(建表,修改表结构)和更新类事务提交都会被阻塞。
全局锁常用于Myisam数据库的备份,加上只读锁之后备份。
但是整个库只读存在风险。
使用全局锁备份的风险

  • 如果在主库上备份,那么备份期间都不能执行更新操作,业务停止。
  • 如果在从库上备份,那么备份期间从库不能执行主库过来的binlog,导致主从延迟。

但是不加锁的话,如果在备份期间,数据进行修改,就会导致数据不一致问题。原库修改了,备份库没改。
保证数据一致的一个办法是在可重复度隔离级别开启一个事务。
mysqldump -single-transaction,导数据之前就会启动一个事务,确保拿到一致性视图,由于mvcc的支持,这个过程中数据时可以正常更新的。
但是single-transaction方法只适用于所有的表使用事务引擎的库。所以Myisam只能使用FTWRL。

为什么不使用set global readonly =true 而是FTWRL

  • 在有些系统中,readonly的值会被用作其他逻辑,比如用来判断一个库是主库还是备库。
  • 执行FTWRL命令之后,由于客户端发生异常断开,那么Mysql会自动释放这个全局锁,整个库回到可以正常更新的状态。如果将整个库设置为readonly之后,客户端发生异常,则数据库会一直保持readonly的状态,这样会导致整个库长时间处于不可写状态风险太高。
表级锁

Mysql里面表级别的锁有两种:一种是表锁,一种是元数据锁(MDL)。
表锁的用法是lock tables … read/write.可以使用unlock tables 主动释放,也可以在客户端断开的时候自动释放。

MDL不需要显式调用,在访问一个表的时候会自动加上。MDL是为了保证读写的正确性。比如查询的时候锁住表,不让其他线程修改表结构。

当对一个表做DML时, 加上MDL读锁。当对一个表做DDL时,加MDL写锁。

  • 读锁之间不互斥。可以同时增删改查
  • 读写锁,写锁之间互斥。

在这里插入图片描述
进行上图操作时,AB正常执行,C被锁住,因为A读锁还没有释放,D因为C被阻塞所以自己也被阻塞。
由此可以看出MDL锁是事务提交之后才释放的。

正确的做法应该是 在alter table 里设定等待时间,如果在这个时间里能够拿到MDL写锁最好,如果不能也不要阻塞后面的业务语句先放弃。然后再重试。

行锁

InnoDB支持行锁,Myisam不支持,只支持到表锁。因此业从务并发度方面来看,InnoDB表现更优秀一些。

在InnoDB事务中,行锁是在需要的时候才加上的,但不是不需要了就可以立马释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。

如果事务中需要锁多个行,要把最可能造成锁冲突,最可能影响并发度的锁尽量往后放。
因为往后放的话离事务提交的时间就越短,即离释放锁的时间越短,堵塞的时间越短。

题外

DDL 数据库定义语言 (修改表字段,建表等)
DML 数据操作语言 (增删改查)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值