mysql从innodb到tokudb引擎时遇到的问题

     收到微信报警说是数据库ssd盘快满了,空间还有100G了…  对于原本3.8T磁盘现在只剩下100G,麻烦事。 现在相关业务的数据库里面有几个表都已经达到800G+了, 这可不是个好现象,所以我考虑把这些innodb的大表全部改成Tokudb的引擎,这样就可以省下不少的空间。  

    业务的架构原本是计划去除Mysql ,重心转移到Elasticsearch上。 但这Elasticsearch经常因为产品的变更把数据都清理掉,重新导入….  这也太不靠谱了。  我们这曾经依赖的Hbase也渐渐被我们放弃了。 


文章写的不是很严谨,欢迎来喷,另外该文后续有更新的,请到原文地址查看更新。

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/


这次的操作环境:

系统: centos 6.7

数据库: percona mysql server

对于TokuDB的压缩算法的选择,我们选择了压缩比率最大的lzma算法.

tokudb_zlib:表启用zlib压缩,压缩效果偏中,CPU消耗偏中,这是默认的选项

tokudb_quicklz:表启用quicklz压缩,压缩效果差,CPU消耗低下,这个不怎么推荐使用,使用tokudb不就是为了压缩; 

tokudb_lzma:表启用lzma压缩,压缩效果好,CPU消耗高,强烈推荐大家用这个,毕竟花费了少量的时间和多数的cpu计算罢了。

我们的Mysql架构是标准的主从方式,然后用keepalived做主从的切换. 

第一个问题是提示空间不够,原本以为innodb 1T的表,转成tokudb只需要300G左右,所以我们只是预留了400G左右,结果就变成下面的情况了. 

mysql> alter table buzz_master.article_content engine=TokuDB, row_format=TOKUDB_LZMA;
ERROR 1030 (HY000): Got error 28 from storage engine

这是mysql的错误日志,我们通过日志可以明确看到是空间不够引起的.

#blog: xiaorui.cc

2016-01-31 09:21:33 17400 [Warning] Disk is full writing './mysqld-relay-bin.020155' (Errcode: 28 - No space left on device). Waiting for someone to free space...
2016-01-31 09:21:33 17400 [Warning] Retry in 60 secs. Message reprinted in 600 secs
2016-01-31 09:22:33 17400 [Warning] Disk is full writing './mysqld-relay-bin.020155' (Errcode: 28 - No space left on device). Waiting for someone to free space...
2016-01-31 09:22:33 17400 [Warning] Retry in 60 secs. Message reprinted in 600 secs
Sun Jan 31 09:22:58 2016 PerconaFT No space when writing 1211 bytes to fd=20 retry in 1 second
Sun Jan 31 09:23:58 2016 PerconaFT No space when writing 1211 bytes to fd=20 retry in 1 second
Sun Jan 31 09:24:58 2016 PerconaFT No space when writing 1211 bytes to fd=20 retry in 1 second
Sun Jan 31 09:25:58 2016 PerconaFT No space when writing 1211 bytes to fd=20 retry in 1 second
Sun Jan 31 09:26:58 2016 PerconaFT No space when writing 1211 bytes to fd=20 retry in 1 second
2016-01-31 09:27:33 17400 [ERROR] Error reading packet from server: Lost connection to MySQL server during query ( server_errno=2013)
2016-01-31 09:27:33 17400 [Note] Slave I/O thread: Failed reading log event, reconnecting to retry, log 'mysql-bin.010699' at position 115194564
2016-01-31 09:27:33 17400 [Warning] Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
2016-01-31 13:17:36 17400 [Note] /usr/sbin/mysqld: Normal shutdown

google了些文档,说是 ERROR 1030 (HY000): Got error 28 from storage engine 这类的问题是临时空间引起的,最后通过实际配置,发现这跟临时空间不是一回事。  alter修改表引擎,或者是增改字段都是在datadir目录进行的。 所以还是想法设法加大datadir数据空间。

这是我自己的mysql空间不足的解决方案:

  1. 加入skip-slave-start参数暂停同步.
  2. 停止/etc/init.d/mysql stop
  3. 把一个大的库mv出去然后必须软连接回来,不然mysql启动的时候回出错。 
  4. 这样我们就空出了datadir的空间,启动mysql,进行alter table 修改表引擎。
  5. 可以根据情况把这些步骤反推下。

话说percona tokudb引擎的压缩效果还是很好的,一般1000G的数据可以压缩到200G,当然这也牺牲了不少cpu消耗.

第二个问题是alter修改tokudb表引擎失败后产生了大文件, 这是个很坑爹的事。  

