MySQL(3)-日志
3. InnoDB日志
3.1 InnoDB架构

分为
- 内存区域架构
- buffer pool
- log buffer
- 磁盘区域架构
- redo log
- undo log
2.1.1 内存区域架构
1)Buffer Pool
定义
InnoDB对会将磁盘中经常访问的数据所在的页存入Buffer Pool中以加快访问速度,这种操作称为预读,后续对磁盘上某条数据做修改时,也是先读取到buffer pool中,再修改buffer pool中的数据
组成
由多个Page组成,其中存储了磁盘上的多行数据,方便了大容量的高效读操作,此外,将Page组织成链表结构,便于采用LRU进行内存淘汰
2)Change Buffer
定义
对于非唯一索引,如果在修改其对应的数据时,行记录不存在于Buffer Pool,那么就将修改操作记录到Change Buffer,等待后面真正读取到该记录到Buffer Pool中时,再将结果进行merge,并修改磁盘中的数据
为何必须非唯一
对于唯一索引,InnoDB需要对记录的唯一性做校验,也就必须从磁盘中读取到数据,而change buffer的存在意义是尽量避免不必要的随机磁盘io,而对于唯一性校验来说,磁盘io是不可避免的,且由于唯一索引b+树的特点,在是自增的情况下,插入操作是一次顺序io,效率是很高的,也就不必有change buffer
3)自适应哈希索引
定义
为了让MySQL性能更接近于基于内存的数据库,对于经常访问的数据,会根据数据的特点,以表的某几列建立hash索引,存储结构类似于hashmap,采用拉链法解决hash冲突,使得查询复杂度降低到O(1)
特性
- 优
- 适应等值比较
- 适应单条数据查询
- 劣
- 不适应范围查询
- 不可用范围或like比较
- 不适用连表查询
- 优
4)Log Buffer
是磁盘上log文件的缓冲区,修改会先记录到此buffer,之后异步的同步到磁盘上的log文件
3.1.2 磁盘区域架构
除了表、索引、表空间之外还有
1)Doublewrite Buffer
buffer pool中对页面的修改信息不会直接同步到对应的表中,而是会以大的连续块的形式调用fsync()写入到双写缓存中,这样在os、存储引擎或其他异常发生时,可以从双写缓存中找到备份
2)redo log
3)undo log
3.2 bin log&redo log&undo log
3.2.1 binlog
1)组成
binlog cache
作为binlog的缓存,会先写入cache中
binlog-xxx
存在于磁盘上的binlog文件,是append only式创建
2)存储内容
可以配置成三种类型
statement
记录为逻辑日志,存储提交的事务的DML语句和事务号
row
记录为物理日志,记录了实际的修改,会使得日志比较大
mixed
前两者的结合
3)作用
多用于主从同步和冷备
4)层级
位于MySQL server层
3.2.2 redo log
1)组成
redo log buffer
作为redo log的缓存,会先写入cache中
ib_logfile-xxx
存在于磁盘上的redo log文件,是循环写入的,对于已经提交的事务,会清空
2)存储内容
是物理日志和逻辑日志的结合,物理体现在记录了具体某一页上发生了修改,逻辑体现在页内的实际修改是以记录DML语句完成的
3)作用
用于宕机恢复,保证一致性
4)层级
位于存储引擎层
3.2.3 undo log
1)组成
undo log
update log
对于未提交的事务内发生的update操作,会存储相反的update
insert log
对于未提交的事务内发生的delete操作,会存储对应的insert
delete log
对于未提交的事务内发生的insert操作,会存储对应的delete
上述log会以事务号的顺序编排成一个链表以便于确定要回滚到哪个事务
2)存储内容
是逻辑日志,存储相反的DML语句
3)作用
用于回滚,保证原子性
4)层级
位于存储引擎层
3.3 事务内修改流程
假设事务内存在一条insert语句,那么实际执行流程如下
- 导入buffer并修改
- 记录undo log
- 记录redo log buffer并写盘
- 2PC提交
详细流程如下
3.3.1 导入buffer并修改
检查buffer pool中是否存在要更新的数据所在的页,如果不存在,需要将页面读入buffer pool,之后修改对应的数据
3.3.2 记录undo log
将delete语句记录到磁盘中的undo log,组织成链表
3.3.3 记录redo log buffer并写盘
将修改记录到buffer,之后根据写盘策略,将buffer中的数据写入到redo log,同步的策略有下面三种,通过设定innodb_flush_log_at_trx_commit完成
0
每次提交都写入redo log buffer,之后每秒执行
fsync()同步到redo log1
每次提交都直接写入到redo log中
2
每次提交写入os cache,之后根据
innodb_flush_log_at_timeout配置,决定多久后fsync()
3.3.4 2PC提交
1)流程
由于InnoDB的redo log出现晚于binlog,且两者都用于crash safe,那么就需要保证binlog和redolog中数据的一致性,这里采用类似于分布式事务中的想法,采用两阶段提交的方式来保证一致性,流程如下(此时默认redo log写盘已经执行)
进入Prepare阶段,设置redo log为prepare
写入binlog cache
进入Commit阶段,设置redo log为commit
根据binlog的写盘策略,将binlog cahce写入binlog,策略有下面三种
0
每次提交写入到os cache
1
每次提交都直接写入bin log
N
每次都写入os cache,累计N个事务再
fsync()
2)异常分析
写redo log宕机
这时可以根据已经落盘的undo log进行回滚
写binlog cache宕机
这时一致性未达成,根据undo log做回滚
提交后宕机
检查redo log中存储的最新事务号是否存在于binlog,如果不存在,将不存在的回滚
3.4 预写日志
预写日志(Write Ahead Log)即在修改磁盘内的数据页中的信息前,将修改信息先写入磁盘中的log文件,如redo log和bin log
这么做有以下优势
顺序io
由于redo log和binlog落盘时是顺序写入的,而如果直接修改磁盘中数据页中的数据,是随机io,效率非常低
并发量大
读写者互不阻塞
fsync调用次数少
相较于直接写入磁盘,WAL的fsync调用次数很少,无需每个事务都写盘
3.5 sync、fsync和fdatasync
3.5.0 延迟写
linux中为了减少磁盘io,在写入磁盘时会经历如下步骤
- 写入os cache
- 写入output queue
- 写入磁盘
只有当os cache满时,才会复制到output queue;只有output queue队首的数据会被写入到磁盘
3.5.1 sync
将数据同步到os cache,并不会等待到写入磁盘后返回,这需要update守护进程周期性调用sync将os cache输出到output queue保证写盘成功
3.5.2 fsync
对于某个文件的fd,调用fsync会在写盘成功后返回,写入的数据包括inode中的文件属性以及文件的数据部分
3.5.3 fdatasync
同样对于某个文件的fd,调用fdatasync会在写盘成功后返回,写入的数据只有文件的数据部分,不包括inode
3.6 double write和redo log
3.6.1 为何需要Doublewrite
buffer pool中的数据要写入到磁盘时,是以页为单位,如果写入过程出现宕机,那么就算有redo log也无法恢复,由于redo log每个页内记录的是逻辑日志,而逻辑日志需要保证表中的数据是完备且未改动的,这样where条件才不会失效,因而redo log并不能保证页面级别的crash safe
3.6.2 Doublewrite实现
1)组成
分为两部分
- 内存中的double write buffer
- 物理磁盘上共享表空间中连续的128个页,即2个区(extent),大小同样为2MB
2)机制
流程如下
- 每次脏页会先复制到double write buffer
- 分两次,每次1MB将页面信息书顺序写入到磁盘上的共享表空间
- 将buffer中的数据调用fsync离散写入磁盘
这样由于在磁盘的共享表空间中记录了页面的详细修改信息,就可以在同步页面到磁盘上时保证crash safe
# 参考
MySQL :: MySQL 5.7 Reference Manual :: 14.4 InnoDB Architecture
为什么数据不会丢,InnoDB的Double Write,你必须知道 - 掘金 (juejin.cn)
MySQL--buffer pool、redo log、undo log、binlog_黄智霖的博客-CSDN博客
Write-Ahead Logging (sqlite.org)
redo log的被动刷盘机制 - 云+社区 - 腾讯云 (tencent.com)
Linux IO同步函数:sync、fsync、fdatasync | Byte_Liu's Blog (byteliu.com)
MySQL(3)-日志的更多相关文章
- MySQL错误日志总结
MySQL错误日志是记录MySQL 运行过程中较为严重的警告和错误信息,以及MySQL每次启动和关闭的详细信息.错误日志的命名通常为hostname.err.其中,hostname表示服务器主机名. ...
- mysql数据库服务日志
mysql数据库服务日志 ①. 错误日志:error_log ②. 普通日志:general_log ③. 慢查询日志:log-slow-query #有3个参数 分割:.mv .编写定时任务并执行: ...
- mysql 二进制日志后缀数字最大为多少
之前看到mysql二进制日志后面会加一个以数字递增为结尾的后缀,一直在想当尾数到达999999后会发生什么情况,先查了一下官网,对后缀有这样一句介绍:The server creates binary ...
- MySQL慢日志监控脚本实例剖析
公司线上的 MySQL 慢日志,之前一直没有做好监控.趁着上周空闲,我就把监控脚本写了下,今天特地把代码发出来与51博友分享一下. 针对脚本的注解和整体构思,我会放到脚本之后为大家详解. 1 2 3 ...
- MySQL二进制日志的备份和恢复
二进制日志:记录数据库修改的相关操作,作用是即时点回复,主从复制 可以按时间滚动,也可以按大小滚动 server-id:服务器身份标识 一.二进制文件的删除方法,千万不要手动删除 PURGE BINA ...
- mysql 的日志文件
mysql的日志文件 日志文件大致分为 error log, binary log, query log, slow query log, innodb redo log ;如图: 1.error ...
- [转载]mysql慢日志文件分析处理
原文地址:mysql慢日志文件分析处理作者:maxyicha mysql有一个功能就是可以log下来运行的比较慢的sql语句,默认是没有这个log的,为了开启这个功能,要修改my.cnf或者在mysq ...
- ELK监控系统nginx / mysql慢日志
ELK监控系统nginx / mysql慢日志 elasticsearch logstash kibana ELK监控系统nginx日志 1.环境准备 centos6.8_64 mini IP:192 ...
- MySQL 错误日志(Error Log)
同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分.MySQL有几种不同的日志文件.通常包括错误日志文件,二进制日志,通用日志,慢查询日志,等等. 这些日志能够帮助我们定位mysqld ...
- Mysql Binlog日志详解
一.Mysql Binlog格式介绍 Mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 1.Statement:每一条会修改数据的sql都会记录在 ...
随机推荐
- ms17-010
永恒之蓝和ms17-010简介: 永恒之蓝(EternalBLUE)"是Shadow Brokers(影子经纪人)黑客组织公布的一款黑客工具,该工具利用的漏洞也被称为MS17-010漏洞,M ...
- 在Ubuntu下的OpenStack中配置使用Spice协议
在Ubuntu下的OpenStack中配置使用Spice协议 by 无若 ####控制节点#安装apt-get install nova-spiceproxy spice-html5 spice-vd ...
- 跟我一起写 Makefile(十一)
make 的运行 ------ 一般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的.但也有时你也许只想让make重编译某些文件,而不 ...
- Java中Lambda表达式基础及使用详解
概述 Lambda 是JDK 8 的重要新特性.它允许把函数作为一个方法的参数(函数作为参数传递进方法中),使用 Lambda 表达式可以使代码变的更加简洁紧凑,使Java代码更加优雅. 标准格式 三 ...
- NOIP 模拟 $14\; \text{队长快跑}$
题解 \(by\;zj\varphi\) 一道很妙的 \(dp\) 题,方程状态不好设置,细节也不少 看到数据范围,直接想离散化 设 \(f_{i,j}\) 表示处理完前 \(i\) 个水晶,其中摧毁 ...
- 题解 P3317 [SDOI2014]重建
题解 前置芝士:深度理解的矩阵树定理 矩阵树定理能求生成树个数的原因是,它本质上求的是: \[\sum_T \prod_{e\in T} w_e \] 其中 \(w_e\) 是边权,那么我们会发现其实 ...
- 题解 v
传送门 考场上只会爆搜--觉得重复状态其实有很多但不知道怎么记忆化,结果-- 对于类似这样n不算太小但只有二三十,而重复状态极多的题其实也是可以跑状压/记搜的,状态可以开map存 然后就是爆搜,就没什 ...
- sentinel使用(结合gateway)
前 如果你想在Spring Cloud Gateway中使用Sentinel Starter,你需要添加Spring - Cloud -alibaba- Sentinel - Gateway依赖,并添 ...
- @NotNull-JSR-303验证
背景 Spring Boot 引入Hibernate Validator 机制来支持 JSR-303 验证规范 实现 请求参数model类: package com.wzq.test.model; i ...
- 【spring 注解驱动开发】spring事务处理原理
尚学堂spring 注解驱动开发学习笔记之 - 事务处理 事务处理 1.事务处理实现 实现步骤: * 声明式事务: * * 环境搭建: * 1.导入相关依赖 * 数据源.数据库驱动.Spring-jd ...