MySQL 临时表位置

问题描述

我在运行查询时收到此错误:

[ERROR] [MY-013132] [Server] The table '/tmp/#sql1127b_9_0' is full!

我进入了 /tmp 目录,但我看不到该表,我假设它在查询运行完成后被删除了。

所以我在查询运行时进入目录(查询需要几分钟才能运行 - 针对 4000 万条记录)。我没有看到桌子。我刷新了目录,还是没看到。我怎么能看到呢?我想查看它并确定它的位置,以便在我有大量可用磁盘空间时弄清楚为什么它会被填满。

我使用的是 MySQL 8.0.23 - 我之前在具有相同数据库和相同查询的同一台机器上使用 MySQL 5.7.33,从来没有遇到过问题。

这是我的磁盘空间:

Filesystem      Size  Used Avail Use% Mounted on
tmpfs           3.2G  3.7M  3.2G   1% /run
/dev/sdc3       215G   38G  167G  19% /
tmpfs            16G     0   16G   0% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/sdb6       107G   81G   21G  80% /media/Kingston_SSD_120GB
/dev/sda        459G  335G  101G  77% /media/Hitachi
/dev/sdc2        33M  7.8M   25M  24% /boot/efi
tmpfs           3.2G  120K  3.2G   1% /run/user/1001

我没有为 /tmp 设置任何磁盘空间 - 可以看出,我在 / 上有 167GB 的可用空间。

解决方法

MySQL 使用了一个一直是 POSIX 系统一部分的技巧。它打开临时文件,并立即取消链接。因此在任何目录列表中都看不到它。但是像 UNIX 和 Linux 这样的 POSIX 系统实际上不应该在进程有一个打开的文件句柄时删除一个未链接的文件。因此,一旦使用临时表的查询完成,它将关闭文件句柄,然后操作系统将自动删除该文件并释放它正在使用的存储空间。

这通常比要求服务器代码记住在完成临时文件后删除它要好。它还解释了线程终止或 mysqld 崩溃之类的问题。至少它不会在你的文件系统中留下陈旧的临时文件。

您可以使用 lsof -s 查看未链接文件的大小。我将留给您查找如何使用该命令的示例(Google 是您的朋友)。

临时文件很可能会占用您 167GB 的可用空间。

或者可能是临时文件只使用了 8GB,但您可能有 20 个线程同时执行相同的查询。我见过这种情况发生过一次。

但更有可能的是,您的值 tmp_table_size 限制了临时表的大小。

如果达到限制,您可以提高该配置选项,在需要时作为会话变量,或在 my.cnf 中全局设置。

但我会首先尝试优化查询。为什么需要创建这么大的临时表?是否可以优化以检查更少的行,或者完全避免创建临时表?

,

来自官方文档:

在 Unix 上,MySQL 使用 TMPDIR 环境变量的值作为存储临时文件的目录的路径名。如果未设置 TMPDIR,MySQL 将使用系统默认值,通常为 /tmp、/var/tmp 或 /usr/tmp。

所以如果你没有配置 TMPDIR,那么你的文件需要在 /tmp,/var/tmp,or /usr/tmp

如果您立即(在一两秒内)收到此错误,我怀疑这是权限问题。但除此之外,看起来临时表真的填满了磁盘。

编辑:尝试在执行查询时查找文件。因为 SQL 错误后文件正在被删除

这个帖子也可以帮到你

How can I limit the size of temporary tables?

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...