RSS
菜单
全部文章快讯开发科技深度热点

第 85 章 冷门加分面试题20题

内容摘要

本篇收录 20 道面试中出现频率不高但答出来很加分的 MySQL 题,覆盖索引、锁、日志、架构、运维的冷门细节。这些题答出来,面试官会觉得你"不仅背过八股,还真懂"。本文基于 MySQL 8.0。

📖 本篇简介:本篇收录 20 道面试中出现频率不高但答出来很加分的 MySQL 题,覆盖索引、锁、日志、架构、运维的冷门细节。这些题答出来,面试官会觉得你"不仅背过八股,还真懂"。本文基于 MySQL 8.0。

目录

  • 1 使用说明
  • 2 冷门加分题1至5
  • 3 冷门加分题6至10
  • 4 冷门加分题11至15
  • 5 冷门加分题16至20
  • 6 加分题汇总表
  • 7 自测练习

1 使用说明

这 20 道题不是高频必考题,但答出来就是加分项。面试时答出一两个冷门细节,面试官对你的评价会从"背过八股"升级为"真的深入研究过"。

答题策略:这些题不用全背,理解原理后能说出大概即可。下表是题目难度分布。

| 难度 | 数量 | 占比 |

|---|---|---|

| 容易想到 | 5 | 25% |

| 需要思考 | 10 | 50% |

| 很冷门 | 5 | 25% |

2 冷门加分题1至5

题目 1:InnoDB 的页为什么默认 16K?

考点:InnoDB 存储架构。

参考答案:16K 是折中。太小(如 4K)一次 IO 读的数据少,范围查询要读很多页;太大(如 64K)单行数据占不满页,浪费空间。16K 匹配机械盘扇区和 SSD 块大小,范围查询和点查都平衡。8.0 支持启动参数调整页大小。

加分点:提到"页是 InnoDB 磁盘读写最小单位,redo log 也是按页记录修改"。

题目 2:change buffer 只缓存什么索引?

考点:InnoDB 写优化。

参考答案:只缓存二级索引(非唯一)。聚簇索引的页本来就要读入 Buffer Pool,不用缓存。唯一索引因为要校验唯一性,也必须立即读盘,用不了 change buffer。

加分点:提到 change buffer 会在缓冲池有空闲时合并写盘。

题目 3:什么是预读?

考点:InnoDB 读优化。

参考答案:InnoDB 预测性地一次读相邻几个页。线性预读:顺序读了 13 个页就预读下一区间;随机预读:一个区里 16 个页都在缓冲池就预读下一区。目的是把随机读变顺序读。

加分点:提到预读可能浪费,8.0 默认关了随机预读。

题目 4:什么是 flushed 脏页刷新的双 write?

考点:崩溃恢复。

参考答案:脏页先写到 doublewrite 区,再写真实位置。防止写一半断电导致页损坏。崩溃恢复时从 doublewrite 区拿完整页。

加分点:提到 SSD 也建议开,因为文件系统块也可能写坏。

题目 5:InnoDB 的事务 ID 是怎么分配的?

考点:MVCC。

参考答案:每个事务启动时分配一个单调递增的 trx_id。读视图记录当时活跃的事务 ID 列表,判断行版本对当前事务可见不可见。

加分点:提到只读事务不分配 trx_id,节省开销。

3 冷门加分题6至10

题目 6:什么是 purge 线程?

考点:MVCC 清理。

参考答案:后台线程清理已经不再被任何读视图需要的 undo log 旧版本。如果 undo 堆积,purge 跟不上,会导致回滚段膨胀、查询变慢。

加分点:提到 purge lag 监控指标。

题目 7:什么是 adaptive hash index?

考点:InnoDB 自动优化。

参考答案:InnoDB 监测到某些页被频繁等值查询,自动在内存里建哈希索引,把 B+树查找变成 O(1)。不需要人工干预。

加分点:提到高并发等值查询时可以观察 AHI 命中率。

题目 8:什么是 insert 意图锁?

考点:间隙锁细分。

参考答案:插入记录前,事务会在插入位置加一个"插入意图锁",告诉别的事务"我准备往这插"。别的事务如果要锁这个间隙,会被阻塞。它是间隙锁的一种。

加分点:提到它减少了幻读冲突。

题目 9:什么是 semi-consistent read?

考点:锁与读。

参考答案:更新语句在遇到行锁时,如果该行已经提交了新版本,会读最新版本再判断。减少锁等待。5.6 后引入。

加分点:提到它只在 RC 和 RR 下行为不同。

