MYSQL——大厂面试问题集合

136 阅读2分钟

摘要

本博文主要是介绍大厂面试过程中涉及到数据库中相关的问题和解答。帮助大家更好的学习与连接数据库相关的原理。

一、数据索引方面问题

如果一个高配的机器,redo log 设置太小,会发生什么情况。

每次事务提交都要写 redo log,如果设置太小,很快就会被写满,也就是下面这个图的状态,这个“环”将很快被写满,write pos 一直追着 CP。

ed1277e36b9142cfb069da7761cc6b2d.png 这时候系统不得不停止所有更新,去推进 checkpoint。这时,你看到的现象就是磁盘压力很小,但是数据库出现间歇性的性能下跌。

如果某次写入使用了 change buffer 机制,之后主机异常重启,是否会丢失 change buffer 和数据。 这个问题的答案是不会丢失,留言区的很多同学都回答对了。虽然是只更新内存,但是在事务提交的时候,我们把 change buffer 的操作也记录到 redo log 里了,所以崩溃恢复的时候,change buffer 也能找回来。

在评论区有同学问到,merge 的过程是否会把数据直接写回磁盘,这是个好问题。这里,我再为你分析一下。

merge 的执行流程是这样的:

  • 从磁盘读入数据页到内存(老版本的数据页。
  • 从 change buffer 里找出这个数据页的 change buffer 记录 (可能有多个),依次应用,得到新版数据页;
  • 写 redo log。这个 redo log 包含了数据的变更和 change buffer 的变更。

到这里 merge 过程就结束了。这时候,数据页和内存中 change buffer 对应的磁盘位置都还没有修改,属于脏页,之后各自刷回自己的物理数据,就是另外一个过程了。

为什么经过这个操作序列,explain 的结果就不对了

delete 语句删掉了所有的数据,然后再通过 call idata() 插入了 10 万行数据,看上去是覆盖了原来的 10 万行。

但是,session A 开启了事务并没有提交,所以之前插入的 10 万行数据是不能删除的。这样,之前的数据每一行数据都有两个版本,旧版本是 delete 之前的数据,新版本是标记为 deleted 的数据。

这样,索引 a 上的数据其实就有两份。

然后你会说,不对啊,主键上的数据也不能删,那没有使用 force index 的语句,使用 explain 命令看到的扫描行数为什么还是 100000 左右?(潜台词,如果这个也翻倍,也许优化器还会认为选字段 a 作为索引更合适)

是的,不过这个是主键,主键是直接按照表的行数来估计的。而表的行数,优化器直接用的是 show table status 的值。

8fbca62316404343b67aeda1b7d026b7.png