稳定高效写入性能
TokuDB索引采用fractal tree结构,索引修改工作由后台线程异步完成 。TokuDB会把每个索引更新转化成一个msg,在server层上下文只把msg加到root(或者某个internal)块msg buffer中便可返回;msg应用到leaf块的工作是由后台线程完成的,此后台线程被称作cleaner,负责逐级apply msg直至leaf块
DML语句被转化成FTINSERT/FTDELETE,此类msg只应用到leaf节点 。
在线加索引/在线加字段被转化成广播msg,此类msg会被应用到每个数据块的每个数据项 。
实际上,fractal tree是buffer tree的变种,在索引块内缓存更新操作,把随机请求转化成顺序请求,缩短server线程上下文的访问路径,缩短RT 。所以,TokuDB在高并发大数据量场景下,可以提供稳定高效的写入性能 。
除此之外,TokuDB实现了bulk fetch优化,range query性能也是不错的 。
在线增加索引
TokuDB支持在线加索引不阻塞更新语句 (insert, update, delete) 的执行 。可以通过变量 tokudbcreateindex_online 来控制是否开启该特性, 不过遗憾的是目前只能通过 CREATE INDEX 语法实现在线创建;如果用ALTER TABLE创建索引还是会锁表的 。
mysql> SHOW CREATE TABLE t_testG Table: t_testCreate Table: CREATE TABLE `t_test` ( `column_a` int(11) NOT NULL, `column_b` int(11) NOT NULL, PRIMARY KEY (`column_a`)) ENGINE=TokuDB DEFAULT CHARSET=latin1 ROW_FORMAT=TOKUDB_SNAPPYmysql> SET GLOBAL tokudb_create_index_online=ON;mysql> CREATE INDEX ind_1 ON t_test(column_b);mysql> SHOW CREATE TABLE t_testG Table: t_testCreate Table: CREATE TABLE `t_test` ( `column_a` int(11) NOT NULL, `column_b` int(11) NOT NULL, PRIMARY KEY (`column_a`), KEY `ind_1` (`column_b`)) ENGINE=TokuDB DEFAULT CHARSET=latin1 ROW_FORMAT=TOKUDB_SNAPPY写过程
如果不考虑unique constraint检查,TokuDB写是异步完成的 。每个写请求被转化成FT_insert类型的msg,记录着要写入的 和事务信息用于跟踪 。
Server上下文的写路径很短,只要把写请求对应的msg追加到roo数据块的msg buffer即可,这是LSM数据结构的核心思想,把随机写转换成顺序写,LevelDB和RocksDB也是采用类似实现 。
由于大家都在root数据块缓存msg,必然造成root块成为热点,也就是性能瓶颈 。
为了解决这个问题,TokuDB提出promotion概念,从root数据块开始至多往下看2层 。如果当前块数据块是中间块并且msg buffer是空的,就跳过这层,把msg缓存到下一层中间块 。
下面我们举例说明write过程 。
假设,insert之qiafractal tree状态如下图所示:
![MySQL高压缩引擎TokuDB 揭秘](http://img.jiangsulong.com/220405/045222A20-1.jpg)
文章插图
- insert 300
![MySQL高压缩引擎TokuDB 揭秘](http://img.jiangsulong.com/220405/0452222S5-2.jpg)
文章插图
- insert 100
![MySQL高压缩引擎TokuDB 揭秘](http://img.jiangsulong.com/220405/0452224549-3.jpg)
文章插图
- insert 211
![MySQL高压缩引擎TokuDB 揭秘](http://img.jiangsulong.com/220405/0452224607-4.jpg)
文章插图
行级锁
TokuDB提供行级锁处理并发读写数据 。
所有的INSERT、DELETE或者SELECT FOR UPDATE语句在修改索引数据结构fractal tree之前,需要先拿记录(也就是key)对应的行锁,获取锁之后再去更新索引 。与InnoDB行锁实现不同,InnoDB是锁记录数据结构的一个bit 。
由此可见,TokuDB行锁实现导致一些性能问题,不适合大量并发更新的场景 。
为了缓解行锁等待问题,TokuDB提供了行锁timeout参数(缺省是4秒),等待超时会返回失败 。这种处理有助于减少deadlock发生 。
读过程
由于中间数据块(internal block)会缓存更新操作的msg,读数据时需要先把上层msg buffer中的msg apply到叶子数据块(leaf block)上,然后再去leaf上把数据读上来 。
推荐阅读
- 梦见几棵大树又高又粗 梦见一颗很高的大树倒了
- 如何挑选娃娃菜
- 清明上坟时间有什么讲究 清明上坟从高祖开始拜还是辈份低开始
- 全球公认最好用的10大眼霜 十大高端眼霜
- 深圳的平安大厦高多少米 深圳最高楼是平安大厦吗
- 高考将近家长要稳字当头 高三家长会发言稿
- 营造拥有你独特气息的高雅茶席
- 汽车发动机水温高报警怎么办?值得收藏备用!
- 事业单位改革后,高校教师、医生、参公人员哪个更有发展?
- 发动机水温高的原因是?