热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Mysql数据库面试必备之三大log介绍

大家好,本篇文章主要讲的是Mysql数据库面试必备之三大log介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下

快,开篇大伙先思考一个问题,MySQL 是怎么保证数据不丢失的呢?

其实要保证数据不丢失,说白了要具有下面两种能力:
(1)能恢复到任何时间点的状态;
(2)能保证 MySQL 在任何时间段突然宕机重启,已提交的数据不会丢失,未提交完整的数据也会自动回滚;

这不就引出来今天要聊的主题了么,实现第一点需要用 bin log,实现第二点需要用 redo log 和 undo log。

了解三大log之前,我们先看一下Mysql数据更新的流程:

在这里插入图片描述

上面这张图包含了 redo log、bin log、undo log 三种日志之间的大致关系,下面进入正题。

一、redo log 重做日志(MySQL 存储引擎 InnoDB 的事务日志)

我们知道 MySQL 数据存在磁盘中,每次读写数据需做磁盘 IO,并发场景下性能差。为此 MySQL 引入缓存 Buffer Pool 做优化。其包含磁盘中部分数据页(page)的映射,来缓解数据库的磁盘压力。

当从数据库读数据时,首先从缓存中读,缓存中没有,则从磁盘读后放入缓存;当向数据库写数据时,先向缓存中写,此时缓存中的数据页数据会变更,该数据页叫脏页,Buffer Pool 中修改完数据后会按照设定的策略再定期刷到磁盘中去,这个过程叫刷脏页

那么问题来了,如果 Buffer Pool 中修改的数据还没有及时的刷到磁盘,MySQL 宕机重启,就会导致数据丢失,无法保证事务的持久性,怎么办?

redo log 解决了这个问题。就是说数据库在修改数据时,会把更新记录先写到 redo log 中,再去修改 Buffer Pool 中的数据,当提交事务时,调用 fsync 把 redo log 刷入磁盘。至于缓存中更新的数据文件何时刷入磁盘,则由后台线程异步处理。

注意:此时 redo log 的事务状态是 prepare,还未真正提交成功,要等 bin log 日志写入磁盘完成后才会变为 commit,事务才算真正提交成功。

redo log 的写入方式?

redo log 采用大小固定循环写入的方式,当写满后,会重新从头开始循环写,类似一个环状。这样设计原因是 redo log 记录的是数据页上的修改,如果 Buffer Pool 中数据页已经刷到磁盘,这些记录就失效了,新日志会将这些失效的记录覆盖擦除。

注意:redo log 满了,在擦除之前,要确保这些要被擦除记录都已经刷到磁盘中了。在擦除旧记录释放新空间期间,不能再接收新的更新请求,此时 MySQL 性能会下降。因此高并发情况下,合理调整 redo log 大小很重要。

crash-safe 能力是什么?

Innodb 引擎有 crash-safe 能力,即事务提交过程中任何阶段,MySQL 宕机重启后都能保证事务的完整性,已提交的数据不会丢失。这种能力是通过redo log保证的,MySQL 宕机重启,系统将自动检查 redo log,将修改还未写入磁盘的数据从 redo log 恢复到 MySQL 中。

二、undo log 回滚日志(MySQL 存储引擎 InnoDB 的事务日志)

undo log 记录的是数据修改之前的状态,属于逻辑日志,起到回滚的作用,是保证事务原子性的关键。
举个栗子:假如更新 ID=1 记录的 name 字段,name 原始数据为小王,现改 name 为小张,事务执行 update X set name = 小张 where id =1 语句时,先在 undo log 中记录一条相反逻辑的 update X set name = 小王 where id =1 记录,这样当某些原因导致事务失败,就可借助 undo log 将数据回滚到事务执行前的状态。

那么问题来了:同一个事务的一条记录被多次修改,难道每次都要把数据修改前的状态写 undo log 吗?

