mysql如何解决大表Alter产生的磁盘空间不足_指定TmpDir路径

星浩酱_4019

星浩酱_4019

2026-05-04

215人浏览

原创

ALTER大表磁盘不足的根本原因是MySQL默认需至少2倍原表空间创建临时表;tmpdir仅对COPY算法生效,且须满足权限、文件系统等条件,而INPLACE、pt-osc、ibdata1场景下无效。

mysql如何解决大表alter产生的磁盘空间不足_指定tmpdir路径

ALTER大表时磁盘空间不足的根本原因

MySQL执行ALTER TABLE(尤其加索引、改列类型、重写行格式)时,默认会创建临时表,数据全量拷贝+排序+重建索引,这个过程需要**至少 2 倍原表大小的空闲空间**(原表 + 新表 + 日志/排序缓冲)。若/tmp或datadir所在分区已满,操作直接失败并报错:ERROR 1034 (HY000): Sort aborted: Server has gone away 或更常见的 ERROR 1038 (HY000): Out of sort memory(实际是磁盘而非内存)。

如何让ALTER走指定磁盘路径(TmpDir)

关键不是改tmpdir变量就能生效——InnoDB在ALTER TABLE ... ALGORITHM=INPLACE不适用时(如加全文索引、改CHAR长度),强制走COPY算法,此时它**只认tmpdir,且要求该路径有足够空间 + MySQL进程有读写权限 + 文件系统支持大文件**。

  • 确认当前tmpdir:
    SELECT @@tmpdir;
  • 修改配置(需重启或动态设置):
    SET GLOBAL tmpdir = '/data/mysql_tmp';
    (注意:仅对新连接生效;若要持久化,写入my.cnf的[mysqld]段并重启)
  • 路径必须由MySQL用户(如mysql)拥有:
    chown mysql:mysql /data/mysql_tmp && chmod 750 /data/mysql_tmp
  • 验证是否生效:执行SHOW VARIABLES LIKE 'tmpdir';,再跑一个ALTER TABLE t1 ADD INDEX idx_x(x);观察/data/mysql_tmp下是否出现#sql-*.ibd或#sql-*.MYD临时文件

tmpdir不是万能解药:这些情况它根本不起作用

tmpdir只影响临时表和排序文件的存放位置,但以下场景它完全无效:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • InnoDB在线DDL(ALGORITHM=INPLACE)本身不建临时表,不走tmpdir,但会锁表或阻塞DML,且仍需redo log和undo空间 —— 这部分空间在innodb_log_group_home_dir和datadir里,无法通过tmpdir转移
  • 使用pt-online-schema-change或gh-ost时,它们自己管理临时表路径(如--chunk-index或--database指定库),与MySQL的tmpdir无关
  • 如果原表在innodb_file_per_table=OFF模式下,所有表数据都挤在ibdata1里,ALTER即使成功,也无法释放旧空间 —— 此时tmpdir再大也救不了磁盘持续膨胀

比改tmpdir更可靠的三件事

临时换路径只是治标。真正压倒性的问题往往出在设计和运维层面:

  • 提前清理:OPTIMIZE TABLE前先DELETE无用历史数据,并ANALYZE TABLE更新统计信息,减小ALTER实际处理量
  • 分批操作:对超大表,用pt-online-schema-change --chunk-size=1000 --max-load="Threads_running=20"控制资源消耗,避免单次占满磁盘
  • 检查innodb_sort_buffer_size(默认1M):太小会导致频繁磁盘排序;太大又吃内存。对大表ALTER,可临时调到4–8M(需评估内存余量)

真正容易被忽略的是:tmpdir路径不能是NFS或某些网络文件系统,MySQL对它的原子写和fsync行为不兼容,可能导致ALTER中途崩溃且无法回滚。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2353

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1439

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

855

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

3312

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

5648

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

1239

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

5931

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

5142

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

6894

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 191人学习