日志作用:
问题:
事务有 4 种特性:ACID,那么事务的四种特性到底是基于什么机制实现呢?
答:
(1): 事务的隔离性由 锁机制 实现。
(2):REDO LOG 提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持 久性。
(3):UNDO LOG 回滚行记录到某个特定版本,用来保证事务的原子性、一致性。
Redo log:
作用:
问题:如何保证在事务提交后即使系统发生了崩溃,这个事务对数据库中所做的更改也不能丢失?
方案一: 在事务提交完成之前把该事务所修改的所有页面都刷新 到磁盘
方案二:通过日志 把 修改 了哪些东西 记录一下 就好。
比如,某个事务将系统 表空间中 第 10 号 页面中偏移量为 100 处的那个字节的值 1 改成 2
我们只需要记录一下:将第 0 号表 空间的 10 号页面的偏移量为 100 处的值更新为 2
组成:
(1): redo log buffer 缓冲区 ,保存在 内存中
redo log buffer 的大小: show variables like ' %innodb_log_buffer_size% ' ;
默认是 16 M, 最大值是 4096M ,最小值为 1M 。
(2): redo log file 文件 ,保存在硬盘中
执行流程:
(1):先将数据从磁盘中读取到 dataBuffer 缓冲区
(2):执行事务中的增删改指令,在dataBuffer中修改。同时生成修改日志存放到 redo log buffer 中
(3):当事务commit的时候,将 redo log buffer 中数据刷盘到 redo log file 中
(4):定期的将 databuffer 中的数据同步到磁盘中
示意图:
注意事项:
(1):当执行增删改操作时,会用到redo日志。查询数据时,没有对数据进行修改,不会用到redo日志
(2):如果一切正常的话,那么 redo log file 其实是没有体现任何作用的
正常情况,MySQL会将 dataBuffer 中的数据定期同步到磁盘中,不需要 redo log file
(3):redo log file 的作用体现在有异常情况发生时。
dataBuffer 是定期存放在 磁盘中,如果在这期间发生宕机,那么dataBuffer 中的数据就会全部丢失。
那么此时,redo log file 中存放着事务对数据的修改日志,当我们重启MySQL时,会根据redo log file修改数据
刷盘策略:
注: 这里的刷盘是指,将 redo log buffer 中的数据刷盘到 redo log file 中,不是从 dataBuffer 刷盘到 磁盘中
因为,只要刷盘到 redo log file 之后,那么服务器无论发生什么变故,都可以重启恢复
三种策略:通过参数 innodb_flush_log_at_trx_commit 设置
(1):设置为 0: 每次事务提交时不刷盘。系统默认 master thread 每隔 1s 进行一次刷盘
(2):设置为 1: 每次事务提交后立即进行刷盘操作。 这也是默认设置
(3):设置为 2: 每次事务提交时都只把 redo log buffer 内容写入 page cache ,不进行同步。
由 os 自 己决定什么时候同步到磁盘文件。
关于 page cache :
redo log buffer 刷盘到 redo log file 的过程并不是真正的刷到磁盘中去,只是刷入到 文件系统缓存 ( page cache )中去(这是现代操作系统为了提高文件写入效率做的一个优化),真正的写入会交给系统自己来决定(比如page cache 足够大了)。
问题:如果交给系统来同 步,同样如果系统宕机,那么数据也丢失了
Undo log:
当我们对某条记录进行修改时,我们会将该记录上的数据记载到该记录对应的Undo日志中。
然后再对记录进行修改。
注: 每一条记录都会有一个指针,指向该记录对应的Undo日志
作用:
回滚事务:
事务需要保证原子性,当执行事务出现问题时。就需要回滚事务,让MySQL恢复到事务执行之前的状态。
而Undo日志就会把需要回滚的信息记录下来,可以用于恢复数据
MVCC:
当事务A正在某条数据进行写操作时,B事务想要读取该数据。此时我们就需要根据MVCC规则来读取。
根据MVCC的规则,很有可能我们需要读取的数据不是当前数据,而是历史数据。
而Undo日志中就记录了关于该数据的历史版本。