MySQL笔记【面试】

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
日志服务 SLS,月写入数据量 50GB 1个月
简介: MySQL笔记【面试】

前言

以下内容源自A minor

仅供学习交流使用

推荐

MySQL

MySQL笔记

【MySQL】基础使用(一):支持的数据类型


【MySQL】基础使用(二):常用 SQL 语句大全


【MySQL】基础使用(三):视图操作及其作用


【MySQL】基础使用(四):用户及权限操作


【MySQL】left join、right join、inner join 区别对比


【MySQL】SQL 查询中 in 和 exists 的区别分析

select from A where op B
in适用于B表较小
因为会把符号条件的B表中的数据存储到内存中构成临时表
再存A表中注意匹配临时表
exists适用于A表较小
把A表数据缓存成临时表,与B表数据逐一匹配

【MySQL】基础使用(五):几条运行监控命令

【MySQL】运行原理(一):整体架构

【MySQL】运行原理(二):查询 SQL 的执行过程分析


【MySQL】运行原理(三):增删改 SQL 执行过程分析


【MySQL】存储引擎(一):存储引擎介绍

InnoDB 支持事务具有外键 行锁
MyISAM 查询。插入效率 表锁 行数

【MySQL】存储引擎(二):InnoDB 内存结构

1.Buffer Pool 缓存池 
当Buffer Pool中有所需页,直接修改 等待后续刷脏处理
当Buffer Pool中没有所需页,磁盘调入内存 此时至少有一次磁盘IO,Change Buffer优化一下
1.1Change Buffer(写缓存) :
针对写操作 Buffer Pool没有所需页
当修改字段是普通索引,直接存入Change Buffer 当下次改页调入内存中,把Change Buffer 记录到数据页的操作merge。
当修改字段是唯一索引,就只能将数据页从磁盘读入到内存,返回给执行
1.2Adaptive Hash Index 
InnoDB存储引擎会监控对表上各个索引页的查询,如果观察到建立哈希索引可以带来速度上的提升,则建立哈希索引,所以叫做自适应哈希索引。
2.Log Buffer(Redo log)
WAL 技术(Write-Ahead Logging),它的关键点就是先写日志,再写磁盘。
顺序IO和随机IO的区别
操作系统内存-页  磁盘-块
Log Buffer的刷盘机制
写到os buffer,写到磁盘的
0 延迟写,延迟刷 1秒
1 实时写,实时刷 事务提交 默认
2 实时写,延迟刷 事务提交 操作系统1秒
redo log(重做日志)有什么特点
物理日志 记录的数据信息 √
逻辑日志 记录的操作信息
二个日志文件 logfile0 logfile1
write pos check point


【MySQL】存储引擎(三):InnoDB 磁盘结构

MySQL的存储结构分为5级:表空间、段、簇、页、行。
表空间:下篇讲 2^32个页 64TB
段:索引段、数据段
簇:区 1MB 64个连续的页
页:16KB