题目 10:什么是 MDl 锁?

考点:表级元数据锁。

参考答案:MySQL 5.5 引入 Metadata Lock。访问表时加 MDl,DDL 修改表结构时要等所有 MDl 释放。防止 DDL 中途和查询冲突。

加分点:提到长事务会阻塞 DDL,MDl 排队。

4 冷门加分题11至15

题目 11:什么是 tablespace 加密?

考点:安全合规。

参考答案:8.0 支持 InnoDB 表空间透明加密,数据文件落盘是密文,内存里明文。等保合规常用。

加分点:提到密钥管理用 keyring 插件。

题目 12:什么是 redo log 的 group commit?

考点:日志刷盘优化。

参考答案:多个事务的 redo 写入合并成一次 fsync,减少刷盘次数。组提交是高并发写入性能的关键。

加分点:提到 binlog 组提交和 redo 组提交的配合。

题目 13:什么是半同步复制的损失?

考点:高可用。

参考答案:半同步复制要等至少一个从库确认收到 binlog,主库提交。比异步多了网络往返延迟,但宕机丢数据风险小。

加分点:提到半同步超时后自动降级异步。

题目 14:什么是 GTID 的 transaction set?

考点:复制原理。

参考答案:每个 GTID 对应一个事务,从库通过对比主库的 executed_gtid_set,知道自己缺哪些事务,自动补齐。切换时不用找 binlog 位点。

加分点:提到 GTID 复制更适合自动化切换。

题目 15:什么是 MHA 的二次切换?

考点:高可用工具。

参考答案:MHA 检测主库宕机后,选最新从库提升为主,其他从库重新指向新主。处理主从延迟数据补全。

加分点:提到 MHA 有个问题是切换时会有短暂写入丢失风险。

5 冷门加分题16至20

题目 16:什么是 information_schema 的 InnoDB 表?

考点:8.0 数据字典。

参考答案:8.0 把元数据存在 InnoDB 内部表,information_schema 视图直接查这些内部表,比 5.7 遍历 frm 文件快很多。

加分点:提到 8.0 的 data dictionary 是事务化的。

题目 17:什么是降序索引?

考点:8.0 新特性。

参考答案:5.7 写 DESC 建索引语法会忽略,实际还是升序。8.0 真正支持降序存储,ORDER BY col DESC 能走索引。

加分点:提到联合索引混合方向的场景。

题目 18:什么是隐藏索引?

考点:8.0 新特性。

参考答案:invisible index 存在但优化器不用。用来软删除索引观察影响,没影响再真删。

加分点:提到它解决了"删索引误删"的风险。

题目 19:什么是直方图?

考点:8.0 统计信息。

参考答案:对列的数据分布建直方图,优化器知道某列值的分布不均匀,选对执行计划。特别是非索引列。

加分点:提到 ANALYZE TABLE UPDATE HISTOGRAM。

题目 20:什么是 hash join?

考点:8.0 优化器。

参考答案:8.0.18 后无索引的等值 JOIN 用 hash join,构建哈希表后探测,比嵌套循环快。

加分点:提到它在内存够时才用,内存不够退化为磁盘。

6 加分题汇总表

| 题号 | 题目 | 所属模块 | 加分度 |

|---|---|---|---|

| 1 | 页为什么 16K | 存储架构 | 高 |

| 2 | change buffer 缓存什么 | 写优化 | 高 |

| 3 | 预读机制 | 读优化 | 中 |

| 4 | doublewrite | 崩溃恢复 | 高 |

| 5 | 事务 ID 分配 | MVCC | 中 |

| 6 | purge 线程 | MVCC 清理 | 高 |

| 7 | 自适应哈希 | 自动优化 | 中 |

| 8 | 插入意图锁 | 间隙锁 | 中 |

| 9 | semi-consistent read | 锁读 | 低 |

| 10 | MDL 锁 | 表锁 | 高 |

| 11 | 表空间加密 | 安全 | 低 |

| 12 | redo group commit | 日志 | 高 |

| 13 | 半同步复制损失 | 高可用 | 中 |

| 14 | GTID transaction set | 复制 | 中 |

| 15 | MHA 二次切换 | 高可用 | 低 |

| 16 | InnoDB 数据字典表 | 8.0 架构 | 中 |

| 17 | 降序索引 | 8.0 新特性 | 中 |

| 18 | 隐藏索引 | 8.0 新特性 | 高 |

| 19 | 直方图 | 8.0 统计 | 中 |

| 20 | hash join | 8.0 优化器 | 中 |

