MySQL为什么会产生这么多临时MYD文件?


9

在托管许多PHP / MySQL网站(照相馆)的Debian Linux服务器上,有时我有“许多”文件,例如/tmp/#sql_6405_58.MYD

例如今天:

[2012-12-15 15:18:11] /tmp/#sql_6405_6.MYD : 88MB
[2012-12-15 15:18:11] /tmp/#sql_6405_3.MYD : 22MB
[2012-12-15 15:18:11] /tmp/#sql_6405_4.MYD : 138MB
[2012-12-15 15:18:11] /tmp/#sql_6405_10.MYD : 88MB
...
[2012-12-15 15:18:11] /tmp/#sql_6405_9.MYD : 15MB
[2012-12-15 15:18:11] /tmp/#sql_6405_65.MYD : 49MB
[2012-12-15 15:18:11] /tmp/#sql_6405_44.MYD : 69MB

(同时59个文件,超过6GB ...是的,我监视/ tmp中的大文件)

不幸的是,/tmp它位于同一个分区,/并且临时中断了Web服务器,因为/我想它已满。然后文件消失,服务器恢复正常。

所有文件名都遵循该#sql_6405_*.MYD模式。我想了解哪个MySQL操作意味着这么多的临时文件。我在此服务器上大约有2000个数据库。是否可以知道与哪个数据库有关?


1
我猜想它们是使用的大型操作的临时数据filesort,而6405是mysql的PID,用于将来自不同服务器实例的临时文件分开。

我应该让管理员提出我的问题吗?

Answers:


14

有一些选项可能导致临时表变为MyISAM表,或者可以将其配置为延迟它。请记住,对于基于磁盘的临时表,没有.frm文件,只有文件.MYD.MYI文件(当然,从不使用.MYI文件,因为它不可能索引内部临时表)。

以下是选项:

您还应该考虑有关内部临时表用法MySQL文档

制作内存临时表的情况是

  • 如果有一个ORDER BY子句和另一个GROUP BY子句,或者ORDER BY或GROUP BY包含联接队列中第一个表以外的表中的列,则会创建一个临时表。
  • DISTINCT与ORDER BY结合使用可能需要一个临时表。
  • 如果使用SQL_SMALL_RESULT选项,则MySQL使用内存中临时表,除非查询还包含需要磁盘存储的元素(稍后描述)。

当内存中的临时表超过了最小值(tmp_table_size或max_heap_table_size)时,mysqld将执行以下操作:

  • 暂停查询
  • 将内存表的内容复制到MyISAM临时表中
  • 丢弃内存表
  • 继续查询,将临时数据发送到MyISAM临时表中

绕过内存中的临时表而使用磁盘的情况是

  • 表中是否存在BLOB或TEXT列
  • GROUP BY或DISTINCT子句中存在任何大于512个字节的列
  • 如果使用UNION或UNION ALL,则SELECT列表中存在大于512字节的任何列

需要进行一些尽职调查以减少磁盘上的临时表创建

  • 设置join_buffer_size更大
  • 设置更大的sort_buffer_size
  • 将tmp_table_size和max_heap_table_size设置得更大
  • 调整查询以最小化甚至防止临时表
  • 创建索引以创建单个表中数据的预排序视图
  • 安装额外的RAM以容纳大型内存临时表

如果经过这样的尽职调查,仍然在磁盘上形成了临时表,这是一个绝望的举动:将基于磁盘的临时表创建映射到内存。

这是使用tmpdir设置16GB RAM磁盘的快捷方法

STEP01)创建RAM磁盘文件夹

mkdir /var/mysql_tmpfs

STEP02)添加到 my.cnf

[mysqld]
tmpdir=/var/mysql_tmpfs

STEP03)将此添加到/ etc / fstab

echo "none /var/mysql_tmpfs tmpfs defaults,size=16g 1 2" >> /etc/fstab

STEP04)重新加载/ etc / fstab

mount -a

步骤05) service mysql restart

此后,所有成为MyISAM的临时表都将写入RAM磁盘。这样可以加快基于磁盘的临时表的创建。

试试看 !!!


1

这些查询将滚动到磁盘上,因为结果对于内存而言太大。

查询完成后,空格将清除。

无法将这些临时文件明确地与查询进行匹配,但是您可以从SHOW FULL PROCESSLIST中获得一些线索,以作好猜测。或显示INNODB状态;或通过查询错误日志查看查询是否失败。


1

每当我们在表上使用alter语句时,它都会创建#sql_6405_3.MYD临时文件,一旦完成,将抛出输出并消失。

在表上进行更改使MySQL将整个数据复制到临时文件#sql.xxx.MYD中,并对创建的临时文件进行更改,然后删除原始数据文件tablename.MYD并将temporay文件重命名为表名。

此外,对于某种排序查询,它还会创建临时文件。

正如我所追踪的。这件事发生了。


0

我认为您可能会在慢查询日志中找到有问题的查询,因为创建大型临时表的查询通常会运行很长时间,因此这在今天我发现/tmp分区已满的服务器上对我有帮助,这是因为类似一个很大的MySQL临时文件,它是4G文件,我在慢速查询日志中找到了该查询,并向开发人员报告了该查询,他们在查询中发现了损坏,并将对其进行修复,这似乎限制了MySQL指令的执行,因此它得以运行很长一段时间,写了一个4G临时文件并填写了/tmp分区。

还有另一种方法可以找到导致这个大的temp文件的原因,它是二进制文件,因此您无法直接读取它,但是我发现可以使用类似Linux的字符串命令在其中包含文本,

strings name-of-mysql-temp-file

我从文字中确定运行了什么MySQL查询并创建了它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.