环球科创网

2022年01月06日整理发布:记录MySQL日志模块

更新时间:2022-01-06 14:28:55

导读 我来告诉你关于记录MySQL日志模块的事情。相信朋友们也应该很关心这个话题。现在,我们来谈谈为我的朋友记录MySQL日志模块。边肖还收集了关

我来告诉你关于记录MySQL日志模块的事情。相信朋友们也应该很关心这个话题。现在,我们来谈谈为我的朋友记录MySQL日志模块。边肖还收集了关于记录MySQL日志模块的相关信息。我希望你看到后会喜欢。

免费学习推荐:mysql视频教程

目录

一.导言

第二,重做日志

三.binlog

四.内部工作流程

MySql学习专栏

1.MySQL基础设施的详细说明

2.MySQL索引底层数据结构和算法

3.MySQL5.7是一个打开binlog日志和数据恢复的简单例子

4.MySQL日志模块

一.导言

MySQL有两个重要的日志模块:重做日志和binlog。

Redlog是InnoDB存储引擎层的日志,binlog是MySQL Server层的日志。两者都是记录一些操作的日志,但是记录格式不同。

第二,重做日志

Redlog:也称为(重做日志)文件,用于记录事务操作的变化。它记录数据修改后的值,无论事务是否提交,都会记录下来。

重做日志文件可以在介质出现故障时派上用场。例如,当数据库断电时,InnoDB存储引擎将使用重做日志恢复到断电前的时间,以确保数据的完整性。

当一条记录需要更新时,InnoDB引擎将首先将该记录写入重做日志并更新内存。此时,更新完成。

InnoDB引擎会在适当的时候将这个操作记录更新到磁盘上,这个更新通常是在系统空闲的时候进行的,这样可以提高更新效率。

说到预写日志技术WAL,它的关键点是先写日志,再写磁盘。

InnoDB的重做日志大小是固定的。例如,它可以配置为一组四个文件,每个文件的大小为1GB,然后总共可以记录4GB的操作。

Redlog会从头写到尾,然后再写回开头,如下图所示。

Write pos是当前记录的位置,写入后移到3号文件的末尾,再回到0号文件的开头。

检查点是目前要擦除的位置,也是向后走的,记录要更新到数据文件后才能循环擦除。

写位置和检查点之间未使用的部分可用于记录新操作。

如果write pos赶上了check point,则意味着重做日志记录已满,此时无法执行新的更新。我们必须先停止并删除一些记录,以推进检查点。

使用重做日志数据库,在数据库异常重启前提交的记录不会丢失。这种能力被称为碰撞安全。

为什么要使用重做日志?

如果我们对数据库进行DML操作,将执行SQL直接写入磁盘,在写入并发量较大时,将数据写入磁盘的压力会受到一定的影响。

当我们的插入操作是发现当前非叶节点的一页中没有足够的数据时,分页算法的效率会很低;

当我使用重做日志时,我首先通过一个“中转站”将我们的DML操作写入日志,然后在空闲时间通过检查点写入磁盘,这样效率要高得多。

设置MySQL重做日志

innodb_log_buffer_size的写入大小:(默认为8m)innodb _ log _ file _ size重做日志文件的大小。Innodb_log_files_in_group指定重做日志文件组的中文。

件的数量默认2innodb_mirrored_log_groups 指定了日志镜像文件组的数量默认1innodb_log_group_home_dir 指定日志文件组所在的路径默认./,表示在数据库的数据目录下innodb_flush_log_at_trx_commit 设置commit时如何将log buffer中日志刷log file中 (值0、1、2)默认1

三. binlog

redo log 是 InnoDB 引擎特有的日志而 Server 层也有自己的日志称为 binlog(归档日志)。

为什么会有两份日志呢

因为最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM但是 MyISAM 没有 crash-safe 的能力binlog 日志只能用于归档。

而 InnoDB 是另一个公司以插件形式引入 MySQL 的既然只依靠 binlog 是没有 crash-safe 能力的所以 InnoDB 使用另外一套日志系统——也就是 redo log 来实现 crash-safe 能力。

这两种日志有以下三点不同。

redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的所有引擎都可以使用。redo log 是物理日志记录的是 "在某个数据页上做了什么修改" ;binlog 是逻辑日志记录的是这个语句的原始逻辑比如 "给 ID=2 这一行的 c 字段加 1" 。redo log 是循环写的空间固定会用完;binlog 是可以追加写入的。 "追加写" 是指 binlog 文件写到一定大小后会切换到下一个并不会覆盖以前的日志。

四. 内部工作流程

以一个表的更新语句为例来看一下执行器和 InnoDB 引擎的内部工作流程:

mysql> update T set c=c+1 where ID=2;

如下图所示浅色框表示是在 InnoDB 内部执行的深色框表示是在执行器中执行的:

执行器先找引擎取 ID=2 这一行。ID 是主键引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中就直接返回给执行器;否则需要先从磁盘读入内存然后再返回。执行器拿到引擎给的行数据把这个值加上 1比如原来是 N现在就是 N+1得到新的一行数据再调用引擎接口写入这行新数据。引擎将这行新数据更新到内存中同时将这个更新操作记录到 redo log 里面此时 redo log 处于 prepare 状态。然后告知执行器执行完成了随时可以提交事务。执行器生成这个操作的 binlog并把 binlog 写入磁盘。执行器调用引擎的提交事务接口引擎把刚刚写入的 redo log 改成提交(commit)状态更新完成。

最后三步看上去有点“绕”将 redo log 的写入拆成了两个步骤:prepare 和 commit其实这就是 "两阶段提交"。

为什么日志需要 "两阶段提交"这里可以用反证法来进行解释。

由于 redo log 和 binlog 是两个独立的逻辑如果不用两阶段提交要么就是先写完 redo log 再写 binlog或者采用反过来的顺序。用前面的 update 语句来做例子我们看看这两种方式会有什么问题。

假设当前 ID=2 的行字段 c 的值是 0再假设执行 update 语句过程中在写完第一个日志后第二个日志还没有写完期间发生了 crash会出现什么情况呢

1. 先写 redo log 后写 binlog。假设在 redo log 写完binlog 还没有写完的时候MySQL 进程异常重启。redo log 写完之后系统即使崩溃仍然能够把数据恢复回来所以恢复后这一行 c 的值是 1。

但是由于 binlog 没写完就 crash 了这时候 binlog 里面就没有记录这个语句。因此之后备份日志的时候存起来的 binlog 里面就没有这条语句。

然后你会发现如果需要用这个 binlog 来恢复临时库的话由于这个语句的 binlog 丢失这个临时库就会少了这一次更新恢复出来的这一行 c 的值就是 0与原库的值不同。

2. 先写 binlog 后写 redo log。如果在 binlog 写完之后 crash由于 redo log 还没写崩溃恢复以后这个事务无效所以这一行 c 的值是 0。

但是 binlog 里面已经记录了“把 c 从 0 改成 1”这个日志。所以在之后用 binlog 来恢复的时候就多了一个事务出来恢复出来的这一行 c 的值就是 1与原库的值不同。

可以看到如果不使用“两阶段提交”那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。

相关免费学习推荐:mysql数据库(视频)

以上就是记录MySQL日志模块的详细内容!

来源:php中文网

免责声明:本文由用户上传,如有侵权请联系删除!