【数据库】MySQL中的几种日志

MySQL中的几种日志

前言

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

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

按照重点程度,这里简单介绍binlog、redo log和undo log

先看一个图,看完文章后可以重新再看看这个图,你也可以自己画并补充的更完整:
在这里插入图片描述

binlog

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

主要有以下作用:

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

知识点:

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

格式:

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

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

statement格式
每一条会修改数据的sql都会记录在binlog中。
1、其优点是:
只需要记录执行语句的细节和上下文环境,避免了记录每一行的变化,在一些修改记录较多的情况下相比row格式能大大减少binlog的日志量,节约IO,提升性能。
另外还可以用于实时的还原。
主从版本可以不一样,从服务器版本可以比主服务器版本高。
2、其缺点是:
为了保证sql语句能在slave上正确执行,必须记录上下文信息,以保证所有语句能在slave得到和在master端执行时候相同的结果。
另外,主从复制时,存在部分函数如sleep以及存错过程在slave上回出现于master结果不一致的情况,而相比row记录每一行的变化细节,绝不会发生这种不一致的情况。

Mixed格式

是以上两种格式的混合。
经过前面的对比,可以发现Row和Statement各有优势,如果可以根据SQL语句取舍可能有更好的性能效果和体验。Mixed就是两种形式的结合。

主从复制
复制时MySQL最重要的功能之一,MySQL集群的高可用、负载均衡和读写分离都是基于复制来实现的。复制步骤如下
1、Master将数据改变记录到binlog中。
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和undo log来完成。redo log又称为重做日志,用来保证事务的持久性,undo log用来保证事务的原子性和MVCC。

rodo log

  • 包含易失的redo log buffer和持久的redo log file两部分
  • 存于redo log file(重做日志文件中)
  • 维护持久性
  • 页操作

在这里插入图片描述

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

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

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

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

undo log

  • 分为insert undo log(insert,insert只对本身事务可见,对其他事务无影响)和update undo log(update/delete)
  • 存于数据库中的undo segment(段)中
  • 用于回滚
  • 用于MVCC(实现非锁定读),读取一行记录时,若已被其他事务占据,则通过undo读取之前的版本
  • 维护原子性
  • 行操作(回滚行记录到某个版本)
  • undo是逻辑日志,只是将数据库逻辑的恢复到执行语句或事务之前。

在数据修改的时候,不仅记录了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 之后可以通过配置选择存储在独立的表空间中。

附:
慢查询日志几个配置参数:
slow_query_log 慢查询开启状态
slow_query_log_file 慢查询日志存放的位置(这个目录需要 MySQL 的运行帐号的可写权限,一般设置为 MySQL 的数据存放目录)
long_query_time 查询超过多少秒才记录
log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)修改参数可以通过配置文件,也可以在数据库中通过SET关键字来设置。

猜你喜欢

转载自blog.csdn.net/thesprit/article/details/112845614