ERROR 1034 (HY000): Incorrect key file for table 'table_name'; try to repair it

222 阅读2分钟

一、背景说明

    本环境为mysql8.0归档数据库,表数据1.5亿+数据量,因需要根据某字段查询,现需要创建索引,创建索引过程中报错Incorrect key file for table 'table_name',找了很多资料发现没有靠谱的不多,大部分都是MYISAM数据恢复的处理,所以简单记录一下。

    原因:mysql大表执行字段增加、索引增加时会对原表进行复制,在副本进行修改,再删除原表,针对新表重命名。再执行表修改时,用户可以查看表,但是表的修改会出现延迟情况,所以在做大表增加索引时临时表的创建。本章问题是因为临时目录/tmp空间不足导致报错。

二、报错情况

执行报错:

mysql> create index idx_tid on oc_b_order(tid);
ERROR 1034 (HY000): Incorrect key file for table 'oc_b_order'; try to repair it

日志报错:

2022-12-06T06:30:58.698617Z 8 [Warning] [MY-012638] [InnoDB] InnoDB: Retry attempts for writing partial data failed.
2022-12-06T06:30:58.698673Z 8 [ERROR] [MY-012639] [InnoDB] InnoDB: Write to file (merge) failed at offset 2988441600, 1048576 bytes should have been written, only 196608 were written. Operating system error number 28. Check that your OS and file system support files of this size. Check also that the disk is not full or a disk quota exceeded.
2022-12-06T06:30:58.698700Z 8 [ERROR] [MY-012640] [InnoDB] InnoDB: Error number 28 means 'No space left on device'

三、分析报错

    mysql错误日志说明原因:磁盘空间不足导致的告警问题原因,同时根据我们操作为大表新增索引,需要应用到临时表,所以通过测试,在增加索引时数据库的tmpdir路径使用率暴增,同时因路径存储空间不足导致创建失败报错。

    /tmp目录系统存储空间仅剩3G。

mysql> show variables like '%tmpdir%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| innodb_tmpdir     |       |
| slave_load_tmpdir | /tmp  |
| tmpdir            | /tmp  |
+-------------------+-------+
3 rows in set (0.01 sec)s

四、问题处理

1、扩展/tmp系统物理磁盘空间;(无法扩展,因此调整数据库路径指向)

2、在空间足够的磁盘创建目录,修改属主,赋权;

# mkdir /mysql_datadir/tmp
# chown mysql:mysql /mysql_datadir/tmp
# chomd 755 /mysql_datadir/tmp

3、因为mysql的tmpdir参数只能在my.cnf中设置,所以数据库需重启

在参数文件中增加
tmpdir=/mysql_datadir/tmp

重启数据库
systemctl restart mysql

4、查看参数(修改成功)

mysql> show variables like '%tmpdir%';
+-------------------+--------------------+
| Variable_name     | Value              |
+-------------------+--------------------+
| innodb_tmpdir     |                    |
| slave_load_tmpdir | /mysql_datadir/tmp |
| tmpdir            | /mysql_datadir/tmp |
+-------------------+--------------------+
3 rows in set (0.14 sec)

五、总结

    1、本报错因临时表空间不足导致在对大表进行变更时空间不足报错;

    2、在数据库建库规划参数时需将tmpdir参数配置足够空间;