不会,因为 undo log 只记录事务开始前数据的原始版本,当再次对这行数据修改时,产生的修改记录会写到 redo log。undo log 负责回滚,redo log负责前滚。

啥是回滚和前滚?

(1)回滚

未提交的事务,即事务未执行 commit。但事务内修改的脏页中,有一部分已刷盘。此时数据库宕机重启,需要回滚来将先前那部分已经刷盘的脏块从磁盘上撤销。

(2)前滚

未完全提交的事务,即事务已经执行 commit,但该事务内修改的脏页中只有一部分数据被刷盘,另一部分还在 buffer pool,此时数据库宕机重启,就要用前滚来将未来得及刷盘的数据从 redo log 中恢复出来并刷盘。 

三、bin log 归档日志(数据库 Server 层二进制逻辑日志、和什么引擎无关)

bin log 记录了用户对数据库所有 sql 操作(不包含查询语句,因为这类操作对数据本身没有修改)。之所以可以称为归档日志,是因为它不会像 redo log 那样循环擦除之前的记录,而是会一直记录日志。一个 bin log 文件默认最大容量1G(可通过 max_binlog_size 参数修改),单个日志超过最大值则会新创建一个文件继续写。
注意:日志可能是基于事务来记录的,而事务不应该跨文件记录,如果 binlog 日志文件达到了最大值但刚好事务还没有提交,此时则不会创建新文件记录,而是继续增大日志。因此 max_binlog_size 的值和实际的 binlog 文件大小不一定相等。

经过上述介绍,binlog 主要用就是主从同步和数据库基于时间点的还原

那么问题来了,可以没有 binlog 吗(有了 redo log 为啥还需要 bin log)?

需要分场景来看:

主从模式下,binlog 是必须的,因为从库的数据同步需要依赖 binlog;

单机模式下,不考虑数据库基于时间点的还原,binlog 就不是必须的,因为有 redo log 就可以保证 crash-safe 能力了;

redo log 的记录修改落盘后,日志会被覆盖掉,无法用于数据恢复等操作,redo log 是 innodb 引擎层实现的,并不是所有引擎都有;

redo log 与 bin log 的区别?

在这里插入图片描述

 什么是 redo log 两阶段提交,为什么要这么做?
更新内存后引擎层写 redo log 将状态改成 prepare 为提交第一阶段,Server 层写 bin log,将状态改成 commit 为提交第二阶段。 两阶段提交目的是确保 binl og 和 redo log 数据一致性。

如果不是两阶段提交可能会出现什么情况?
1)假设先写 redo log 再写 bin log,即 redo log 没有 prepare 阶段,写完直接置为commit,然后再写 bin log。如果写完 redo log 后还没写完 bin log 数据库宕机了,重启后系统自动用 redo log 恢复,此时会造成磁盘上数据页数据比 bin log 上的记录数据多,数据不一致。
2)假设先写 bin log 再写 redo log,如果写完 bin log 没写完 redo log 数据库宕机了,那么 bin log 上的记录就会比磁盘上数据页的记录多一些,下次用 bin log 恢复数据,恢复后的数据和原来的数据不一致。

描述一下 redo log 容灾恢复过程?
如果 redo log 是完整(commit 状态)的,直接用 redo log 恢复;
如果 redo log 是预提交 prepare 但不是 commit 状态,此时要去判断 binlog 是否完整,如果完整(commit)那就提交 redo log,再用 redo log 恢复,不完整就回滚事务。

 到此这篇关于Mysql数据库面试必备之三大log介绍的文章就介绍到这了,更多相关Mysql三大log内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文介绍了sqlserver云存储和本地存储的区别,云存储是将数据存储在网络上,方便查看和调用;本地存储是将数据存储在电脑磁盘上,只能在存储的电脑上查看。同时提供了几种启动sqlserver的方法。此外,还介绍了如何导出数据库的步骤和工具。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
author-avatar
gaoyizhen92
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有