7 自测练习

自测 1:change buffer 为什么不能缓存唯一索引?

<details>

<summary>参考答案</summary>

唯一索引要校验唯一性,必须立即读盘检查有没有重复值,不能像普通二级索引那样先缓存后合并。所以 change buffer 只对非唯一二级索引生效。

</details>

自测 2:MDl 锁为什么会阻塞 DDL?

<details>

<summary>参考答案</summary>

查询访问表时加共享 MDl,DDL 要加排他 MDl。如果有长事务一直持有共享 MDl,DDl 就要排队等,后面的查询也被堵住。这是生产常见的"DDL 卡死"原因。

</details>

自测 3:purge 线程跟不上会怎样?

<details>

<summary>参考答案</summary>

undo log 旧版本不被清理,回滚段膨胀,查询要遍历更长的版本链,变慢。监控 purge lag。

</details>

练习 1:从这 20 题里挑 5 个你最不熟的,回到对应章节深入理解。

7.1 冷门知识深入讲解

下面把前面 20 道题里最容易被追问的几个点展开讲。

深入一:为什么 8.0 默认页还是 16K?

InnoDB 页大小从 4K 到 64K 可选,默认 16K。选 16K 是因为它平衡了点查和范围查:点查只要一页,16K 一次 IO 读够;范围查连续读,16K 比 4K 少读一半页。机械时代对齐扇区,SSD 时代对齐块。8.0 支持启动时用 innodb_page_size 改,但改了要重建实例。

深入二:change buffer 的合并时机

change buffer 里的二级索引写操作,什么时候真正写盘?三个时机:一是这页被读到缓冲池时合并;二是后台线程定期 merge;三是库干净关闭时。如果 change buffer 太大,合并时会造成 IO 抖动。

深入三:purge lag 怎么看

Purge lag 是 undo log 清理滞后的指标。如果有长事务一直持有读视图,purge 不能清理那个视图之后的 undo,导致 undo 表空间膨胀。监控 SHOW STATUS LIKE 'Innodb_undo%'。

深入四:MDL 锁排队怎么破

生产常见"一条 DDL 卡住整个库":长事务持共享 MDL,DDL 排队,后面所有新查询也排队。解法是 kill 那个长事务,或者用 pt-online-schema-change 做在线 DDL。

深入五:半同步复制的超时降级

半同步复制配置了 rpl_semi_sync_master_timeout,从库超时没确认,主库自动降级为异步复制,保证写入不阻塞。降级后从库追上来不会自动切回半同步,需要手动或等重启。

7.2 冷门知识速查表

| 知识点 | 一句话 |

|---|---|

| 页大小 | 默认 16K,可配 4K~64K |

| change buffer | 只缓存非唯一二级索引写 |

| 预读 | 顺序读多了自动预读下一区 |

| doublewrite | 脏页先写共享区再写真实位置 |

| purge 线程 | 清理旧版本 undo |

| 自适应哈希 | 热点页自动建哈希索引 |

| 插入意图锁 | 插入前加的间隙锁 |

| semi-consistent read | 更新时读最新版本再判断 |

| MDL 锁 | 表级元数据锁防 DDL 冲突 |

| 表空间加密 | 落盘密文内存明文 |

| redo 组提交 | 多个事务合并一次 fsync |

| 半同步降级 | 超时自动转异步 |

| GTID set | 从库对比缺哪些事务 |

| MHA | 主库宕机自动切从库 |

| 数据字典 | 8.0 元数据事务化 |

| 降序索引 | 8.0 真正降序存储 |

| 隐藏索引 | 存在但优化器不用 |

| 直方图 | 列数据分布统计 |

| hash join | 无索引等值 JOIN 的哈希算法 |

| 持久化自增 | 8.0 重启不跳号 |

7.3 怎么复习这些冷门题

冷门题不用全背,记住"这个点存在"即可。面试时被问到,能说出"我记得有个 XX 机制,大概是做 YY 的"就够了。下面这张表给你复习优先级。

| 优先级 | 知识点 | 理由 |

|---|---|---|

| 必背 | doublewrite、MDL、purge | 高频追问 |

| 选背 | change buffer、组提交 | 加分项 |

| 了解 | 加密、直方图 | 知道就行 |

| 可弃 | MHA 细节、预读算法 | 太冷门 |

#### 7.4 更多冷门细节

下面再补充 10 个冷门但加分的知识点。

| 知识点 | 一句话解释 |

|---|---|

| change buffer 上限 | innodb_change_buffer_max_size 控制占缓冲池比例 |