【MySQL】存储引擎(四):InnoDB 磁盘结构(表空间

1.system tablespace(系统表空间)
UndoLogs 在后面介绍
InnoDB数据字典 由内部系统表组成,存储表和索引的元数据(定义信息)
双写缓冲区
  InnoDB的页和操作系统的页大小不一致,InnoDB页大小一般为16K,操作系统页大小为4K,InnoDB的页写入到磁盘时,一个页需要分4次写。
  部分写失效(partial page write)
  页的副本就是 double write,InnoDB的双写技术。通过它实现了数据页的可靠性。
ChangeBuffer 已介绍
2.file-per-table tablespaces(独占表空间)
3.general tablespaces(通用表空间)
4.temporary tablespaces(临时表空间)
5.undo log tablespace 
undo log(撤销日志或回滚日志)
逻辑格式的日志

【MySQL】存储引擎(五):重做日志(redo log),回滚日志(undo log),二进制日志(binlog

1.重做日志(redo log)
MySQL更新数据--为了减少磁盘IO,有了Buffer Pool缓存页数据--在内存中--防止丢失--redo log
确保事务的持久性
物理日志
2.回滚日志(undo log)
原子性底层就是通过undo log实现的
作用 回滚数据 MVCC
逻辑日志
3.二进制日志(binlog)
主从同步 还原
STATMENT、ROW、和MIXED
=> undo log 和 redo log
=> redo/undo log 和 binlog

【MySQL】索引原理(一):索引的存储结构是什么?数组?链表?树?

1.数组/链表
2.二叉查找树(BST Binary Search Tree) 
  查找效率与树的深度有个 斜树 O(n)
3.平衡二叉树(AVL Tree)(左旋、右旋)
  左右子树的深度差不超过1
4.多路平衡查找树(B Tree)(分裂、合并)
  二叉效率低
5.B+树(加强版多路平衡查找树)
  数据都在叶子结点上 
6.为什么不用红黑树?
  BST 黑平衡
  1、只有两路;2、不够平衡
7.哈希表也能作为索引?
  哈希冲突(采用拉链法解决)
  Memcache 支持
  Mysql InnoDB 自适应哈希

【MySQL】索引原理(二):B+Tree索引的实现,MyISAM 和 InnoDB

1.MyISAM
.MYD 数据文件  .MYI 索引文件
都是非聚簇索引 存的是地址 都需回表操作
2.InnoDB
.ibd 
聚簇索引 完整数据
非聚簇索引 主键 回表到聚簇索引
B+Tree是通过不断的分叉和合并操作使树保持平衡的,而这个时候键值的地址会发生变化,所以在辅助索引里面不能存储地址。
隐藏地址 rowid
select _rowid name from user_info;

【MySQL】索引原理(三):联合索引(最左前缀原则),覆盖索引,索引条件下推

1.联合索引与最左前缀原则
全值匹配我最爱,最左前缀要遵守
带头大哥不能死,中间兄弟不能断
索引列上少计算,范围之后全失效
like百分写最右,覆盖索引不写星
不等空值还有or,索引失效要少用
2.覆盖索引
不用回表
3.索引条件下推(ICP)
先筛选,最后回表
只适用于二级索引。ICP 的目标是减少访问表的完整行的读数量从而减少 I/O 操作。

【MySQL】索引原理(四):创建索引的几点建议,列的离散度,前缀索引

1.列的离散度
建立索引,要使用离散度(选择度)更高的字段。
2.前缀索引
我们可以通过截取字段的前面一部分内容建立索引,这个就叫前缀索引。

【MySQL】事务与锁(一):详解数据库事务及并发时可能出现的问题

1.什么是事务?
  不可以再分
2.事务的四大特性
  原子性 undo log
  一致性 其余三个保证
  隔离性 
  持久性 redo log和double write双写缓冲保证
3.数据库如何操作事务?
  显示开启 begin
  隐式开启 autocommit=0
4.事务并发会带来什么问题?
  脏读:事务A读取到了事务B已经修改但尚未提交的数据
  不可重复读:事务A读取到了事务B已经提交的修改数据 导致自己读的和上一次不一样
  幻读:事务A读取到了事务B提交的新增数据,不符合隔离性
5.如何解决并发处理事务带来的问题?
  5.1 SQL92标准 
  隔离级别
  读未提交
  读已提交
  可重复读
  串行化
  5.2 InnoDB 对隔离级别的支持
  可重复读可以解决幻读

【MySQL】事务与锁(二):事务并发控制方案(LBCC + MVCC)

1.LBCC 方案
基于锁的并发控制 Lock Based Concurrency Control(LBCC)。
读未提交(Read Uncommitted)
  解决更新丢失问题。如果一个事务已经开始写操作,那么其他事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现,即事务需要对某些数据进行修改必须对这些数据加 X 锁,读数据不需要加 S 锁。
读已提交(Read Committed)
  解决了脏读问题。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。这可以通过“瞬间共享读锁”和“排他写锁”实现, 即事务需要对某些数据进行修改必须对这些数据加 X 锁,读数据时需要加上 S 锁,当数据读取完成后立刻释放 S 锁,不用等到事务结束。
可重复读取(Repeatable Read)
  禁止不可重复读取和脏读取,但是有时可能出现幻读数据。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
  Mysql默认使用该隔离级别。这可以通过“共享读锁”和“排他写锁”实现,即事务需要对某些数据进行修改必须对这些数据加 X 锁,读数据时需要加上 S 锁,当数据读取完成并不立刻释放 S 锁,而是等到事务结束后再释放。
串行化(Serializable)
  解决了幻读的问题的。提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
不支持并发的读写操作
问题
  如果仅仅是基于锁来实现事务隔离,一个事务读取的时候不允许其他时候修改,那就意味着不支持并发的读写操作,而我们的大多数应用都是读多写少的,这样会极大地影响操作数据的效率。
  所以我们还有另一种解决方案,如果要让一个事务前后两次读取的数据保持一致,那么我们可以在修改数据的时候给它建立一个备份或者叫快照,后面再来读取这个快照就行了。这种方案我们叫做多版本的并发控制 Multi Version Concurrency Control(MVCC)。
2.MVCC 优化
多版本并发控制(Multi-Version Concurrency Control, MVCC)是MySQL中基于乐观锁理论实现隔离级别的方式,用于实现读已提交和可重复读取隔离级别的实现。
最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度。
以 InnoDB 为例,每一行中都冗余了两个字断。一个是行的创建版本,一个是行的删除(过期)版本。具体的版本号(trx_id)存在 information_schema.INNODB_TRX 表中。版本号(trx_id)随着每次事务的开启自增。
事务每次取数据的时候都会取创建版本小于当前事务版本的数据,以及过期版本大于当前版本的数据。
PS:在 InnoDB 中,MVCC 是通过 Undo log 实现的;Oracle、Postgres等等其他数据库都有MVCC的实现。
3.最终策略:LBCC+MVCC
在 InnoDB 中,MVCC 和锁是协同使用的,这两种方案并不是互斥的。
问题一:各个隔离级别如何实现?
  1)Read Uncommited:RU 隔离级别,不做并发控制
  2)Read Commited:RC 隔离级别
    快照读:MVCC,每次快照读时都生成 ReadView,读完就销毁
    当前读:记录锁(RC 不支持 Gap Lock),直到事务结束才释放
      隐式:insert、delete、update 默认使用
      显式:select for update / lock in share mode
