MySQL高压缩引擎TokuDB 揭秘


MySQL高压缩引擎TokuDB 揭秘

文章插图
 
原文出处:http://MySQL.taobao.org/monthly/2017/07/04/
HybridDB for MySQL(原名petadata)是面向在线事务(OLTP)和在线分析(OLAP)混合场景的关系型数据库 。HybridDB采用一份数据存储来进行OLTP和OLAP处理,解决了以往需要把一份数据多次复制来分别进行业务交易和数据分析的问题,极大地降低了数据存储的成本,缩短了数据分析的延迟,使得实时分析决策称为可能 。
HybridDB for MySQL兼容MySQL的语法及函数,并且增加了对Oracle常用分析函数的支持,100%完全兼容TPC-H和TPC-DS测试标准,从而降低了用户的开发、迁移和维护成本 。
TokuDB是TokuTek公司(已被 Percona收购)研发的新引擎,支持事务/MVCC,有着出色的数据压缩功能,支持异步写入数据功能 。
TokuDB索引结构采用fractal tree数据结构,是buffer tree的变种,写入性能优异,适合写多读少的场景 。除此之外,TokuDB还支持在线加减字段,在线创建索引,锁表时间很短 。
Percona Server和Mariadb支持TokuDB作为大数据场景下的引擎,目前官方MySQL还不支持TokuDB 。ApsaraDB for MySQL从2015年4月开始支持TokuDB,在大数据或者高并发写入场景下推荐使用 。
TokuDB优势
数据压缩
TokuDB最显著的优势就是数据压缩,支持多种压缩算法,用户可按照实际的资源消耗修改压缩算法,生产环境下推荐使用zstd,实测的压缩比是4:1 。
目前HybridDB for MySQL支持6中压缩算法:
  • lzma: 压缩比最高,资源消耗高
  • zlib:Percona默认压缩算法,最流行,压缩比和资源消耗适中
  • quicklz:速度快,压缩比最低
  • snAppy:google研发的,压缩比较低,速度快
  • zstd:压缩比接近zlib,速度快
  • uncompressed:不压缩,速度最快
Percona建议6核以下场景使用默认压缩算法zlib,6核以上可以使用压缩率更高的压缩算法,大数据场景下推荐使用zstd压缩算法,压缩比高,压缩和解压速度快,也比较稳定 。
用户可以在建表时使用ROW_FORMAT子句指定压缩算法,也可用使用ALTER TABLE修改压缩算法 。ALTER TABLE执行后新数据使用新的压缩算法,老数据仍是老的压缩格式 。
mysql> CREATE TABLE t_test (column_a INT NOT NULL PRIMARY KEY, column_b INT NOT NULL) ENGINE=TokuDB ROW_FORMAT=tokudb_zstd;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_ZSTDmysql> ALTER TABLE t_test ROW_FORMAT=tokudb_snappy;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_SNAPPYTokuDB采用块级压缩,每个块大小是4M,这是压缩前的大小;假设压缩比是4:1,压缩后大小是1M左右 。比较tricky地方是:TokuDB压缩单位是partition,大小是64K 。相比innodb16K的块大小来说要大不少,更有利压缩算法寻找重复串 。
上面提到,修改压缩算法后新老压缩格式的数据可以同时存在 。如何识别呢?
每个数据块在压缩数据前预留一个字节存储压缩算法 。从磁盘读数据后,会根据那个字节的内容调用相应的解压缩算法 。
另外,TokuDB还支持并行压缩,数据块包含的多个partition可以利用线程池并行进行压缩和序列化工作,极大加速了数据写盘速度,这个功能在数据批量导入(import)情况下开启 。
在线增减字段
TokuDB还支持在轻微阻塞DML情况下,增加或删除表中的字段或者扩展字段长度 。
执行在线增减字段时表会锁一小段时间,一般是秒级锁表 。锁表时间短得益于fractal tree的实现 。TokuDB会把这些操作放到后台去做,具体实现是:往root块推送一个广播msg,通过逐层apply这个广播msg实现增减字段的操作 。
需要注意的:
  • 不建议一次更新多个字段
  • 删除的字段是索引的一部分会锁表,锁表时间跟数据量成正比
  • 缩短字段长度会锁表,锁表时间跟数据量成正比
mysql> ALTER TABLE t_test ADD COLUMN column_c int(11) NOT NULL;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, `column_c` int(11) NOT NULL, PRIMARY KEY (`column_a`), KEY `ind_1` (`column_b`)) ENGINE=TokuDB DEFAULT CHARSET=latin1 ROW_FORMAT=TOKUDB_SNAPPYmysql> ALTER TABLE t_test DROP COLUMN column_b;mysql> SHOW CREATE TABLE t_testG Table: t_testCreate Table: CREATE TABLE `t_test` ( `column_a` int(11) NOT NULL, `column_c` int(11) NOT NULL, PRIMARY KEY (`column_a`)) ENGINE=TokuDB DEFAULT CHARSET=latin1


推荐阅读