看 MySQL InnoDB 和 BoltDB 如何写磁盘
写磁盘问题
DB 产品,会 WAL 后再写磁盘; WAL 日志又称 redo 日志,用于失败时的恢复操作
似乎挺严谨,但是还是有问题:如果写磁盘的那页还没写完,断电
该页使用 redo 日志文件也无法恢复正确了
看下 MySQL InnoDB 存储引擎、 BoltDB 是如何解决该问题
MySQL InnoDB 存储引擎的两次写
顾名思义,就是写 2 次:
0. 从胀页缓存
(内存)到两次写缓存
(内存)
- 先顺序写到
磁盘共享表空间
中(连续存储,顺序写,性能很高) - 再离散写磁盘页(真正落地)
写坏情况恢复:
- 如果 2 步骤写坏,从 1 的
磁盘共享表空间
恢复 - 如果 1 步骤写坏,从 redo 日志恢复
因为实际磁盘页未被写坏,因此总能 redo 正确
BoltDB 双 meta 页切换
BoltDB 当前 meta 页指向磁盘 B+ 树
写操作:
写时拷贝
meta 页到副本 meta 页- 查找复制目标
叶子页
(新),写磁盘 - 对
叶子页
(新)到副本 meta 页的root 间的中间节点页,也重新指向并写磁盘 - 最后切换 meta 页
BoltDB 的实现构思巧妙,相当于新建 1 棵 B+ 树,原子切换 meta 页
需要写的页数 1 页到 N 页不等(数据少,就在 meta 页)
MySQL InnoDB 和 BoltDB 实现对比
- MySQL InnoDB 实现朴实; BoltDB 构思精巧
- MySQL InnoDB 写入算法稳定; BoltDB 根据数据量大小,需要写的页数不稳定
- 根据产品应用角度, MySQL InnoDB 的写入算法应该更实用