几个月前写过一篇简单的关于TokuDB的文章 tokuDB存储引擎的安装、配置、使用及注意事项 这段时间撑着有点空详细的过了 一遍官方文档并结合使用做了一下总结。
偷个懒就不做仔细的排版了【csdn 为啥莫名其妙的删除了我这篇文章,能否给个解释,我重发一次你再删试试】
1,支持集聚二级索引
CREATE TABLE table (
column_a INT,
column_b INT,
column_c INT,
PRIMARY KEY index_a (column_a),
CLUSTERING KEY index_b (column_b)) ENGINE = TokuDB;
即二级索引也包含了所有列的信息
2、在线索引创建(没说在线删除)
tokudb_create_index_online : 控制索引的创建是hot还是阻塞更新的默认是online hot
但是有一个限制就是必须是create index 的方式,如果使用的是alter table 那么自动变成offline
,hot index创建会比较慢,建议多个索引创建一个一个来。
3、 在线加添加,删除,扩展和重命名列 (HCADER)
tokuDB 允许在线删除,添加和扩展列的长度(只支持char, varchar, varbinary, and integer 类型)
Temporary 表不建议使用该功能,因为Temporary通常比较小,使用普通的改表方式往往更快
他的主要原理是先修改数据字典(这个阻塞的时间非常非常的短),然后表里的数据,放在后台慢慢修改(直到下次行数据被读入内存的时候)
如果修改列名的操作,会在(停机期间)完成整个列名修改的全过程,而磁盘上列对应的数据是不需要做任何的修改。
如果想让列的添加 删除和扩展立即生效可执行 OPTIMIZE TABLE x
TokuDB v7.1.0, OPTIMIZE TABLE is also hot,
每次的添加,删除,扩展列,重命名等每一个修改都必须是单独的sql ,而不能混合到一条sql中,也就是说避免添加列的时候又扩展或删除其他列等
上述修改过程虽然都是对数据字典进行修改,但是也会短暂的持有表锁,而持有的时候则视当前表在内存中的dirty page的多少来决定,应为
mysql在修改数据字典前需要关闭表并且将表相关的所有dirty page进行刷盘。故持有锁的时间主要取决于脏页刷盘的时间
如果需要删除的列刚好被某个index 包含,那么建议先将索引删除,然后再删除列,否则删除列的过程将非常慢
在线列属性的扩展的限制:
1)、只支持 char, varchar, varbinary, and integer 这些数据类型
2)、列不能存在于任何主键或二级索引中(如果是二级索引建议先删除二级索引)
3)、每次只能修改一列,否则就不能是在线修改而是阻塞式修改如:
建议:ALTER TABLE table
CHANGE column_old column_new
DATA_TYPE REQUIRED_NESS DEFAULT
4)、不支持如下数据类型:TIME, ENUM, BLOB, TINYBLOB, MEDIUMBLOB, LONGBLOB
4 、压缩
tokudb提供了不同类型的压缩模式,不同的模式对cpu的消耗也不一样,普通压缩消耗cpu性能相对少,而高级别的压缩往往非常消耗cpu性能。
压缩比,除了取决于压缩模式外还和真实的数据有关。
tokudb的压缩主要由后台线程来完成,也就是说对数据库性能的影响不大,“一般建议6核心以内的cpu 可采用标准默认的压缩模式”,当然主要
还是的看业务需求
CREATE TABLE table (
column_a INT NOT NULL PRIMARY KEY,
column_b INT NOT NULL) ENGINE=TokuDB
ROW_FORMAT=row_format;
创建表的时候如果不指定行格式,那么tokudb默认采用zlib格式的压缩模式
关于TokuDB行格式
tokudb_row_format 可以设置如下的几个值:
tokudb_default: 设置默认的压缩行为。在 TokuDB 7.1.0版本,默认使用zlib 库进行压缩,未来版本可能会改变。
tokudb_fast: 使用quicklz 库的压缩模式。
tokudb_small: 使用 lzma 库的压缩模式。
另外用户可能会直接修改压缩库,即可能压缩模式的名字和上面不一样,那么可以用如下名字的压缩模式
tokudb_zlib: 使用 zlib 库的压缩模式,提供了中等级别的压缩比和中等级别的CPU消耗。
tokudb_quicklz: 使用 quicklz 库的压缩模式, 提供了轻量级的压缩比和较低基本的CPU消耗。
tokudb_lzma: 使用lzma库压缩模式,提供了高压缩比和高CPU消耗。
tokudb_uncompressed: 不使用压缩模式。
可以使用如下命令修改行格式:
ALTER TABLE table_name ROW_FORMAT=row_format;
注意修改行格式(该操作是online的)只是会影响新插入的数据,故建议还执行一次OPTIMIZE_TABLE table。
5、 指定tokuDB文件目录
tokudb_data_dir:
指定tokudb数据文件目录,默认情况下为mysql的数据目录
tokudb_log_dir:
指定tokudb的日志文件目录,默认情况下为mysql数据目录,配置日志目录必须是绝对路径,不过一般建议将数据文件和日志文件放在同一个目录
tokudb_tmp_dir:
指定tokudb临时文件目录 ,默认是mysql的数据目录,建议将它单独设置
6、 安装[所有的操作都在root用户下]
操作系统和内存的要求:
操作系统要求: TokuDB 只支持 64-bit Linux .
内存要求: 至少 1GB ,不过实际当中建议最少 2GB 内存
1), tokuDB安装
http://docs.tokutek.com/tokudb/tokudb-index-installation.html
http://www.tokutek.com/download.php
下载完成后进行md5校验
md5sum mysql-5.5.40-tokudb-7.5.3-linux-x86_64.tar.gz
2), 创建MySQL用户并指定用户组
groupadd mysql
useradd mysql9999 -g mysql
3), 解压
tar xvzf mysql-5.5.40-tokudb-7.5.3-linux-x86_64.tar.gz
4), 关闭当前存在的实例
mysql_stop.sh -P xxxx
cd /usr/local
mv mysql55 mysql55.bak
ln -s mysql-5.5.40-tokudb-7.5.3-linux-x86_64/ mysql55
5), 执行mysql_upgrade 更新系统表
/usr/local/mysql55/bin/mysql_upgrade -uroot -pxxoo -S /tmp/mysql9999.sock
6), 更新插件plug-ins TokuDB v7.1 版本引入3个新的和删除了2个以前存在的插件
INSTALL PLUGIN TokuDB SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_file_map SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_fractal_tree_info SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_fractal_tree_block_map SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_trx SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_locks SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_lock_waits SONAME 'ha_tokudb.so';
SET GLOBAL default_storage_engine=TokuDB;
DELETE FROM mysql.plugin WHERE NAME LIKE 'tokudb_user_data%';
如果要卸载
UNINSTALL PLUGIN tokudb ;
UNINSTALL PLUGIN tokudb_file_map ;
UNINSTALL PLUGIN tokudb_fractal_tree_info;
UNINSTALL PLUGIN tokudb_fractal_tree_block_map;
UNINSTALL PLUGIN tokudb_trx ;
UNINSTALL PLUGIN tokudb_locks;
UNINSTALL PLUGIN tokudb_lock_waits;
另外进入数据目录删除tokudb相关的文件
并且注释掉my.cnf toku相关的配置参数即可
7), 验证tokuDB是否安装成功
登陆mysql 执行
SHOW PLUGINS
| TokuDB_trx | ACTIVE | INFORMATION SCHEMA | ha_tokudb.so | GPL |
| TokuDB_locks | ACTIVE | INFORMATION SCHEMA | ha_tokudb.so | GPL |
| TokuDB_lock_waits | ACTIVE | INFORMATION SCHEMA | ha_tokudb.so | GPL |
| TokuDB | ACTIVE | STORAGE ENGINE | ha_tokudb.so | GPL |
| TokuDB_file_map | ACTIVE | INFORMATION SCHEMA | ha_tokudb.so | GPL |
| TokuDB_fractal_tree_info | ACTIVE | INFORMATION SCHEMA | ha_tokudb.so | GPL |
| TokuDB_fractal_tree_block_map | ACTIVE | INFORMATION SCHEMA | ha_tokudb.so | GPL
或执行
SHOW ENGINES
| TokuDB | DEFAULT | Tokutek TokuDB Storage Engine with Fractal Tree(tm) Technology | YES | YES | YES |
如果上述信息都ok ,那么说明安装成功
8), 配置tokuDB相关参数
tokudb_data_dir = /data1/mysql0000/tokudb_data
tokudb_tmp_dir = /data1/mysql0000/tokudb_tmp
default_storage_engine = tokuDB
tokudb_directio = 1
tokudb_cache_size = 16G
tokudb_loader_memory_size = 256M
tokudb_commit_sync = 0
7、tokuDB 变量 [不全]
1),客户端session 变量(可动态修改)
unique_checks :唯一性检查,如果表都有自增主键并且没有unique key 那么可以考虑关闭 SET unique_checks=OFF [on (default),off]
tokudb_commit_sync :该变量控制事物提交是否实时刷盘 [on(default) ,off ]
tokudb_pk_insert_mode:
该变量控制表上无二级索引或二级索引的的每一个列都属于主键的情况下 REPLACE INTO 和 INSERT IGNORE 插入主键的策略
0, 不管表上是否定于了trigger插入效率都非常高,如果复制格式使用的是row模式,那么REPLACE INTO 和 INSERT IGNORE 语句将会失败
1, (default) 如果表没有定义trigger 则插入效率非常高,如果表上有触发器则插入操作会比较慢,如果复制格式使用的是row模式,那么REPLACE INTO 和 INSERT IGNORE 语句将会失败
2, 插入非常慢,所有定于在表上的trigger都不受任何影响,row模式复制下REPLACE INTO 和 INSERT IGNORE 语句依然正常
tokudb_load_save_space:
控制批量加载的行为,当设置为off[on (default)]的时候,批量加载时tokuDB内部使用非压缩格式来存储中间转换数据(这会消耗更多cpu)
tokudb_create_index_online:
控制使用CREATE INDEX(alter talbe 都是非在线)来创建索引的时候是否是在线[on (default)]添加[off 表示非在线]
tokudb_block_size:
Fractal tree 内部和 叶子节点默认块大小为4M,该变量控制这些节点(未压缩)的大小,修改该变量只会影响之后创建表的操作,对于已经存在的表可以使用dump和loader方式来改变块大小
... ...
2),服务器端变量[不全](重启操作)
tokudb_fsync_log_period:控制fsync()执行频率(单位:毫秒) 设置为0的时候,每次事物提交进行一次fsync()调用(default:0)
tokudb_cache_size:(核心参数)单位:byte 控制tokuDB缓存大小默认是1/2物理内存,如果使用的是buffer io 那么建议使用默认值如果是 direct IO 则建议设置为80%的物理内存
tokudb_directio:控制写模式是buffer io 还是 direct io模式是off
tokudb_lock_timeout:控制事物等待锁的超时时间 单位:毫秒 默认值:4000 (4秒)
tokudb_checkpointing_period:控制两次checkpoint的时间间隔,默认 60 秒不建议修改
tokudb_cleaner_period:控制清理线程的启动间隔时间默认是1秒,0表示关闭清理线程
tokudb_rpl_unique_checks: 控制备库复制插入操作的时候是否做一致性检查默认是ON (该参数生效的前提是 read_only 必须为 1 binlog_format 为row)
tokudb_rpl_lookup_rows:控制备份复制是否检查删除和更新行日志事件
tokudb_fs_reserve_percent :控制文件系统空闲空间的百分比(默认 5,无法在线设置),建议设置为物理内存的一半(50% memory)当可用的数据空间小于文件系统容量的%5时 tokuDB将禁止插入操作
8、已知问题
innodb :tokuDB团队对mysql源码进行了一些修改,目的是为了让innodb和tokuDB更好的兼容
复制: tokuDB支持复制和binlog,但有一个限制即,因为tokuDB没有实现自增锁,故在SBR复制模式下并发插入(一个sql多个插入)的时候可能会
导致主备库自增长值不一样(RBR模式不会有问题)
未确定的问题:使用load data infile 加载数据的时候可能这样的错误:ERROR 1030 (HY000): Got error 1 from storage engine. 意思是说临时文件目录磁盘空间不足
而实际上可能磁盘空间很充足
大页内存问题:当系统开启大页内存模式时tokuDB将无法启动关闭方式是以root用户执行:echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled如果想重启后
生效,可以加入到/etc/rc.local里
两段式提交的不同:开启xa特性后如果发现deadlock 事物innodb 会主动强制kill死锁,而tokuDB不会
MySQL 5.5 和 MariaDB 5.5 对索引的多类型操作:索引的在线添加和删除必须是单个ddl语句执行一个操作,而不能单个ddl语句既add又delete
9、 tokuDB 锁视图
1), tokudb_trx : 存储了当前客户端对应的事物信息
如下语句可以查询对应的事物:
SELECT * FROM information_schema.tokudb_trx,
information_schema.processlist
WHERE trx_mysql_thread_id = id;
2),tokudb_locks: 存储事物相关的锁信息
如下语句可以查询事物对应的锁信息:
SELECT id FROM information_schema.tokudb_locks,
information_schema.processlist
WHERE locks_mysql_thread_id = id;
3), tokudb_lock_waits:存储事物之间锁等待(或锁请求冲突)的相关信息
10、 常见问题
1),tokuDB 能支持哪些事物相关的操作?
BEGIN TRANSACTION, END TRANSACTION, COMMIT, ROLLBACK, SAVEPOINT, and RELEASE SAVEPOINT 这些都支持
2),如何查看表和物理文件对应的关系?
tokudb_file_map 表存储了所有 Fractal Tree 索引及其对应的物理文件 其中internal_file_name 表示真实的文件名
示例:
SELECT * FROM information_schema.tokudb_file_map;
-----------------------------------------------------{}---{}--------+-------------------+
| dictionary_name | internal_file_name | table_schema | table_name | table_dictionary_name |
-----------------------------------------------------{}---{}--------+-------------------+
| ./test/test-key-ind_id | ./_test_test_key_ind_id_44_3_1b_P_0.tokudb | test | test | key-ind_id |
| ./test/test-main | ./_test_sql_7d29_22_main_3d_2_1b.tokudb | test | test | main |
| ./test/test-status | ./_test_sql_7d29_22_status_3d_1_1b.tokudb | test | test | status |
-----------------------------------------------------{}---{}--------+-------------------+
3), 当磁盘空间满了,会发生神马情况?
当因为执行LOAD DATA IN FILE 或 CREATE INDEX 等操作导致磁盘占满时,tokuDB会报如下错误并终止语句的执行:
ERROR 1030 (HY000): Got error 1 from storage engine
之前占用的临时目录的空间也会被释放。
其他情况,当可用数据目录空间小于 %5的磁盘空间的时候(默认%5)插入操作和事物都会被禁止,直到有足够空闲空间后恢复正常
tokudb_fs_reserve_percent 参数控制数据目录空闲空间占文件系统容量的百分比建议设置内存大小的50%
另外,tokuDB每隔5秒回对空闲空间进行一次检查,如果一旦小于tokudb_fs_reserve_percent 阈值则禁止插入,并将告警信息写入日志文件
如果因为其他应用导致磁盘完全占满tokuDB将会僵死(不会崩溃)可能还能响应部分sql语句。
如果想恢复必须释放足够的空间(两倍阈值容量)插入操作才可以恢复
4),如何备份
1,花钱买tokuDB的企业级备份工具
2,mysql官方工具 如:mysqldump
3,第三方工具:mydumper (我们打算使用的方式)
4,停机冷备
5,文件系统镜像
5), 默认隔离级别
tokuDB默认隔离级别是 repeatable-read 一共支持四种隔离级别:repeatable-read, serializable, read-uncommitted 和 read-committed
6), 最大行大小
innodb row的最大大小是64k 而tokuDB是 32MB
7), tokuDB支持外键么
tokuDB 不支持外键 即使你声明了也会被忽略
8), 删除索引是”在线“是否是在线的
不是,因为tokuDB每一个索引对应于文件系统的一个文件,因此在删除的索引文件的那段时间表会被锁定,不过不用担心,删除文件这个操作通常非常快