MySQL 中有六种日志文件,分别是:

重做日志(redo log)、回滚日志(undo log)、二进制日志(binlog)、错误日志(errorlog)、慢查询日志(slow query log)、一般查询日志(general log),中继日志(relay log)。

之前没认真学习过,上次去面试被问死了,痛定思痛整理下相关的知识。

binglog

最早接触 binlog 是做数据库主从同步的时候,知道是通过同步 binlog 实现的。binlog 是 没有 MySQL sever 层维护的一种二进制日志,与 innodb 引擎中的 redo/undo log 是完全不同的日志。其主要是用来记录对 MySQL 数据更新或潜在发生更新的 SQL 语句,并以 “事务”的形式保存在磁盘中。

binlog 主要有以下作用:

  • 复制:MySQL 主从复制在 Master 端开启 binlog,Master 把它的二进制日志传递给 slaves 并回放来达到 master-slave 数据一致的目的
  • 数据恢复:通过 mysqlbinlog 工具恢复数据
  • 增量备份

几个知识点:

  • binlog 不会记录不修改数据的语句,比如Select或者Show
  • binlog 会重写日志中的密码,保证不以纯文本的形式出现
  • MySQL 8 之后的版本可以选择对 binlog 进行加密
  • 具体的写入时间:在事务提交的时候,数据库会把 binlog cache 写入 binlog 文件中,但并没有执行fsync()操作,即只将文件内容写入到 OS 缓存中。随后根据配置判断是否执行 fsync。
  • 删除时间:保持时间由参数expire_logs_days配置,也就是说对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。

管理

有这几个常用的命令可以查看 binlog 的状态:

binlog 的配置信息:show variables like '%log_bin%';

binlog 的格式:show variables like 'binlog_format';

日志的文件列表:show binary logs;

当前日志的写入状态:show master status;

清空 binlog 日志:reset master;

格式

binlog 日志有 Row、Statement、Mixed 三种格式。可以通过 my.cnf 配置文件及 set global binlog_format='ROW/STATEMENT/MIXED'进行修改,命令行 show variables like 'binlog_format' 命令查看 binglog 格式。

Row格式

Row 格式仅保存记录被修改细节,不记录 sql 语句上下文相关信息。新版本的 MySQL 默认是 Row 格式。

  • 优点:能非常清晰的记录下每行数据的修改细节,不需要记录上下文相关信息,因此不会发生某些特定情况下的存储过程、函数或者触发器的调用触发无法被正确复制的问题,任何情况都可以被复制,且能加快从库重放日志的效率,保证从库数据的一致性
  • 缺点:由于所有的执行的语句在日志中都将以每行记录的修改细节来记录,因此,可能会产生大量的日志内容,干扰内容也较多。比如一条 update 语句,如修改多条记录,则 binlog 中每一条修改都会有记录,这样造成 binlog 日志量会很大,特别是当执行alter table之类的语句的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中,实际等于重建了表。

Statement格式

每一条会修改数据的 sql 都会记录在 binlog 中。

  • 优点:只需要记录执行语句的细节和上下文环境,避免了记录每一行的变化,在一些修改记录较多的情况下相比 Row 格式能大大减少 binlog 日志量,节约 IO,提高性能。

另外还可以用于实时的还原。

主从版本可以不一样,从服务器版本可以比主服务器版本高。

  • 缺点:为了保证 sql 语句能在 slave 上正确执行,必须记录上下文信息,以保证所有语句能在 slave 得到和在 master 端执行时候相同的结果。

另外,主从复制时,存在部分函数(如 sleep)及存储过程在 slave 上会出现与 master 结果不一致的情况,而相比 Row 记录每一行的变化细节,绝不会发生这种不一致的情况。

Mixed格式

以上两种格式混合。

经过前面的对比,可以发现 Row 和 Statement 各有优势,如果可以根据 sql 语句取舍可能会有更好地性能和效果。Mixed 便是以上两种形式的结合。不过,新版本的 MySQL 对 Row 模式也做了优化,并不是所有的修改都会完全以 Row 形式来记录,像遇到表结构变更的时候就会以 Statement 模式来记录,如果 SQL 语句确实就是 update 或者 delete 等修改数据的语句,那么还是会记录所有行的变更;因此,现在一般使用 Row 即可。

主从复制

复制是 MySQL 最重要的功能之一,MySQL 集群的高可用、负载均衡和读写分离都是基于复制来实现。复制步骤如下:

  1. Master 将数据改变记录到二进制日志(binary log)中。
  2. Slave 上面的 IO 进程连接上 Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容。
  3. Master 接收到来自 Slave 的 IO 进程的请求后,负责复制的 IO 进程会根据请求信息读取日志指定位置之后的日志信息,返回给 Slave 的 IO 进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到 Master 端的 binlog 文件的名称以及 binlog 的位置。
  4. Slave 的 IO 进程接收到信息后,将接收到的日志内容依次添加到 Slave 端的 relaylog 文件的最末端,并将读取到的 Master 端的 binlog 的文件名和位置记录到 masterinfo 文件中,以便在下一次读取的时候能够清楚的告诉 Master 从某个 binlog 的哪个位置开始往后的日志内容
  5. Slave 的 SQL 进程检测到 relaylog 中新增加了内容后,会马上解析 relaylog 的内容成为在 Master 端真实执行时候的那些可执行的内容,并在自身执行。

