赞
踩
缓冲池是InnoDB存储引擎中一块连续的内存区域,用于缓存磁盘上的数据页和索引页。由于内存访问速度远快于磁盘访问,因此将经常访问的数据和索引加载到缓冲池中,可以显著提高数据库的读写性能。缓冲池的工作原理主要基于“时间局部性”和“空间局部性”原则,即最近访问过的数据在未来很可能再次被访问,且一个数据项被访问时,与其相邻的数据项也很可能被访问。
MySQL中内存结构由多个缓冲区构成主要由Buffer Pool、Change Buffer和Log Buffer,如下图所示
Buffer Pool:缓冲池是主内存中的一个区域(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。
Buffer Pool默认大小是128M, 以Page页为单位,Page页默认大小16K,如上图中的每个小方格代表Page页。底层采用链表数据结构管理Page。根据状态,将Page分为三种类型:
Change Buffer :更改缓存区(针对非唯一二级索引)
,在执行DML(insert、update)语句时,如果这些数据的Page没有在Buffer Pool中,不会直接操作磁盘
,而会将数据变更操作存在缓冲区Change Buffer中,在未来数据被读取到Buffer Pool中,再将数据合并到Buffer Pool中,最后将合并后的数据刷新到磁盘中。
change buffer更新流程
Change Buffer的意义是什么?
与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引,(聚集索引通常是有序插入)。这样随机顺序的插入会导致删除和更新操作可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO。有了Change Buffer之后,我们可以在缓冲池Buffer Pool中进行合并处理,减少磁盘IO。
在进行修改时,如果索引设置唯一性,InnoDB必须要做唯一性校验,因此必须查询磁盘,做一次IO操作。会直接将记录查询到BufferPool中,然后在缓冲池修改,不会在ChangeBuffer操作。
Log Buffer :日志缓冲区,用来保存要写入到磁盘中的log日志数据(redo log、undo log)默认大小16MB,日志缓冲区的日志会定期刷新到磁盘中。如果需要更新、插入或删除多行的事务,增加日志缓冲区的大小可以节省磁盘IO。
其中两个重要的参数
事务有4种特性:原子性、一致性、隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢?
REDO LOG 称为 重做日志 ,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持
久性。
UNDO LOG 称为 回滚日志 ,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。
有的DBA或许会认为 UNDO 是 REDO 的逆过程,其实不然。
InnoDB存储是以页为单位来管理存储空间的,在真正访问页面之前,需要把在磁盘上的页缓存到内存中的Buffer Pool之后才可以访问。所有的变更都必须先更新缓冲池中的数据,然后缓冲池中的脏页会以一定的频率被刷入磁盘中(checkpoint机制)
,通过缓冲池来优化CPU和磁盘之间的鸿沟,这样就可以保证整体的性能。
checkpoint机制
可以保证数据的最终落盘,然而由于checkpoint 并不是每次变更的时候就触发 的,而是master线程隔一段时间去处理的。所以最坏的情况就是事务提交后,刚写完缓冲池,数据库宕机了,那么这段数据就是丢失的,无法恢复。那么如何保证这个持久性呢?
一个简单的做法 :在事务提交完成之前把该事务所修改的所有页面都刷新到磁盘,但是这个简单粗暴的做法有些问题另一个解决的思路 :我们只是想让已经提交了的事务对数据库中数据所做的修改永久生效,即使后来系统崩溃,在重启后也能把这种修改恢复出来。所以我们其实没有必要在每次事务提交时就把该事务在内存中修改过的全部页面刷新到磁盘,只需要把 修改 了哪些东西 记录一下 就好。
比如,某个事务将系统表空间中 第10号 页面中偏移量为 100 处的那个字节的值 1 改成 2,我们只需要记录一下:将第0号表空间的10号页面的偏移量为100处的值更新为 2 。
redo log buffer
,另一个是磁盘上的日志文件: redo log file
。Redo log可以简单分为以下两个部分:redo log buffer、redo log file
mysql> show variables like '%innodb_log_buffer_size%';
+------------------------+----------+
| Variable_name | Value |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
以一个更新事务为例,redo log 流转过程,如下图所示:
第1步:先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝
第2步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值
第3步:当事务commit时,将redo log buffer中的内容刷新到 redo log file,对 redo log file采用追加写的方式
第4步:定期将内存中修改的数据刷新到磁盘中
redo log的写入并不是直接写入磁盘的,InnoDB引擎会在写redo log的时候先写redo log buffer,之后以 一定的频率 刷入到真正的redo log file 中。这里的一定频率怎么看待呢?这就是我们要说的刷盘策略。
注意,redo log buffer刷盘到redo log file的过程并不是真正的刷到磁盘中去,只是刷入到 文件系统缓存(OS Buffer)
中去(这是现代操作系统为了提高文件写入效率做的一个优化),真正的写入会交给系统自己来决定
innodb_flush_log_at_trx_commit 参数设置
针对这种情况,InnoDB给出 innodb_flush_log_at_trx_commit 参数,该参数控制 commit提交事务
时,如何将 redo log buffer 中的日志刷新到 redo log file 中。
缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统缓冲区( OS Buffer )。因此, redo log buffer 写入 redo logfile 实际上是先写入 OS Buffer,然后再通过系统调用 fsync() 将其刷到 redo log file.
Redo Buffer 持久化到 redo log 的策略,可通过 Innodb_flush_log_at_trx_commit
设置:
参数值 | 含义 |
---|---|
0 (延迟写) | 事务提交时不会将 redo log buffer 中日志写入到 os buffer , 而是每秒写入 os buffer 并调用 fsync() 写入到 redo log file 中。 也就是说设置为0时是(大约)每秒刷新写入到磁盘中的,当系统崩溃,会丢失1秒钟的数据。 |
1 (实时写,实时刷) | 事务每次提交都会将 redo log buffer 中的日志写入 os buffer 并 调用 fsync() 刷到 redo log file 中。这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO的性能较差。 |
2 (实时写, 延时刷) | 每次提交都仅写入到 os buffer ,然后是每秒调用 fsync() 将 os buffer 中的日志写入到 redo log file 。 |
一般建议选择取值2,因为 MySQL 挂了数据没有损失,整个服务器挂了才会损失1秒的事务提交数据
undo log是一种用于撤销回退的日志,在数据库事务开始之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。
Undo Log产生和销毁:Undo Log在事务开始前产生;事务在提交时,并不会立刻删除undo log,innodb会将该事务对应的undo log放入到删除列表中,后面会通过后台线程purge thread进行回收处理。
注意: undo log也会产生redo log,因为undo log也要实现持久性保护。
提供回滚操作【undo log实现事务的原子性】
在数据修改的时候,不仅记录了redo log,还记录了相对应的undo log,如果因为某些原因导致事务执行失败了,可以借助undo log进行回滚。
undo log 和 redo log 记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。
提供多版本控制(MVCC)【undo log实现多版本并发控制(MVCC)】
MVCC,即多版本控制。在MySQL数据库InnoDB存储引擎中,用undo Log来实现多版本并发控制(MVCC)。当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据【快照读】。
总体记录undo日志和redo日志流程如下图:
先找是否有加载对应的BufferPool有就使用没有就加载读取 ----> 写入UndoLog —>操作执行数据 —> 写入RedoLogBuffer内存 ----> 写入RedoLog到磁盘文件
undo log 基本概念
注意: undo log也会产生redo log,因为undo log也要实现持久性保护。
undo log的作用
redo log 基本概念
redo log buffer
,另一个是磁盘上的日志文件: redo log file
。redo log的作用
bin log基本概念
bin log的作用
1)redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。
2)redo log是物理日志,记录的是“在XXX数据页上做了XXX修改”;binlog是逻辑日志,记录的是原始逻辑,其记录是对应的SQL语句。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。