mysql之锁优化

前言

之前的文章,我们对锁的种类,和锁的一些用途,进行了简单的讲解。今天我们将接着上张的内容,对锁的优化进行介绍。

语句层面

首先,我们从语句层面介绍下怎么进行锁优化。之前的文章我们介绍过,锁实在sql执行的时候才会加锁。但是锁的释放,却是在事务提交之后,才会释放。这样就会带来一个问题。如下图
在这里插入图片描述
假如,这是一个电影院的一个购票业务。电影院叫b,客户为a,a想在b买一张电影票,上图则是一个完整的买票流程。然后这个时候,c也想从电影院买张票,那么c和a冲突的地方就是第二条语句。如果我们把第二条语句放在最后,那么a和c冲突的时间是不是就会缩短。因为锁是在最后事务提交的时候才会释放,那么放在最后执行冲突语句,锁持续的时间就是最短的。这样就可以减少锁的时间,减少并发冲突的时间。

死锁

说起死锁,相必大家都不会陌生,因为这个在java中也是十分的常见的。产生死锁的原因就是双方互相占有对方所需要的的互斥资源,且短时间内,不会释放。那么从这个描述上呢,我们基本可以有四种解决方法。但是在mysql中呢,大致有两种解决方法。因为mysql中的锁不会像java中的锁,那么便于操作。如下图
在这里插入图片描述
事务a和事务b相互需要对方的行锁,导致死锁的产生。这个时候大致有两种策略。
1.直接进入等待,直到超时,这个超时的参数可以自己设置。
2.死锁检测,检测到这个死锁,然后对其中一个事务进行回滚,释放出另一个事务需要的锁,以便两个语句都能进行下去。
但是开启死锁检测是十分的消耗性能的,比如一千个事务同时更新同一行数据,那么死锁基本要检测1000x1000行数据,消耗太大。
那遇到这种热点表怎么办呢,最好的办法就是控制并发,可以用一个队列(不管是在数据库中实现,还是依靠消息中间件实现,都可以),让进来的事务进行排队,同一时间至多有10个,或者20个可以对这行数据进行修改,这样就可以很好的实现并发修改了。

如何安全地给小表加字段

首先我们要解决长事务,事务不提交,就会一直占着 MDL 锁。在 MySQL 的 information_schema 库的 innodb_trx 表中,你可以查到当前执行中的事务。如果你要做 DDL 变更的表刚好有长事务在执行,要考虑先暂停 DDL,或者 kill 掉这个长事务。但考虑一下这个场景。如果你要变更的表是一个热点表,虽然数据量不大,但是上面的请求很频繁,而你不得不加个字段,你该怎么做呢?这时候 kill 可能未必管用,因为新的请求马上就来了。比较理想的机制是,在 alter table 语句里面设定等待时间,如果在这个指定的等待时间里面能够拿到 MDL 写锁最好,拿不到也不要阻塞后面的业务语句,先放弃。之后开发人员或者 DBA 再通过重试命令重复这个过程。

总结

今天我们继续上篇文章,对锁的优化进行了讲解,但是只是在语句层面进行大致的讲解。同时也介绍的死锁的出现原因,和怎么避免死锁的方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mark---小鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值