undo log 和 redo log

undo log 和 redo log 其实都不是 MySQL 数据库层面的日志,而是 InnoDB 存储引擎的日志。二者的作用联系紧密,事务的隔离性由锁来实现,原子性、一致性、持久性通过数据库的 redo log 或 redo log 来完成。redo log 又称为重做日志,用来保证事务的持久性,undo log 用来保证事务的原子性和 MVCC。

redo log

功能

和大多数关系型数据库一样,InnoDB 记录了对数据文件的物理更改,并保证总是日志先行,也就是所谓的 WAL,即在持久化数据文件前,保证之前的 redo 日志已经写到磁盘。由于 redo log 是顺序整块写入,所以性能要更好。

重做日志两部分组成:一是内存中的重做日志缓冲(redo log buffer),是易失的;二是重做日志文件(redo log file),是持久的。redo log 记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。

写入过程

在一条语句进行执行的时候,InnoDB 引擎会把新记录写到 redo log 日志中,然后更新内存,更新完成后就算是语句执行完了,然后在空闲的时候或者是按照设定的更新策略将 redo log 中的内容更新到磁盘中。

更详细的步骤,需要了解两个关键词:checkpoint 和 LSN(Log Sequence Number),前者检查点简单来说就是把脏页刷到磁盘的时间点,这个时间点之前的数据都已经保存到了持久存储。而 LSN 是 InnoDB 使用的一个版本标记的计数,它是一个单调递增的值。数据页和 redo log 都有各自的 LSN。每次把 redo log 中的内容写入到实际的数据页之后,就会把 LSN 也同步过去。如果发生了宕机,我们可以根据数据页中的 LSN 值和 redo log 中 LSN 的值判断需要恢复的 redo log 的位置和大小。redo log 同样也有自己的缓存,所以也涉及到刷盘策略,是通过innodb_flush_log_at_trx_commit这个参数控制的。

当对应事务的脏页写入到磁盘之后,redo log 的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。

存储结构

这一块应该就没必要深入了,redo log 的存储都是以块(block)为单位进行存储的,每个块的大小为 512 字节。同磁盘扇区大小一致,可以保证块的写入是原子操作。

另外 redo log 占用的空间是固定的,会循环写入。文件大小由innodb_log_file_size参数控制。

undo log

undo log 有两个作用:提供回滚和多版本并发控制下的读(MVCC),也即非锁定读

在数据修改的时候,不仅记录了redo,还记录了相对应的 undo,如果因为某些原因导致事务失败或回滚了,可以借助该 undo 进行回滚。

undo log 和 redo log 记录物理日志不一样,它是逻辑日志。可以认为当 delete 一条记录时,undo log 中会记录一条对应的 insert 记录,反之亦然,当 update 一条记录时,它记录一条对应相反的 update 记录。

有时候应用到行版本控制的时候,也是通过 undo log 来实现的:当读取的某一行被其他事务锁定时,它可以从 undo log 中分析出该行记录以前的数据是什么,从而提供该行版本信息,让用户实现非锁定一致性读取。

undo log 是采用段(segment)的方式来记录的,每个 undo 操作在记录的时候占用一个 undo log segment

另外,undo log 也会产生 redo log,因为 undo log 也要实现持久性保护。

当事务提交的时候,InnoDB 不会立即删除 undo log,因为后续还可能会用到 undo log,如隔离级别为 repeatable read 时,事务读取的都是开启事务时的最新提交行版本,只要该事务不结束,该行版本就不能删除,即 undo log 不能删除。

当事务提交之后,undo log 并不能立马被删除,而是放入待清理的链表,由 purge 线程判断是否有其他事务在使用 undo 段中表的上一个事务之前的版本信息,决定是否可以清理 undo log 的日志空间。

在 MySQL 5.7 之前,undo log 存储在共享表空间中,因此有可能大大增加表空间的占用,5.7 之后可以通过配置选择存储在独立的表空间中。

三种日志总结

首先 InnoDB 完成一次更新操作的具体步骤:

  1. 开启事务
  2. 查询待更新的记录到内存,并加 X 锁
  3. 记录 undo log 到内存 buffer
  4. 记录 redo log 到内存 buffer
  5. 更改内存中的数据记录
  6. 提交事务,触发 redo log 刷盘
  7. 记录 bin log
  8. 事务结束

慢查询日志

几个配置参数:

  • slow_query_log 慢查询开启状态
  • slow_query_log_file 慢查询日志存放的位置(这个目录需要 MySQL 的运行帐号的可写权限,一般设置为 MySQL 的数据存放目录)
  • long_query_time 查询超过多少秒才记录
  • log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)

修改参数可以通过配置文件,也可以在数据库中通过SET关键字来设置。

参考文章

腾讯工程师带你深入解析 MySQL binlog

详细分析MySQL事务日志(redo log和undo log)

MySQL中的重做日志(redo log),回滚日志(undo log),以及二进制日志(binlog)的简单总结

