【第五章:MySQL数据库】第22节:MySQL - 必知必会(下)


大家好,上一小节中我们对MySQL中的索引和存储引擎做了简单的介绍。本小节中,我们接着学习MySQL相关知识点,包括日志模块,锁机制以及事务等重要知识点,希望大家可以有效理解与掌握。


(1)MySQL的日志模块binlog和redo log有了解吗?

答:在MySQL的使用中,更新操作也是很频繁的,如果每一次更新操作都根据条件找到对应的记录,然后将记录更新,再写回磁盘,那么IO成本以及查找记录的成本都很高。所以,出现了日志模块,即我们的update更新操作是先写日志,在合适的时间才会去写磁盘,日志更新完毕就将执行结果返回给了客户端。

MySQL中的日志模块主要有redo log(重做日志)和binlog(归档日志)。

redo log:

redo log是InnoDB引擎特有的日志模块,redo log是物理日志,记录了某个数据页上做了哪些修改。InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是1GB,那么redo log总共就可以记录 4GB的操作。从头开始写,写到末尾就又回到开头循环写。

InnoDB的redo log保证了数据库发生异常重启之后,之前提交的记录不会丢失,这个能力称为crash-safe。

binlog:

binlog是Server层自带的日志模块,binlog是逻辑日志,记录本次修改的原始逻辑,说白了就是SQL语句。binlog是追加写的形式,可以写多个文件,不会覆盖之前的日志。通过mysqlbinlog可以解析查看binlog日志。binlog日志文件的格式:statement,row,mixed。

  • statement格式的binlog记录的是完整的SQL语句,优点是日志文件小,性能较好,缺点也很明显,那就是准确性差,遇到SQL语句中有now()等函数会导致不准确
  • row格式的binlog中记录的是数据行的实际数据的变更,优点就是数据记录准确,缺点就是日志文件较大。
  • mixed格式的binlog是前面两者的混合模式

业界目前推荐使用的是 row 模式,因为很多情况下对准确性的要求是排在第一位的。

解析:

MySQL的日志模块属于有点深度的知识点,在校招面试中考察不深,我们仅仅对这部分知识有个初步的认识和了解,就足以在面试中留下好印象并且获得加分。

在更新数据库的时候,通过redo log和binlog的两阶段提交,可以确保数据库异常崩溃之后数据的正确恢复。

在对数据库误操作之后,可以通过备份库+binlog可以将数据库状态恢复到“任意“时刻。

接下来,我们看一个关于日志模块的问题分析:

面试官:为什么MySQL会突然变慢一下?

当内存数据页和磁盘数据页内容不一致的时候,这个内存页就是“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,这个时候的内存页就是”干净页“。

前面我们介绍了更新数据库的时候是先写日志,当合适的机会(空闲)出现的时候才会更新磁盘。但是当redo log 写满了,要 flush 脏页,也就是把内存里的数据写入磁盘,会导致MySQL执行速度突然变慢一瞬间。


(2)MySQL事务有哪些特性?(重点掌握)

答:事务是单个逻辑工作单元执行的一系列操作,是一个不可分割的工作单位。满足如下的四大特性:

  • 原子性(Atomicity):事务作为一个整体被执行 ,要么全部执行,要么全部不执行;
  • 一致性(Consistency):保证数据库状态从一个一致状态转变为另一个一致状态;
  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行;
  • 持久性(Durability):一个事务一旦提交,对数据库的修改应该永久保存

解析:

MySQL事务又是一个几乎必考的MySQL知识点,可以拓展的知识点较多,我们一起来接着看如下的考察点。

面试官:“如果不做控制,多个事务并发操作数据库会产生哪些问题吗?“

  • 丢失更新:

两个不同事务同时获得相同数据,然后在各自事务中同时修改了该数据,那么先提交的事务更新会被后提交事务的更新给覆盖掉,这种情况先提交的事务所做的更新就被覆盖,导致数据更新丢失。

  • 脏读:

