之前学习了LRU算法和Mysql缓冲池使用的LRU变体算法,其中有个共同点就是当LRU链表写满以后如果再有新数据进来会淘汰尾部的数据,那么Mysql淘汰这些尾部数据的时候是否会进行什么操作呢?这就是我们在最后提到了一个参数Modified db pages,即脏页。
1.什么是脏页?
- 脏页,这个名词很抽象从字面意思去看可能很不解,脏页是当内存中的数据页和磁盘中的数据页内容不一致时,这个数据页称之为脏页。因为从操作系统的角度来讲,自己读入的数据被外部所修改等于被污染,所以叫脏页。
- 当内存中的数据页和磁盘中的数据页数据一致,叫干净页。
2.脏页什么时候会刷新?
- 缓冲池(buffer pool)空间不足,也就是LRU链表写满时,新数据进来时淘汰掉的尾部数据脏页。
- redo log不可用时,需要强制将脏页列表中的一些数据页刷入磁盘。
- Mysql在服务器负载较小时,会主动进行刷脏操作。
- Mysql服务正常关闭,会刷新所有脏页。
3.什么是redo log?
InnoDB中两块非常重要的日志,一个是undo log,另外一个就是我们接下来要学习的redo log。前者用来保证事务的原子性以及InnoDB的MVCC(Mutil-Version Concurrency Control),后者用来保证事务的持久性。
那么什么时候写redo log呢?当数据库对数据做修改的时候,需要把数据页从磁盘读到缓冲池中,然后在缓冲池中进行修改。但是InnoDB采用的是WAL(Write Ahead Log)策略来防止数据丢失,也就是事务提交时,先写redo log才会再去修改内存数据页。
redo log的文件名默认以ib_logfile{NUM},存储在my.cnf中datadir目录下面,受以下两个参数控制
- innodb_log_file_size,日志大小
- innodb_log_files_in_group,日志个数,默认是2个。
所以redo log的大小等于innodb_log_files_in_group*innodb_log_file_size。
既然redo log会产生,那么什么时候会被覆盖呢?redo log被设计成可循环使用,当日志文件写满时那些已经被刷入磁盘中的数据就可以被覆盖啦。
WAL(Write Ahead Log),是关系数据库系统中用于提供原子性和持久性(ACID属性中的两个)的一系列技术,ARIES是WAL系列技术常用的算法,在文件系统中WAL通常称为journaling。WAL的主要思想是将元数据的实时变更操作写入日志文件中,然后在系统负载较小时再把日志刷入磁盘。主要是为了减少磁盘的IO操作,此处就不展开学习了。先Mark一下

