网站分哪些种类,优速网站建设优化seo,知名自助建站平台,免费crm目录 逻辑存储结构
架构
概述
内存结构
Buffer Pool#xff08;缓冲池#xff09;
Change Buffer#xff08;更改缓冲区#xff09;
Adaptive Hash Index#xff08;自适应hash索引#xff09;
Log Buffer#xff08;日志缓冲区#xff09;
磁盘结构
System T…目录 逻辑存储结构
架构
概述
内存结构
Buffer Pool缓冲池
Change Buffer更改缓冲区
Adaptive Hash Index自适应hash索引
Log Buffer日志缓冲区
磁盘结构
System Tablespace系统表空间
File-Per-Table Tablespaces
General Tablespaces Undo Tablespaces
emporary Tablespaces
Doublewrite Buffer Files双写缓冲区
Redo Log重做日志
后台线程
Master Thread
IO Thread
Purge Thread
Page Cleaner Thread
事务原理
事务基础
redo log
undo log
MVCC
基本概念
隐藏字段
undo log
ReadView
原理分析
RC隔离级别
RR隔离级别 逻辑存储结构 表空间
表空间是InnoDB存储引擎逻辑结构的最高层如果用户启用了参数innodb_file_per_table在8.0版本中默认开启则每张表都会有一个表空间xxx.ibd一个mysql实例可以对应多个表空间用于存储记录、索引等数据
段
段分为数据段Leaf node segment、索引段Non-leaf node segment、回滚段Rollback segmentInnoDB是索引组织表数据段就是B树的叶子节点索引段即为B树的非叶子节点段用来管理多个区
区
区是表空间的单元结构每个区的大小为1M默认情况下InnoDB存储引擎页大小为16K即一个区中一共有64个连续的页
页
页是InnoDB存储引擎磁盘管理的最小单元每个页的大小默认为16KB为了保证页的连续性InnoDB存储引擎每次从磁盘申请4-5个区
行
InnoDB存储引擎数据是按行进行存放的
在行中默认有两个隐藏字段
Trx_id每次对某条记录进行改动时都会把对应的事务id赋值给trx_id隐藏列Roll_pointer每次对某条引记录进行改动时都会把旧的版本写入到undo日志中然后这个 隐藏列就相当于一个指针可以通过它来找到该记录修改前的信息
架构
概述
MySQL5.5版本开始默认使用InnoDB存储引擎它擅长事务处理具有崩溃恢复特性在日常开发中使用非常广泛
下图是InnoDB架构图左侧为内存结构右侧为磁盘结构 内存结构 主要分为四部分Buffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer
Buffer Pool缓冲池
InnoDB存储引擎基于磁盘文件存储访问物理硬盘和在内存中进行访问速度相差很大为了尽可能弥补这两者之间的I/O效率的差值就需要把经常使用的数据加载到缓冲池中避免每次访问都进行磁盘IO
在InnoDB的缓冲池中不仅缓存了索引页和数据页还包含了undo页、插入缓存、自适应哈希索引以及InnoDB的锁信息
缓冲池是主内存中的一个区域里面可以缓存磁盘上经常操作的真实数据在执行增删改查操作时先操作缓冲池中的数据若缓冲池没有数据则从磁盘加载并缓存然后再以一定频率刷新到磁盘从而减少磁盘IO加快处理速度
缓冲池以Page页为单位底层采用链表数据结构管理Page。根据状态将Page分为三种类型
free page空闲page未被使用clean page被使用page数据没有被修改过dirty page脏页被使用page数据被修改过页中数据与磁盘数据不一致
在专用服务器上通常将多达80%的物理内存分配给缓冲池参数设置show variables like innodb_buffer_pool_size; Change Buffer更改缓冲区
更改缓冲区针对于非唯一二级索引页在执行DML语句时如果这些数据页没有在缓冲池中不会直接操作磁盘而会将数据变更存在更改缓冲区中在未来数据被读取时再将数据合并恢复到缓冲区中再将合并后的数据刷新到磁盘中
更改缓冲区的意义 与聚集索引不同二级索引通常是非唯一的并且以相对随机的顺序插入二级索引删除和更新也可能会影响索引树中不相邻的二级索引页如果每一次都操作磁盘会造成大量的磁盘IO。有了更改缓冲区后可以在缓冲池中进行合并处理减少磁盘IO
Adaptive Hash Index自适应hash索引
自适应hash索引用于优化对缓冲池数据的查询MySQL的InnoDB引擎中虽然没有直接支持hash索引但提供了自适应hash索引hash索引在进行等值匹配时性能高于B树索引因为hash索引一般只需要一次IO而B树可能需要几次匹配所以hash索引的效率要更高但hash索引又不适合做范围查询、模糊匹配
InnoDB存储索引会监控对表上各索引页的查询如果观察到在特定的条件下hash索引可以提升速度则建立hash索引称之为自适应hash索引
自适应hash索引无需人工干预是系统根据情况自动完成的
参数adaptive_hash_index
Log Buffer日志缓冲区
日志缓冲区用于保存要写入到磁盘中的log日志数据redo log、undo log默认大小为16MB日志缓冲区的日志会定期刷新到磁盘中如果需要更新、插入或删除许多行的事务增加日志缓冲区的大小可以节省磁盘IO
参数
innodb_log_buffer_size缓冲区大小
innodb_flush_log_at_trx_commit日志刷新到磁盘的时机取值主要包含以下三个
1日志在每次事务提交时写入并刷新到磁盘默认值0每秒将日志写入并刷新到磁盘一次2日志在每次事务提交后写入并每秒刷新到磁盘一次 磁盘结构 System Tablespace系统表空间
系统表空间是更改缓冲区的存储区域如果表是在系统表空间而不是每个表文件或通用表空间中创建的它也可能包含表和索引数据在MySQL5.x版本中还包含InnoDB数据字典、undo log等
参数innodb_data_file_path 系统表空间默认的文件名为ibdata1
File-Per-Table Tablespaces
如果开启了innodb_file_per_table开关则每个表的文件表空间包含单个InnoDB表的数据和索引并存储在文件系统上的单个数据文件中
开关参数innodb_file_per_table默认开启每创建一个表都会产生一个表空间文件 General Tablespaces
通用表空间通过CREATE TABLESPACE语法创建在创建表时可以指定该表空间
创建表空间
CREATE TABLESPACE ts_name ADD DATAFILE file_name ENGINE engine_name;
创建表时指定表空间
CREATE TABLE xxx ... TABLESPACE ts_name; Undo Tablespaces
撤销表空间MySQL示例在初始化时会自动创建两个默认的undo表空间初始大小16M用于存储undo log日志
两个文件undo_001和undo_002
emporary Tablespaces
InnoDB使用会话临时表空间和全局临时表空间存储用户创建的临时表等数据
Doublewrite Buffer Files双写缓冲区
InnoDB引擎将数据页从缓冲区刷新到磁盘前先将数据页写入双写缓冲区文件中便于系统异常时恢复数据 Redo Log重做日志
重做日志是用来实现事务的持久性该日志文件由两部分组成重做日志缓存redo log buffer和重做日志文件redo log前者是在内存中后者是在磁盘中当事务提交之后会把所有修改信息都存到该日志中用于在刷新脏页到磁盘发生错误时进行数据恢复使用
以循环方式写入重做日志文件涉及两个文件 后台线程 在InnoDB的后台线程中分为4类分别是Master Thread 、IO Thread、Purge Thread、 Page Cleaner Thread
Master Thread
核心后台线程负责调度其他线程还负责将缓冲池中的数据异步刷新到磁盘中保持数据的一致性还包括脏页的刷新、合并插入缓存、undo页的回收
IO Thread
在InnoDB存储引擎中大量使用了AIO来处理IO请求这样可以极大地提高数据库的性能而IO Thread主要负责这些IO请求的回调 查看InnoDB的状态信息其中包含IO Thread信息
show engine innodb status \G; Purge Thread
主要用于回收事务已经提交了的undo log在事务提交之后undo log可能不用了就用它来回收
Page Cleaner Thread
协助Master Thread刷新脏页到磁盘的线程它可以减轻Master Thread的工作压力减少阻塞
事务原理
事务基础
事务是一组操作的集合它是一个不可分割的工作单位事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求即这些操作要么提示成功要么同时失败
特性
原子性Atomicity事务是不可分割的最小操作单元要么全部成功要么全部失败一致性Consistency事务完成时必须使所有的数据都保持一致状态隔离性Isolation数据库系统提供的隔离机制保证事务在不受外部并发操作影响的独立环境下运行持久性Durability事务一旦提交或回滚它对数据库中的数据的改变就是永久的
研究事务的原理就是探究MySQL的InnoDB引擎是如何保证事务的这四大特性的
对于这四大特性实际上分为两部分原子性、一致性、持久性是由InnoDB中的两份日志来保证的分别是redo log和undo log隔离性是通过数据库的锁和MVCC来保证的 redo log
重做日志记录的是事务提交时数据页的物理修改是用来实现事务的持久性
该日志文件由两部分组成重做日志缓存redo log buffer和重做日志文件redo log前者是在内存中后者是在磁盘中当事务提交之后会把所有修改信息都存到该日志中用于在刷新脏页到磁盘发生错误时进行数据恢复使用
当在一个事务中执行多个增删改的操作时InnoDB引擎会先操作缓冲池中的数据如果缓冲区没有对应的数据会通过后台线程将磁盘中的数据加载出来存放在缓冲区中然后将缓冲池中的数据修改修改后的数据页称为脏页。 而脏页则会在一定的时机通过后台线程刷新到磁盘中从而保证缓冲区与磁盘的数据一致。而缓冲区的脏页数据并不是实时刷新的而是一段时间之后将缓冲区的数据刷新到磁盘中假如刷新到磁盘的过程出错了而提示给用户事务提交成功而数据却没有持久化下来这就出现问题了没有保证事务的持久性 有了redolog之后当对缓冲区的数据进行增删改之后会首先将操作的数据页的变化记录在redo log buffer中。在事务提交时会将redo log buffer中的数据刷新到redo log磁盘文件中。过一段时间之后如果刷新缓冲区的脏页到磁盘时发生错误此时就可以借助于redo log进行数据恢复这样就保证了事务的持久性。而如果脏页成功刷新到磁盘或涉及到的数据已经落盘此时redo log就没有作用了可以删除了所以存在的两个redolog文件是循环写的
那为什么每一次提交事务要刷新redo log到磁盘中而不是直接将buffer pool中的脏页刷新到磁盘因为在业务操作中操作数据一般都是随机读写磁盘的而不是顺序读写磁盘。而redo log在往磁盘文件中写入数据由于是日志文件所以都是顺序写的。顺序写的效率要远大于随机写。 这种先写日志的方式称之为WALWrite-Ahead Logging undo log
回滚日志用于记录数据被修改前的信息作用包含提供回滚保证事务的原子性和MVCC多版本并发控制
redo log记录物理日志undo log记录逻辑日志当delete一条记录时undo log中会记录一条对应的insert记录当update一条记录时undo log会记录一条对应相反的update记录当执行rollback时就可以从undo log中的逻辑记录读取到相应的内容并进行回滚
Undo log销毁undo log在事务执行时产生事务提交时并不会立即删除undo log因为这些日志可能还用于MVCC
Undo log存储undo log采用段的方式进行管理和记录存放在rollback segment回滚段中内部包含1024个undo log segment
MVCC
基本概念
当前读
读取的是记录的最新版本读取时还要保证其他并发事务不能修改当前记录会对读取的记录进行加锁例如select ... lock in share mode(共享锁)select ... for update、update、insert、delete(排他锁)都是一种当前读
快照读
简单的select不加锁就是快照读快照读读取的是记录数据的可见版本有可能是历史数据不加锁是非阻塞读
Read Committed每次select都生成一个快照读
Repeatable Read开始事务后第一个select语句才是快照读的地方
Serializable快照读会退化为当前读
MVCC
全程Multi-Version Concurrency Control多版本并发控制指维护一个数据的多个版本使得读写操作没有冲突快照读为MySQL实现MVCC提供了一个非阻塞读功能MVCC的具体实现还需要依赖于数据库记录中的三个隐藏字段、undo log日志、readView
隐藏字段
创建表时InnoDB会自动添加三个隐藏字段 前两个一定会添加第三个取决于当前表有没有主键如果有则不会添加
undo log
回滚日志在insert、update、delete时产生的便于数据回滚的日志
当insert时产生的undo log日志只在回滚时需要在事务提交后可被立即删除
当update、delete时产生的undo log日志不仅在回滚时需要在快照读时也需要不会立即被删除
版本链
有一张表原始数据为 DB_TRX_ID代表最近修改事务ID记录插入这条记录或最后一次修改该记录的事务ID是自增的DB_ROLL_PTR由于这条数据是刚插入的没有被更新过所以字段值为null
有四个并发事务在同时访问这张表
第一步 当事务2执行第一条修改语句时会记录undo log日志记录变更之前的数据然后更新记录并且记录本次操作的事务ID回滚指针回滚指针用来指定如果发生回滚回滚到哪一个版本 第二步 当事务3执行第一条修改语句时会记录undo log日志记录变更之前的数据然后更新记录并且记录本次操作的事务ID回滚指针 第三步 当事务4执行第一条修改语句时会记录undo log日志记录变更之前的数据然后更新记录并且记录本次操作的事务ID回滚指针 结论不同事务或相同事务对同一条记录进行修改会导致该记录的undo log生成一条记录版本链表链表的头部是最新的旧记录链表的尾部是最早的旧记录
ReadView
ReadView读视图是快照读SQL执行时MVCC提取数据的依据记录并维护系统当前活跃的事务未提交的id
ReadView包含四个核心字段 版本链数据的访问规则
trx_id代表当前undo log版本链对应事务id 不同的隔离级别生成ReadView的时机不同
READ COMMITTED在事务中每一次执行快照读时生成ReadView
REPEATABLE READ仅在事务中第一次执行快照读时生成ReadView后续复用该ReadView
原理分析
RC隔离级别
RC隔离级别下在事务每一次执行快照读时生成ReadView
在事务5中查询了两次id为30的记录由于隔离级别为Read Committed所以每一次进行快照读都会生成一个ReadView那么两次生成的ReadView如下 那么这两次快照读在获取数据时就需要根据所生成的ReadView以及ReadView的版本链访问规则到undolog版本链中匹配数据最终决定此次快照读返回的数据
第一次快照读具体的读取过程 在进行匹配时会从undo log的版本链从上到下逐个进行匹配
匹配如下记录对应的trx_id为4将4代入右侧的匹配规则中都不满足继续匹配
直到第三条匹配此次快照读返回的数据就是版本链中记录的这条数据 第二次快照读具体的读取过程 第二条匹配此次快照读返回的数据就是版本链中记录的这条数据 RR隔离级别
RR隔离级别下仅在事务中第一次执行快照读时生成ReadView后续复用该ReadView 在RR隔离级别下只是在事务中第一次快照读时生成ReadView后续都是复用该ReadView那么既然ReadView都一样ReadView的版本链匹配规则也一样那么最终快照读返回的结果也是一样的
因此MVCC的实现原理就是通过InnoDB表的隐藏字段、undo log版本链、Readview来实现的MVCC 锁实现了事务的隔离性一致性由redo log与undo log实现