事务A读取了事务B未提交的数据,由于事务B回滚,导致了事务A的数据不一致,结果事务A出现了脏读;

  • 不可重复读:

一个事务在自己没有更新数据库数据的情况,同一个查询操作执行两次或多次得到的结果数值不同,因为别的事务更新了该数据,并且提交了事务。

  • 幻读:

事务A读的时候读出了N条记录,事务B在事务A执行的过程中增加 了1条,事务A再读的时候就变成了N+1条,这种情况就叫做幻读。

注意:幻读是指一种结构上的改变,比如说条数发生了改变;不可重复读是指读出的数值发生了改变。

面试官:“MySQL数据库事务的隔离级别有哪些?“

为了避免数据库事务操作中的问题,MySQL定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。

  • 读未提交(Read Uncommitted):

允许脏读取。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。

  • 读已提交(Read Committed):

允许不可重复读取,但不允许脏读取。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

  • 可重复读(Repeatable Read):

禁止不可重复

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Java开发岗高频面试题全解析 文章被收录于专栏

<p> Java开发岗高频面试题全解析,专刊正文共计31节,已经全部更新完毕。专刊分9个模块来对Java岗位面试中的知识点进行解析,包括通用面试技能,Java基础,Java进阶,网络协议,常见框架以及算法,设计模式等。专刊串点成面的解析每个面试题背后的技术原理,由浅入深,循序渐进,力争让大家掌握面试题目的背后的技术原理,摒弃背题模式的陋习。 专刊详细信息,请查阅专刊大纲和开篇词的介绍。 本专刊购买后即可解锁所有章节,故不可以退换哦~ </p> <p> <br /> </p>

全部评论
“允许脏读取。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。”此处是不是应该是“另一个事务不允许同时”进行写操作呀?
2 回复 分享
发布于 2020-08-12 17:42
打卡
1 回复 分享
发布于 2020-01-10 21:20
1 回复 分享
发布于 2020-01-13 19:09
<div> <br /> InnoDB行级锁是通过锁索引记录实现的,如果更新的列没建索引是会锁住整个表的。 </div> <div> <br /> </div> <div> 这句话应该这样理解:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁;也就是说后面的where条件中没有根据索引来检索数据的就会升级为表锁!!!(实验验证过)<br /> </div>
1 回复 分享
发布于 2020-04-14 18:58
打卡
点赞 回复 分享
发布于 2020-01-20 17:05
<div> <span style="color:#333333;">MVCC多版本并发控制以及undo log(回滚日志)</span><br /> </div> <div> 希望更新下这个,网上太坑人了 </div>
点赞 回复 分享
发布于 2020-04-14 16:56
MySQL建表的约束条件那里可以回答三范式的内容吗
点赞 回复 分享
发布于 2020-05-03 09:28
05/11 Mark
点赞 回复 分享
发布于 2020-05-12 06:50
你好,请问next key lock怎么理解
点赞 回复 分享
发布于 2020-05-16 20:45
什么情况下会用到表级锁
点赞 回复 分享
发布于 2020-05-20 19:36
二刷打卡
点赞 回复 分享
发布于 2020-08-23 10:47
打卡 一刷。
点赞 回复 分享
发布于 2020-09-12 13:14
打卡,一刷
点赞 回复 分享
发布于 2020-09-26 17:06
除了行锁,表锁,还有页锁呢
点赞 回复 分享
发布于 2020-10-08 15:38
打卡
点赞 回复 分享
发布于 2021-02-28 15:06
请问ABA问题为什么是一个问题呢?如果值改回了A,那从A修改不是本身就是符合预期的吗?
点赞 回复 分享
发布于 2022-06-29 14:26
打卡
点赞 回复 分享
发布于 2023-09-11 12:27 河南

相关推荐

点赞 评论 收藏
分享
评论
3
1
分享

创作者周榜

更多
牛客网
牛客企业服务