Mysql:全局锁和表锁?干什么用的?

本文介绍了MySQL数据库的锁机制,主要讨论了全局锁、表级锁(包括表锁和元数据锁MDL)的概念、应用场景及优缺点。全局锁用于全库备份,通过FTWRL实现,但可能影响业务;表级锁中的表锁用于控制并发,而MDL则在访问表时自动加锁,防止DML和DDL冲突。总结了不同锁的使用场景和注意事项,强调在高并发环境下合理使用锁的重要性。
摘要由CSDN通过智能技术生成
  • MySql的锁,数据库锁设计的初衷是处理并发问题

  • 作为多用户共享的资源,当出现并发访问时,数据库需要合理的控制资源的访问规则,锁就是实现访问规则的数据结构

    根据加锁的范围,Mysql里面的锁大致可以分为:

  • 全局锁

  • 表级锁

  • 行锁

(1)全局锁

全局锁就是对整个数据库实例加锁,整个库就会处于只读状态。

(1)Mysql提供了一个加全局读锁的方法

命令:Flush tables with read lock(FTWRL).

使用这个命令后,整个数据库处于只读状态,之后其他线程的数据更新语句(数据增删改),数据定义语句(建表,修改表结构等)和更新类事务提交语句,都会被阻塞。

(2)全局锁的应用场景是:给全库做逻辑备份。(也就是把整个库的表都select出来存成文本)

(3)使用全局锁的局限:

  • 如果是在主库上进行备份,那么备份期间,数据库数据都不能更新,业务就得停摆。

  • 如果是在从库上进行备份,那么备份期间从库不能执行从主库同步过来的binlog(给某行给某行某个字段做了什么修改),会导致主从延迟。

(4)备份为什么一定要加锁?

如果不加锁,在备份的过程中,有个线程进来修改了部分数据,然后前面备份的数据和后面备份的数据会对应不上。也就是说,备份的库不是一个逻辑时间点,视图的逻辑不一致。

(5)有一个方法可以拿到一致性视图:

在可重复读的隔离级别下开启一个事务,因为可重复读,只要这个事务不提交,那么事务开启后看到数据一直都是刚开启时的数据,就可以拿到一致性视图。

官方自带的逻辑备份工具是mysqldump,当mysqldump使用参数-single-transaction的时候,导出数据之前就会启动一个事务,确保拿到一致性视图。由于MVCC的支持,这个过程中数据是可以正常更新的。

  • FTWRL确保不会有其他线程对数据做更新,然后对整个库做备份,备份过程中,整个库处于只读状态。(所有引擎都可以使用,不支持事务的引擎用这个方式)

  • mysqldump自带备份工具,需要支持事务的引擎,才能使用。

(6)既然只要全库只读,为什么不使用set global readonly=true的方式呢?

  • 一是,在有些系统中,readonly的值会被用来做其他逻辑,比如判断一个库是主库还是备库,因此不建议使用。

  • 二是,在异常处理机制上有差异:

    如果使用FTWRL命令后,客户端发生异常,Mysql会自动释放这个全局锁,整个库就可以回归到正常状态。

    如果将readonly的值设置为true的话,客户端发生异常,整个库就会一直处在readonly状态,会使整个库长时间处于不可更新状态。

(2)表级锁

表级锁有两种:

  • 表锁

  • 元数据锁(MDL)

    (1)表锁的语法是lock tables ...read/write

    与FTWRL类似,可以用unlock tables主动释放锁,也可以在客户端断开的时候自动释放。

    lock tabeles 除了会限制别的线程的读写外,还会限制本线程的操作

    例子:某个线程A执行lock tables t1 read,t2 write; 这个语句,则其他线程些写t1,读写t2的语句都会被阻塞。

    同时线程A在执行unlock tables之前,也只能执行读t1,读写t2的操作,写t1都不允许。

    对于InnoDB引擎这种支持行锁的引擎,一般不使用表锁来控制并发,锁住整个表的代价太大。

    表锁一般是用在数据库引擎不支持行锁的时候才会被用到!!!

(2)元数据锁(MDL)

MDL不需要显式使用,在访问一个表的时候会自动加上。

MDL的作用是:防止DML(表数据增删改查)和DDL(表结构修改)并发冲突。

Mysql5.5版本中引入的MDL,当对一个表做增删改查时,加MDL读锁,当要对表结构变更时,加MDL写锁。

  • 读锁之间不互斥,因此可以有多个线程可以同时对一张表增删改查。

  • 读锁和写锁之间,写锁和写锁之间是互斥的,用来保证变更表结构操作的安全性。

    (如果有两个线程同时给一个表加字段,其中一个要等另一个执行完才能开始执行)

在事务中的MDL锁在语句执行开始时申请,语句结束后并不会马上释放,而是要等整个事务提交再释放。

长事务一直不提交,那么会一直占着MDL锁,如果你要变更的表正好有长事务在执行,要么你暂停表结构变更(DDL),要么杀掉这个长事务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值