0%

MySQL TokuDB 引擎 (Percona Server)

Percona Server 可以看做是 Linux 上优化过的 MySQL,比如 Percona 针对 InnoDB 优化的 XtraDB 引擎是兼容InnoDB的,Percona还提供了 TokuDB 版本的Percona Server,TokuDB 是一个面向大数据,支持事务的存储引擎,有着非常好的随机写性能,并且支持在线 DDL。

Percona Server 可以看作是 MySQL 的增强版,因为和 MySQL 几乎完全兼容,在使用 yum 安装的时候只是包名不一样,安装后的产物都几乎相同。

特性:

  • 高压缩比,默认使用 zlib 进行压缩,尤其是对字符串 (varchar,text等) 类型有非常高的压缩比,比较适合存储日志、原始数据等。一般有5-10倍压缩比。
  • 在线添加索引,不影响读写操作
  • HCADER 特性,支持在线字段增加、删除、扩展、重命名操作,(瞬间或秒级完成)
  • 支持完整的 ACID 事务机制
  • 非常快的写入性能(索引的原因)
  • 支持show processlist 进度查看

缺点:

  • 读响应时间比 InnoDB 长,因为压缩解压缩的原因。CPU 占用会高2-3倍,但由于压缩后空间小,IO 开销低
  • 不支持外键,据说触发器等高级特性也尽量不要使用。

适用场景:

  • 访问频率不高的数据或历史数据归档
  • 数据表非常大并且时不时还需要进行 DDL 操作

更多介绍参见官网:https://www.percona.com/doc/percona-server/5.6/tokudb/tokudb_intro.html

与 Oracle MySQL的版本区别

1
2
3
4
5
6
7
# Percona Server
mysql Ver 14.14 Distrib 5.6.30-76.3, for Linux (x86_64) using 6.0
Server version: 5.6.30-76.3 Percona Server (GPL), Release 76.3, Revision 3850db5

# Oracle MySQL
mysql Ver 14.14 Distrib 5.6.20, for Linux (x86_64) using EditLine wrapper
Server version: 5.6.20-log Source distribution

安装 Percona Server

官网:https://www.percona.com/

使用官方 yum 源安装:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装repo
yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm

# 检查安装成功
yum list | grep Percona-Server

# 安装 server, client, devel
yum install Percona-Server-server-56 Percona-Server-client-56 Percona-Server-devel-56

# 直接使用默认配置启动 (个人习惯启动脚本为mysqld)
mv /etc/init.d/mysql /etc/init.d/mysqld
/etc/init.d/mysqld start

# 客户端连接检查
mysql -uroot
Server version: 5.6.30-76.3 Percona Server (GPL), Release 76.3, Revision 3850db5

实际上以上与 mysql-server,mysql-devel, mysql-client 正好对应

安装后推荐使用我们的配置对照修改各项配置,目录位置等:

修改完后重新启动 MySQL 服务

安装 TokuDB 引擎

1
2
3
4
5
6
7
8
9
10
11
12
# 自动依赖安装jemalloc模块,安装后需重启服务
yum install Percona-Server-tokudb-56

# 执行自动化安装脚本,要求MySQL服务在启动状态
ps_tokudb_admin --enable -uroot

# TokuDB 要求关闭操作系统透明大页面功能,我们需要加到系统启动/etc/rc.local中,同时需要审视你自己的应用
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

# 再次重启,登陆安装成功后查看
mysql> SHOW ENGINES;

TokuDB 引擎使用

压缩率测试

某某数据,600W+ 记录,属于宽表,其中主要为 Text 类型长文本,压缩率高达1:7,最终空间大小对比:

1
2
3
4
5
# MYSIAM 70G / TokuDB 8G
70G data/test/xxxxx_myisam.MYD

ToKuDB
8.1G tokudata/_test_xxxxx_main_34_1_1d_B_0.tokudb

某某基本信息数据,属于高表,4000W+记录,压缩率1:2.5,空间大小对比:

1
2
3
4
5
6
7
# MyISAM 30G / TokuDB 12G
27G yyyyy_160525.MYD
2.8G yyyyy_160525.MYI

963M _test_yyyyy_tokudb_key_Key_10_1_1d_B_1.tokudb
178M _test_yyyyy_tokudb_key_Updated_10_1_1d_B_2.tokudb
11G _test_yyyyy_tokudb_main_10_1_1d_B_0.tokudb

当我们把 TokuDB 表记录插如到2.5亿,占用空间仅 46G,此时如果是 MyISAM 应该要破百G

