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

9 mysql myisam temporary-tables

在 Debian Linux 服务器上,托管许多 PHP/MySQL 网站(图片库),有时我有“很多”文件,例如/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
Run Code Online (Sandbox Code Playgroud)

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

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

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

Rol*_*DBA 15

有一些选项可以导致临时表具体化为 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
Run Code Online (Sandbox Code Playgroud)

STEP02) 将此添加到 my.cnf

[mysqld]
tmpdir=/var/mysql_tmpfs
Run Code Online (Sandbox Code Playgroud)

STEP03) 将此添加到 /etc/fstab

echo "none /var/mysql_tmpfs tmpfs defaults,size=16g 1 2" >> /etc/fstab
Run Code Online (Sandbox Code Playgroud)

STEP04) 重新加载 /etc/fstab

mount -a
Run Code Online (Sandbox Code Playgroud)

STEP05) service mysql restart

在此之后,所有成为 MyISAM 的临时表都被写入 RAM 磁盘。这应该会加速基于磁盘的临时表的创建。

试一试 !!!


小智 1

这些查询会滚动到磁盘上,因为结果对于内存来说太大。

查询完成后,空间将被清除。

没有办法将这些临时文件明确地与查询相匹配,但是您可以从 SHOW FULL PROCESSLIST 中获得线索来做出很好的猜测;或显示 INNODB 状态;或者如果查询失败,请查看错误日志。