你能确定下面以tokudb为后缀的文件哪些是成功的,哪些是失败的?   通过这些文件名我只能确定所属数据库,但确定不了他所属那个表。
我后来是根据改动时间确认哪个是失败的文件.  

以前都是使用pt-online-change来alter操作表有时也会失败,但他的失败的表在show tables时轻易看到,不怪我这么整tokudb.

#blog: xiaorui.cc
#alter table buzz_master.article_content engine=TokuDB, row_format=TOKUDB_LZMA;

drwx------ 2 mysql mysql  4.0K Feb  2 12:06 buzz_master
-rw-rw---- 1 mysql mysql  891G Feb  2 15:17 _buzz_master_sql_43f8_a09_key_idx_content_md5_1d5dd74_1_1d_B_3.tokudb
-rw-rw---- 1 mysql mysql  980M Feb  2 12:07 _buzz_master_sql_43f8_a09_key_idx_created_on_1d5dd74_1_1d_B_2.tokudb
-rw-rw---- 1 mysql mysql   50G Feb  2 14:38 _buzz_master_sql_43f8_a09_key_url_md5_1d5dd74_1_1d_B_1.tokudb
-rw-rw---- 1 mysql mysql   359G Feb  2 15:26 _buzz_master_sql_43f8_a09_main_1d5dd74_1_1d_B_0.tokudb
-rw-rw---- 1 mysql mysql   64K Feb  2 13:11 _buzz_master_sql_43f8_a09_status_1d5dd71_1_1d.tokudb
-rw-rw---- 1 mysql mysql   32K Feb  2 12:06 _buzz_master_sql_4741_c_main_3040e7f_2_1d.tokudb
-rw-rw---- 1 mysql mysql  60.5G Feb  2 15:26 _buzz_master_sql_4741_c_main_3040e81_1_1d_B_0.tokudb
-rw-rw---- 1 mysql mysql   16K Feb  2 12:06 _buzz_master_sql_4741_c_status_3040e7f_1_1d.tokudb
-rw-rw---- 1 mysql mysql  69.8G Feb  2 15:16 _buzz_master_sql_a66b_d_key_article_id_25a4e6b_1_1d_B_1.tokudb
-rw-rw---- 1 mysql mysql   730G Feb  2 15:26 _buzz_master_sql_a66b_d_key_keyword_pub_date_25a4e6b_1_1d_B_2.tokudb
-rw-rw---- 1 mysql mysql  501G Feb  2 15:26 _buzz_master_sql_a66b_d_main_25a4e6b_1_1d_B_0.tokudb
-rw-rw---- 1 mysql mysql   64K Feb  2 12:06 _buzz_master_sql_a66b_d_status_25a4e68_1_1d.tokudb

第三个问题, 从innodb转到tokudb的消耗时间…  我这边的为了后期优化性能,mysql直接都上ssd,结果一个1000T的表从innodb到tokudb,一共花费了20个小时…    16个核心的cpu,跑满了10个… 


alter table xxx engine=TokuDb其实是分两个步骤的

第一步是做数据整理,会把innodb里的数据fetch出来放到一个tokudbxxx文件里

Fetched about 193000 rows ,loading data ....


| 12 | root        | localhost | NULL        | Query   |    7 | Fetched about 193000 rows, loading data still remains
                     | alter table buzz_master.article_content engine=TokuDB, row_format=TOKUDB_LZMA |         0 |

第二步是把tokudbxxx临时文件加载并加索引啥的. 

Loading of data about 0.0% done



|  1 | system user |           | buzz_master | Connect | 11628 | Waiting for table metadata lock  | insert into article
_content values(468955254, 'xœ=O[N݀I)ûOPŠPŒ”j ––51ˆ)W†;÷œ–„                           |         0 |             0 |
|  2 | system user |           | NULL        | Connect | 15020 | Waiting for master to send event | NULL
                                                                                  |         0 |             0 |
| 12 | root        | localhost | NULL        | Query   | 11637 | Loading of data about 0.0% done  | alter table buzz_ma
ster.article_content engine=TokuDB, row_format=TOKUDB_LZMA                        |         0 |             0 |

Tokudb对于那种写多读少的业务还是很适合的,至于性能? 我们这没啥感觉,通过metric监控数值对比没什么明显差异.     我现在对于Tokudb唯一的焦虑就是备份, 不能热备份呀.  搜狐那边的tokudb使用的是lvm磁盘快照。 

END….


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

1 Response

发表评论

邮箱地址不会被公开。 必填项已用*标注