MySQL 锁

        根据加锁的范围,MySQL里面的锁大致可以分成全局锁、表级锁和行锁三类。

        全局锁就是对整个数据库实例加锁。MySQL提供了一个加全局锁的方法,命令是Flush tables with read lock(FTWRL)。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句、数据定义语句和更新事务的提交语句。全局锁的典型使用场景是做全库逻辑备份,也就是把整库每个表都select出来存成文本。

        表级别的锁有两种:一种是表锁,一种是元数据锁。

        表锁的语法是lock tables... read/write。与FTWRL类似,可以用unlock tables主动释放锁,也可以在客户端断开的时候自动释放。需要注意,lock tables语法除了会限制别的线程读写外,也限定了本县城接下来的操作对象。

        元数据锁是MDL,不需要显式使用,在访问一个表的时候会被自动动加上。MDL的作用是,保证读写的正确性。当一个表做增删改查操作的时候,加MDL读锁;当要对表结构变更操作的时候,加MDL写锁。读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。读写锁之间、写锁之间是互斥的,用来保证变更结构操作的安全性。因此,如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行。

        虽然MDL锁是系统默认会加的,但却是你不能忽略的一个机制。比如下面这个例子,经常有人掉到这个坑里:给一个小表价格字段,导致整个库挂了。

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。...
    花神子阅读 575评论 2 1
  • MDL锁 对表的增删改查,都需要MDL锁,无所不在 MDL读锁之间不互斥,但MDL读写锁互斥 #举个栗子 假设t是...
    飞翔的Tallgeese阅读 1,089评论 1 0
  • MySQL锁分类 全局锁 表级锁 行锁 间隙锁 next-key lock 全局锁 作用范围:对整个数据库实例加锁...
    慧鑫coming阅读 400评论 0 3
  • 一、概述 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种...
    不变甄心阅读 2,743评论 0 3
  • “啊——” 一声呻吟,熟悉的尾音足够拖长,以至于这短暂的气音在意识里仿佛无限拉伸,勾起不断回味。 但到...
    复更欢阅读 3,097评论 0 4