对MySQL8做了一个大致的学习汇总。第一个版本的大纲如下图。
MySQL8大纲(v1.0.0)
认识MySQL
定义
- 数据库:数据库是数据文件和其他文件的集合。
- 数据库实例:数据库实例是由进程和内存组成。数据库实例是真正操作数据库文件。
- MySQL是一个单进程多线程架构的数据库。
架构体系
- SQL执行分层
- 连接器->查询缓存->分析器->优化器->执行器->存储引擎
- 连接器
- 查询缓存(8.0版本已经弃用)
- 分析器
- 优化器
- 执行器
- 存储引擎
- 分层内容
- 执行顺序
- 体系结构
- 连接层
- SQL层
- 网络通信
- 线程处理
- 用户密码认证
- 查询缓存
- 解析器
- 优化器
- 执行器
- 权限判断
- 预处理
- 定义:存储引擎是以插件式的方式运行,主要用于数据存户与检索。可以根据MySQL内部的接口实现自定义存储引擎。
- 分类
- Memory
- ARCHIVE
- NDB
- 数据文件存放内存,默认使用哈希索引、只支持表锁、不支持TEXT和BLOB类型数据、varchar按照定长方式存储
- 数据压缩存储、只支持INNSERT和SELECT操作
- 数据全部存放内存
- MyISAM
- InnoDB
- Maria
- 支持表锁、全文索引、GEO、缓存区只存储索引内容
- 支出表锁、行锁、MVVC、事务、自适应哈希索引、
- 支持缓存数据和索引文件、支持行锁、支持MVVC、支持事务和非事务;旨在替代MyISAM
- 官方存储引擎
- 第三方存储引擎
- 存储引擎层
- 服务层
- 文件
- MYD
- MYI
- frm
- ibd
优势
- 跨平台
- 移植性强
- 开源版和企业版
- 成本低
InnoDB存储引擎
认识InnoDB
- InnoDB存储引擎是MySQL第一个支持完整ACID事务的存储引擎,它以插件是的方式在MySQL5.5版本开始作为默认的存储引擎。
- InnoDB存储引擎支持行锁、MVCC、外键和提供一致性非锁定读等特点。
体系架构
- InnoDB存储引擎由多个内存块组成,这些内存组成了一个大的内存池。
- 内存池
- 作用
- 分类
- 刷新内存中的数据。
- 已修改的数据文件刷新到磁盘中。
- 异常情况下,数据回滚到正常情况。
- 负责脏页的刷新。
- 事务提交之后,负责回收已经使用并分配的undo页。
- 负责IO请求回调,进行数据的读写操作。
- 核心线程,将缓冲池的数据刷新到磁盘中,保证数据的一致性、脏页的刷新、合并插入缓冲池、undo页回收等。
- Master 线程
- IO 线程
- Purge 线程
- Page Cleaner 线程
- 线程
内存
- 缓冲池
- 配置缓冲区大小:innodb_buffer_pool_size
- 作用:数据从内存中去读写,以提高并发能力。通过CheckPoint机制刷新到磁盘中。
- 内容:索引页、数据页、undo页、锁、插入缓冲、自适应hash、数据字典等信息。
- 在1.0.x版本开始,允许创建多个缓冲池实例。降低了数据库内部的资源竞争,提高数据并发能力。
- 配置项
- 重做日志缓冲池
- 配置缓冲区大小:innodb_log_buffer_size
- Master线程每一秒将缓冲区的日志写入到重做日志文件。
- 事务提交时将缓冲区的日志写入到重做日志文件。
- 当缓冲区日志可用空间小于1/2时,触发写入重做日志文件。
- 作用:先将重做日志写入到重做日志缓冲区,在根据一定频率(一般是1s)将缓冲区的日志写入到缓冲日志文件中。
- 触发机制
- 配置项
- 额外内存池
- 内存管理
- 定义:缓冲池按照LRU算法,对缓存池中的页进行排序。最频繁使用的放在LRU列表最前面,使用最少的放在LRU列表最后面。
- 触发机制:当缓冲池不能存放新的页时,就会触发LRU机制。
- LRU算法优化:InnoDB对LRU算法做了一定的优化。当有新写入页时,并不是直接写入页的尾部,而是插入到midpoint位置。midpoint表示新写的页插入位置。可以通过innodb_old_blocks_pct进行配置。在该值的前面就成为new列表,后面则成为old位置。new列表表示最为活跃的热点数据。
- 为什么InnoDB需要对LRU算法进行优化,而不是直接使用LRU算法呢?
- InnoDB对LRU算法进行了优化,优化了哪些内容?
- LRU List
- Free List
- Flush List
库与表操作
数据库文件
- 配置文件
- 日志文件
- 错误日志文件
- 全量日志文件
- 慢查询日志文件
- 二进制日志文件(DML)
- 审计日志文件
- 中继日志文件
- 事务日志(undo log和redo log)
- PID 文件
- Socket 文件
- 表结构文件
- 存储引擎文件
- redo 日志(物理日志)
- undo 日志(逻辑日志)
数据库与表
- 字符集
- 数据库
- create database 数据库名称
- rename database 数据库名 to 新数据库名
- 数据表
- create table 数据表名 (表字段) engine=表存储引擎
- alter table 数据表名 rename to 新数据表名
- rename table 数据表名 to 新数据表名
- alter table 数据表名称 操作
- 数据类型
- datetime、timestamp、year、date、time等
- char、varchar、text、blob等
- int、double、decimal等
- 数值类型
- 字符串类型
- 时间类型
- JSON类型
- 枚举类型
- 查询
- 等值查询
- 不等值查询
- 自连接查询
- 交叉连接
- 内连接
- 外连接
- 联合查询
- 嵌套查询
高级特性
事务
- 事务定义
- 一组DML语句的集合
- 事务分类
- 扁平化事务
- 带有保存点扁平化事务
- 链式事务
- 嵌套事务
- 分布式事务
- 存储引擎
- InnoDB
- 提交方式
- 全部回滚
- 全部提交
- 提交点(savepoint)
- 显式提交
- 隐式提交
- 自动提交(默认情况)
- ACID
- 未提交读
- 提交读
- 可重复读(读的是当前事务开始的数据)
- 串行(数据行加表级共享锁)
- 脏读
- 幻读(update/delete)
- 不可重复读(insert)
- 幻读
- 不可重复度
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
- truncate 与 delete 区别
- truncate清空表主键,从 0 开始。
- truncate 不可回滚,delete 支持回滚。
- 删除数据
- 相同点
- 不同点
- 分布式事务
- MVVC
- 1.DB_TRX_ID:用来标识最近一次对本行记录做修改的事务的标识符,即最后一次修改本行记录的事务id。delete操作在内部来看是一次update操作,更新行中的删除标识位DELELE_BIT。
- 2.DB_ROLL_PTR:指向当前数据的undo log记录,回滚数据通过这个指针来寻找记录被更新之前的内容信息。
- 3.DB_ROW_ID:包含一个随着新行插入而单调递增的行ID, 当由innodb自动产生聚集索引时,聚集索引会包括这个行ID的值,否则这个行ID不会出现在任何索引中。
- 4.DELELE_BIT:用于标识该记录是否被删除。
- innodb存储引擎中,每行数据都包含了一些隐藏字段:DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR和DELETE_BIT。
- 多版本并发控制简单的说就是当前事务只能看见已经提交的数据记录,看不到正在修改的数据记录。所以我们只要弄清楚那些事务对于当前事务是已经提交的,那些事务对于当前事务是活跃的。
- 实现原理
- 相关字段
视图
存储过程
触发器
锁
锁介绍
- (存储引擎)表锁和行锁。InnoDB支持表锁和行锁,MyISAM只支持表锁。
- 定义:锁是防止并发式访问同一数据,导致数据不能达到一致性的数据保护机制。
锁类型
- 读锁
- 语法 -- 写锁 select * from tableName where id = ? for update; -- 读锁 select * from tableName where id = ? in share model;
- 行锁种类
- InnoDB添加锁,是添加到索引列。如果不是则会发生意向锁。
- 定义:根据锁的颗粒度划分,意向锁是InnoDB中的表锁形式。意向锁会锁住库中的表、数据页,然后在锁住数据行。
- 定义:在对某一行添加锁时,其他的线程是不能对该行进行update、delete操作。
- 定义:当InnoDB扫描索引时,会对选中的索引添加一个写锁。在对索引记录的两边添加一个间隙锁锁。
- 在RR事务隔离级别情况下,如果发生间隙锁。当时加锁的线程执行了事务的提交操作,在等待锁的线程中是可以查看到修改行对应的数据变化。
- Next-key Locks
- 读锁
- 语法
启用锁
LOCK TABLES table_name [READ | WRITE];
释放锁UNLOCK TABLES;
- 锁竞争
- 1.加锁的session可以执行插入、删除、修改和查询。
- 0:不支持插入。
- 2:强制支持在表的末尾插入新数据。
- 配置项(concurrent_insert)
- 行锁(InnoDB)
- 当前session对某一行加锁,没有索引的情况下。会自动进行锁升级,将行锁升级为表锁。其他的session将无法做加锁、查询、更新、创建和删除操作。
- 当前session对某一行加锁,其他的session不能对当前加锁的行进行加锁、更新和删除,但是可以进行查询。
- 加锁的session只能执行查询,不能进行更新、插入和删除。
表锁与行锁区别(分析角度)
- 颗粒度
- 开销
- 并发程度
常见问题
- InnoDB
- 自动监控锁超时
- 写优先权大于读
- 锁等待
锁监控
- INNODB_TRX(表)
- INNODB_LOCK_WAITS(表)
- infomation-schema(库)
索引
- 索引定义
- 索引是一种为了快速检索数据的数据结构
- 索引检索方式
- 索引检索快,是因为选择了合适的数据结构。
- 索引检索时,首先会去查找索引key对应的索引页,然后把该页的数据加载到内存中,然后通过在内存中进行筛选,得到数据的物理地址。然后根据物理地址在去磁盘中进行查找。
- 索引的优缺点
- 索引存储在磁盘中,会占空磁盘空间。对于查询效率来说,这一点磁盘空间不足考虑。
- 对数据的增删改,都会去维护索引。因此也有时间消耗。
- 通过索引的顺序查找数据,查询快。由原来的随机查找变为索引顺序查找。
- 优点
- 缺点
- 索引分类(按照存储引擎分类)
- myisam存储引擎为了检索全文的一种索引类型。主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。全文索引在InnoDB1.2.x版本中也同样支持并且具备更多的功能。
- 是一种等值检索的索引,在innodb中是自适应的,无法人为的去设置,而是通过MySQL内部自动根据情况来设置。
- 为了存储地理空间数据的一类索引。
- 是一种由B树和索引访问顺序演变而来的索引,也就是我们常说的一种索引类型。
- B Tree
- 空间索引(InnoDB不支持)
- Hash索引
- 全文索引
- InnoDB存储引擎中的索引
- 失效场景
- 使用LIKE进行模糊查找
- 使用OR进行逻辑或查找
- 使用IN进行范围查找
- 索引列与索引列比较
- 索引列使用了表达式、函数
- 索引对应列的类型,与条件中的类型不一致(需要注意MySQL在一些情况下回做隐式转换。)
- 用>、<或者!=这样的比较运算符
- 说明
- 创建索引的几种场景
- 索引创建规范
- 索引虽然能够帮助我们高效查询数据。但是在做DDL操作时,索引内部需要进行维护,这也是有消耗的。因此创建索引不是越多查询效率就越高,也不是越少越好。我们需要把我好其中的度。
- 数据量大,查询频繁。
- 针对条件查询时,创建索引。
- 尽可能的使用联合索引,而不是创建多个单列索引。
- 针对where查询条件的字段,创建索引。
- 查询频率高的字段,创建索引。
- 尽可能的使用唯一索引,因为唯一索引的key是唯一的,查询效率更快。
- 索引的名称尽可能的短,因为索引的名称也要占磁盘空间。
- 索引列的区分度越高越好。 例如在sex(性别)上创建索引就不是一个很好的方式。因为性别无非就是三种情况。这里的区分度指的是索引列的值存在多种情况。
- 创建索引
- 删除索引
- 查看索引
- alter table table_name(表名) add [primary key | uniique | index | fulltext] index_name(索引名)(column_name[长度])[asc|desc]
- create [primary key | uniique | index | fulltext] index index_name(索引名) on table_name(表名)(column_name[长度])[asc|desc]
- drop index index_name(索引名称) on table_name(表名)
- show index form table_name(表名)
- 聚集索引
- 非聚集索引
- 区别
- InnoDB是一种索引组织表,表中的每一行数据都是按照主键的顺序来存储的。聚集索引正是使用表的每一个主键构建的一个B Tree结构的索引。
- 聚集索引的子节点存储的是表中的行数据。
- 说明
- 定义:以某一列的某些特点字符作为索引的前缀。可以看成是普通索引的升级版。
- 适用的字段类型
- 优缺点
- text
- blob
- varchar
- 便于快速检索数据。
- 不能使用在order by情况中。
- 不能使用在group by的情况中。
- 不能使用在覆盖索引的情况中。
- 创建的索引长度,最好是根据column_name对应的长度来确定。
- 定义:一个索引包含(覆盖)所有查询字段的值。
- 优势
- 举例: 在name 字段创建了一个索引。使用如下查询就是一个覆盖索引。select id, name from user where name = '张三'。因为 id 是一个默认的主键索引,而name 字段也是一个索引。在存储的时候,会将 name 和 id 存储到一块。因此在查询的时候,包含了所有的查询字段的值。如果是select id, name, age from user where name = '张三'。就会从新回盘查找。
- 失效问题(常见)
- 1.索引的数目始终是小于数据表的数目。
- 2.顺序访问,避免随机 IO(索引存储的是有顺序的)。
- 3.减少系统调用(部分存储引擎,如 MyISAM在内存中存储的是索引),读取数据还需要系统层面。
- 4.在 InnoDB 的聚簇索引中,可以减少二次索引开销。
- 减少回表查询。
- 作用
- 原因
- 没有任何索引能覆盖到该查询。
- 进行报错前缀的like 比较操作。
- 定义:由两个或者两个以上的列组成的索引集合。联合索引要求在使用时,要遵循最左侧原则(在一些统计类型的查询中,MySQL内部优化器会存在使用索引的情况。)。
- 优缺点
- 减少数据检索范围。
- 必须遵循前缀索引原则,够则索引会生效。
- 没有任何限制,就是单纯的一个索引,就是为了某一列的快速检索。
- 定义:索引列的值不能重复,但是可以为NULL。
- 语法:alter table table_name add unique(column_name)
- 唯一索引
- 普通索引
- 联合索引
- 覆盖索引
- 前缀索引
- InnoDB是一种索引组织形式的表,表都是根据主键顺序进行排序。
- 聚集索引其实就是一种索引组织形式,索引的键值决定了数据行的物理存储顺序。
- 主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。
- 非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。
- 普通索引需要先搜索一次索引树,得到主键索引的值,然后在根据主键索引检索出数据。
- 二叉树
- 平衡二叉树(AVL树)
- B树
- 索引访问顺序(ISAM)
- B Tre
- 当数据量大的时候,树的高度大(节点多),检索数据同样会很慢,导致效率不高。
- 插入数据非常简单,只需要根据每一个节点的值进行大小比较,就可以确定新插入的值放在什么位置。
- 每一个节点只会存在两个子节点,节点左侧的值一定是小于根节点的值,节点右侧的值一定是大于根节点的值。
- 特点
- 优点
- 缺点
- 由于需要保证树节点的高度差,则数据结构内部做更新、删除和插入操作时,需要对树的内部结构进行调整,频繁的进行树的左右旋转,也会导致执行效率低下。
- 平衡二叉树是由二叉树演变而来的一种数据结构,同样也遵循二叉树的特点;二叉树对于树的节点高度,要求相差不能大于1,如果大于1则会通过左右旋进行调整,保证树的节点高度差。
- 平衡二叉树是由于二叉树的缺点,进行优化、演变而来的数据结构。
- 平衡二叉树是由二叉树演变而来的一种数据结构,同样也遵循二叉树的特点;二叉树对于树的节点高度,要求相差不能大于1,如果大于1则会通过左右旋进行调整,保证树的节点高度差。
- 特点
- 优点
- 缺点
- B数的内部节点和叶子节点存放的都是索引的key和值。相对B Tree占用的空间大、存储的数据小。
- 随机访问,不属于索引顺序访问。
- 对于数据结构的更新、插入以及删除相对平衡二叉树更加高效;一个节点上可以存在2个以上的子节点,树的高度就可以降低,因此查询的效率也高很多。
- 是一种自平衡的树,能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除的动作,都在对数时间内完成。
- B树,概括来说是一个一般化的二叉查找树(binary search tree)一个节点可以拥有2个以上的子节点。
- 与自平衡二叉查找树不同,B树适用于读写相对大的数据块的存储系统,例如磁盘。B树减少定位记录时所经历的中间过程,从而加快存取速度。
- B树这种数据结构可以用来描述外部存储。这种数据结构常被应用在数据库和文件系统的实现上。
- 总结下来,就是在平衡二叉树上面的一种延伸。相对平衡二叉树内部的左旋和右旋更加高效,同时一个节点上可以存在多个子节点。
- 特点
- 优点
- 缺点
- 数据的访问是有序的,这样可以更加快速的找到需要的数据。
- 这种算法也是MyISAM存储引擎采用的一种算法结构
- 特点
- 优点
- 索引的存储非常高效。
- 索引的key按照顺序排列,查询效率高。并且索引页之间,都是通过指针连接起来,查找时无需额外消耗。
- B Tree是由B树和索引访问顺序算法结合而成的。既满足B数的特点也满足索引访问顺序的特点。
- 特点
- 优点
- 提到索引,一般会以InnoDB存储引擎为主。该存储引擎底层使用的是B Tree数据结构,要了解该数据结构就需要了解其他的几种数据结构。
- 说明
- 数据结构的演变
- 索引分类
- 索引语法
- 高效使用索引
- 索引常见问题
- hash索引
- 不能使用范围查找。
- 不能进行比较查找。
- 不能进行排序。
- 不需要像B tree进行逐级查找,只需要进行一次的hash计算,就等定位到数据,检索快。
- InnoDB存储引擎会根据表的使用情况,自动生成hash索引,不能通过人为的干预生成hash索引。
- 定义:通过将键值进行hash计算,检索时通过过相同的hash方式进行等值查找的一种存储策略方式。查询效率高,时间复杂度为O1。
- 优缺点:
- 常用工具
- id
- select_type
- table
- partitions
- type
- possible_keys
- key
- key_len
- ref
- rows
- filtered
- Extra
- 查询编号。
- subquery
- derived:包含在from子句的子查询中的select。
- union
- union result
- 查询类型。
- 查询表。
- all:全盘扫描。
- index:
- range:
- ref
- eq_ref
- const、system null
- 查询类型
- 查询的key。
- 决定那个索引key查询表。
- 索引key长度。
- 显示key列记录在索引查找中使用的列或者常量。
- 查找数据,读取的行数。
- using index:使用了覆盖索引。
- using where:存储引擎检索行后在进行过滤。不是所有的where条件查询都会出现。
- using temporary:使用了一个临时表。
- using filesort:使用了外部索引排序,而不是按索引次序从表中读取数据。排序可能是内存中或者硬盘中进行。
- Table
- Non_unique
- Key_name
- Seq_in_index
- Column_name
- Collation
- Cardinality
- Sub_part
- Packed
- Null
- Index_type
- Index_comment
- Comment
- 数据表名
- 非唯一索引
- 索引名称
- 索引中该列的位置
- 索引的表字段名称
- 列使用什么方式存储在索引中。值可以是A或者NUll。B Tree的总是A。
- 如果使用的是Heap存储引擎并且开启hash索引,就会显示为NULL。因为hash是根据hash桶存放索引数据,而不是通过顺序存放。
- 索引中唯一值的数目的估计值。
- 如果非常小,可以考虑进行删除。
- 优化器会根据这个值来进行判断,是否使用这个索引。
- 该值不是实时更新的,可以使用analyze table进行优化。
- 是否列的部分被索引。
- 关键字是否被压缩。
- 是否索引的列含所有NULL值。
- 索引类型。
- 索引描述。
- 查看索引(show index from table_name)
- 查看SQL索引情况(explain select xxxx;)
- extra出现 “useing index” 则使用的是覆盖索引,只扫码索引的数据,而不是按照索引的顺序读取每一行,开销小。
- 避免了排序,但是要按照索引的顺序去读取数据,则属于磁盘随机读,开销大。
- 和全盘扫描一样,只是在查询时按照索引的顺序进行扫码而不是行。这样会发生磁盘随机IO操作。
- 场景的有between 和 where中有 >、<这列的比较运算符。
- 有限制的索引范围扫描。
- 叫ref是因为该索引要跟某个参考值进行对比。这个值可以是常量,也可以是多表查询结果。
- 此类索引只能是非唯一索引或者唯一索引中的非唯一前缀。
- 索引范围查找。
- 出现在主键或者唯一索引的情况中。
- 最多返回一条符合条件的记录。
- 例如 select * from table where id = 1;
- 能对查询的某一个部分转化为一个常量。
- 优化阶段分解查询语句,执行阶段无需在查找表。
- 场景问题
- 说明:面试官一般会变着不同的方式问你,其实文问的无非就是同样的基础知识
- 主要就是罗列几种索引失效的场景。可以根据上面的总结回顾。一般有wherein, like,联合索引会多一点。
- 如果不是索引覆盖的情况下,就会进行回表查找。
- 是否所有的非聚集索引,都会重新回表查找一次?
- 列举几个索引字段,问你是否使用到索引?为什么没有用到?如何优化?
- 都有哪些索引?
- 索引的底层数据结构是怎么样的?
高可用
主从复制
- 简述
- 容灾备份
- 缓解高并发
- 是什么:将一台服务的数据复制到其他的一台或者多台服务上。
- 为什么
- 常见架构模式
- 一主一从
- 一主多从
- 级联主从
- 多主一从
- 双向主从
- 实现原理
- 重点参数
- 具体配置
- 同步模式
- 半同步复制
- 异步复制
- 实现模式
- GTID模式
- binary Postion模式
- 常见问题
- 数据延迟
- 数据一致性
数据备份与恢复
备份原因
- 灾难恢复
- 测试使用
- 数据审计
备份方式
- 冷备份(停机备份)
- 热备份方式一样都可以
- 数据库服务需要停止
- 数据完整性高
- 优点
- 缺点
- 备份方式
- 热备份(运行时备份)
- 增加了数据库服务压力
- 容易出现数据不一致性
- 不影响数据库服务运行
- 裸文件备份
- 逻辑备份
- xtrabackup
- 只能导出数据,不能导出数据表
- 数据恢复快
- 多线程导出
- 单线程模式
- 会增加表锁
- 导出的SQL语句,恢复慢
- 可读性高
- mysqldump
- mysqldumper
- select xxx into outfile
- 备份方式
- 优点
- 缺点
备份结果
- 全量备份
- 增量备份