| 页压缩 | 8.0 支持 transparent page compression |

| 表压缩 | ROW_FORMAT=COMPRESKEY 压缩 BLOB |

| innodb status | 看 InnoDB 内部运行状态 |

| undo 截断 | innodb_undo_log_truncate 自动收缩 undo |

| 临时表空间 | 磁盘临时表存放位置 |

| 排序合并 | filesort 用临时表归并排序 |

| 半连接优化 | 子查询改 semi join |

| 派生表合并 | 优化器把派生表合并到外层 |

| 条件下推 | WHERE 条件下推到存储引擎 |

#### 7.5 冷门题怎么准备

冷门题不用死记硬背。准备方法是:每个知识点记住"它是干嘛的",面试时能说出大概即可。

| 准备方法 | 做法 |

|---|---|

| 看官方文档 | 翻 InnoDB 架构章节 |

| 看性能博客 | 看大厂 DBA 博客 |

| 看源码注释 | GitHub 上 InnoDB 源码注释 |

| 实际实验 | 自己搭环境验证 |

| 面试攒题 | 把被问到的冷门题记下来 |

#### 7.6 冷门题出现频率

| 频率 | 知识点 |

|---|---|

| 高频追问 | doublewrite、MDL、purge |

| 偶尔问 | change buffer、组提交 |

| 很少问 | 加密、直方图细节 |

| 几乎不问 | 预读算法细节 |

7.7 冷门知识点完整列表

下面这张表把 MySQL 里所有值得了解的冷门点列全,共 30 条。

| 序号 | 知识点 | 一句话解释 |

|---|---|---|

| 1 | 页大小 | 默认 16K,可配 4K 到 64K |

| 2 | change buffer | 缓存非唯一二级索引写 |

| 3 | 线性预读 | 顺序读多了自动预读下一区 |

| 4 | 随机预读 | 区内页都在缓冲池就预读 |

| 5 | doublewrite | 脏页先写共享区再写真实位置 |

| 6 | purge 线程 | 清理旧版本 undo |

| 7 | 自适应哈希 | 热点页自动建哈希索引 |

| 8 | 插入意图锁 | 插入前加的间隙锁 |

| 9 | semi-consistent read | 更新时读最新版本再判断 |

| 10 | MDL 锁 | 表级元数据锁 |

| 11 | 表空间加密 | 落盘密文内存明文 |

| 12 | redo 组提交 | 多事务合并一次 fsync |

| 13 | 半同步复制 | 等从库确认再提交 |

| 14 | GTID set | 从库对比缺哪些事务 |

| 15 | MHA | 主库宕机自动切从库 |

| 16 | 数据字典 | 8.0 元数据事务化 |

| 17 | 降序索引 | 8.0 真正降序存储 |

| 18 | 隐藏索引 | 存在但优化器不用 |

| 19 | 直方图 | 列数据分布统计 |

| 20 | hash join | 无索引等值 JOIN |

| 21 | 持久化自增 | 8.0 重启不跳号 |

| 22 | 原子 DDL | DDL 事务化 |

| 23 | 并行回放 | 从库多线程重演 |

| 24 | WRITESET | 按行哈希并行回放 |

| 25 | undo 截断 | 自动收缩 undo 表空间 |

| 26 | 页压缩 | 透明页压缩 |

| 27 | 临时表空间 | 磁盘临时表位置 |

| 28 | 派生表合并 | 优化器合并派生表 |

| 29 | 条件下推 | WHERE 下推到引擎 |

| 30 | 半连接优化 | 子查询改 semi join |

7.8 冷门题复习优先级

| 优先级 | 数量 | 知识点 |

|---|---|---|

| 必背 | 5 | doublewrite、MDL、purge、change buffer、组提交 |

| 选背 | 10 | 间隙锁细分、GTID、并行回放、隐藏索引、直方图 |

| 了解 | 15 | 加密、压缩、预读、MHA 细节 |

7.9 InnoDB 内部结构速查

| 组件 | 作用 |

|---|---|

| Buffer Pool | 缓存数据页索引页 |

| Change Buffer | 缓存二级索引写 |

| Adaptive Hash Index | 热点页自动哈希 |

| Log Buffer | redo 写前缓冲 |

| 数据字典 | 元数据事务化 |

| Doublewrite | 防页部分写 |

| Insert Buffer | 老名字即 change buffer |

| Purge 系统 | 清理旧版本 |

| Undo 日志 | 回滚与 MVCC |

| Redo 日志 | 崩溃恢复 |

