对MySQL的一些
改进想法和实现

      彭立勋
 WWW.PengLiXun.COM




                     淘宝核心系统研发
MySQL目前存在的瓶颈
•   单查询不能有效利用多核
•   单文件不能有效利用多路径
•   数据文件扩展全局锁
•   事务写日志持有锁太久
•   两级B树锁不能有效并发
•   拆分数据无法有效聚合
•   误操作数据不能有效闪回
•   ……
如何解决?
• 并发
• 拆分锁
• 缩短锁的持有时间
单查询不能有效利用多核
• 对某些查询,可以并行处理
• 例如:SELECT count(*) FROM table WHERE
  col1 BETWEEN a AND b;

• 我们完全可以把[a,b]区间分成小区间并发:
• SELECT count(*) FROM table WHERE col1
  BETWEEN a AND x1;
• SELECT count(*) FROM table WHERE col1
  BETWEEN x1 AND x2;
• …
• SELECT count(*) FROM table WHERE col1
  BETWEEN xn AND b;
单文件不能有效利用多路径
• 在innodb_per_table下,每个表一个独立文件
• 如果没有好的RAID卡?如果有多个SSD?……

• 其实InnoDB的数据结构已经支持单表空间多文
  件——因为共享表空间就支持多文件!
• 对独立表空间也把fil_space_t-
  >chain(fil_node_t)用起来

• 如何计算page和node_id的对应关系?
• 除最后一个文件都必须固定大小
• 固定表空间文件数量
数据文件扩展全局锁
• fil_system->mutex锁定所有表空间操作

• 怎么解决?
• 5.6:扩展文件用fil_space_t->being_extend标
  记即可
• 我们的方案:预扩展
事务写日志持有锁太久
• 写事务日志整个过程持有log_sys->mutex

• 有必要吗?
• 写日志时已经知道要写的日志有多长。
• 因此没有必要

• 如何解决?
• 用log_sys->mutex申请一段可以写日志的空间
  ,释放锁后再写,后面需要提交的事务继续申
  请后面的位置即可。
两级B树锁不能有效并发
• InnoDB的B-tree只有两个Latch,非叶子节点使
  用index->latch,叶子节点使用page->latch。

• 如果B-Tree要扩展节点,对不起,整个B-Tree
  都需要锁定。

• 解决方案:
• 利用B-Link和IM协议来操作B-Tree。
• 为每层页加锁,而不是整个非叶子节点加锁。
拆分数据无法有效聚合
• MySQL最常见的用法?拆分!

• 拆完以后,数据想换个维度分析怎么办?
• 现在只能依赖中间件……

• MySQL已经准备好了干嘛不用?所有
  SlaveIO/SQL相关函数都用Master_info*传递复
  制信息。
• 为每个函数传递不同的Master_info*即可实现多
  主!
Transfer
Transfer
误操作数据无法有效闪回
• 如果bug不小心损坏了数据怎么办……

• 现在的办法:最近的全备+binlog

• 但是……binlog里有完整的操作数据啊~为何不
  用?

• 将binlog中的Log_event修改为逆操作类型!从
  文件尾部向头部执行,逆转操作!
• MySQL也可以像Oracle一样闪回~
广告时间
• 淘宝MYSQL开源平台:mysql.taobao.org
Q&A
E-Mail: PengLiXun@gmail.com

对MySQL的一些改进想法和实现