(以innodb存储引擎为例)

一、几个基本知识介绍

1.InnoDB有一种缓冲池的技术,将磁盘读到的页放到一块内存区域中。

我们读取数据时,并不是只将满足条件的数据加载到内存中,而是一块数据(局部性原理,我们需要的数据的附近的数据也有可能在未来会被读取),也就是数据页;

页是一个存储引擎从磁盘读取数据到内存的最小单位;

2.脏页

修改数据的时候,会先修改内存缓冲区(buffer pool)里面的页;内存的数据页和磁盘数据不一致,即为脏页。

3.刷脏

将缓冲区的数据写入磁盘(每隔一段时间,一次性完成多个修改)

4.重做日志 redo log

为防止数据库宕机、一些刷脏操作未能执行造成的数据丢失,InnoDB会将所有对数据页的修改操作专门写入redo log(数据来自buffer pool缓冲区)。

疑问:写入redolog也是对磁盘进行操作,为什么不直接写入db文件,而要先写日志再写数据文件?

原因:

刷盘是随机I/O,它会一次次的找到我们需要修改的数据并完成修改,速度缓慢;

而redolog记录的是“在数据页上做了什么修改”,如果我们找到了第一条要修改的数据,那么后面我们所需的数据一定在这条数据的后面,这也是顺序I/O。

优点:A.延迟刷盘时机,提升系统的吞吐量;B.崩溃恢复。

其他特点:

-redo log是物理日志,记录的是“在某个数据页上做了什么修改”;

-循环写,空间固定会用完,用完后覆盖之前完成的记录。

5.undo log

记录事务发生之前的数据状态(如果修改数据时出现异常,可以用undo log来实现回滚操作)

6.归档日志 bin log

记录所有的DDL和DML语句,可用于主从复制和数据恢复:

A.用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。

B.用于数据库的基于时间点的还原。 (每日备份的数据库+bin log完成数据恢复)

逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。

二、更新语句的执行过程简述

1.先从内存或者磁盘中拿到这条数据;

2.执行器对数据状态进行修改;

3.将原来的数据状态记录到undo log;

4.调用存储引擎的API接口,在内存(buffer pool)中更新数据状态;并且,将修改后的数据记录到redo log,此时redo log进入prepare状态,并告知执行器;

5.执行器收到通知后记录binlog,并把 binlog 写入磁盘;

6.调用存储引擎接口,设置redo log为commit状态。更新完成。

注:当对应事务的脏页写入到磁盘之后,redo log的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。


有理解错误的地方,望留言指正,谢谢!

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

一个喜欢拔刀的萌新Coder