| Rollback Segment | undo 段 |

| Checkpoint | 脏页刷盘点 |

| LRU 链表 | Buffer Pool 淘汰 |

| Flush List | 脏页链表 |

| Page Cleaner | 刷脏线程 |

| IO Threads | 后台 IO 线程 |

| Page | 最小存储单位 16K |

| Extent | 64 个页组成区 |

| Segment | 区的集合 |

| Tablespace | 表空间 |

| Row | 行记录 |

| Field | 列 |

| Index | 索引 |

| B+Tree | 索引结构 |

| MVCC | 多版本 |

7.10 复习建议

冷门题复习不用贪多。把上面表里的高频 10 个练熟,面试够用。

7.11 冷门题补充

| 知识点 | 一句话 |

|---|---|

| innodb_page_size | 默认 16K |

| innodb_flush_method | O_DIRECT |

| innodb_io_capacity | 刷脏 IO 上限 |

| innodb_max_dirty_pages_pct | 脏页水位 |

| innodb_lru_scan_depth | LRU 扫描深度 |

| innodb_page_cleaners | 刷脏线程数 |

| innodb_read_io_threads | 读 IO 线程 |

| innodb_write_io_threads | 写 IO 线程 |

| innodb_doublewrite | 双写缓冲 |

| innodb_use_native_aio | 原生异步 IO |

| innodb_flush_neighbors | 刷邻居页 |

| innodb_adaptive_flushing | 自适应刷脏 |

| innodb_autoinc_lock_mode | 自增锁模式 |

| innodb_lock_wait_timeout | 锁等待超时 |

| innodb_deadlock_detect | 死锁检测 |

| innodb_status_output_locks | 状态输出锁 |

| innodb_buffer_pool_dump_at_shutdown | 关闭 dump |

| innodb_buffer_pool_load_at_startup | 启动恢复 |

| innodb_checksum_algorithm | 页校验 |

| innodb_log_checksums | redo 校验 |

7.12 复习建议

冷门题记住"存在"即可,不用深究。

7.13 冷门补充

| 知识点 | 一句话 |

|---|---|

| 页大小 | 16K |

| change buffer | 二级索引写缓存 |

| doublewrite | 双写 |

| purge | 清理 undo |

| 自适应哈希 | 热点哈希 |

| 插入意图锁 | 间隙锁 |

| MDL | 元数据锁 |

| 组提交 | 合并 fsync |

| GTID | 全局事务 ID |

| 并行回放 | 多线程重演 |

| 隐藏索引 | 存在不用 |

| 直方图 | 数据分布 |

| hash join | 哈希连接 |

| 持久化自增 | 不跳号 |

| 原子 DDL | 事务化 |

7.14 复习

冷门题记住存在即可。

7.15 收尾

冷门题记住存在即可。

| 优先级 | 数量 |

|---|---|

| 必背 | 5 |

| 选背 | 10 |

| 了解 | 15 |

7.16 复习方法

| 方法 | 做法 |

|---|---|

| 看文档 | 翻架构章节 |

| 看博客 | 大厂 DBA |

| 做实验 | 搭环境验证 |

7.17 结尾

20 道冷门题到此结束,记住存在即可。

7.18 冷门题相关命令

-- 查看 change buffer 状态(本示例基于 MySQL 8.0)
SHOW ENGINE INNODB STATUS;
-- 在 INSERT BUFFER AND ADAPTIVE HASH INDEX 段查看

-- 查看 purge 状态(本示例基于 MySQL 8.0)
SHOW STATUS LIKE 'Innodb_purge%';

-- 查看 MDL 锁等待(本示例基于 MySQL 8.0)
SELECT * FROM performance_schema.metadata_locks;

7.19 更多调试命令

-- 查看 MDL 锁(本示例基于 MySQL 8.0)
SELECT object_name, lock_type, lock_status
FROM performance_schema.metadata_locks;

-- 查看 InnoDB 行锁等待(本示例基于 MySQL 8.0)
SELECT * FROM performance_schema.data_lock_waits;
-- 查看 histogram 信息(本示例基于 MySQL 8.0)
SELECT histogram FROM information_schema.column_statistics
WHERE table_name = 'orders';

下一篇预告:第 86 章 新手易踩的面试表达坑

— 全文完 —回到顶部 ↑
下载推广海报

文章推广海报

《第 85 章 冷门加分面试题20题》完整推广海报
DISCUSSION

文章回复

0 条公开回复
未登录回复需要审核后公开
还没有回复,欢迎参与讨论。