逻辑存储架构
表空间 段 区 页 行 ,一个页16K
表空间:ibd文件用于存储记录 索引等数据
段:innodb是索引组织表,数据段B+数的叶子结点, 索引段B+ 树的非叶子结点 , 回滚段
区: 1M,一个区包含64 个连续的数据页
页:16K innodb磁盘管理最小的单元,为了保证页的连续性,每次向磁盘申请空间时一般会申请4-5个区
行:innodb存储引擎是按行进行存放的。trx- id 每次对某条记录进行改动时,就会把对应的事务id赋值给trx-id隐藏列中 row- pointer 每次对某条记录进行改动时,都会把旧的版本写入到undo日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的记录
内存架构
支持事务,有崩溃恢复的特效,5.5之后默认innodb存储引擎
buffer pool:缓冲池上主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作是,先操作缓冲池中的数据,如果缓冲池中没有数据 ,会从磁盘加载并缓存,再以一定的频率刷新到磁盘,从而减少磁盘io,加快处理速度
缓冲池以页为单位底层采用链表数据结构进行管理 根据状态将页分为三类:
free page: 空闲page未被使用
clean page: 被使用page 数据没有被修改过
dirty page: 脏页 被使用page数据被修改共,页中数据与磁盘中的数据不一致
Change buffer:
更改缓冲区 ,针对于非唯一二级索引页,在执行dml语句时,如果这些数据page 没有在buffer pool中,不会直接操作磁盘 ,而会将数据变更存在更改缓冲区中,在未来数据读取时,再将数据合并恢复到buffer pool 中,再将合并后的数据刷到磁盘中
change buffer 的意义:二级索引一般是非唯一的,并且相对随机的顺序插入二级索引,同样 删除和更新可能会影响索引树中不相邻的二级索引 如果每一次都操作磁盘,会造成大量的磁盘IO 有了change buffer 之后就可以在缓冲池里合并处理,减少磁盘IO
adaptive hash index :自适应hash 索引,用于优化buffer pool 数据的查询,innodb 存储引擎会监控对表上各索引页的查询,如果观察到hash 索引可以提升速度,就建立hash索引
log buffer : 日志缓冲区,用来保存写入到磁盘中的log日志数据,默认大小为16MB,日志缓冲区的日志会定期刷新到磁盘中,如果需要更新 插入或删除许多行的事务,增加缓冲区的大小可以节省磁盘io
磁盘结构:
system tablespace: 系统表空间是更改缓冲区的存储区域,如果表是在系统表空间而不是每个表文件或通用表空间中创建的,它也可能包含表和索引数据
file per table space:每个表的文件表空间包含单个innodb表的数据和索引,并存储在文件系统上的单个数据文件中
general tablesapce : 通用表空间
undo tablesapce: 撤销表空间,mysql在初始化时会自动创建两个默认的undo表空间 用于存储undo log日志
temporary tablesapce: innodb 使用会话临时表空间和全局临时表空间 存储用户创建的临时表等数据
doublewrite buffer files:
双写缓冲区,innodb 引擎将数据页从buffer pool 刷新到磁盘前,先将数据页写入双写缓冲区文件中 便于系统异常时恢复数据
read log: 重做日志 用来实现事务的持久性,该日志右两部分组成,重做日志缓冲以及重做日志文件,前者是在内存中 后者是在磁盘中,当事务提交之后会把所有的修改信息都存到该日志中,用于刷新脏页到磁盘时 恢复使用
事务是一组操作的整体,要么同时成功,要么同时失败
acid
持久性由redo log 保证
redolog: 重做日志 记录该是事务提交数据页的物理修改 用来实现事务的持久性
该日志文件由两部分组成: 重做日志缓冲 以及重做日志文件,前者是在内存中的后者是在磁盘中,当事务提交后会把所有修改信息都存到该日志文件中, 用于在刷新脏页到磁盘发生错误时,恢复数据 保证数据持久性
顺序磁盘IO 的性能高于随机磁盘IO
undolog: 保证事务的原子性,保存数据更改之前的数据,记录的是逻辑日志,保存每一步操作之前的操作,当回滚时就可以从undolog中读取原来的数据,undolog存放在回滚段中
MVCC
当前读:
读取的是记录的最新版本,读取是还要保证其他并发事务不能修改当前记录 会对读取记录进行加锁 ,共享锁排他锁属于当前读
快照读:
简单的不加锁的select就是快照读 ,快照读读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读
读已提交:每次select都会生成一个快照读
可重复读:开启事务第一个select语句是快照读的地方
串行化:快照读会退化为当前读
mvcc
多版本并发控制 ,维护一个数据的多个版本,使得读写操作没有冲突,快照读为mysql实现mvcc提供了一个非阻塞读功能,mvcc实现还需要依赖数据库中的额三个隐式字段,undolog日志,readview
mvcc 实现原理
记录中的隐藏字段:
DB-trx-id: 最近修改事务的id,记录插入这条记录或做后一次修改记录事务的id
db-roll-ptr: 回滚指针,指向这条记录的上一个版本,用于配合undolog ,指向上一个版本
db-row-id:隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段