没想到MySQL还会问这些...
前言
文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y
在前一阵子,大哥问过我:”你知道MySQL的原子性是怎么保证的吗“。我懵逼了,MySQL怎么保证原子性?我不会啊。
谁都知道在事务里边原子性的意思:”一个事务包含多个操作,这些操作要么全部执行,要么全都不执行“
于是大哥就给我讲:”用的就是 undo log
啊“。
我:”卧槽,又是知识盲区“
后来在网上翻了一下,MySQL里边还有几种常见的log
,分别为:
undo log
binlog
redo log
如果你也未曾关注过这些log
,麻烦在评论区给我留个言,让我觉得不是只有我一个人这么菜,行不行?
后来我又去搜了一下,其实这几种log在面试的时候也经常会问到,这篇文章以最简单的方式来讲讲,希望对大家有帮助。
一、什么是binlog
binlog
其实在日常的开发中是听得很多的,因为很多时候数据的更新就依赖着binlog
。
举个很简单的例子:我们的数据是保存在数据库里边的嘛,现在我们对某个商品的某个字段的内容改了(数据库变更),而用户检索的出来数据是走搜索引擎的。为了让用户能搜到最新的数据,我们需要把引擎的数据也改掉。
一句话:数据库的变更,搜索引擎的数据也需要变更。
于是,我们就会监听binlog
的变更,如果binlog
有变更了,那我们就需要将变更写到对应的数据源。
什么是
binlog
?
binlog
记录了数据库表结构和表数据变更,比如update/delete/insert/truncate/create
。它不会记录select
(因为这没有对表没有进行变更)
binlog
长什么样?
binlog
我们可以简单理解为:存储着每条变更的SQL
语句(当然从下面的图看来看,不止SQL,还有XID「事务Id」等等)
binlog
一般用来做什么
主要有两个作用:复制和恢复数据
- MySQL在公司使用的时候往往都是一主多从结构的,从服务器需要与主服务器的数据保持一致,这就是通过
binlog
来实现的 - 数据库的数据被干掉了,我们可以通过
binlog
来对数据进行恢复。
因为binlog
记录了数据库表的变更,所以我们可以用binlog
进行复制(主从复制)和恢复数据。
二、什么是redo log
假设我们有一条sql语句:
update user_table set name='java3y' where id = '3'
MySQL执行这条SQL语句,肯定是先把id=3
的这条记录查出来,然后将name
字段给改掉。这没问题吧?
实际上Mysql的基本存储结构是页(记录都存在页里边),所以MySQL是先把这条记录所在的页找到,然后把该页加载到内存中,将对应记录进行修改。
现在就可能存在一个问题:如果在内存中把数据改了,还没来得及落磁盘,而此时的数据库挂了怎么办?显然这次更改就丢了。
如果每个请求都需要将数据立马落磁盘之后,那速度会很慢,MySQL可能也顶不住。所以MySQL是怎么做的呢?
MySQL引入了redo log
,内存写完了,然后会写一份redo log
,这份redo log
记载着这次在某个页上做了什么修改。
其实写redo log
的时候,也会有buffer
,是先写buffer
,再真正落到磁盘中的。至于从buffer
什么时候落磁盘,会有配置供我们配置。
写redo log
也是需要写磁盘的,但它的好处就是顺序IO
(我们都知道顺序IO比随机IO快非常多)。
所以,redo log
的存在为了:当我们修改的时候,写完内存了,但数据还没真正写到磁盘的时候。此时我们的数据库挂了,我们可以根据redo log
来对数据进行恢复。因为redo log
是顺序IO,所以写入的速度很快,并且redo log
记载的是物理变化(xxxx页做了xxx修改),文件的体积很小,恢复速度很快。
三、binlog和redo log
看到这里,你可能会想:binlog
和redo log
这俩也太像了吧,都是用作”恢复“的。
其实他俩除了"恢复"这块是相似的,很多都不一样,下面看我列一下。
存储的内容
binlog
记载的是update/delete/insert
这样的SQL语句,而redo log
记载的是物理修改的内容(xxxx页修改了xxx)。
所以在搜索资料的时候会有这样的说法:redo log
记录的是数据的物理变化,binlog
记录的是数据的逻辑变化
功能
redo log
的作用是为持久化而生的。写完内存,如果数据库挂了,那我们可以通过redo log
来恢复内存还没来得及刷到磁盘的数据,将redo log
加载到内存里边,那内存就能恢复到挂掉之前的数据了。
binlog
的作用是复制和恢复而生的。
- 主从服务器需要保持数据的一致性,通过
binlog
来同步数据。 - 如果整个数据库的数据都被删除了,
binlog
存储着所有的数据变更情况,那么可以通过binlog
来对数据进行恢复。
又看到这里,你会想:”如果整个数据库的数据都被删除了,那我可以用redo log
的记录来恢复吗?“不能
因为功能的不同,redo log
存储的是物理数据的变更,如果我们内存的数据已经刷到了磁盘了,那redo log
的数据就无效了。所以redo log
不会存储着历史所有数据的变更,文件的内容会被覆盖的。
binlog和redo log 写入的细节
redo log
是MySQL的InnoDB引擎所产生的。
binlog
无论MySQL用什么引擎,都会有的。
InnoDB是有事务的,事务的四大特性之一:持久性就是靠redo log
来实现的(如果写入内存成功,但数据还没真正刷到磁盘,如果此时的数据库挂了,我们可以靠redo log
来恢复内存的数据,这就实现了持久性)。
上面也提到,在修改的数据的时候,binlog
会记载着变更的类容,redo log
也会记载着变更的内容。(只不过一个存储的是物理变化,一个存储的是逻辑变化)。那他们的写入顺序是什么样的呢?
redo log
事务开始的时候,就开始记录每次的变更信息,而binlog
是在事务提交的时候才记录。
于是新有的问题又出现了:我写其中的某一个log
,失败了,那会怎么办?现在我们的前提是先写redo log
,再写binlog
,我们来看看:
- 如果写
redo log
失败了,那我们就认为这次事务有问题,回滚,不再写binlog
。 - 如果写
redo log
成功了,写binlog
,写binlog
写一半了,但失败了怎么办?我们还是会对这次的事务回滚,将无效的binlog
给删除(因为binlog
会影响从库的数据,所以需要做删除操作) - 如果写
redo log
和binlog
都成功了,那这次算是事务才会真正成功。
简单来说:MySQL需要保证redo log
和binlog
的数据是一致的,如果不一致,那就乱套了。
- 如果
redo log
写失败了,而binlog
写成功了。那假设内存的数据还没来得及落磁盘,机器就挂掉了。那主从服务器的数据就不一致了。(从服务器通过binlog
得到最新的数据,而主服务器由于redo log
没有记载,没法恢复数据) - 如果
redo log
写成功了,而binlog
写失败了。那从服务器就拿不到最新的数据了。
MySQL通过两阶段提交来保证redo log
和binlog
的数据是一致的。
过程:
阶段1:InnoDB
redo log
写盘,InnoDB 事务进入prepare
状态阶段2:
binlog
写盘,InooDB 事务进入commit
状态每个事务
binlog
的末尾,会记录一个XID event
,标志着事务是否提交成功,也就是说,恢复过程中,binlog
最后一个 XID event 之后的内容都应该被 purge。
四、什么是undo log
undo log
有什么用?
undo log
主要有两个作用:回滚和多版本控制(MVCC)
在数据修改的时候,不仅记录了redo log
,还记录undo log
,如果因为某些原因导致事务失败或回滚了,可以用undo log
进行回滚
undo log
主要存储的也是逻辑日志,比如我们要insert
一条数据了,那undo log
会记录的一条对应的delete
日志。我们要update
一条记录时,它会记录一条对应相反的update记录。
这也应该容易理解,毕竟回滚嘛,跟需要修改的操作相反就好,这样就能达到回滚的目的。因为支持回滚操作,所以我们就能保证:“一个事务包含多个操作,这些操作要么全部执行,要么全都不执行”。【原子性】
因为undo log
存储着修改之前的数据,相当于一个前版本,MVCC实现的是读写不阻塞,读的时候只要返回前一个版本的数据就行了。
最后
这篇文章把binlog
/redo log
/undo log
最核心的知识给讲了,还有一些细节性的东西可以自行去补充(比如binlog
有几种的模式,以及文章提到的刷盘策略等等)
如果觉得学到了,请给我个赞行不行。
参考资料:
- https://www.jianshu.com/p/4bcfffb27ed5
- https://yq.aliyun.com/articles/617335
- MySQL的ACID原理!
- MySQL 是如何实现 ACID 中的 D 的?
- https://www.cnblogs.com/myseries/p/10728533.html
如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号「Java3y」。
-
没想到MySQL还会问这些...的更多相关文章
- 本以为精通Android事件分发机制,没想到被面试官问懵了
文章中出现的源码均基于8.0 前言 事件分发机制不仅仅是核心知识点更是难点,并且还是View的一大难题滑动冲突解决方法的理论基础,因此掌握好View的事件分发机制是十分重要的. 一.基本认识 1. 事 ...
- centos clamav杀毒软件安装配置及查杀,没想到linux下病毒比windows还多!
centos clamav杀毒软件安装配置及查杀,没想到linux下病毒比windows还多! 一.手动安装 1.下载(官网) cd /soft wget http://www.clam ...
- 【原创】这道Java基础题真的有坑!我也没想到还有续集。
前情回顾 自从我上次发了<这道Java基础题真的有坑!我求求你,认真思考后再回答.>这篇文章后.我通过这样的一个行文结构: 解析了小马哥出的这道题,让大家明白了这题的坑在哪里,这题背后隐藏 ...
- 杀死众筹的N种方法:没想到山寨大军也参与了
众筹作为当下创业者筹集资金,将创意变为现实的最重要手段之一,正面临着越来越多的困难,甚至衍生出杀死众筹的N种方法.甚至这些方法还分为了两类,就众筹本身看,杀死它们的主要方法是:创业者卷钱跑路. ...
- 没想到 Google 排名第一的编程语言,为什么会这么火?
没想到吧,Python 又拿第一了! 在 Google 公布的编程语言流行指数中,Python 依旧是全球范围内最受欢迎的技术语言! 01 为什么 Python 会这么火? 核心还是因为企业需要用 ...
- 没想到,Git居然有3种“后悔药”!
没想到,Git居然有后悔药! 你知道Git版本控制系统中都有哪些"后悔药"吗? 本文通过案例讲解git reset . git revert . git checkout在版本控制 ...
- 万万没想到!ModelArts与AppCube组CP了
摘要:嘘,华为云内部都不知道的秘密玩法,我悄悄告诉您! 双"魔"合璧庆双节 ↑开局一张图,故事全靠编 华为云的一站式开发平台ModelArts和应用魔方AppCube居然能玩到一起 ...
- 除了增删改查你对MySQL还了解多少?
目录 除了增删改查你对MySQL还了解多少? MySQL授权远程连接 创建用户.授权 客户端与服务器连接的过程 TCP/IP 命名管道和共享内存 Unix域套接字文件 查询优化 MySQL中走与不走索 ...
- 没想到吧!这个可可爱爱的游戏居然是用 ECharts 实现的!
摘要:echarts 是一个很强大的图表库,除了我们常见的图表功能,还可以自定义图形,这个功能让我们可以很简单地在画布上绘制一些非常规的图形,基于此,我们来玩一些花哨的:做一个 Flappy Bird ...
随机推荐
- TCP\IP协议簇-各层主要协议帧格式
本文只是对各协议的概要,详细请参考rfc文件. 官方下载地址:https://tools.ietf.org/rfc/index rfc中文:http://man.chinaunix.net/devel ...
- TZOJ-STL系列题
C++实验:STL之vector #include <bits/stdc++.h> using namespace std; void Input(vector<int>&am ...
- [LC] 39. Combination Sum
Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), fin ...
- SpringMVC配置前端控制器的路径问题
在使用SpringMVC时,都需要在web.xml中配置一个前端控制器DispatcherServlet 控制器是一个servlet,但这个路径配置就有很多种,之前都是以扩展名配置的路径,如*.do, ...
- file,path,uri互相转换
uri 转 file :File file = new File(new URI(uri.toString())); uri 转 path: Path path = Files.get(uri); f ...
- cs231n spring 2017 lecture9 CNN Architectures
参考<deeplearning.ai 卷积神经网络 Week 2 听课笔记>. 1. AlexNet(Krizhevsky et al. 2012),8层网络. 学会计算每一层的输出的sh ...
- G 小石的图形
题目链接:https://ac.nowcoder.com/acm/contest/949/G 思路: 思路是很简单,一个小学数学题.但是n次WA后才过,重点就在pi的表示上,pi最精确的表示方式是ac ...
- Linux启动初始化配置文件浅析
转自:http://blog.51cto.com/19055/1144600 1)/etc/profile 登录时,会执行. 全局(公有)配置,不管是哪个用户,登录时都会读取该文件. (2)/ec ...
- java使用jackson生成和解析JSON
java使用jackson生成和解析JSON 1.导包 2.生成json和解析json package test; import com.fasterxml.jackson.core.JsonProc ...
- Dangling meta character '' near index 0
1.replaceAll()方法报错 对字符串使用replaceAll()方法替换 * ? + / | 等字符的时候会报以下异常 Dangling meta character '*' near in ...
- 本以为精通Android事件分发机制,没想到被面试官问懵了