MyISAM表默认4GB限制源于4字节行指针(2³²行),非存储引擎硬上限;突破需同时满足:操作系统支持大文件、MySQL启用LFS、建表时显式指定足够大的MAX_ROWS(如10⁹)以触发指针升级,AVG_ROW_LENGTH仅影响行密度估算。
MySQL启动时创建的MyISAM表,默认用4字节行指针(myisam_data_pointer_size=4),对应理论最大行数 2³² ≈ 42.9亿,按平均行长算下来刚好卡在约4GB。这不是存储引擎本身的封顶值,而是默认配置+常见文件系统限制共同导致的“感知上限”。实际能否突破,取决于三个条件:操作系统是否支持大文件、MySQL版本是否启用LFS、建表时是否显式指定MAX_ROWS和AVG_ROW_LENGTH。
MAX_ROWS,不能只调AVG_ROW_LENGTH
AVG_ROW_LENGTH本身不改变容量上限,它只影响MySQL估算行密度时的初始值;真正决定文件能写多大的,是MAX_ROWS——它会反向推导出所需指针长度,并覆盖myisam_data_pointer_size配置。例如:
CREATE TABLE t (id INT, data TEXT) ENGINE=MyISAM MAX_ROWS=1000000000 AVG_ROW_LENGTH=200;
这个语句会让MySQL自动选用6字节指针(支持2⁴⁸行),从而将单表理论上限推到256TB。注意:MAX_ROWS必须设为具体整数,设成0或留空等于没设。
ALTER TABLE t MAX_ROWS=1000000000 AVG_ROW_LENGTH=200;在线修改(不锁表,但会触发REPAIR TABLE式重建)SHOW TABLE STATUS LIKE 't';,检查Max_data_length字段是否已更新Max_data_length仍是4294967295(即2³²−1),说明MAX_ROWS未生效——常见原因是数值太小,没触发指针升级即使MySQL允许256TB,你的ext4分区若挂载时用了-O ^large_file,或者跑在32位内核+老glibc上,open()系统调用仍可能返回EFBIG错误。关键检查项:
getconf FILESIZEBITS /,输出≥64才表示内核支持大文件df -T .,ext4/xfs/btrfs通常支持≥16TB,fat32/ntfs需额外验证Got error 24 from storage engine或write failed on MyISAM file,大概率是OS层拒绝写入超限文件Linux 2.4+、x86_64、ext4默认支持单文件≥16TB;Windows下必须用NTFS,且要禁用“压缩”和“加密”属性——这两项会让MySQL写入失败。
key_buffer_size和表大小无关,别混淆有人以为把key_buffer_size设大就能撑住大MyISAM表,这是典型误解。key_buffer_size只缓存.MYI索引块,不影响.MYD数据文件的物理尺寸。哪怕你把key_buffer_size设到32G,一个200GB的MyISAM表照样能建出来——只是查询慢、缓存命中率低而已。真正制约表大小的,永远是MAX_ROWS推导出的指针长度,以及OS对单个文件的写入权限。
容易被忽略的是:MyISAM表一旦含大量TEXT/BLOB字段,其INDEX_LENGTH在information_schema里统计准确,但Data_length可能严重低估真实磁盘占用——因为外部存储的BLOB不计入该字段。查真实大小请用du -sh *.MYD。