mysql笔记 | innodb引擎以及引擎中的MVCC实现

1.逻辑存储结构

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第1张图片

表空间:innodb_file_per_table默认开启,每个表都有独立表空间(和2中磁盘的独立表空间对应,不开启innodb_file_per_table,可能用到2中的通用表空间)

段:innodb是按照索引存储,所以又会分成数据段、索引段和回滚段。

区:1m 每次会申请4-5个区,保证页的连续性

页:16k,所以一般一个区64页

行:每行数据会有两个隐藏字段:

Trix_id改行数据参与某个事务操作时,标记事务id

Roll_pointer作为指针对应undo中操作该行的日志

2.架构

innodb引擎擅长事务处理,具有崩溃恢复特性

2.1内存结构

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第2张图片

(1)buffer pool 主要区域,缓存磁盘中的数据,修改数据的时候先修改buffer pool中的数据,修改了的页称为脏页,定期刷新进磁盘。减少了磁盘io,加快了处理速度。

show variables like ‘innodb_buffer_pool_size’;查看大小。

(2)change buffer。对于非唯一的二级索引页,当修改的数据页没有从磁盘进入buffer pool时,会先记录在这里。等buffer pool读取数据页时,再修改。

因为二级索引是非唯一的,直接修改磁盘是随机IO。现在这些数据都进入了buffer pool,可以合并处理。

(3)自适应hash 索引。当innodb认为hash索引更快时,会建立hash索引。

(4)log buffer 缓存日志数据。包括redolog 和undolog,定期刷新到磁盘。

innodb_log_buffer_size:日志缓冲区大小,默认16m

innodb_logbuffer_at_trix_commit:1表示事务提交时刷新;2表示事务提交或每秒都刷新;0表示每秒

2.2磁盘结构

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第3张图片

(1)系统表空间,时change buffer的存储区域

(2)独立表空间,就是1里面提到的表空间,现在默认开启,每个表都有独立的ibd文件。

开关是innodb_file_per_table,默认开启

(3)通用表空间,就是创建一个空间ibd文件,多张表一起用

--创建通用表空间并加入表
CREATE TABLESPACE ts_name ADD DATAFILE 'file_name' ENGINE = engine_name;
--在该表空间再创建表
CREATE TABLE xxx ... TABLESPACE ts_name;

(4)undolog表空间。创建两个undolog表记录undolog,初始大小16m

(5)临时表空间

(6)双写缓冲区 innoDB引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件

中,便于系统异常时恢复数据

(7)redolog。事务持久性的。。当事务提交之后会把所有修改信息都会存到该日志中, 用于在刷新脏页到磁盘时,发生错误时, 进行数据恢复使用

2.3后台线程

(1)master 线程

核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中, 保持数据的一致性,

还包括脏页的刷新、合并插入缓存、undo页的回收 。

(2)IO 线程

在InnoDB存储引擎中大量使用了AIO来处理IO请求, 这样可以极大地提高数据库的性能,而IO

Thread主要负责这些IO请求的回调。

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第4张图片

(3) purge 线程 回收undo页

(4)page cleaner 线程 协助 Master Thread 刷新脏页到磁盘的线程,减少阻塞

3.事务原理

事务在基础篇介绍过了。

原子性、一致性、隔离性,持久性

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第5张图片

3.1redo log

作用:保证事务的持久性,如果数据从内存的buffer pool刷新到磁盘中的时候出错,进行数据恢复。由于刷新进磁盘是一段时间才刷新,那么事务可能已经提交成功,但刷新磁盘时出错,数据未持久改变。

redolog实现方式:

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第6张图片

日志是增删改的时候记录数据,事务提交时写入磁盘的(日志写入是顺序写,占io小很多,数据大部分情况是随机写)。如果刷新缓冲区的脏页到磁盘时,发生错误,此时就可以借助于redo log进行数据恢复。

销毁:写入磁盘后,循环写销毁。

3.2undo log

回滚日志。

作用:提供回滚(保证事务的原子性) 和MVCC(多版本并发控制)

作用方式:undolog记录的是逻辑日志(redo log是物理日志),会记录增删改的反向操作。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

销毁:事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。

存储:undo log采用段的方式进行管理和记录,存放在前面介绍1中的 rollback segment回滚段中,内部包含1024个undo log segment。

4MVCC(重点!!!!!)

Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。

4.1快照读与当前读

带锁的语句都是当前读,读取最新数据;

传统select是快照读,读取可读版本。例如RR隔离条件下就是开启事务后的第一次select时生成的快照。

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第7张图片

4.2隐藏字段

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第8张图片

事务id自增

在引擎逻辑存储架构也提到过。主要是事务id和回滚日志的指针。

查看表结构的命令:ibd2sdi stu.ibd

4.3undolog日志

当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。

而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。

3.2中介绍过概念,这里着重说版本链。

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第9张图片

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第10张图片

多个事务操作某行数据时,每次更改的结果会记录undo log的指针,得到更改之前的数据。更改之前的数据的undo log日志指针再用来的得到 再上一个版本。如此行程版本链。

最终我们发现,不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。

4.4readView

读视图(ReadView)时快照读sql获取版本的依据,记录了并维护系统当前活跃的事务(未提交的)id。

readview有四个字段。(别忘了事务id是自增的)

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第11张图片

根据readview就有了版本链数据的访问规则

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第12张图片

它这个最后的目标就是实现了:当前事务更新的数据/非活跃的最大事务id更新的数据版本进行快照读

4.5MVCC原理

在RC隔离级别下,事务的每次select,都生成快照读。以之前的例子:

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第13张图片

每次查询生成快照读的时候都生成readview,根据生成的readview寻找版本。

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第14张图片

寻找时是按照上述undolog日志版本链从头到尾的顺序,看是不是当前版本的更改/readview中非活跃事务,如果满足则确定查询版本。

如图中例子,分别是版本2和版本3。所以RC是不可重复读的。

在RR隔离条件下:只用第一次select的生成的readview,所以是可重复读的。

mysql笔记 | innodb引擎以及引擎中的MVCC实现_第15张图片

你可能感兴趣的:(mysql,java,数据库,分布式,大数据,mysql,mvc)