美文网首页
MySQL-全句锁、表锁和元数据锁

MySQL-全句锁、表锁和元数据锁

作者: ging_efcf | 来源:发表于2020-07-08 11:05 被阅读0次
全局锁

全局锁是锁住整个数据库实例,只能读,任何关于更新操作的语句都会阻塞。

全局锁的适用场景

针对数据库做全库的逻辑备份操作时,需要使用全局锁。

全局锁的影响:

  • 如果在主库上做全局锁操作,业务基本停摆
  • 如果在从库上做全局锁操作,备份期间从库不能更新主库同步过来的binlog,可能导致主从不一致

如果不加锁,备份完成后可能得到不一致的状态,不安全,所以一定要加锁。

如何加全局锁?
  1. 非innodb引擎,需要使用Flush table with read lock命令
  2. innodb引擎,可以使用mysqldump命令实现,加入一个参数 --single-transaction,在备份前开启一个事务,保证视图的一致性。
  3. (不建议使用)set global readonly=true; 原因如下:
    • 修改参数的影响面大。有些系统中,这个参数用来作其他用途,比如判断是主库还是从库,因此修改这个参数的影响面比较大。
    • 异常的处理机制不友好。FTWRL如果客户端连接异常断开,mysql会自动释放全局锁;如果设置参数,出现异常后,数据库仍旧是readonly为true的状态,风险较高。

表锁

表锁是锁住整张表,通过不同的表锁设置,控制并发访问。某些引擎不支持行锁,需要通过表锁来控制并发。支持行锁的引擎,就不建议使用表锁了。

如何加表锁?

lock tables t1 read,t2 write;
这个语句有两个含义:

  • 对其他线程来说,t1表,可以读,不可以写;t2表,读写都不可以
  • 对本线程来说,t1表只能读,t2表只能读写

元数据锁(Metadata Lock 简称MDL)

元数据锁主要是面向DML和DDL之间的并发控制,如果对一张表做DML增删改查操作的同时,有一个线程在做DDL操作,不加控制的话,就会出现错误和异常。元数据锁不需要我们显式的加,系统默认会加。

元数据锁的原理

当做DML操作时,会申请一个MDL读锁
当做DDL操作时,会申请一个MDL写锁
读锁之间不互斥,读写和写写之间都互斥。

实验验证
mysql实验环境:5.7
mysql客户端:mysql命令行工具

一共开启3个session,SessionA,SessionB,SessionC。

第一次实验:
时间线和执行命令如下

A:begin; select * from t;-------------------------------------------------commit;------------
----------------------------B: alter table t add f1 int;-----------------------------------------
--------------------------------------------------------C: select * from t;----------------------

实验结果:
在执行commit前,B和C都会阻塞住。
执行commit后,看起来B先返回数据,C后返回数据。

第二次实验:
时间线和执行命令如下

A:begin; select * from t;---------------------------------------------------------commit;----
----------------------------B: alter table t add f2 int;---------------------------------------commit--
----------------------------------------------------------C: begin; select * from t;-------------

实验结果:
在执行commit前,B和C都会阻塞住。
执行commit后,B正常返回,C依旧阻塞住。

在B执行commit后,C正常返回。

元数据实验结果分析

现象1
当开启一个事务时,在事务中做DML操作时,就会拿到读锁,在事务未提交之前,如果有一个DDL操作,那么会阻塞,同时还会阻塞后面的所有读和写操作。

原因
获取锁有一个队列,写操作先进入队列中,并且写操作的优先级很高,如果写操作被阻塞了,后面的读和写都会被阻塞。

现象2
在读和写都被阻塞后,提交事务,看起来反倒是读先拿到锁,返回数据。

原因
mysql5.6以后,加入了onlineDDL的操作,一共有5个步骤。

  1. 申请MDL写锁
  2. 申请到后降级为读锁
  3. 真正的DDL操作
  4. 申请MDL写锁
  5. 释放锁

在SessionA的事务提交后,确实是SessionB写操作先拿到写锁,然后在第二步降级为读锁后,后面的SessionC的读操作就可以正常获取读锁,执行后返回。

  • 如果SessionC释放了读锁,SessionB的写操作在第四步的时候就可以成功
  • 如果SessionC没释放读锁,SessionB的写操作在第四步就会阻塞住

所以SessionC如果是自动提交,执行完毕后自动释放锁,SessionB也可以返回;SessionC如果使用begin手动开启事务,执行完成后,commit前都不会释放锁,SessionB也就会一直阻塞,直到SessionC执行了commit操作SessionB才会返回。

相关文章

  • MySQL-全句锁、表锁和元数据锁

    全局锁 全局锁是锁住整个数据库实例,只能读,任何关于更新操作的语句都会阻塞。 全局锁的适用场景 针对数据库做全库的...

  • MySQL听讲(四)——数据库锁

    数据库的锁分为全局锁、表锁、行锁。 科普 锁的缩写:MDL(metadata lock):元数据锁。 全局锁 表锁 行锁

  • 丁奇-MySQL实战读书笔记6

    全局锁 全局锁就是对整个数据库实例加锁,全局锁的典型使用场景是,做全库逻辑备份。 表级锁 一种是表锁,一种是元数据...

  • InnoDB引擎的行锁和表锁

    在Mysql中,Innodb数据引擎支持行锁和表锁,Myisam数据引擎只支持表锁 1 行锁和表锁 行锁是通过索引...

  • Innodb-Insert-锁

    锁类型 元数据锁 表锁 IX 自增锁 自增锁模式通过参数innodb_autoinc_lock_mode来控制,加...

  • (MySQL死锁认识二)数据库中的锁

    数据库中的锁按照不同的方式区分有不同的结果,按照锁的粒度区分,可分为表级锁和行级锁 表锁和行锁 表锁意为对整张表加...

  • MySQL锁机制

    MySQL主要有表锁,行锁和页锁,页锁用得少,本文主要介绍表锁和行锁。 一、锁的分类 从对数据的操作类型来分,可以...

  • mysql的几种锁

    一,按照对数据操作的锁粒度(锁级别)来分:行级锁,表级锁,页级锁 MyISAM和MEMORY采用表级锁(table...

  • MySQL表级锁

    表级锁的种类 MySQL里面表级别的锁有两种,一种是表锁,另一种是元数据锁(MDL, meta data lock...

  • 一、Mysql优化

    锁 1. 表锁 表锁开销小,加锁快,不会出现死锁,并发度低一般update和delete操作会使用表级锁。全表扫描...

网友评论

      本文标题:MySQL-全句锁、表锁和元数据锁

      本文链接:https://www.haomeiwen.com/subject/hkbqcktx.html