SecureFiles 不提供压缩或去重能力,其存储的是原始字节流;压缩需应用层预处理,去重须依赖哈希(推荐 SHA256)与唯一索引配合实现,小文件盲目压缩反而增体积。
SecureFiles 本身不提供压缩或去重能力
mysql 的 securefiles 是一种存储大对象(blob/text)的底层引擎,它比旧的 myisam 风格的 legacyfiles 更安全、更高效,但它不负责压缩,也不做内容去重。你看到的“压缩”效果,往往来自上层配置或外部工具;而“去重”必须由应用层或专用存储系统实现。
常见错误现象:SHOW VARIABLES LIKE 'innodb_file_per_table' 或 innodb_file_format 被误认为控制压缩——其实它们只影响表空间组织方式;启用 ROW_FORMAT=COMPRESSED 也仅对 InnoDB 表数据页有效,对 SecureFiles 存储的 BLOB 内容无直接作用。
-
SecureFiles存储的是原始字节流,MySQL 不解析其内容,因此无法基于内容哈希判断重复 - 若用
COMPRESSED行格式建表,BLOB字段仍以明文存入SecureFiles,压缩发生在页级,不可控且不适用于小文件场景 - 真正想压缩小文件,得在写入前用
zlib.compress()、lz4.frame.compress()等处理字节,再存为BLOB
大批量小文件该用什么存:别硬塞进 MySQL
每秒写入数百个 1–10 KiB 的文件到 SecureFiles,会迅速暴露瓶颈:事务开销高、ibdata1 膨胀快、备份恢复慢、主从延迟飙升。这不是设计目标,而是反模式。
典型使用场景:用户上传头像、日志切片、IoT 设备采集的小传感器包、CI 构建产物缓存——这些更适合对象存储或专用文件系统。
- 用
S3/MinIO+ 前端加ETag(即 MD5/SHA256)做客户端去重,服务端可配合PUT时检查If-None-Match - 本地部署选
WORM(Write Once Read Many)支持好的方案,如borgbackup或restic,它们天然带内容定义块(content-defined chunking)和全局去重 - 若必须用 MySQL,把小文件聚合成大块再存,比如按小时/用户 ID 打包成
TAR或ZIP,并单独维护索引表记录内部路径与偏移
手动实现去重的关键点:哈希不能只靠 MD5
想在数据库里自己做去重,核心是“内容相同 → ID 相同”。但只算 MD5(file_bytes) 很危险:碰撞概率低不等于零,且 MySQL 的 MD5() 函数不支持二进制输入,容易因字符集转换出错。
性能与兼容性影响明显:在 INSERT ... SELECT 中实时计算 SHA256,会使写入吞吐下降 3–5 倍;而把哈希存在单独列并建唯一索引,又要求应用层严格保证一致性。
- 务必用
SHA2(file_bytes, 256)替代MD5(),且在应用层用hashlib.sha256()计算后以hex形式传入,避免 MySQL 自动编码转换 - 哈希列类型推荐
CHAR(64)(SHA256 hex)+COLLATE ascii_bin,防止大小写或空格隐式转换 - 不要依赖
INSERT IGNORE或ON DUPLICATE KEY UPDATE做“存在则跳过”,需先SELECT查哈希,再决定 INSERT 或复用 ID——否则并发写入可能漏判
压缩小文件反而可能增大体积
小于 1 KiB 的纯文本或已压缩格式(如 .jpg、.png、.zip)再用通用算法压缩,大概率变大。这不是 bug,是熵决定的。
实测常见情况:gzip 压缩一个 200 字节的 JSON,输出常为 280+ 字节;zstd -1 在 1 KiB 以下也频繁失能。盲目开启压缩,会让磁盘占用更高、CPU 白耗。
- 加个简单判断:文件长度
< 1024且扩展名在['jpg', 'jpeg', 'png', 'gif', 'mp4', 'pdf']中,直接跳过压缩 - 若用
LZ4,注意它的最小有效单元是 64 KiB,小文件压缩率极差,不如不用 - 真正有效的做法是分层:元数据(JSON/YAML)走 GZIP,原始二进制(图片/音频)原样存,靠 CDN 或对象存储自动选择传输编码
去重和压缩都是有代价的操作,不是开关一开就变好。最易被忽略的是:你存的“小文件”是否真的需要独立寻址?很多情况下,合并 + 索引 + 客户端缓存,比追求单文件极致压缩更实在。

















