《MySQL 是怎样运行的》读后思考
背景说明
最近读《MySQL 是怎样运行的》,对 InnoDB 引擎有了更深刻的认识,本着加深理解的想法。特将自己的读后体会记录下来,如有错误,请帮忙留言指正。
所有内容及参考文档都是基于 5.7 版本(存储引擎:InnoDB)。
系统架构
模块解释:
Connectors:各种平台的 MySQL Client,实现了与 MySQL Server 的通信协议
Connections Pool:连接层,通信协议、线程处理、用户名密码认证
通信协议检测客户端版本是否兼容;线程处理负载分配线程;用户名密码认证负责鉴权
SQL 层:存储引擎交互接口、SQL 解析器、SQL 优化器、结果缓存及 Server buffer
Enterprise Management Services & Utilities:MySQL Server 管理工具
Plugable Storage Engines:存储引擎
File System:文件系统
数据结构
MySQL InnoDB 有很多实现结构,这里只取两张较为常用、有代表性的结构图
内存结构
表空间-文件结构
优秀设计
下图是执行流程白盒图(引自网络)
内存缓存
所有关于文件系统的增删改查都是先在内存进行,能缓存下来的都缓存下来了,server 相当于都是访问的内存结构
随机 IO 变顺序 IO
redo log 的处理思想太厉害了,将随机 IO 转换为顺序 IO 增加机械硬盘的处理效率,即使是固态硬盘也是非常友好(硬盘缓存)
链表随处可见、信手拈来
存储结构(页的组织,页内记录的组织)、逻辑结构(聚簇索引、二级索引)都通过链表组织起来,增、删、改非常迅速
树结构用的炉火纯青
通过树结构逐级定位页、页内跳表,这种查找结构,在应对普通 1000 万行查找,2-3 级索引,2-3 跳表查询,就 OK 了,对于按行存储的数据库非常优秀了
MVVC 控制
通过 undo log、read view 实现用户的读隔离,真是精彩
遗留问题
并非完全解决幻读问题
update 语句都是当前读,当更新时都是获取 change buffer,而不是 undo 后的版本
新插入的记录,当被 update 后,trx_id 就变成了当前事务了
select …… for update 加锁时,携带条件
select * from demo where id=1 and conditon; //加锁 id=1 成功,不管 condition 是否 true
select * from demo where id in(1, 2) and condition; //condition=false,加锁 id=1,2 失败;condition=true,加锁 id=1,2 成功
体会
这次更加深入的了解 MySQL InnoDB,深刻的体会到“魔鬼藏在细节中”,看到 MySQL 大叔在组合使用各种数据结构和算法时,由衷的惊叹各种设计的巧妙与深刻。
我现在对 MySQL 的理解还停留在结构、概念、算法的理解上,还是较为抽象的。想必更加多的细节与实现,会有更多惊喜。以后一定多多积累学习,有机会多读读源码,看看项目代码结构,一定会加深自己对存储系统的理解。
加油、加油!!!
附录
《MySQL 内核源码解读-SQL 解析一》
https://blog.51cto.com/wangwei007/2300217?source=drh
《MySQL InnoDB 存储引擎大观》
https://www.jianshu.com/p/d4cc0ea9d097
版权声明: 本文为 InfoQ 作者【彬】的原创文章。
原文链接:【http://xie.infoq.cn/article/854bb02c9bb4f286ff7f87a28】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论