小结:
  正因为是 ReadView 是一致性视图是会变化的,所以快照读下 RC 会出现不可重复读问题
  正因为是记录锁,锁的只是单条记录,所以 RC 在当前读下会出现幻读的问题。
注:RC 不管单行还是范围查找,都不会用到gap lock;除了两种特殊情况——外键约束检查(foreign-key constraint checking)以及重复键检查(duplicate-key checking)时会使用间隙锁封锁区间。
3)Repeatable Read:RR 隔离级别
  快照读:MVCC,第一次快照读时生成 ReadView,事务提交时销毁
  当前读:当前元素临键锁(左开右闭) + 相邻间隙锁,直到事务结束才释放
    隐式:insert、delete、update 默认使用
    显示:select for update / lock in share mode
小结:
  正因为视图的一致性,所以快照读下 RR 解决了不可重复读问题
  正因为间隙锁,锁住了元素及左右区间(无法添加系元素),所以当前读下 RR 解决了幻读问题(InnoDB,有争议)
4)Serializable:串行化
所有的 select 语句都会被隐式的转化为 select … in share mode,会和 insert、update、delete 互斥。
问题二:所以,事务隔离级别怎么选?
RU 和 Serializable 肯定不能用。为什么有些公司要用 RC,或者说网上有些文章推荐有 RC?
RC 和 RR 主要有几个区别:
  RR 的间隙锁会导致锁定范围的扩大
  条件列未使用到索引,RR 锁表,RC 锁行
  RC的“半一致性”(semi-consistent)读可以增加 update 操作的并发性。
在RC中,一个update语句,如果读到一行已经加锁的记录,此时InnoDB返回记录最近提交的版本,由MySQL上层判断此版本是否满足 update的where条件。若满足(需要更新),则MySQL会重新发起一次读操作,此时会读取行的最新版本(并加锁)。
实际上,如果能够正确地使用锁(避免不使用索引去加锁),只锁定需要的数据,用默认的RR级别就可以了。

【MySQL】事务与锁(三):事务并发控制方案(MVCC)

1.MVCC是什么
  MVCC的核心思想是: 我可以查到在我这个事务开始之前已经存在的数据,即使它在后面被修改或者删除了。在我这个事务之后新增的数据,我是查不到的。
  这个快照什么时候创建?读取数据的时候,怎么保证能读取到这个快照而不是最新的数据?这个怎么实现呢?
  InnoDB为每行记录都实现了两个隐藏字段:
  DB_TRX_ID,6字节:插入或更新行的最后一个事务的事务ID,事务编号是自动递增的(我们把它理解为创建版本号,在数据新增或者修改为新数据的时候,记录当前事务ID)。
  DB_ROLL_PTR,7字节:回滚指针(我们把它理解为删除版本号,数据被删除或记录为旧数据的时候,记录当前事务ID)。我们把这两个事务ID理解为   版本号。
MVCC的查找规则:只能查找创建时间小于等于当前事务ID的数据,且删除时间大于当前事务ID的行(或未删除)。

【MySQL】事务与锁(四):事务并发控制方案(LBCC)

1.锁的粒度
  行锁 表锁
  加锁效率 冲突的概率
2.锁的基本模式
  2.1 共享锁/排他锁(行级别读/写锁)
  2.2 意向共享锁/意向排他锁(表级别读/写锁)
  问题一:锁的作用是什么?它跟Java里面的锁是一样的,是为了解决资源竞争的问题,Java里面的资源是对象,数据库的资源就是数据表或者数据行。所以锁是用来解决事务对数据的并发访问的问题的。
  问题二:锁到底锁住了什么呢?当一个事务锁住了一行数据的时候,其他的事务不能操作这一行数据,那它到底是锁住了这一行数据,还是锁住了这一个字段,还是锁住了别的什么东西呢?锁的其实是索引,详情见 行锁到底锁住的是什么?
