MySQL学习之MySQL基本架构与锁

目录
  • MySql架构
  • MySQL锁
    • 锁的分类
      • 按粒度分
      • 按功能分
    • 锁的演示
      • 表锁
      • 行锁
      • 意向锁

MySql架构

  • SQL Layer

    • Connection Pool : 连接池,用于接收连接请求和管理连接。
    • ManagementService&Utilities 管理服务组件和工具组件,主要提供了一些备份,安全,主从,集群,等功能。
    • SQL Interface:主要提供了SQL语句接口。包括SQL解析器,优化器,缓存等。将我们输入的SQL语句,解析成节点树,然后传递给存储引擎执行。
  • Storage Engine Layer:可插拔式的存储引擎。常用的有InnoDB,MyISAM等
  • File System : 底层文件系统。保存数据,索引,日志等文件。

MySQL锁

锁的分类

按粒度分

  • 全局锁(锁database,由SQL Layer层实现)
  • 表级锁(由SQL Layer层实现)
    • 表数据锁
    • 元数据锁
  • 行级锁(由存储引擎实现,如InnoDB):

    可以锁行,也可以锁行与行之间的间隙

按功能分

  • 共享锁(S锁)(读锁)
  • 排他锁(X锁)(写锁)

锁的演示

表锁

  • 表数据锁
-- 对product表加读锁
-- 其他进程仍然可以对product表进行读取,但不能写(包括加读锁本身这个进程,也无法写)
lock table product read;
-- 加锁后,该进程只能访问product表,无法访问其他表。
select * from seller;
ERROR 1100 (HY000): Table 'seller' was not locked with LOCK TABLES
-- 当然可以让当前进程给seller表加锁
lock table seller read;
-- 如此以来,便可以访问seller表,但由于一个进程只能持有一个表锁,故原先的product表锁被释放,product表无法访问

-- 其他未持有锁的session可以访问任意表

-- 释放锁
unlock tables;
-- 或者
unlock table;
-- 上面两句效果一样
-- 只会释放当前连接进程所持有的表锁,而不是释放所有锁,

-- 对product表加写锁
lock table product write;
-- 其他线程对product表既不能读,也不能写

-- 查看表锁状态
show open tables;

-- 注意,一个连接进程,最多只能持有1个表锁
  • 元数据锁(Meta Data Lock)

MDL无需显式使用,在访问一个表时,会自动加元数据锁。MDL的作用是为了保证读写的正确性。

MDL读锁:在对某个表进行增删改查操作时,加MDL读锁。

MDL写锁:在对某个表的结构进行修改(DDL)时,加MDL写锁。

读锁之间不互斥,读写,写写之间互斥。这样是为了保证对表结构操作的安全性。

MDL可以认为是表结构锁。需要改表结构时,自动加MDL写锁,其他时候加MDL读锁

DML,DQL语句,会自动加MDL的读锁

DDL语句,会自动加MDL的写锁

-- 线程A
begin;
select * from product;
-- 在一个事务内,MDL锁是一直被持有的

-- 此时另起一个,线程B
alter table product add type varchar(10);
-- 执行上面的sql,会发现被阻塞住,因为线程B这一句需要MDL写锁

-- 再回到线程A
commit;
-- 线程A提交事务后,释放MDL读锁
-- 此时能看到线程B的sql执行成功

注意:如上图所示,session A 和 session B可以正常执行,session C 就被阻塞了,因为session C需要申请MDL写锁,关键是,session D也会被阻塞。当session A 提交后,会先执行session D,最后再执行session C

观察发现,如果先开启事务,在事务里执行DDL,先不提交当前事务。再另起一个线程,执行DML,发现DML不会被阻塞。

这是因为DDL在执行完成后,会自动立刻commit(自动commit后会释放MDL写锁)。

