我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MYSQL高级

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MYSQL高级

MYSQL高级

相关术语介绍

多版本并发控制

MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version ConcurrencyControl)(注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Control)。MVCC最大的好处,相信也是耳熟能详:读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能,这也是为什么现阶段,几乎所有的RDBMS,都支持了MVCC。

当前读和快照读

在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。

  • 快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。
  • 当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。 以MySQL InnoDB为例:
  • 快照读:简单的select操作,属于快照读,不加锁。(当然,也有例外,下面会分析)
    	select * from table where ?;
    
  • 当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。所有以上的语句,都属于当前读,读取记录的最新版本。并且,读取之后,还需要保证其他并发事务不能修改当前记录,对读取记录加锁。
    	select * from table where ? lock in share mode;//共享锁(S)
    	select * from table where ? for update;//排他锁(X)
    	insert into table values (...) ; //排他锁(X)
    	update table set ? where ? ; //排他锁(X)
    	delete from table where ? ; //排他锁(X)12345开课吧java高级架构师
    

聚集索引

Cluster Index:聚簇索引。

InnoDB存储引擎的数据组织方式,是聚簇索引表:完整的记录,存储在主键索引中,通过主键索引,就可以获取记录所有的列。关于聚簇索引表的组织方式,可以参考MySQL的官方文档:Clustered and Secondary Indexes 。本课程就不再做具体的介绍。接下来的部分,主键索引/聚簇索引 两个名称,会有一些混用,望读者知晓。

最左前缀原则

顾名思义,就是最左优先,这个最左是针对于组合索引和前缀索引,理解如下:

  1. 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
  2. =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

两阶段锁

传统RDBMS加锁的一个原则,就是2PL (Two-Phase Locking,二阶段锁)。相对而言,2PL比较容易理解,说的是锁操作分为两个阶段:加锁阶段与解锁阶段,并且保证加锁阶段与解锁阶段不相交。

Gap锁和Next-Key锁

InnoDB中的完整行锁包含三部分:记录锁(Record Lock)、间隙锁(Gap Lock)、Next-Key Lock。以下定义摘自MySQL官方文档

记录锁(Record Locks):记录锁锁定索引中一条记录。
间隙锁(Gap Locks):间隙锁要么锁住索引记录中间的值,要么锁住第一个索引记录前面的值或者最后一个索引记录后面的值。 Next-Key Locks:Next-Key锁是索引记录上的记录锁和在索引记录之前的间隙锁的组合。

隔离级别

Read Uncommited

  • 可以读取未提交记录。此隔离级别,不会使用,忽略

Read Committed (RC)

  • 针对当前读,RC隔离级别保证对读取到的记录加锁 (记录锁),存在幻读现象。

Repeatable Read (RR)

  • 针对当前读,RR隔离级别保证对读取到的记录加锁 (记录锁),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入 (间隙锁),不存在幻读现象。

Serializable

  • 从MVCC并发控制退化为基于锁的并发控制。不区别快照读与当前读,所有的读操作均为当前读,读加读锁 (S锁),写加写锁 (X锁)。
  • Serializable隔离级别下,读写冲突,因此并发度急剧下降,在MySQL/InnoDB下不建议使用。

