无知的我正在复习MySQL进阶知识。。。。
笔记特点是 我重新整理了涉及资料的一些语言描述、排版,而使用了自己比较容易理解的描述、同样是回答了一些常见关键问题
如果有遇到有任何无法进展问题或者疑惑的地方,应该在讨论区留言 或者 其他途径以寻求及时的帮助,以加快学习效率 或者 培养独立解决问题的能力、扫清盲点、补充细节
表空间是 InnoDB存储引擎逻辑结构的最高层, 如果用户启用了参数 innodb_file_per_table(在8.0版本中默认开启) ,则每张表都会有一个表空间(xxx.ibd)
在行中 默认有两个隐藏字段 它们的作用是
Trx_id(最后一次操作事务的id):保存事务id。每次对某条记录进行改动时,都会把对应的事务id赋值给trx_id隐藏列。
Roll_pointer(列指针):保存修改前的信息。每次对某条引记录进行改动时,都会把旧的版本写入到undo日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。
下面是InnoDB架构图,左侧为内存结构,右侧为磁盘结构
内存结构分为四大块 uffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer
缓冲池 意义
为了避免每次访问都磁盘I/O,而是对经常使用的数据,加载到缓冲池中 并 访问。
缓冲池 内部数据
不仅缓存了索引页和数据页,还包含了undo页、插入缓存、自适应哈希索引以及InnoDB的锁信息等等。
缓冲池 运行机制
在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。
缓冲池 以Page页为单位 并 分为以下三类
free page:空闲page,未被使用。
clean page:被使用page,数据没有被修改过。
dirty page:脏页,被使用page,数据被修改过,但是没有同步到磁盘中,导致二者存储的数据不一致
Change Buffer
更改缓冲区 机制
在执行DML语句时,如果这些数据Page没有在Buffer Pool中,不会直接操作磁盘,而会将数据暂时存储在缓冲区 Change Buffer中,在未来数据被读取时,再将数据合并恢复到Buffer Pool中,再将合并后的数据刷新到磁盘中。(它的操作只作用于 二级索引页)
更改缓冲区 意义
为了解决 删除和更新可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO,导致磁盘消耗过大的问题。这是因为与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引,如下图。
Adaptive Hash Index
自适应hash索引 意义
用于优化对Buffer Pool数据的查询。这是因为hash索引在进行等值匹配时(不做范围查询、模糊匹配等),一般性能是要高于B+树的,因为hash索引一般只需要一次IO即可,而B+树,可能需要几次匹配,所以hash索引的效率要高
自适应hash索引 机制
InnoDB存储引擎会监控对表上各索引页的查询,如果观察到在特定的条件下hash索引可以提升速度,则建立hash索引(可以通过这个参数选择是否开启:adaptive_hash_index)
Log Buffer
日志缓冲区 机制
如果需要更新、插入或删除许多行的事务,增加日志缓冲区的大小可以节省磁盘 I/O。这是因为它是用来保存要写入到磁盘中的log日志数据(redo log 、undo log),日志缓冲区的日志会定期刷新到磁盘中。(默认大小为 16MB)
日志缓冲区 参数
innodb_log_buffer_size(缓冲区大小)
innodb_flush_log_at_trx_commit(日志刷新到磁盘时机)取值主要包含以下三个
1: 日志在每次事务提交时写入并刷新到磁盘,默认值。
0: 每秒将日志写入并刷新到磁盘一次。
2: 日志在每次事务提交后写入,并每秒刷新到磁盘一次。
System Tablespace 查看存放的位置参数:innodb_data_file_path
系统表空间,默认的文件名叫 ibdata1。
File-Per-Table Tablespaces 开关参数:innodb_file_per_table(默认开启)
每创建一个表,都会产生一个表空间文件。如图
General Tablespaces 创建通用表空间参数 :CREATE TABLESPACE
A. 创建表空间
CREATE TABLESPACE ts_name ADD DATAFILE 'file_name' ENGINE = engine_name;
B. 创建表时指定表空间
CREATE TABLE xxx ... TABLESPACE ts_name;
后台线程 意义
内存中我们所更新的数据,又是如何到磁盘中的呢? 此时,就涉及到一组后台线程
在InnoDB的后台线程中,分为4类
Master Thread 、IO Thread、Purge Thread、Page Cleaner Thread。
1). Master Thread
2). IO Thread
在InnoDB存储引擎中大量使用了AIO来处理IO请求, 这样可以极大地提高数据库的性能,而IOThread主要负责这些IO请求的回调。
IO线程的类型
查看InnoDB的状态信息,其中就包含IO Thread信息
show engine innodb status \G;
@0代表线程在等待接收请求
@aio代表异步非阻塞io
3)Purge Thread
主要用于回收事务已经提交了的undo log。在事务提交之后,undo log可能不用了,就用它来回收。
4)Page Cleaner Thread
协助 Master Thread 刷新脏页到磁盘的线程。从而可以减轻 Master Thread 的工作压力,从而减少阻塞。