一、总览与对比类
Q1:MySQL 有哪些存储引擎?
InnoDB:默认,支持事务、行锁、外键、崩溃恢复。
MyISAM:不支持事务和行锁,表锁,查询快,适合读多写少。
Memory:内存表,速度快,重启丢失。
Archive:高压缩,只支持插入和查询,适合归档。
CSV:以 CSV 文件存储。
NDB:集群引擎。
面试重点通常是 InnoDB vs MyISAM。
Q2:InnoDB 和 MyISAM 的区别?
Q3:为什么 MySQL 默认用 InnoDB?
支持事务,保证 ACID。
行锁,并发高。
支持崩溃恢复,数据安全。
支持外键、MVCC。
综合能力最强,适合大多数场景。
Q4:MyISAM 还有什么用?
读多写少、不需事务的场景。
COUNT(*)快,因为存了行数。全文索引较早支持。
现代基本被 InnoDB 取代。
二、InnoDB 内存结构类
Q5:InnoDB 的内存结构有哪些?
Buffer Pool:缓冲池,缓存数据页和索引页,最重要。
Change Buffer:写缓冲,缓存非唯一二级索引的修改。
Log Buffer:redo log 缓冲。
Adaptive Hash Index:自适应哈希索引。
Double Write Buffer:双写缓冲,防页断裂。
Q6:Buffer Pool 的作用?
缓存磁盘上的数据页,读写先走内存。
减少磁盘 I/O,是 InnoDB 性能核心。
大小由
innodb_buffer_pool_size控制,通常设物理内存 50%~70%。
Q7:Buffer Pool 的 LRU 有什么改进?
朴素的 LRU 会被全表扫描污染。
InnoDB 把 LRU 分成 young 区(5/8)和 old 区(3/8)。
新页先插入 old 区头部,再次访问且超过
innodb_old_blocks_time才移到 young 区。防止一次性扫描把热数据挤出去。
Q8:Change Buffer 是什么?
缓存非唯一二级索引的写操作(INSERT、UPDATE、DELETE)。
等页被读入内存时再 merge,减少随机 I/O。
唯一索引不能用它,因为要读盘校验唯一性。
由
innodb_change_buffer_max_size控制。
Q9:Log Buffer 是什么?
redo log 的内存缓冲。
事务提交时先写 Log Buffer,再按策略刷盘。
大小由
innodb_log_buffer_size控制。
Q10:Double Write 是什么?为什么需要?
刷脏页时先写到 double write buffer,再写数据文件。
防止页断裂(写到一半宕机)。
崩溃恢复时用 double write 修复损坏页。
三、InnoDB 磁盘结构类
Q11:InnoDB 的磁盘结构层次?
表空间(tablespace)→ 段(segment)→ 区(extent)→ 页(page)→ 行(row)。
页默认 16KB,区默认 1MB(64 个页)。
段分数据段、索引段、回滚段。
Q12:什么是表空间?
系统表空间:
ibdata1,存数据字典、回滚段等。独立表空间:
innodb_file_per_table=ON,每表一个.ibd。通用表空间、undo 表空间、临时表空间。
推荐独立表空间,便于管理和回收。
Q13:InnoDB 的行格式有哪些?
COMPACT:5.6 默认,变长字段长度列表 + NULL 标志位。
REDUNDANT:旧格式,空间浪费。
DYNAMIC:5.7 默认,溢出页存大字段。
COMPRESSED:压缩格式。
Q14:大字段怎么存?
行内放不下时,存到溢出页,行内只留 20 字节指针。
DYNAMIC 格式下,大字段完全溢出。
COMPACT 下可能留部分前缀。
Q15:页的内部结构?
页头、页目录、用户记录、空闲空间、页尾。
页目录用槽位加速页内查找。
记录按主键有序,用链表连接。
四、索引结构类
Q16:InnoDB 和 MyISAM 的索引结构区别?
InnoDB:聚簇索引,主键索引叶子存整行;二级索引叶子存主键值。
MyISAM:非聚簇索引,索引叶子存行地址,数据和索引分离。
Q17:什么是聚簇索引?
数据行和主键索引存在一起,叶子节点就是数据页。
一张表只有一个聚簇索引,通常是主键。
没主键时选唯一非空索引,再没有就生成隐藏 row_id。
Q18:为什么推荐自增主键?
顺序插入,减少页分裂和碎片。
主键小,二级索引也小。
UUID 随机插入导致页分裂、性能下降。
Q19:回表是什么?
二级索引查到主键值,再回聚簇索引查整行。
覆盖索引可避免回表。
五、事务与锁相关类
Q20:InnoDB 怎么实现事务?
原子性:undo log。
持久性:redo log。
隔离性:锁 + MVCC。
一致性:由以上共同保证。
Q21:InnoDB 的锁有哪些?
行锁:记录锁、间隙锁、临键锁、插入意向锁。
表锁:意向锁、MDL。
默认行锁,无索引时退化为表锁。
Q22:InnoDB 的 MVCC 怎么实现?
隐藏列
DB_TRX_ID、DB_ROLL_PTR。undo log 版本链。
ReadView 可见性判断。
六、崩溃恢复与持久化类
Q23:InnoDB 怎么保证崩溃恢复?
redo log 重放已提交事务。
undo log 回滚未提交事务。
double write 修复页断裂。
两阶段提交保证 redo 和 binlog 一致。
Q24:什么是页断裂?
刷 16KB 页时写到一半宕机,页损坏。
double write 先写副本,恢复时用副本修复。
Q25:innodb_flush_log_at_trx_commit 怎么影响持久性?
=1:每次提交刷盘,不丢。=0:每秒刷,可能丢 1 秒。=2:提交写 OS cache,宕机可能丢。
七、实战与选型类
Q26:什么时候选 MyISAM?
读多写少、不需事务、能接受表锁。
需要快速
COUNT(*)。现代生产基本不用,除非特殊场景。
Q27:Memory 引擎适用场景?
临时表、缓存、会话数据。
速度快,但重启丢失,不支持大字段。
生产核心数据不用。
Q28:Archive 引擎适用场景?
日志、归档数据。
高压缩,只支持 INSERT 和 SELECT。
不支持索引(除自增主键)。
Q29:怎么查看表的存储引擎?
SHOW TABLE STATUS LIKE 't';SHOW CREATE TABLE t;information_schema.TABLES。
Q30:怎么修改存储引擎?
ALTER TABLE t ENGINE=InnoDB;会重建表,大表耗时长,需低峰执行。
八、高频陷阱题
Q31:InnoDB 的 COUNT(*) 为什么慢?
不存总行数,要扫索引统计。
MyISAM 存了行数,所以快。
优化:用最小二级索引扫、计数表、缓存。
Q32:InnoDB 支持全文索引吗?
MySQL 5.6+ 支持。
早期只有 MyISAM 支持。
Q33:InnoDB 表一定比 MyISAM 慢吗?
不一定。读多写少时 MyISAM 可能略快。
但 InnoDB 行锁、事务、崩溃恢复综合更优。
现代硬件下差距很小。
Q34:Change Buffer 对唯一索引有效吗?
无效。唯一索引要读盘校验唯一性,不能延迟。
只对非唯一二级索引有效。
Q35:Buffer Pool 越大越好吗?
不是。太大会挤占 OS 内存,影响文件和连接。
一般设物理内存 50%~70%。
评论