全局锁

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

全局锁的适用场景

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

全局锁的影响:

  • 如果在主库上做全局锁操作,业务基本停摆
  • 如果在从库上做全局锁操作,备份期间从库不能更新主库同步过来的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;-----------------------------------------------
----------------------------------------------------------C: begin; select * from t;------------commit-

实验结果:

在执行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-全句锁、表锁和元数据锁的更多相关文章

  1. SQL Server 锁表、查询被锁表、解锁相关语句

    SQL Server 锁表.查询被锁表.解锁相关语句,供参考. --锁表(其它事务不能读.更新.删除) BEGIN TRAN SELECT * FROM <表名> WITH(TABLOCK ...

  2. sql server锁表、查询被锁表、解锁被锁表的相关语句

    MSSQL(SQL Server)在我的印象中很容易锁表,大致原因就是你在一个窗口中执行的DML语句没有提交,然后又打开了一个窗口对相同的表进行CRUD操作,这样就会导致锁表.锁表是一种保持数据一致性 ...

  3. Oracle锁表与解锁 对象锁与解锁

    阅读目录 锁表与解锁 查看锁表进程SQL语句 解锁 对象锁与解锁 回到顶部 锁表与解锁 查看锁表进程SQL语句 select * from v$session t1, v$locked_object ...

  4. SQL Server 手工 锁表、查询被锁表、解锁相关语句

    SQL Server 手工 锁表.查询被锁表.解锁相关语句 --锁表(其它事务不能读.更新.删除) BEGIN TRAN SELECT * FROM <表名> WITH(TABLOCKX) ...

  5. oracle 查看锁表情况并处理锁表

    /* *locked *query locked object and analyse reason,kill it * */ select 'alter system kill session '' ...

  6. oracle查看锁表进程,杀掉锁表进程[转载]

    select sess.sid,     sess.serial#,     lo.oracle_username,     lo.os_user_name,     ao.object_name,  ...

  7. Oracle 查看锁表进程_杀掉锁表进程 [转]

    查看锁表进程SQL语句1: select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo ...

  8. oracle查看锁表进程,杀掉锁表进程

    查看锁表进程SQL语句1: select sess.sid,     sess.serial#,     lo.oracle_username,     lo.os_user_name,     ao ...

  9. Mysql InnoDB行锁不使用索引锁表的时候会锁整张表

    原文:http://www.thinkphp.cn/topic/41577.html 如果使用针对InnoDB的表使用行锁,被锁定字段不是主键,也没有针对它建立索引的话.行锁锁定的也是整张表.锁整张表 ...

  10. 【MySQL】MySQL 常用语法之锁表与解锁表

    mysql 锁表语句: Lock锁整张表: 写锁定: LOCK TABLES products WRITE: 写锁,锁定之后,只有当前线程可以进行读操作和写操作,其他线程读操作和写操作均被堵塞.... ...

随机推荐

  1. 使用ollama玩转本地大模型

    使用ollama玩转本地大模型 https://ollama.com/download 安装 安装验证 测试 ollama run llama2 ollama run qwen

  2. .net core反射练习-简易版IOC容器实现

    实现一个简易的IOC容器 先说一下简单思路,参考ServiceCollection,需要一个注册方法跟获取实例方法,同时支持构造函数注入.那么只需要一个地方存储注册接口跟该接口的继承类,以及根据类的构 ...

  3. GIMP 开源、免费,功能强大的图像编辑软件

    引言 万事开头难,打造个人网站,图片处理是必不可少的,老王的电脑还是 10 年前配置的,日常使用倒还流畅,但要是使用 Photoshop 就有些吃力,特别是越新的版本.然后,发现 GIMP 这个开源的 ...

  4. CDS标准视图:维护策略数据 I_MaintenanceStrategyData

    视图名称:维护策略数据 I_MaintenanceStrategyData 视图类型:基础视图 视图代码: 点击查看代码 @AbapCatalog.sqlViewName: 'IMAINTSTRATD ...

  5. 前端(一)-Html

    1.网页基本信息 <!DOCTYPE html> 浏览器使用的规范 <head> 网页头 <body> 主体部分 <meta> 元数据 meta的nam ...

  6. SpringBoot 项目模板-摆脱步步搭建

    本文以一个简单的电商订单系统为例,源代码请访问: git clone https://github.com/e-commerce-sample/order-backendgit checkout a4 ...

  7. 第五章 ReentrantLock源码解析

    最常用的方式: int a = 12; //注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁与copyOnWriteArrayList中的全局锁 final Reentrant ...

  8. Spring Boot前后端分离直接访问静态页+ajax实现动态网页

    Spring Boot前后端分离直接访问静态页+ajax实现动态网页. 一般java里面Spring Boot项目的静态资源resources/下面有两个文件夹和一个配置文件,分别是static/目录 ...

  9. Dibble pg walkthrough Intermediate

    nmap 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_Can't get ...

  10. 0101-win10 jkd配置注意事项

    更换新的电脑预装win10家庭版,根据常规方法配置jdk8后运行javac提示:不是内部或外部命令,也不是可运行的程序或批处理文件. 1 设置变量classpath时前面有个点(完成这一步后javac ...