帮助中心/最新通知

质量为本、客户为根、勇于拼搏、务实创新

< 返回文章列表

【服务器相关】Mysql optimize table 时报错:Temporary file write fail的解决

发表时间:2025-06-16 03:46:00 小编:主机乐-Yutio

1. 问题描述

当我们执行 optimize table xxx ; 尝试进行碎片整理时,也可能报错 Temporary file write failure.

Tips: MySQL 8.x

这里也备注一下修改方式 (若能接受重启MySQL,那么可以这样做)


#1.查看 tmpdir
mysql> SHOW VARIABLES LIKE ‘tmpdir’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| tmpdir| /tmp|
+—————+——-+
1 row in set (0.00 sec)

#2.创建 tmpdir目录

mkdir -p /data/tmpdir
chown -R mysql:mysql /data/tmpdir
chmod a+w /data/tmpdir

#3. 修改MySQL配置,设置 tmpdir
vim /etc/my.cnf
把tmpdir设置到 /data/tmpdir
tmpdir=/data/tmpdir

# 4. 修改完成后,重启mysql服务
service mysqld restart

Tips: 官方建议可以给 tmpdir 变量配置多个目录分摊负载 。

3. 方案三: 为 online ddl 单独设置 innodb_tmpdir , 此变量允许动态设置,无需重启mysql即可生效。【推荐】

  • innodb_tmpdir : 此选项在 MySQL 5.7.11 中引入,以帮助避免由于大型临时排序文件而可能发生的临时目录溢出

设置方式:


#注意: 执行前必须确保 /mnt/mysql-innodb-temp 目录已经创建了,并且给这个目录设置权限,确保MySQL能够读写改目录
mysql> set global innodb_tmpdir= ‘/mnt/mysql-innodb-temp’
“`

下面是操作(踩坑)示例:

“`sh
# 注意: 必须先在系统上创建临时文件目录,并且确保mysql用户有权限访问这个目录
mysql> show VARIABLES like ‘innodb_tmpdir’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| innodb_tmpdir | |
+—————+——-+
1 row in set (0.09 sec)

# 1. 设置 innodb_tmpdir
mysql> set global innodb_tmpdir= ‘/mnt/mysql-innodb-temp’;
#或者执行
mysql> set @@global.innodb_tmpdir=/mnt/mysql-innodb-temp

# 如果报错 ERROR 1231 (42000): Variable ‘innodb_tmpdir’ can’t be set to the value of ‘/mnt/mysql-innodb-temp’ 则说明这个目录跟 data-dir 重复了,如果没重复则执行这个已经查看详情
# 显示最近一次警告信息
# 语法: SHOW WARNINGS [LIMIT [offset,] row_count]
mysql> SHOW WARNINGS;
+———+——+——————————————————————————————-+
| Level | Code | Message |
+———+——+——————————————————————————————-+
| Warning | 1210 | InnoDB: Path doesn’t exist. |
| Error | 1231 | Variable ‘innodb_tmpdir’ can’t be set to the value of ‘/mnt/mysql-innodb-temp’ |
+———+——+——————————————————————————————-+

# Path doesn’t exist. 说明该目录不存在, 创建目录后再执行命令,如果发现依然报错,那么也可能是因为没有文件权限
mysql>SHOW WARNINGS limit 10;
+———+——+———————————————————————————+
| Level | Code | Message |
+———+——+———————————————————————————+
| Warning | 1210 | InnoDB: Server doesn’t have permission in the given location. |
| Error | 1231 | Variable ‘innodb_tmpdir’ can’t be set to the value of ‘/mnt/mysql-innodb-temp’ |
+———+——+———————————————————————————+
2 rows in set (0.00 sec)

# 那么设置该目录的文件权限即可。
> chmod 777 /mnt/mysql-innodb-temp

# 再回到 mysql 发现执行成功了!
mysql> set @@global.innodb_tmpdir=’/mnt/mysql-innodb-temp’;
Query OK, 0 rows affected (0.00 sec)

# 检查下效果
mysql>show VARIABLES like ‘innodb_tmpdir’;
+—————+———————————–+
| Variable_name | Value |
+—————+———————————–+
| innodb_tmpdir |/mnt/mysql-innodb-temp |
+—————+———————————–+
1 row in set (0.01 sec)

小结一下 :

innodb_tmpdir , 此变量允许动态设置,无需重启mysql即可生效。

  • 有效值是 MySQL 数据目录路径(data-dir)以外的任何目录路径。
  • 设置innodb_tmpdir要求用户有file权限
  • 引入该innodb_tmpdir选项是为了帮助避免溢出位于tmpfs文件系统上的临时文件目录。ALTER TABLE由于在重建表的 联机操作期间创建的大型临时排序文件可能会发生此类溢出。
  • 主从复制模式中,建议 innodb_tmpdir在每台服务器上单独配置。

3. 解决了上面的问题后,再执行DDL, 就会发现能执行成功了


mysql> optimize local table t_word;
————————-+———-+———-+——————————————————————-+
| Table | Op | Msg_type | Msg_text|
+————————-+———-+———-+——————————————————————-+
| abc.t_word| optimize | note | Table does not support optimize, doing recreate + analyze instead |
| abc.t_word| optimize | status | OK|
+————————-+———-+———-+——————————————————————-+
2 rows in set (2 hours 29 min 54.20 sec)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。


联系我们
返回顶部