申请MDL锁的操作会形成一个队列,队列中写锁获取优先级高于读锁。一旦出现写锁等待,不但当前操作会被阻塞,同时还会阻塞后续该表的所有操作。事务一旦申请到MDL锁后,直到事务执行完才会将锁释放。(这里有种特殊情况如果事务中包含DDL操作,mysql会在DDL操作语句执行前,隐式提交commit,以保证该DDL语句操作作为一个单独的事务存在,同时也保证元数据排他锁的释放。

行锁

行锁是由存储引擎实现的。InnoDB支持行锁和事务,MyISAM不支持行锁和事务。

InnoDB的行锁是通过给索引项加锁实现的。所以,若不是通过索引条件检索的数据,InnoDB会使用表锁

InnoDB的行锁

按照锁定范围分3种:

  • Record Lock:记录锁,锁定索引中的一条记录
  • Gap Lock:间隙锁,锁定记录间的间隙
  • Next-Key Locks:记录锁+间隙锁组合

按功能分为

  • 共享读锁
  • 排他写锁

DML语句(INSERT/UPDATE/DELETE)会自动加上排他锁

对于普通SELECT语句,InnoDB不加锁(是通过MVCC的一致性非锁定读的方式完成的,这个后序再做总结),可以通过以下方式,手动添加锁

-- 共享读锁
SELECT * FROM product LOCK IN SHARE MODE;

-- 排他写锁
SELECT * FROM product FOR UPDATE;

-- 查看行锁情况
show status like '%innodb_row_lock%';

意向锁

是InnoDB实现的表级锁,在内部使用,无需用户干预。

MySQL有多粒度的锁实现,即行锁和表锁。那么意向锁存在的意义是为了协调行锁和表锁。试想事务A申请了某表某一行的写锁X,事务B申请了该表的写锁X,那么事务B按理说也能修改事务A锁定的某一行,这就产生了冲突。如果没有意向锁,某事务申请表锁时,可能就得一行一行的扫描,看看是不是所有行都没有锁,所有行都没锁时,才能成功加表锁。这样效率就会很低。

所以意向锁的作用就是表明某个事务有加行锁的意图,即,有人锁住了某一行,或者将要锁住某一行,这样在其他人在加表锁时,就能直接根据意向锁的情况,判断是否能够加表锁,而不必一行一行扫描了。

意向共享锁 (IS):加行共享锁前,必须先取得IS锁

意向排他锁(IX):加行排他锁前,必须先取得IX锁

意向锁的作用主要是为了在针对全表操作时获得性能提升。

比如:事务A对某一行加了锁(无论是读锁还是写锁),事务B尝试加表锁,这时如果没有意向锁,就需要遍历检测每一行是否持有行锁,这样性能是极低的。

意向锁只和表锁互斥。

对于上表,可以做如下理解:

若某个表存在IS锁,说明有个事务对某一行加了读锁,此时若要对该表加表锁,只能加S锁,不能加X锁。所以IS和S兼容,和X互斥。

若某个表存在IX锁,说明有个事务对某一行加了写锁,此时若要对该表加表锁,都会被阻塞,S锁和X锁都不能加。所以IX和S和X都互斥。

IX和IX可以共存,可以理解为,有2个事务分别对不同的行加了写锁。

到此这篇关于MySQL学习之MySQL基本架构与锁的文章就介绍到这了,更多相关MySQL基本架构与锁内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL悲观锁与乐观锁的实现方案

    目录 前言 实战 1.无锁 2.悲观锁 3.乐观锁 总结 前言 悲观锁和乐观锁是用来解决并发问题的两种思想,在不同的平台有着各自的实现.例如在Java中,synchronized就可以认为是悲观锁的实现(不严谨,有锁升级的过程,升级到重量级锁才算),Atomic***原子类可以认为是乐观锁的实现. 悲观锁 具有强烈的独占和排他特性,在整个处理过程中将数据处于锁定状态,一般是通过系统的互斥量来实现.当其他线程想要获取锁时会被阻塞,直到持有锁的线程释放锁. 乐观锁 对数据的修改和访问持乐观态度,假设

  • Mysql锁机制之行锁、表锁、死锁的实现

    目录 一.Mysql锁是什么?锁有哪些类别? 二.行锁和表锁的区别 三.InnoDB死锁概念和死锁案例 死锁场景一之selectforupdate: 死锁场景二之两个update 四.程序开发过程中应该如何注意避免死锁 一.Mysql锁是什么?锁有哪些类别? 锁定义:    同一时间同一资源只能被一个线程访问    在数据库中,除传统的计算资源(如CPU.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据

  • MySQL insert死锁问题解决详细记录

    目录 Insert死锁问题剖析 前置知识 构造死锁 原因 故死锁产生的原因 MySQL 5.7 的死锁 前提 示例 原因 解决方案 总结 Insert死锁问题剖析 线上有个批量的insert … on duplicate key update语句引发的死锁问题,查过很多资料并且亲自尝试过后,发现好多博客说的都是错的,其实本身只跟insert的顺序有关,在此记录一下备忘. 前置知识 X型锁:排他锁 S型锁:共享锁 行锁:锁住一行记录 Next-Key锁:左开右闭区间 Gap锁:左右开区间 构造死锁

  • Mysql事物锁等待超时Lock wait timeout exceeded;的解决

    目录 问题场景 原因分析 解决方案 参考信息 工作中同事遇到此异常,查找解决问题时,收集整理形成此篇文章. 问题场景 问题出现环境:1.在同一事务内先后对同一条数据进行插入和更新操作:2.多台服务器操作同一数据库:3.瞬时出现高并发现象: 不断的有一下异常抛出,异常信息: org.springframework.dao.CannotAcquireLockException: ### Error updating database.  Cause: java.sql.SQLException: L

  • mysql中如何查看表是否被锁问题

    目录 如何查看是否发生死锁 死锁发生情况及原因 产生原因 发生死锁的几种情况 总结 如何查看是否发生死锁 在使用mysql的时候,如何查看表是否被锁呢? 查看表被锁状态和结束死锁步骤: 1.在mysql命令行执行sql语句 use dbName; // 切换到具体数据库 show engine innodb status; // 查询db是否发生死锁 2.查看数据表被锁状态 show OPEN TABLES where In_use > 0; 该语句可以查询到当前锁表的状态 3.分析锁表的SQL

  • MySQL数据库体系架构详情

    目录 一.MySQL体系架构 二.网络连接层 三.数据库服务层 四.连接池 五.系统管理和控制工具 六.SQL接口 七.解析树 八.查询优化器 九.缓存 十.存储引擎层 十一.系统文件层 十二.日志文件 1.错误日志 2.通用查询日志 3.二进制日志 4.慢查询日志 十三.数据文件 1.db.opt文件 2.frm文件 3.MYD文件 4.MYI文件 5.ibd文件 6.ibdata文件 7.ibdata1文件 8.ib_logfile0和ib_logfile1文件 十四.配置文件 1.pid文

  • MySQL数据库表被锁、解锁以及删除事务详解

    目录 背景 故障追踪 解决方案 第一步:查看表使用 第二步:查看进程 第三步:查看当前运行的所有事务 第四步:查看当前出现的锁 第五步:查询锁等待的对应关系 第六步:kill掉事务 MySQL的锁 MySQL锁表场景 Waiting for table metadata lock 场景一:长事务运行,阻塞DDL,继而阻塞所有同表的后续操作. 场景二:为提交事务,阻塞DDL,继而阻塞所有同表的后续操作. 场景三:显式事务失败操作获得锁,未释放 小结 总结 背景 在程序员的职业生涯中,总会遇到数据库

  • MySQL双主(主主)架构配置方案

    在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动.因此,如果是双主或者多主,就会增加mysql入口,增加高可用.不过多主需要考虑自增长ID问题,这个需要特别设置配置文件,比如双主,可以使用奇偶,总之,主之间设置自增长ID相互不冲突就能完美解决自增长ID冲突问题. 主从同步复制原理 在开始之前,我们先来了解主从同步复制原理. 复制分成三步: 1. master将改变记录到二进制日志(binary

  • MySQL学习之MySQL基本架构与锁

    目录 MySql架构 MySQL锁 锁的分类 按粒度分 按功能分 锁的演示 表锁 行锁 意向锁 MySql架构 SQL Layer Connection Pool : 连接池,用于接收连接请求和管理连接. ManagementService&Utilities 管理服务组件和工具组件,主要提供了一些备份,安全,主从,集群,等功能. SQL Interface:主要提供了SQL语句接口.包括SQL解析器,优化器,缓存等.将我们输入的SQL语句,解析成节点树,然后传递给存储引擎执行. Storage

  • MySQL 学习总结 之 初步了解 InnoDB 存储引擎的架构设计

    一.存储引擎 上节我们最后说到,SQL 的执行计划是执行器组件调用存储引擎的接口来完成的. 那我们可以理解为:MySQL 这个数据库管理系统是依靠存储引擎与存放数据的磁盘文件进行交互的. 那么 MySQL 有哪些存储引擎呢? 主要有 MyISAM.InnoDB.Memory等等.而现在互联网中,基本都是使用 InnoDB 存储引擎,所以接下来我将简单总结自己关于 InnoDB 存储引擎的学习,比较简单的介绍 InnoDB 存储引擎里面的组件. 二.缓冲池 我们现在都知道了,数据库的数据是存放在磁

  • mysql 5.7 docker 主从复制架构搭建教程

    分享mysql 5.7 docker 主从复制架构搭建教程,供大家参考,具体内容如下 环境版本: MySQL :  5.7.13 Docker : 1.11.2 CentOS : 7.1 1.先在两个物理机上分别安装两个MySQL.命令如下 复制代码 代码如下: docker pull mysql:5.7.13  docker run --name anuo-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=qaz.00JK -d mysql:5.7.13 2.

  • 一千行的MySQL学习笔记汇总

    本文详细汇总了MySQL学习中的各类技巧,分享给大家供大家参考. 具体如下: /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限验证登录MySQL */ mysqld --skip-grant-tables -- 修改root密码 密码加密函数password() update mysql.user set password=password('root'); SHOW PROCE

  • MySQL学习第一天 第一次接触MySQL

    一.什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据. 我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢.所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理的大数据量.所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据. RDBMS即关系数据库管理系统(Relational Database Mana

  • MySql学习笔记之事务隔离级别详解

    背景 说的事务,大家应该都不陌生,开发用到 MySql 数据库的时候,通常会用到事务.其中比较经典的例子就是转账,比如你要给小明转 50 块钱,而此时你的银行卡也就只有 50 块钱. 对于转账过程在代码程序里会有一系列的操作,比如查询账户余额.余额加减.更新余额等,这些操作必须保证是一起处理的,不然等程序查完之后,如果账号 50 块钱还在,然后再给另外一个朋友转账,如果银行也处理的话,没有保证整个流程数据一致性的话,这不就乱套了吗?这时就要用到"事务"了. 事务介绍 简单来说,事务就是

  • 超全MySQL学习笔记

    MyISAM和InnoDB 对比 MyISAM InnoDB 主外键 不支持 支持 事务 不支持 支持 行表锁 表锁,操作时即使操作一条记录也会锁住一整张表,不适合高并发的操作 行锁,操作时只锁住某一行,不会影响到其他行,适合高并发 缓存 只缓存索引,不缓存其他数据 缓存索引和真实数据,对内存要求较高,而且内存大小对性能有影响 表空间 小 大 关注点 性能 事务 默认安装 Y Y 性能下降SQL慢的原因: 查询语句写的差 索引失效 关联查询太多join (设计缺陷或不得已的需求) 服务器调优及各

  • PHP通过插入mysql数据来实现多机互锁实例

    本文实例讲述了PHP通过插入mysql数据来实现多机互锁的方法,分享给大家供大家参考.具体实现方法如下: 在执行流程之前可以加一般锁,shell枷锁函数如下,如果成功则会返回0,否则返回非0值: 复制代码 代码如下: function get_lock() {     local dataId="${1}"     local dataDate="${2}" local sql="insert intot_trans_lock     (dataId, d

  • MySQL学习笔记之数据定义表约束,分页方法总结

    本文实例讲述了MySQL学习笔记之数据定义表约束,分页方法.分享给大家供大家参考,具体如下: 1. primary key 主键 特点:主键是用于唯一标识一条记录的约束,一张表最多只能有一个主键,不能为空也不能重复 create table user1(id int primary key,name varchar(32)); mysql> insert into user1 values(1,'hb'); Query OK, 1 row affected (0.10 sec) mysql>

  • MySQL学习第六天 学习MySQL基本数据类型

    还记得上一篇学习的内容吗?不记得再看一看MySQL学习第五天 MySQL数据库基本操作,温故可以知新! 数据类型是指列.存储过程参数.表达式和局部变量的数据特征,它决定了数据的存储方式,代表了不同的信息类型.MySQL中常用的的数据类型包括:数值类型.日期和时间类型和字符串类型等.  一.数值类型 MySQL支持所有标准SQL中的数值类型,其中包括严格数据类型(INTEGER.SMALLINT.DECIMAL.NUMBERIC),以及近似数值数据类型(FLOAT.REAL.DOUBLE.PRES

随机推荐