Mysql学习笔记
前言
本文将介绍MySQL数据库的三个核心概念:buffer pool、redo log和binlog。buffer pool是通过缓存数据来提高数据库性能的重要组件,redo log确保在出现错误时恢复并保护数据,而binlog记录所有的数据库更改以备份和复制。通过了解和实践这些组件,可以优化MySQL数据库的性能和可靠性。
一、buffer poll
1. 为什么要有buffer poll
简单来说,数据的增删改查每次都从磁盘直接读取,随机磁盘io成本很高。因此我们把一部分数据拿到内存中(既buffer poll),每次操作数据更新内存后顺序写入redolog,减少了随机IO,增加了数据库的性能。
2. buffer poll中的页
页是buffer poll 与磁盘之间数据交换的基本单位,一个页的默认大小为 16KB。
2.1 脏页,干净页,空闲页
1 空闲页: buffer poll中未使用到的页;
2 干净页:页上的数据与磁盘一致的页;
3 脏页:页上的数据与磁盘不一致的页;
2.2 脏页是怎么产生的
这里我想重点说一下,看了很多资料,有三个名词很容易混淆。
动作 | 含义 | 是否落入数据库 |
---|---|---|
write | 指把数据写入page catch(可以理解为系统缓存) | 否 |
fsync | 一般指把系统缓存的数据写入log文件(如binlog.file,redolog.file),而不是数据库 | 否 |
刷脏页 | 意思是把更改的数据真正更新到数据库 | 是 |
理解了以上表格的含义,脏页产生的原因就出来了。
因为每次更新buffer poll后,数据仅仅是成功写入了log文件中;所以,磁盘给到buffer
poll的数据,可能还没同步到数据库,导致脏页的产生。
既然有了脏页,我们肯定要定期清理,所以就有了刷脏的概念。
2.3 刷脏页
刷脏页是指在buff poll中脏页的更改同步到磁盘的过程。
2.3.1 刷新脏页的时机
- 当 redo log 日志满了的情况下,会主动触发脏页刷新到磁盘。
- Buffer Pool 空间不足时,需要将一部分数据页淘汰掉,如果淘汰的是脏页,需要先将脏页同步到磁盘。
- MySQL 认为空闲时,后台线程回定期将适量的脏页刷入到磁盘。
- MySQL 正常关闭之前,会把所有的脏页刷入到磁盘。
3. 系统宕机buffer poll会发生什么
当系统遇到宕机或者崩溃的情况时,由于buffer pool是存在内存上的,那么buffer poll中未来得及刷盘的脏页上的对应的数据就会丢失,导致大量更新操作的数据与数据库不一致。
举个栗子:
假如之前小明有10元钱的记录恰好在buffer poll的某个干净页A上,期间小红向小明又转账了10元,小明的记录变为20元。此时A页为脏页,但是由于数据库之前有大量更新,没达到刷脏条件,宕机重启后,buffer poll数据消失,小明丢了10块钱,且不知道怎么丢的。
因此我们需要通过记录buffer poll的动作,持久化到磁盘中。即redo log
二、redo log与bin log
1. redo log与bin log作用
如上文所说,redo log是用来记录buffer poll的修改日志,可以保证在系统宕机后,通过redolog文件恢复数据库。保证了数据的持久性。
而bin log是作为辅助功能,把所有的数据库更新操作记录到日志中,MySQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性。
2. 执行流程
3. redo log如何保证数据不丢失?redo log和bin log的双一刷盘机制。
为了保证数据不丢失,innoDB通过后台线程每1秒把提交的数据同步到redolog文件中,并且在每次提交事务都把相应的更改写入redolog。与此同时在事务提及的同时,同时写入到binlog,之后redolog才算真正提交。
个人的理解是,一次事务提交先写redolog,之后等待binlog写完,redolog才把此次作为一次完整的提交。
因此系统宕机后是以redolog中commit的部分作为恢复依据。
日志 | 配置项 | 含义 |
---|---|---|
redolog | innodb_flush_log_at_trx_commit = 0 | 表示每隔一秒把log buffer写入redolog文件(最晚延迟一秒) |
redolog | innodb_flush_log_at_trx_commit = 1 | 表示每次提交事务写入(几乎没延迟) |
redolog | innodb_flush_log_at_trx_commit = 2 | 每次提交事务写入page cache(最晚延迟一秒) |
binlog | sync_binlog = 0 | 提交事务都写入binlog cache(可能会丢失) |
binlog | sync_binlog = 1 | 每次提交事务都写入binlog(几乎无丢失) |
binlog | sync_binlog = n | 每n次提交事务都写入binlog(最多丢失n个事务) |
总结
本文主要从个人理解的角度介绍Mysql的buffer poll、redo log 、bin log。如有错误或疑问,请各位大佬前辈们指正。
[参考文档]:MySql45讲
[参考文档]:公z号程序猿阿星