使用tmpfs文件系统做MySQL tmpdir潜在的问题

2014-11-24 18:09:02 · 作者: · 浏览: 0

当时的机器环境信息:


bug信息(MySQL-5.5.30社区版):


条件1:innodb,因为只有innodb才支持AIO特性,因此这是条件之一。条件2:temporary table。因为我们仅仅在tmpdir上使用到了临时表所以必须得有使用到tmpdir的地方,那就是临时表了。那么你认为你们线上会创建innodb类型的临时表吗?至少我没找到理由要这么做。临时表分两种,显式和隐式,create temporary这是显式临时表,绝大部分都会创建为memory类型;MySQL内部运行过程中创建的临时表叫隐式临时表,比如一个SQL查询,比如表结构变更、比如load data infile。而默认的情况下隐式临时表都是memory类型,当超出参数设定值后就会自动转换为myisam类型,所以也用不到innodb。


所以我说一般这个bug不会出现,从某种角度来说这个bug没修复也是件好事,因为修复之后如果要继续使用tmpfs做为tmpdir,而一旦tmpfs不支持AIO,那么innodb_use_native_aio会被关闭,但AIO对于IO密集型应用来说性能有一定的提升,具体数据应该是tps提升15%左右,当然这与底层存储设备、IO线程数都有关系,所以这个数值并不会一定准确,但是可以肯定的是性能不会下降。


但即使这个bug永远不会触发,使用tmpfs做tmpdir还是会存在一些问题的,前面说了DDL、load data infile会使用tmpdir,而这些操作需要的临时表空间是很大的,如果使用tmpfs很有可能瞬间对内存的冲击很大,导致系统抖动、swap大量使用等等从而造成性能影响。所以建议线上还是不要使用tmpfs较好。


最后再介绍一个跟tmpfs相关的bug,也是在这次测试时发现的,当然就显得更加不重要了。前面测试tmpfs不支持AIO这个bug时用的是5.5.30版本,为了测试公司内部的5.5.12是否存在相同的问题,于是也做了同样的测试 create temporary table tmp(a int)engine=innodb ,结果error log中有如下信息:


130306 10:46:51 InnoDB: O_DIRECT is known to result in 'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662
130306 10:46:51 InnoDB: Failed to set O_DIRECT on file /dev/shm/#sql26a1_1_0.ibd: OPEN: Invalid argument, continuing anyway
130306 10:46:51 InnoDB: O_DIRECT is known to result in 'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662
130306 10:46:52 InnoDB: Operating system error number 22 in a file operation.
InnoDB: Error number 22 means 'Invalid argument'.
InnoDB: Some operating system error numbers are described at
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/operating-system-error-codes.html
InnoDB: File name /dev/shm/#sql26a1_1_0.ibd


这个bug很明显tmpfs上不支持在open的时候加O_DIRECT参数,原理是什么呢?根据个人理解,我觉得是因为tmpfs采用vm实现,就是page cache那层(参见tempfs和ramfs对比分析那篇文章里面说的tmpfs与ramfs性能比较那段),而O_DIRECT的目的就是绕过page cache这层,所以tmpfs不支持O_DIRECT自然也就是情理之中了。


之前一直认为使用tmpfs做tmpdir会加速大临时表速度,觉得如果内存充足是个不错的选择,看来还是会存在很多问题。所以很多东西还是要多测试、多思考,当然还要对底层很多原理性的东西有一定了解,这样才能更好的解决问题。