行锁原理分析

  • 简单SQL的加锁分析:

    1. select * from t1 where id = 10;
    2. delete from t1 where id = 10;
  • RC隔离级别下:

    1. id是主键
      • 只需要将主键上id = 10的记录加(索引=10)上X锁即可
    2. id唯一索引
      1. 找到索引=10上X锁
      2. 找到这条记录的主键 (回主键索引(聚簇索引) )索引加锁 (如果并发一个sql语句根据主键查询,如果这条记录没有在主键索引上加锁,则会违背同一条记录的修改操作)
    3. id唯一索引
      1. 满足SQL查询条件的记录,都会被加锁。
      2. 这些记录在主键索引上的记录,也会被加锁。
    4. id 无索引
      1. 如果一个条件无法通过索引快速过滤,那么存储引擎层面就会将所有记录加锁后返回,然后由MySQL Server层进行过滤。因此也就把所有的记录,都锁上了。
      2. 在MySQL Server过滤条件,发现不满足后,会调用unlock_row方法,把不满足条件的记录放锁 (违背了2PL的约束)。这样做,保证了最后只会持有满足条件记录上的锁,但是每条记录的加锁/放锁操作还是不能省略的。
  • RR隔离级别:

    1. id是主键 (同上) 只需要将主键上id = 10的记录加(索引=10)上X锁即可
    2. id唯一索引(同上) 两个X锁,id唯一索引满足条件的记录上一个,对应的聚簇索引上的记录一个
    3. id非唯一索引
      1. 循环定位到第满足查询条件的记录,加记录上的X锁,加GAP上的GAP(间隙锁)锁,然后加主键聚簇索引上的记录X锁
      • 非唯一索引的存储结构: B树, 一个节点存储多个数据,左边的节点索引<当前节点>右侧节点, 如果其他session在这个区间插入或者删除数据,导致幻读,因为间隙锁的存在会解决这个问题, 我个人理解为一个双向链表,每一个元素都有向前向后的指针,如果两个元素中间存在间隙锁,则无法插入或更新数据
    4. id无索引
      1. 会锁上表中的所有记录,同时会锁上聚簇索引内的所有GAP,杜绝所有的并发更新/删除/插入操作。当然,也可以通过触发semi-consistent read,来缓解加锁开销与并发影响,但是semi-consistent read本身也会带来其他问题,不建议使用。
    • Serializable
    1. 会对sql1 加读锁
  • 一条复杂SQL的加锁分析

    	Table: t1(id primary key, userid,pubtime,comment);
    	index: idx_te_pu(pubtime, id key);
    	sql  : delete from t1 where pubtime>1 and pubtime <20 and userid ="os" and content = "1"
    
    • RR隔离级别
    1. 在pubtime的范围内加x锁和GAP锁
    2. 根据1对应的数据的主键加X锁(回表)
    • 测试
    	CREATE TABLE `t1` (
    	`id`  int(11) NOT NULL ,
    	`pubtime`  int(2) NULL DEFAULT NULL ,
    	`userid`  varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
    	`content`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
    	PRIMARY KEY (`id`),
    	INDEX `pu` (`pubtime`, `userid`) USING BTREE);
    
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("1", "1", "1", NULL);
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("10", "1", "a", NULL);
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("2", "2", "2", NULL);
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("4", "3", "b", NULL);
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("22", "5", "os", NULL);
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("5", "10", "os", "1");
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("100", "20", "c", NULL);
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("30", "21", "d", NULL);
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("31", "31", "e", NULL);
    	INSERT INTO `t1` (`id`, `pubtime`, `userid`, `content`) VALUES ("32", "32", "e", NULL);
    
    
  • sessiona

    1. set autocommit = 0;
    2. "delete from t1 where pubtime>1 and pubtime <20 and userid ="os" and content = "1""
  • sessionb

    1. update t1 set content = 4 where id = 30;
  • 进入阻塞状态 猜想: 因为content没有索引导致所有行加X锁

    
    	mysql> show status like "%row_lock%";
    	+-------------------------------+--------+
    	| Variable_name                 | Value  |
    	+-------------------------------+--------+
    	| Innodb_row_lock_current_waits | 1      |
    	| Innodb_row_lock_time          | 460003 |
    	| Innodb_row_lock_time_avg      | 25555  |
    	| Innodb_row_lock_time_max      | 51004  |
    	| Innodb_row_lock_waits         | 18     |
    	+-------------------------------+--------+
    	5 rows in set (0.00 sec)
    
    
    • Innodb_row_lock_current_waits | 1 |有一个等待
  • 执行commit并回复数据后

    1. sessiona 执行delete from t1 where pubtime>4 and pubtime <20 and userid ="os";
    2. sessionb INSERT INTO t1 (id, pubtime, userid, content) VALUES ("19", "19", "d", ""); 会进入等待 取消命令( ctrl +c) 被阻塞,原因是pubtime在 索引3到20范围内, 此时已对该区域加GAP(间隙锁)
    3. sessionb INSERT INTO t1 (id, pubtime, userid, content) VALUES ("21", "21", "d", ""); 执行成功
    4. sessionb INSERT INTO t1 (id, pubtime, userid, content) VALUES ("25", "18", "d", ""); 被阻塞,原因是pubtime在 索引3到20范围内, 此时已对该区域加GAP(间隙锁)

