答案是主从复制中SQL线程在从库执行DDL或引用临时表时,因tmp_table_size与max_heap_table_size不等或ibtmp1空间耗尽,导致临时表被迫落盘并报“The table is full”或“Incorrect key file”错误。
主从复制本身不直接生成临时文件,但复制过程中的DDL操作、SQL线程执行、临时表同步等行为会触发临时空间暴涨——问题通常出在从库,且常被误判为“主库写多”,实际是SQL线程在从库本地执行时撑爆ibtmp1或/tmp。
这是最直接的信号。一旦show slave statusG中出现:
Last_SQL_Errno: 1034 + Last_SQL_Error: Error 'Incorrect key file for table ...' → 基本锁定为临时表落盘失败Last_SQL_Error里带The table is full → 不一定是磁盘满,更可能是内存临时表阈值被卡死,被迫写入磁盘临时空间SQL线程(即Slave_SQL_Running: No),和IO线程无关临时文件溢出不是偶发事件,而是持续性压力积累。用状态变量确认趋势:
SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables';,记录每秒增量;若稳定 >50次/秒,说明大量查询被迫落盘Created_tmp_tables,算比值:Created_tmp_disk_tables / Created_tmp_tables > 0.1即属异常ALTER TABLE、CREATE TABLE ... SELECT或大批次INSERT ... SELECT同步发生?这类DDL/DML在从库回放时会重建临时结构别只看df -h根分区——MySQL可能把临时文件写到了意想不到的地方:
SELECT @@tmpdir;,常见值有/tmp、/var/tmp、/data/mysql/tmp,对应挂载点要单独df -h
SELECT @@innodb_temp_data_file_path;,默认是ibtmp1:12M:autoextend,它会无限增长直到磁盘满lsof +D /path/to/tmpdir确认是不是mysqld进程在往里面狂写(注意:重启前ibtmp1不会缩容,即使删了临时表)盲目调参可能让问题更隐蔽:
STOP SLAVE SQL_THREAD;,避免新临时表持续生成DROP TEMPORARY TABLE IF EXISTS(如有显式创建)、KILL掉长时间Creating sort index或Copying to tmp table状态的连接SELECT @@tmp_table_size, @@max_heap_table_size; —— 两个值单位是字节,必须完全一致;若不等,MySQL永远按小的那个截断tmp_table_size = 268435456和max_heap_table_size = 268435456(即256MB),不能只改一个真正棘手的点在于:DDL操作(比如ADD COLUMN)在从库回放时,即使主库没报错,从库也可能因ibtmp1已占上百GB而无法分配新段——此时RESET SLAVE无用,STOP SLAVE也救不了,唯一解是重启MySQL释放ibtmp1。但重启前得确保没有长事务卡住binlog位置,否则主从数据会断层。