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

这里也备注一下修改方式 (若能接受重启MySQL,那么可以这样做)
#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即可生效。【推荐】
nnodb_tmpdir : 此选项在 MySQL 5.7.11 中引入,以帮助避免由于大型临时排序文件而可能发生的临时目录溢出设置方式:
下面是操作(踩坑)示例:
“`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即可生效。
3. 解决了上面的问题后,再执行DDL, 就会发现能执行成功了
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。