死锁原理与分析

1. 每个事务执行两条SQL,分别持有了一把锁,然后加另一把锁,产生死锁。
2. 多个事物对两条记录同时更新,sessiona先持有 a记录, sessionb先持有b记录,sessiona更新b记录的时候 需要获取sessionb的锁,但是sessionb 去更新a记录的时候同样需要获取sessiona的锁,导致死锁.
  • 如何解决死锁呢?MySQL默认会主动探知死锁,并回滚某一个影响最小的事务。等另一事务执行完成之后,再重新执行该事务。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MYSQL高级

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MYSQL 高级

SQL查询流程: 1. 通过客户端/服务器通信协议与 MySQL 建立连接2. 查询缓存,这是 MySQL 的一个可优化查询的地方,如果开启了 Query Cache 且在查询缓存过程中查 询到完全相同的 SQL 语句,则将查询结果直接返回给客户端;如果没有开
MYSQL 高级
2018-06-04

MYSQL高级

相关术语介绍多版本并发控制MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version ConcurrencyControl)(注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrenc
MYSQL高级
2017-10-03

三、mysql高级操作

二、分库 三、分表
三、mysql高级操作
2016-03-05

MYSQL 一些 高级语法

从一个表中复制列插入到指定的表中:# 字段的值必须一样INSERT INTO table2SELECT * FROM table1;select 子查询where子查询# 必须针对一个字段进行查询 (单列)Select 列名From table1Where 列
MYSQL 一些 高级语法
2020-06-01

MYSQL事务篇(高级篇)

1.事务介绍:一般是指要做的或所做的事情。 在计算机 术语 中是指访问并可能更新数据库中各种 数据项 的一个程序 执行单元 (unit)2.数据库事务具有ACID四大特性。ACID是以下4个词的缩写:原子性(atomicity) :事务最小工作单元,要么全成功
MYSQL事务篇(高级篇)
2015-04-25

Mysql高级05-SQL语句

SQL库结构操作SQL 1、查看所有数据库show databases;2、切换使用数据库use 数据库名; 3、创建数据库create database 数据库名;create database 数据库名 charset "utf8";4、删除数据库drop
Mysql高级05-SQL语句
2014-06-05

详解高性能mysql之MySQL高级特性总结

MySQL是一款广泛使用的关系型数据库管理系统,具有高性能和高可靠性的特点。在高性能MySQL中,有一些高级特性可以帮助提升数据库的性能和可靠性。下面是对这些高级特性的详细解释。1. 主从复制(Master-Slave Replicatio
2023-09-22

MySQL高级篇——索引简介

🙌作者简介:数学与计算机科学学院学生、分享学习经验、生活、 努力成为像代码一样有逻辑的人 🌙个人主页:阿芒的主页 文章目录 👩‍🔧索引是什么👩‍&
2023-08-16

【MySQL】细谈SQL高级查询

文章目录 一、前言 & 准备工作二、简易高级查询⚙ 准备工作1、查询每一门课程及其先修课程2、查询和“刘涛”在一个班级的学生的信息3、查询选修了‘计算机基础’课的学生的学号、姓名③ 连接方式④ 子查询嵌套方式 4、查询没有
【MySQL】细谈SQL高级查询
2023-12-23

MySQL数据表高级操作

一、克隆/复制数据表二、清空表,删除表内的所有数据删除小结 三、创建临时表四、MySQL中6种常见的约束1、外键的定义2、创建外键约束作用3、创建主表test44、创建从表test55、为主表test4添加一个主键约束。主键
2023-08-17

MySQL 的主从复制(高级篇)

首先要明白为什么要用 mysql 的主从复制:1–在从服务器可以执行查询工作 (即我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)2–在从主服务器进行备份,避免备份期间影响主服务器服务;(确保数据安全)3–当主服务器出现问题时,可以切换到从服务器
MySQL 的主从复制(高级篇)
2016-04-17

MySQL高级(五)——慢查询日志

具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10秒以上的语句。由他来查看哪些SQL超出了我们的最大忍耐时间值,比如一条sql执行超过5秒钟,我们就算慢SQL,希望
MySQL高级(五)——慢查询日志
2018-03-26

编程热搜

目录