3.行锁的算法
  3.1 记录锁 
    第一种情况,当我们对于唯一性的索引(包括唯一索引和主键索引)使用等值查询,精准匹配到一条记录的时候,这个时候使用的就是记录锁。
  3.2 间隙锁
    第二种情况,当我们查询的记录不存在,没有命中任何一个record,无论是用等值查询还是范围查询的时候,它使用的都是间隙锁。
    注意,间隙锁主要是阻塞插入insert,而没有阻塞select。相同的间隙锁之间不冲突。
    Gap Lock 只在隔离级别 RR 中存在
  3.3 临键锁
    第三种情况,当我们使用了范围查询,不仅仅命中了 Record 记录,还包含了 Gap 间隙,在这种情况下我们使用的就是临键锁,它是MySQL里面默认的行锁算法,相当于记录锁加上间隙锁。
    临键锁与间隙锁不同的是,它除了锁住原本的临键区间,还会锁住最后一个key的下一个左开右闭的区间
    为什么要锁住下一个左开右闭的区间?——为了解决幻读的问题。所以,我们看下MySQL InnoDB里面事务隔离级别的实现。为什么 InnoDB 的RR 级别能够解决幻读的问题,就是用临键锁实现的。

【MySQL】事务与锁(五):行锁到底锁住的是什么?记录?字段?索引?

在没有索引或者没有用到索引的情况下,会锁住整张表  
隐藏字段ROWID做索引了
为什么锁表,是因为查询没有使用索引,会进行全表扫描,然后把每一个隐藏的聚集索引都锁住了。
InnoDB 的行锁,就是通过锁住索引来实现的。
总结一下:
  行锁在 InnoDB 中是基于索引实现的,所以一旦某个加锁操作没有使用索引,那么该锁就会退化为表锁
  除了直接在主键索引加锁,我们还可以通过辅助索引找到相应主键索引后再加锁

【MySQL】事务与锁(六):死锁问题分析

【MySQL】性能调优(一):配置。连接配置优化

【MySQL】性能调优(二):表结构。建表及存储引擎几点建议

【MySQL】性能调优(三):SQL。慢查询日志及SQL优化建议

1.慢日志
2.SQL 优化建议

【MySQL】性能调优(四):SQL。EXPLAIN 执行计划详解

【MySQL】性能调优(五):架构。集群及分库分表

【MySQL】性能调优(六):业务层。减轻数据库压力

最后

2022/11/20 23:22

这篇博客能写好的原因是:站在巨人的肩膀上

这篇博客要写好的目的是:做别人的肩膀

开源:为爱发电

学习:为我而行

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
10天前
|
存储 SQL 关系型数据库
MySQL进阶突击系列(03) MySQL架构原理solo九魂17环连问 | 给大厂面试官的一封信
本文介绍了MySQL架构原理、存储引擎和索引的相关知识点,涵盖查询和更新SQL的执行过程、MySQL各组件的作用、存储引擎的类型及特性、索引的建立和使用原则,以及二叉树、平衡二叉树和B树的区别。通过这些内容,帮助读者深入了解MySQL的工作机制,提高数据库管理和优化能力。
|
1月前
|
SQL 关系型数据库 MySQL
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
MySQL慢查询优化、索引优化,是必知必备,大厂面试高频,本文深入详解,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验分享。
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
|
2月前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
1月前
|
SQL 缓存 关系型数据库
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴因未能系统梳理MySQL缓存机制而在美团面试中失利。为此,尼恩对MySQL的缓存机制进行了系统化梳理,包括一级缓存(InnoDB缓存)和二级缓存(查询缓存)。同时,他还将这些知识点整理进《尼恩Java面试宝典PDF》V175版本,帮助大家提升技术水平,顺利通过面试。更多技术资料请关注公号【技术自由圈】。
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
|
1月前
|
SQL 算法 关系型数据库
面试:什么是死锁,如何避免或解决死锁;MySQL中的死锁现象,MySQL死锁如何解决
面试:什么是死锁,死锁产生的四个必要条件,如何避免或解决死锁;数据库锁,锁分类,控制事务;MySQL中的死锁现象,MySQL死锁如何解决
|
1月前
|
SQL 关系型数据库 MySQL
美团面试:Mysql如何选择最优 执行计划,为什么?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴面试美团时遇到了关于MySQL执行计划的面试题:“MySQL如何选择最优执行计划,为什么?”由于缺乏系统化的准备,小伙伴未能给出满意的答案,面试失败。为此,尼恩为大家系统化地梳理了MySQL执行计划的相关知识,帮助大家提升技术水平,展示“技术肌肉”,让面试官“爱到不能自已”。相关内容已收录进《尼恩Java面试宝典PDF》V175版本,供大家参考学习。
|
2月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
4天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
13 3
|
4天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
20 3
|
4天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE 'log_%';`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
25 2