启用innodb_file_per_table是TB级单表前提,关闭时所有数据挤入不可收缩的ibdata1;需检查变量值、配置文件设置、重建大表,并匹配XFS等支持大文件的文件系统及调优buffer_pool和redo日志参数。

MySQL本身不设TB级单表的硬性上限,但默认配置和常见部署方式会让它在几十GB就出问题——关键不在“能不能”,而在“怎么不让它崩”。
确认并启用 innodb_file_per_table
这是TB级单表的前提。若关闭,所有InnoDB表数据都挤进ibdata1,一旦膨胀就无法收缩,且监控、迁移、空间回收全部失效。
- 检查当前状态:
SHOW VARIABLES LIKE 'innodb_file_per_table';,返回ON才安全 - 若为
OFF,需在my.cnf中添加:[mysqld] innodb_file_per_table = ON
,然后重启MySQL(注意:该设置只对新表生效) - 已有大表迁移到独立表空间:执行
ALTER TABLE t1 ENGINE=InnoDB;(本质是重建表,期间锁表,建议低峰操作)
避免操作系统和文件系统成为瓶颈
哪怕InnoDB支持PB级,Linux上ext4默认单文件上限是16TB,但前提是启用large_file特性且mkfs时指定了-T largefile;而XFS原生支持单文件>500TB,更稳妥。
- 查当前文件系统类型:
df -T /var/lib/mysql - 查单文件最大尺寸:
getconf FILESIZEBITS /var/lib/mysql(返回64表示支持大文件) - 不要用
FAT32或老旧ext2挂载数据目录——它们连4GB都扛不住
调大关键缓冲与日志参数
单表TB级后,innodb_buffer_pool_size太小会导致频繁刷脏、IO打满;innodb_log_file_size太小则事务提交频繁触发checkpoint,拖慢写入。
-
innodb_buffer_pool_size建议设为物理内存的50%~75%,但不低于2GB(128MB默认值完全不够) -
innodb_log_file_size总和(innodb_log_files_in_group × innodb_log_file_size)建议 ≥ 4GB,否则大事务可能报ERROR 1114 (HY000): The table is full(实际是redo log撑爆) - 修改日志大小需停库:删旧
ib_logfile*,改配置,再启服务(务必先备份!)
行格式选DYNAMIC或COMPRESSED
默认DYNAMIC已足够,但若字段含大量TEXT/BLOB,REDUNDANT或COMPACT会把前768字节存进主键页,极易撑爆16KB页结构,引发“页分裂雪崩”。
- 建表时显式指定:
CREATE TABLE t1 (id BIGINT, content LONGTEXT) ROW_FORMAT=DYNAMIC; - 已有表升级:
ALTER TABLE t1 ROW_FORMAT=DYNAMIC;(同样会锁表重建) -
COMPRESSED可省空间,但压缩/解压耗CPU,OLTP写多场景慎用
真正卡住TB级单表的,往往不是InnoDB本身,而是没关掉innodb_file_per_table、用错文件系统、或者让ibdata1吸走了所有增长空间——这些点一旦漏掉,后面调buffer、扩日志全白搭。


