1
2
3
1.7G    /opt/mysql/data/_test_sql_3f84_b_key_Key_5a_3_1d.tokudb
993M /opt/mysql/data/_test_sql_3f84_b_key_Updated_5a_4_1d.tokudb
44G /opt/mysql/data/_test_sql_3f84_b_main_5a_2_1d.tokudb

索引动态创建与删除

TokuDB 允许你动态创建索引,而不影响插入、查询操作,该操作会再后台进行:

1
2
3
4
SET tokudb_create_index_online=on;
CREATE INDEX index ON table (field_name);

CREATE UNIQUE INDEX `Key` ON `yyyyy_tokudb`(`Key`);

注意:只能使用 CREATE INDEX 语句,而不能使用 ALTER(同样会阻塞)

在线添加、删除字段、扩展字段、字段改名

该表,600W+,8G,秒级完成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 新增字段
mysql> ALTER TABLE `test`.`xxxxx_tokudb` ADD COLUMN `Test` varchar(255) AFTER `Html`
Affected rows : 0, Time: 2.69sec

# 删除已存在的字段
mysql> ALTER TABLE `test`.`xxxxx_tokudb` DROP COLUMN `xxxxxEmail`;
Affected rows : 0, Time: 2.03sec
mysql> ALTER TABLE `test`.`yyyyy_tokudb` ADD COLUMN `Test` text AFTER `Updated`;
Query OK, 0 rows affected (2.74 sec)

mysql> ALTER TABLE `test`.`yyyyy_tokudb` DROP COLUMN `Test`;
Query OK, 0 rows affected (1.53 sec)

mysql> ALTER TABLE `test`.`yyyyy_tokudb` DROP COLUMN `Boss`;
Query OK, 0 rows affected (1.54 sec)

注意:

  • 扩展字段长度,只支持 char, varchar, varbinary, integer 类型,并且不能是主键与二级索引键。
  • 增加、删除、扩建字段长度,更改列名,都需要独立的单语句操作。否则会引起阻塞。(一次只进行一个操作)
  • 避免在添加、删除索引期间进行增、删、扩、更操作
  • 避免删除一个在索引中的列,这种情况需要先删除索引,再删除字段
  • 更改列名不支持以下类型:TIME, ENUM, BLOB, TINYBLOB, MEDIUMBLOB, LONGBLOB

查询测试

针对某某数据 4100W+,对 MyISAM 与 TokuDB 两种引擎,进行 SELECT * FROM 全表扫描,游标读取并获取数据

1
2
3
4
5
6
7
8
SELECT * FROM yyyyy_myisam
2016-05-30 10:15:11,538 INFO [main] (EnterpriseTokuDB.java:103) - Memory:max/total/free 25612/25612/24589
2016-05-30 10:22:10,629 INFO [main] (EnterpriseTokuDB.java:105) - loop 41000000 : 4329 ms

SELECT * FROM yyyyy_tokudb
2016-05-30 10:23:12,410 INFO [main] (EnterpriseTokuDB.java:103) - Memory:max/total/free 25612/25612/24589
2016-05-30 10:30:07,614 INFO [main] (EnterpriseTokuDB.java:105) - loop 41000000 : 4359 ms
两者均耗时共 7分 左右

TokuDB获取数据时候需要解压缩,所以响应时间增多,但由于数据只有MyISAM的1/3,降低了IO。整体读响应时间相差无几。

导入导出

尽量使用 LOAD DATA,比 mysqldump 要快,并且可以用 show processlist 看到进度

使用问题

SELECT COUNT(*) 和 InnoDB 相同,需要全表扫描。
AUTO_INCREMENT 不能通过 ALT 语句回退,比如你插入了10000 ID,AUTO_INCREMENT变为10001,这时候你删除 ID=10000 记录,想将AUTO_INCRMENT 重设为10001,这不支持。

参考文档

TokuDB简介:http://mysql.taobao.org/monthly/2015/04/02/

TokuDB数据文件大小计算:http://mysql.taobao.org/monthly/2015/06/10/

TokuDB索引结构–Fractal Tree:http://mysql.taobao.org/monthly/2016/04/09/

TokuDB 使用简单说明:http://highdb.com/tokudb-%E7%89%B9%E6%80%A7%E6%A6%82%E8%A7%88/

mysql从innodb到tokudb引擎时遇到的问题:http://xiaorui.cc/2016/02/02/mysql%E4%BB%8Einnodb%E5%88%B0tokudb%E5%BC%95%E6%93%8E%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/

TokuDB的索引结构–分形树的实现:http://www.bitstech.net/?s=tokudb