关于MySQL对于后端程序员的重要性不言而喻,而InnoDB也已经是MySQL默认的存储引擎。作为我们每天打交道的存储引擎,我们对它可能需要对它有更多的了解。这样对于很多灵异事件,才能从容应对。

本次文章的内容大部分来自MySQL8.0的官方文档,之所以没有选择现成的资料,而去挑战自己的弱点——英语。是因为最近意识到,学习知识应该到知识的源头,可能最开始会很吃力,但我相信对于后续的技术提升一定是有帮助的。与所有希望在技术上深挖的程序员同胞共勉~

简介

首先来看官方文档对InnoDB的解释:

InnoDB是一个平衡了高可用和高性能的通用存储引擎。

优势

  • 保护用户数据:DML操作,通过事务来遵循ACID模型

  • 高性能:行级锁,一致性读取

  • 最小化主键查找的IO:聚簇索引

  • 数据完整性:外键

  • 崩溃恢复

  • 在主内存缓存索引数据和缓存表

  • 外键

  • 校验机制

  • 只要你在设计表时选择了合适的主键,主键列where、order by、group by、join操作会被自动优化

  • 自适应哈希索引

InnoDB架构

InnoDB的整体架构可以分为两个部分:内存架构、磁盘架构



使用InnoDB表的限制,来自MySQL官方文档,感觉有些还是挺有趣的,但可能实际场景中并不会用到:

  1. 一个表最多包含1017列,表示并没有创建过这样多列的表

  2. 一个表最多可以创建64个二级索引

  3. 索引键前缀长度限制为3072字节

Undo Log 和 Redo Log

这里还有两个Log区域需要关注一下:

Undo Log

Undo Log是与事务读写关联的,主要作用在事务回滚和多版本并发控制中。

Undo Log在回滚段中存储,回滚段在Undo表空间和全局临时表空间中。Undo log被分为insert undo log 和update undo log。Insert undo log 只在事务回滚时需要,一旦事务提交就被丢弃。Update undo log 也被用在一致性读,在一致性读中可能需要update undo log的信息来生成该行数据早期的版本。

关于undo log的建议

定期地提交事务,包括哪些只包含一致性读的事务,否则,InnoDB不会丢弃update undo log中的数据,回滚段会变得越来越大,占满空间。undo log中回滚段的物理空间,通常小于相应插入或更新的行,可以利用这个信息计算回滚段需要的空间

Redo Log

也就是ib_logfile0和ib_logfile1两个文件

这里结合的是MySQL的WAL(Write-Ahead Logging)也就是先写日志,再写磁盘,具体过程是下面这样:当有一条记录要更新,先将记录写到redo log,并更新内存,InnoDB会在空闲的时候,把操作记录更新到磁盘。

官方建议的最佳实践

  • 指定主键

  • 外键

  • 关闭自动提交

  • DML的事务进行分组

  • 不要用lock table,如果希望某行的独占写,用 select … for update

  • 启用innode_file_per_table