IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> MySQL的Binary Log和Redo Log学习 -> 正文阅读

[游戏开发]MySQL的Binary Log和Redo Log学习

MySQL的Binary Log和Redo Log学习

? 上一篇博客介绍了MySQL的基础架构,这一篇就来讲一讲MySQL中比较重要的两个日志,物理日志Redo Log(后面都称为重做日志)和逻辑日志Binary Log(后面都称为二进制日志)。(其他日志也重要,但是面试官问的少。。。)

重做日志介绍

? 重做日志是属于InnoDB引擎的日志,InnoDB还有一个比较重要的日志undo log,这个也是后面MVCC需要介绍的。前一篇博客中讲了InnoDB是引擎层,所以重做日志就属于引擎层,不是所有引擎都可以使用,例如MyISAM引擎就没有这个日志文件。

? 重做日志是一种基于磁盘的数据结构,用于在MySQL崩溃恢复期间纠正由不完整事务写入的数据。在正常操作期间,重做日志对由 SQL 语句或低级 API 调用产生的更改表数据的请求进行编码。在MySQL意外关闭之前但是数据文件未完成更新的时候,InnoDB会在初始化期间和接受连接之前自动执行重做日志中的信息。默认情况下,重做日志在磁盘上由两个名为ib_logfile0ib_logfile1的文件物理表示。MySQL 以循环方式写入重做日志文件。这个介绍来自于官网。redo log

? 不难看出,重做日志的作用是为了InnoDB引擎在数据库意外关闭后仍能恢复数据,同时纠正不完整事务的脏数据。重做日志的文件是固定大小的两个,具体的名字和如何查会在后面提到。重做日志是物理日志,记录的是“在某个数据页上做了什么修改”。而且只记录数据最终的状态。

二进制日志介绍

? 二进制日志是位于Server层的日志模块。InnoDB最开始是MySQL的一个插件,后来因为好用被MySQL引入,最开始的MySQL默认引擎是MyISAM,所以最开始其他引擎是通过二进制日志来实现执行语句记录的。

? 二进制日志包含描述数据库更改的“事件”,例如表创建操作或表数据更改。它还包含可能已进行更改的语句的事件(例如, DELETE不匹配任何行),除非使用基于行的日志记录。二进制日志还包含有关每条语句使用更新数据多长时间的信息。二进制日志有两个重要用途:

  • 对于主从复制,二进制日志提供了要发送到副本的数据更改的记录。主数据库将其本身的二进制日志中包含的信息发送到其副本,这些副本执行这些事务以进行主数据库上相同的数据更改的操作。

  • 某些数据恢复操作需要使用二进制日志。恢复备份后,将重新执行备份后记录的二进制日志中的事件。这些事件使数据库从备份点开始更新。二进制日志对意外停止具有弹性。只有完整的事件或事务被记录或回读。

? 详细可以参考官方对于binloog的介绍

两个日志文件的不同

? 可能这样叙述有些模糊不清,大家很可能分不太清这两个日志模块。下面就说一下这两个日志模块的区别。(借鉴了林晓斌大佬的文章)

  • redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。
  • redo log是物理日志,记录的是“在某个数据页上做了什么修改”,里面的内容是二进制的记录形式;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”,里面的内容可以通过命令转换成人类可识别语言。
  • redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

如何查看这两个日志文件

? 说了这么多的概念,下面就来实际操作一下,查看一下这两个日志文件,查看里面的内容。

查看重做日志文件

? 可以通过show global variables like "innodb_log%";命令查看重做日志的信息,再去对应的目录查看具体的文件即可。image-20220417155402835

? 可以看到文件名为ib_logfile1的日志文件,这些文件都是固定大小的,数据会重复刷入,MySQL会定期将数据刷入磁盘中,然后清空重做日志对应的记录内容。下面就是打开的内容,可以看到,某些内容都是0000,有些则是存在具体的数据。如果想看具体的数据代表什么意思,可以参考官方的一个小工具,查看重做日志的工具。检查和打印集群重做日志的内容

image-20220417155723678

查看二进制日志文件

? 二进制文件因为是Serve层的日志模块,所以支持相对于重做日志来说要多一些。可以通过一些命令来查看具体的内容。如下所示:

# 查看binlog是否开启
show variables like '%log_bin%';
# 查看binlog格式
show variables like "%binlog_format%";
# 查看binlog文件有哪些
show binary logs;
# 查看binlog内容
show binlog events in '文件名'

image-20220417160612865

? 想要看具体的内容,需要使用mysqlbinlog命令,执行结果如下所示:

image-20220417160723072

? 这里需要注意,二进制日志默认是没有打开的,需要设置一下。设置如下:

log-bin=mysql-bin # 开启Binlog 一般只需要修改这一行即可
binlog-format=ROW # 设置格式 此行可以不加 命令设置即可 详见下方拓展
server_id=1  # 配置serverID  这一行本来就存在,不同服务需要设置不一样,例如主从之间不可设置一样。

? 这里有一个坑,因为windows的文件权限和linux的不一样,我一直比较喜欢使用docker启动开发环境,这样就导致了在windows下启动mysql镜像实例,就算指定配置文件也不生效,因为配置文件的权限过高,只要将配置文件的权限降低即可。算是运行中遇到的一个小坑吧。执行的命令如下:chmod 0444 *.cnf(在git的shell中执行就可以,cmd下需要修改命令)。

? 二进制日志的语句格式是存在三种的。生产大部分都是ROW格式,因为我不是DBA,具体的原因也没有详细探索。

  • MySQL 中的复制功能最初是基于 SQL 语句从源到副本的传播。这称为基于语句的日志记录。您可以通过使用 启动服务器来使用此格式 --binlog-format=STATEMENT。

  • 在基于行的日志记录(默认)中,源将事件写入二进制日志,指示单个表行如何受到影响。您可以通过以 --binlog-format=ROW.

  • 第三个选项也可用:混合日志记录。对于混合日志,默认使用基于语句的日志,但在某些情况下,日志模式会自动切换为基于行的日志,如下所述。您可以通过使用选项 启动mysqld使 MySQL 显式使用混合日志记录–binlog-format=MIXED。

两阶段提交

? 上面介绍两个日志模块,下面就介绍一下MySQL中的两阶段提交,同时将这两个日志模块串联起来。

? MySQL中的事务大家都比较熟悉了,一个事务执行后要么成功,要么不成功,不会影响到数据库的一致性。如果提交过程中出现断电和其他意外情况,如果没有对应的措施就会导致数据丢失或者错乱。两阶段提交也是为了保证这个的,同时也是为了保证 redo log 和 binlog 的逻辑一致性。下面就林晓斌大佬的文章介绍一下。

? 我们以这条语句的执行为例UPDATE test SET c=c+1 WHERE id=2来介绍一下两阶段提交。

image-20220417163100747

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

? 这里就是两阶段提交的示例过程,简单来说流程就是先记录到redo log中,但是事务状态为prepare状态,当binlog记录完毕后,redo log将事务状态标记为提交状态,代表事务完成。

? 虽然林晓斌大佬讲了两阶段提交的流程和不这样会造成的后果,但是没有介绍为什么这样设计,本人能力也有限,暂时没有搞明白,当作后续的一个提升点吧,有时间再去详细了解。

? 本篇博客就结束了,主要记录了两个日志模块,重做日志和二进制日志。然后介绍了如何查看对应的文件,最后则是简单介绍了两阶段提交。

? 就这样吧,结束。

参考的文章:

MySQL官方文档

如何查看binlog

redo log的详细介绍

MySQL45讲

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 18:15:32  更:2022-04-18 18:15:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:13:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码