🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。
🍊支持作者: 点赞👍、关注💖、留言💌~
这两天大聪明一直在处理项目的线上问题,其实导致问题出现的原因也很简单:由于项目对接了银行的接口,每笔支付业务都需要将数据库里的用户信息(银行卡号、开户手机号、开户人姓名)取出来进行拼接,并发送给银行做校验,但是由于开户人姓名的问题导致支付失败了… 最终我们定了一个解决方案,将系统数据库里存储的开户人姓名和银行存储的开户人姓名前都加上一个统一的前缀标识,以此来让银行对我们平台的用户信息与其他用户信息进行区分,对我们平台用户的业务处理走其他的校验方式,保证后续的支付业务可以正常运行。其实处理起来也很简单,就是在 Mysql 里执行 update 语句批量修改数据就可以了,但是在实际操作的时候却没那么顺利了…
由于需要执行的 update 语句比较多(大概24W条左右),所以我们将这些 sql 语句以“万”为单位拆成了24个可执行的 .sql 文件,在修改数据的时候就分别去执行它们。但是在我执行完第一个 .sql 文件后去执行第二个 .sql 文件的时候,发现执行时间一直在边长,但是进度条却是纹丝不动😥
看到这里,可能各位小伙伴就已经猜到我所遇到的问题了~ 没错,就是表被锁了😂
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。那么我们先看一下什么是锁表👇
在 Mysql 中,锁表的原因是一个程序执行了对表的 insert、update 或者 delete 操作但还未 commite 时,另一个程序也对同一个表进行相同的操作,则此时会发生资源正忙的异常,也就是锁表。
看到这我们也不难总结出引起锁表的原因了👇
俗话说的好:繁琐问题必有猥琐解法~ 解决 Mysql 的锁表也非常简单,既然锁表发生在该表被占用的情况下,那么我们直接把占用该表的进程结束掉就可以了 😎
🍋具体操作步骤🍋
🍓步骤一:show OPEN TABLES where In_use > 0; (显示的结果就是被锁的表,有的表会关联别的表则会导致多个表被锁~ 其实可以越过这个步骤,因为第二步你能知道那些操作锁表了。)
🍓步骤二:show processlist; (查看进程,并且要记住进程号,也就是第一个id字段)
🍓步骤三:kill xxx (直接 kill 掉这个进程)
🍓步骤四:show OPEN TABLES where In_use > 0; (再检查一下锁有没有被释放掉)
🍋 辅助操作(可用可不用哦~) 🍋
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST where length(info) >0;(查看正在执行的进程)
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;(查看已经被锁住的表相关信息)
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;(查看等待被锁的表相关信息)
本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇
希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)
如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。
你在被打击时,记起你的珍贵,抵抗恶意;
你在迷茫时,坚信你的珍贵,抛开蜚语;
爱你所爱 行你所行 听从你心 无问东西