MySQL innoDB——redo log/undo log

15.6.6撤消日志

15.6.5重做日志

删除对于job收缩日志失败547_MySQL中常见的几种日志相关推荐

  1. 分布式事务中常见的三种解决方案

    分布式事务中常见的三种解决方案 目录 一.分布式事务前奏 二.柔性事务解决方案架构 (一).基于可靠消息的最终一致性方案概述 (二).TCC事务补偿型方案 (三).最大努力通知型 三.基于可靠消息的最 ...

  2. 对Java中常见的四种I/O模型理解

    对Java中常见的四种I/O模型理解 1.1 知识科普 1.1.1 同步阻塞I/O(Blocking I/O) 1.1.1.1 阻塞与非阻塞 1.1.1.2 同步与异步 1.1.1.3 同步阻塞I/O ...

  3. zhlan--Python中常见的几种格式化输出

    >>>Python中常见的几种格式化输出 # 字符串格式化:name = input('请输入你的名字:')sex = input('请输入你的性别:')print('欢迎你'+na ...

  4. python中常见的几种错误

    python中常见的几种错误: 1.end前面一定加逗号 2.命令输入错误 3.冒号中英文切换 4.命令缩进错误 5.等于号要双等于,否则一个等于号是赋值 6.命令之间正确搭配

  5. Git工作流中常见的三种分支策略:GitFlow、GitHubFlow和GitLabFlow

    摘要:聊一聊Git中的工作流--分支策略. 本文分享自华为云社区<Git工作流中常见的三种分支策略:GitFlow.GitHubFlow以及GitLabFlow>,原文作者:敏捷的小智. ...

  6. 虚拟化中常见的三种硬盘模式

    虚拟化中常见的三种硬盘模式 1.厚置备延迟置零: 默认的创建格式,创建过程中为虚拟磁盘分配所需空间.创建时不会擦除物理设备上保留的任何数据,没有置零操作,当有IO操作时,需要等待清零操作完成后才能完成 ...

  7. Java中常见的几种任务调度框架对比

    Java 任务调度框架对比 一. 概述 二. 对比 三. 参考 一. 概述 本文准备Java中常见的几种任务调度框架进行对比,其中包括Quartz.Elastic Job以及xxl-job. 二. 对 ...

  8. PCBA加工中常见的两种焊接方式详解

    PCBA加工中常见的两种焊接方式详解 PCBA加工,两种常见的焊接方式就是回流焊和波峰焊,与手动焊接技术相比,自动焊接技术具有减少人为因素的影响.提高效率.降低成本.提高质量等优势,在PCBA加工中, ...

  9. 手把手教你用plotly绘制excel中常见的8种图表

    最近不是在学习plotly嘛,为了方便理解,我们这里取excel绘图中常见的16种图表为例,分两期演示这些基础图表怎么用plotly进行绘制! 第一部分:柱状图.条形图.折线图.面积图.饼图与圆环图. ...

最新文章

  1. php 7月世界排名2017,TIOBE2017榜单公布,PHP还会是世界上最好的语言吗?
  2. insert式注射攻击解析
  3. xslt中的Javascript取得xml中的参数
  4. explicit构造函数
  5. php mysql 随机排序函数_php+mysql实现数据库随机重排实例
  6. H5调用手机拨打电话的功能
  7. mysql查询表名匹配只有字母的_MySQL按某些匹配字母查询表
  8. 如何将字符串数组的空格去除_java中如何将数组转换为List
  9. 基于Geoserver配置多图层地图以及利用uDig来进行样式配置
  10. 面对互联网上的汩汩恶意,如何构建反欺诈体系?
  11. mac下载的api文档怎么_Python调用百度API实现语音识别(二)
  12. 利用linux打造工科男的办公娱乐利器 ——以centos为例
  13. shell清空数据库表
  14. JAVA最全最细基础知识点
  15. 百度AI开放平台学习——EasyDL经典版-图像分类模型训练与验证
  16. Vue中动态绑定自定义快捷键
  17. 法学生民法方面的论文选题,有什么推荐吗?
  18. Oracle数据库启动过程详解
  19. printJs 打印HTML 去掉页眉页脚
  20. 产品经理:能不能让这串数字滚动起来?

热门文章

  1. 某些equipment无法顺利download到CRM的原因
  2. 一个最简单的例子学会使用nodejs redis库进行数据库操作
  3. SAP透明工厂和弹性制造的原型mockup - SAP 工业 4.0 的一个尝试
  4. SAP CRM和Cloud for Customer中的Event handler(事件处理器)
  5. 使用工具Source Monitor测量您Java代码的环复杂度
  6. mysql 回表查询优化_MySQL中的回表查询与索引覆盖:一次百万级别分页查询使用Limit 从90秒到0.6毫秒的优化...
  7. 苹果APPLE最新MI芯片笔记本安装第三方内核扩展
  8. 本地缓存需要高时效性怎么办_详解微信小程序缓存--缓存时效性
  9. 工作空间出错_实践 | WMS系统,对于仓库工作效率和成本管控的意义
  10. css固定在右中间位置,css布局,左右固定中间自适应实现