最近撞大运了,每天都能遇到几个有趣的问题。
晚饭之后简单记录一下。

现象:有个项目调用接口连接超时,排查了一圈,发现往数据库插入数据时卡住了,程序没有做任何响应。最终的原因是服务器中存放mysql数据所在的磁盘分区被占满了,罪魁祸首是一个名为ibtmp1的文件(将近352G)。
ibtmp1这玩楞是个啥?
查看官方文档后发现这是非压缩的innodb临时表的独立表空间。通过innodb_temp_data_file_path
参数指定文件的路径,文件名和大小,默认配置为ibtmp1:12M:autoextend
,也就是说在支持大文件的系统这个文件大小是可以无限增长的。
ibtmp1增长的原因:
btmp1增长主要与SQL有关,尤其是大量的分组聚合,排序,join查询SQL,通常如下情况会造成iptmp1上涨:
- 查询语句会先查询temp_table_size(内存分配)的量,当临时存储的量超过这个参数限制时,就会在iptmp1中申请占用空间
- select order group by GROUP BY 无索引字段或group by + order by 的子句字段不一样时。
- select (select) 子查询
- insert into select ... from ... 表数据复制
- select union select 联合语句
想来想去这些个原因,我好想都没涉及到,也没再次复现,先记录一下,留院观察吧。
解决办法:
- 限制ibtmp1文件大小,修改my.cnf配置:
innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:5G
- 优化SQL,避免使用临时表
- 启mysql实例释放ibtmp1文件(重启mysql之后 ibtmp1会释放,恢复到默认的12M,可惜回恢复之后没能复现)
网友评论