mysql查看数据库大小(MySQL压缩表,也能不物理扩容解决数据库磁盘爆满问题。)

mysql查看数据库大小(MySQL压缩表,也能不物理扩容解决数据库磁盘爆满问题。)
MySQL压缩表,也能不物理扩容解决数据库磁盘爆满问题。

MySQL压缩表就是通过调整KEY_BLOCK_SIZE大小(可选1、2、、4/8/16)压缩表或特定算法(如zlib、lz4、zstd)压缩页,对表中的数据和索引进行无损压缩,减少磁盘存储占用的一种表优化方式。

做后端开发、DBA的同学,大概率都遇到过这样的困境:数据库磁盘告急,日志表、历史归档表越存越大,扩容成本高不说,还拖慢IO性能;备份耗时越来越久,甚至影响业务正常运行。

其实不用急着扩容,MySQL自带的压缩表功能,就能轻松解决这个问题,并且以CPU小幅开销,换磁盘空间大幅节省,最高能省70%,还能间接提升IO效率。

一、先搞懂:MySQL压缩表到底是什么

简单说,MySQL压缩表就是通过调整KEY_BLOCK_SIZE大小(可选1、2、、4/8/16)压缩表或特定算法(如zlib、lz4、zstd)压缩页,对表中的数据和索引进行无损压缩,减少磁盘存储占用的一种表优化方式。

核心原理很简单:数据库中的数据(尤其是文本、JSON、日志类数据)存在大量重复序列,压缩算法会找到这些重复序列并进行编码,存储时只保留一份编码信息,读取时再解码还原,全程不丢失任何数据。

1. 主要特点

MySQL的表进行压缩具备如下主要特点:

  • 无损压缩:压缩和解压过程完全可逆,不会导致数据丢失,这是数据库压缩的核心要求,也是和普通文件压缩的关键区别。
  • 压缩方式:MySQL支持表压缩(ROW_FORMAT=COMPRESSED)和页压缩(COMPRESSION参数),前者兼容旧版本,后者是MySQL8.0.20+新增,更轻量化、不锁表。
  • 核心特点:以CPU开销换磁盘空间——压缩/解压时会消耗少量CPU资源,适合读多写少的场景,不适合高并发写入的表(如实时交易表)。

2. 适合压缩的表

不是所有表都适合压缩,如果出现数据库服务器磁盘空间不足且不宜扩容的情况下,优先压缩这些表:

  • 历史归档表、日志表(如操作日志、接口日志):数据写入后几乎不修改,读多写少,压缩收益最高。
  • 大表(百万级+数据):包含大量TEXT、VARCHAR、JSON字段,重复数据多,压缩率可达40%-70%。
  • 备份表、只读表:无需频繁写入,压缩后可大幅减少备份体积和存储成本。

3. 不适合压缩的表

有些表强行压缩,会导致性能下降,甚至影响后续的写入(新增数据或加索引等会报错),例如下列这些表:

  • 高并发写入表(如订单表、用户行为表):频繁写入会反复压缩/解压,CPU负载飙升,写入延迟增加。
  • 小表(万级以下数据):压缩收益甚微,反而浪费CPU资源。
  • 包含大量BLOB、大二进制字段的表:这类数据压缩效果差,还会增加CPU负担。

如果处理不当,会出现如下错误:

ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting blobs, is 65535. This includes storage overhead, so the actual maximum row size is less.

或者:

ERROR 1030 (HY000): Got error -1 from storage engine

文件格式如果是老的格式(老版本物理方式原地升级),则可能会报如下错误:

ERROR 1478 (HY000): InnoDB table 'db.tbl' has row_format=COMPRESSED but the innodb_file_format is Antelope. Support for COMPRESSED row format requires innodb_file_format=Barracuda.

二、 实操案例

1. 表行格式压缩

本次在MySQL5.7中选取一张超过1kw的表(tb2)。

压缩前,磁盘空间占用632M。

查看当前表的行格式:

show  table status like 'tb2';

对该表进行压缩。

alter table tb2 row_format='compressed';

压缩后,空间降至232M。

2. 页压缩

MySQL8.0 中选取一张表,压缩前占用空间68M。

mysql查看数据库大小(MySQL压缩表,也能不物理扩容解决数据库磁盘爆满问题。)

通过页压缩方式处理:

mysql> alter table orders COMPRESSION='zlib', ALGORITHM = INPLACE, LOCK = NONE;

执行完空间如下:

可以看出,空间并没有降低,主要原因是该命令只修改了表的元数据,仅对后续新增的数据启用压缩,而不会压缩表中已有的存量数据,需要重建表来压缩存量数据。

因此进行优化(重建)处理:

mysql> alter table orders engine =innodb;

重建后大小如下:

3. 压缩前后空间对比

压缩率是与当前表中存储的数据及压缩方式有关,本文中2个案例的压缩率如下:

状态

压缩前占用(MB)

压缩后占用(MB)

压缩率

行格式压缩

632

232

63.29%

页压缩(zlib)

68

52

23.53%

三、总结

MySQL压缩表,是以CPU小幅开销,换磁盘空间大幅节省的实用优化手段,尤其适合日志表、归档表等读多写少的大表,最高可省70%存储空间,还能减少IO压力、缩短备份时间。核心记住3点:选对场景(读多写少大表)、选对方式(8.0+优先页压缩)、避开坑点(不盲目压缩高并发表)。

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有