buffer pool缓冲区
Buffer Pool 即缓冲池,是 InnoDB 存储引擎中一块重要的内存区域。它的核心作用是作为磁盘数据页和索引页在内存中的缓存区域,通过减少磁盘 I/O 操作,显著提升数据库的读写性能。
update语句的整体执行流程和select语句是一样的。
mysql想完成数据的修改,会先从存储引擎层读取数据,把数据读取到服务层进行数据的修改,再通过存储引擎层把数据更新到数据库中。
mysql每次读取数据都会读取16384个字节的数据,默认是16KB的数据。一页的数据。
在innodb引擎中设计了 buffer pool 缓冲区。Mysql从磁盘中通过IO读取数据到buffer pool中,引擎从bffer pool中获取数据,然后修改,再把数据写入到buffer pool中。从而完成读写的操作,因为是基于内存的操作,所以速度是非常快的。
脏数据:buffer pool中的数据,还没有同步到磁盘中的数据称为脏数据
innodb的脏页刷新机制说明:
1、当innodb中的脏页比例超过innodb_max_dirty_pages_pct_lwm的值时,这个时候innodb就会开始刷新脏页到磁盘。
2、当innodb中的脏页比例超过innodb_max_dirty_pages_pct_lwm的值,而且还超过innodb_max_dirty_pages_pct时innodb就会进入勤快刷新模式(agressively flush)这个模式下innodb会把脏页更快的刷新到磁盘。
对于控制刷新机制的各个参数的说明:
1、innodb_max_dirty_pages_pct默认值为75,也就是说当脏页比例超过75%时才会进入勤快刷新模式。
2、innodb_max_dirty_pages_pct_lwm默认值是0,0对于innodb_max_dirty_pages_pct_lwm来说是一个特殊值,它表示不启用这个功能;由于没有启用这个功能,也就是说innodb_buffer_pool中的脏页比例会操持在75%左右。
查看buffer pool的大小,默认是128M
show VARIABLES like '%innodb_buffer_pool%';
redo log 日志
问题:innodb引擎把数据存入到buffer pool中,如果还没来得及把数据刷新到磁盘上,这个时候数据库的服务挂掉了,那么数据就丢失了?mysql是如何解决这个问题的呢?
为了解决该问题,mysql设计了redo log的日志,基于磁盘的方式存储的。
概念:在 InnoDB 存储引擎中,Redo Log(重做日志)是一种极为关键的日志文件,它主要用于保障事务的持久性。持久性是事务 ACID 特性之一,意味着一旦事务提交,其对数据库所做的修改就会永久保存,即便系统在事务提交后出现崩溃,数据也不会丢失。
问题:数据没有直接存入到磁盘上,而是先存入到buffer pool中,然后再刷入磁盘,目的是为了性能考虑,但是现在有需要存入到redo log 日志的磁盘文件中,这样性能不就下降了?
答案:性能肯定是会有一些影响,但是需要保证数据可恢复的能力。写入redo log磁盘文件中的速度会更快一些。
随机磁盘IO和顺序磁盘IO的区别。
随机磁盘IO的情况是数据是会分散到不同的扇区去存储,因为底层是通过索引的顺序来存储,索引会存储到不同的扇区。那么更新数据的时候会增加寻道的时间,写入数据会变慢。
顺序磁盘IO是按着顺序追加写入的。
innodb_log
InnoDB_log
是 MySQL 中 InnoDB 存储引擎用于管理日志的相关组件和机制,主要包括重做日志(Redo Log)和撤销日志(Undo Log)
通过命令查看innodb_log相关的信息。
show VARIABLES like '%innodb_log%';
日志存储的文件路径是 .\ 表示当前数据目录下,打开文件夹查看。
undo log 日志
undo log可以称为撤销日志或者回滚日志,站在事务的角度,undo log可以保证事务的原子性。
日志中记录的反向操作,例如:把username=”张三” 修改成了username=”赵四”,那么undo log中记录的是原来的值,即 username=”张三” 这样数据库再发生回滚操作的时候,可以把数据恢复回来。
作用
- 事务回滚:在事务执行过程中,如果遇到错误或者用户执行 ROLLBACK 语句,InnoDB 会使用 Undo Log 来撤销尚未提交的事务对数据的修改,将数据恢复到事务开始前的状态,以保证事务的原子性,即事务要么全部执行成功,要么完全不执行。
- MVCC:Undo Log 为 MVCC 提供了实现基础。它记录了数据在不同时间点的版本信息,使得在并发访问时,不同的事务能够看到数据的一致性视图,避免脏读、不可重复读和幻读等问题,提高了数据库的并发性能。
与 Redo Log 的对比
- Redo Log 主要用于保证事务的持久性,在数据库崩溃或故障后,通过 Redo Log 来恢复已提交事务对数据的修改,确保数据不会丢失。而 Undo Log 主要用于事务的回滚和 MVCC,保证事务的原子性和并发访问的一致性。
- Redo Log 是在事务提交前将修改操作记录到日志中,而 Undo Log 是在事务执行过程中,对数据进行修改时就记录下修改前的数据状态。
- Redo Log 通常是顺序写入磁盘,以提高写入性能;而 Undo Log 的写入相对较为随机,因为它需要根据事务的执行情况随时记录和更新。
在本地存储的位置。
bin log 日志
binary log 二进制日志,属于mysql服务层的日志。
binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。
binlog不会记录SELECT和SHOW这类操作,因为这类操作对数据本身并没有修改,但你可以通过查询通用日志来查看MySQL执行过的所有语句。
作用
- 帮你找回丢失的数据:假如你不小心误删了一些数据,或者数据库出了问题,Binlog 就可以帮你把数据库恢复到之前的某个状态,就像有个时光机,能让数据库 “回到过去”,把丢失的数据找回来。
- 实现数据的复制:在一些大型的数据库系统中,常常会有多个数据库服务器,其中一个是主服务器,其他的是从服务器。主服务器上的数据一旦有了变化,就会把这些变化记录在 Binlog 里,然后把 Binlog 发送给从服务器,从服务器按照 Binlog 里记录的内容,在自己身上做同样的操作,这样就能保证所有服务器上的数据都是一样的,就像一群人按照同一个剧本演戏,保证大家的 “表演” 都一样。
- 检查数据库的操作:通过查看 Binlog,你可以知道数据库里都发生了什么操作,是谁在什么时候做的。这就好像有个监控器,能帮你了解数据库的 “一举一动”,对于检查数据库的安全和排查问题很有帮助。
主要用于主从复制和数据恢复。在主从复制中,主库将 Binlog 发送给从库,从库依据其中的内容重建主库上执行的操作,实现数据同步。在数据恢复时,可根据 Binlog 将数据库恢复到某个时间点。比如,主从复制架构下,主库数据更新后,通过 Binlog 把更新传递给从库。
可以使用命令查看
show GLOBAL VARIABLES like '%log_bin%';
bin log主从复制的原理流程图
三个日志的区别
日志用途
- Redo Log:保证事务的持久性。当数据库发生崩溃时,利用 Redo Log 能够将已提交但还未持久化到磁盘的数据页更改重新应用,让数据库恢复到崩溃前的状态。举例来说,在银行系统里,一个转账事务提交后,系统突然崩溃,借助 Redo Log 就可确保转账操作最终完成。
- Undo Log:主要用于事务回滚和多版本并发控制(MVCC)。在事务需要撤销时,Undo Log 能把数据恢复到事务开始前的状态,保证事务的原子性。在 MVCC 中,它能为不同事务提供数据的历史版本,实现并发事务的一致性读取。例如,若一个事务在修改数据时出错,就可以利用 Undo Log 回滚到修改前的状态。
- Binlog:主要用于主从复制和数据恢复。在主从复制中,主库将 Binlog 发送给从库,从库依据其中的内容重建主库上执行的操作,实现数据同步。在数据恢复时,可根据 Binlog 将数据库恢复到某个时间点。比如,主从复制架构下,主库数据更新后,通过 Binlog 把更新传递给从库。
日志内容
- Redo Log:记录的是物理级别的更改,也就是数据页的更改情况,像某个数据页的某个偏移量处被修改成了什么值。
- Undo Log:记录的是逻辑级别的操作,即如何撤销事务的修改。例如,若事务执行了插入操作,Undo Log 就记录相应的删除操作。
- Binlog:记录的是逻辑 SQL 语句(Statement 格式)、行数据的更改(Row 格式)或者两者混合(Mixed 格式)。
存储位置
- Redo Log:通常存储在磁盘上的特定日志文件组里,一般是
ib_logfile0
、ib_logfile1
等。 - Undo Log:存储在 InnoDB 的系统表空间或者独立的撤销表空间中。
- Binlog:存储在磁盘上,文件名由
log_bin
参数指定,文件名格式通常是mysql - bin.xxxxxx
。
写入方式
- Redo Log:采用顺序写入的方式,性能较高。因为顺序写入能减少磁盘寻道时间,提高写入效率。
- Undo Log:写入相对随机,需要根据事务的执行情况随时记录和更新。
- Binlog:也是顺序写入,不过写入时机和 Redo Log 不同。它是在事务提交时写入,而 Redo Log 在事务执行过程中就开始写入。
适用范围
- Redo Log:只适用于 InnoDB 存储引擎。
- Undo Log:同样仅适用于 InnoDB 存储引擎。
- Binlog:适用于 MySQL 的所有存储引擎。