扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
使用OPTIMIZE TABLE语句可以。
成都创新互联公司主营武陵网站建设的网络公司,主营网站建设方案,APP应用开发,武陵h5小程序开发搭建,武陵网站营销推广欢迎武陵等地区企业咨询
OPTIMIZE TABLE语法
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...
如果您已经删除了表的一大部分,或者如果您已经对含有可变长度行的表(含有VARCHAR, BLOB或TEXT列的表)进行了很多更改,则应使用OPTIMIZE TABLE。被删除的记录被保持在链接清单中,后续的INSERT操作会重新使用旧的记录位置。您可以使用OPTIMIZE TABLE来重新利用未使用的空间,并整理数据文件的碎片。
在多数的设置中,您根本不需要运行OPTIMIZE TABLE。即使您对可变长度的行进行了大量的更新,您也不需要经常运行,每周一次或每月一次即可,只对特定的表运行。
OPTIMIZE TABLE只对MyISAM, BDB和InnoDB表起作用。
对于MyISAM表,OPTIMIZE TABLE按如下方式操作:
1. 如果表已经删除或分解了行,则修复表。
2. 如果未对索引页进行分类,则进行分类。
3. 如果表的统计数据没有更新(并且通过对索引进行分类不能实现修复),则进行更新。
对于BDB表,OPTIMIZE TABLE目前被映射到ANALYZE TABLE上。对于InnoDB表,OPTIMIZE TABLE被映射到ALTER TABLE上,这会重建表。重建操作能更新索引统计数据并释放成簇索引中的未使用的空间。
要重新使用未使用的空间并减小文件的尺寸,则使用OPTIMIZE TABLE语句或myisamchk应用程序重新编排表。OPTIMIZE TABLE更简便,但是myisamchk速度更快。
压缩表从名字上来看,简单理解为压缩后的表,也就是把原始表根据一定的压缩算法按照一定的压缩比率压缩后生成的表。
1.1 压缩能力强的产品
表压缩后从磁盘占用上看要比原始表要小很多。如果你熟悉列式数据库,那对这个概念一定不陌生。比如,基于 PostgreSQL 的列式数据库 Greenplum;早期基于 MySQL 的列式数据库 inforbright;或者 Percona 的产品 tokudb 等,都是有压缩能力非常强的数据库产品。
1.2 为什么要用压缩表?
情景一:磁盘大小为 1T,不算其他的空间占用,只能存放 10 张 100G 大小的表。如果这些表以一定的比率压缩后,比如每张表从 100G 压缩到 10G,那同样的磁盘可以存放 100 张表,表的容量是原来的 10 倍。情景二:默认 MySQL 页大小 16K,而 OS 文件系统一般块大小为 4K,所以在 MySQL 在刷脏页的过程中,有一定的概率出现页没写全而导致数据坏掉的情形。比如 16K 的页写了 12K,剩下 4K 没写成功,导致 MySQL 页数据损坏。这个时候就算通过 Redo Log 也恢复不了,因为几乎有所有的关系数据库采用的 Redo Log 都记录了数据页的偏移量,此时就算通过 Redo Log 恢复后,数据也是错误的。所以 MySQL 在刷脏数据之前,会把这部分数据先写入共享表空间里的 DOUBLE WRITE BUFFER 区域来避免这种异常。此时如果 MySQL 采用压缩表,并且每张表页大小和磁盘块大小一致,比如也是 4K,那 DOUBLE WRITE BUFFER 就可以不需要,这部分开销就可以规避掉了。查看文件系统的块大小:
root@ytt-pc:/home/ytt# tune2fs -l /dev/mapper/ytt--pc--vg-root | grep -i 'block size'Block size: 4096
1.3 压缩表的优势
压缩表的优点非常明显,占用磁盘空间小!由于占用空间小,从磁盘置换到内存以及之后经过网络传输都非常节省资源。
简单来讲:节省磁盘 IO,减少网络 IO。
1.4 压缩表的缺陷
当然压缩表也有缺点,压缩表的写入(INSERT,UPDATE,DELETE)比普通表要消耗更多的 CPU 资源。
压缩表的写入涉及到解压数据,更新数据,再压缩数据,比普通表多了解压和再压缩两个步骤,压缩和解压缩需要消耗一定的 CPU 资源。所以需要选择一个比较优化的压缩算法。
1.5 MySQL 支持的压缩算法
这块是 MySQL 所有涉及到压缩的基础,不仅仅用于压缩表,也用于其它地方。比如客户端请求到 MySQL 服务端的数据压缩;主从之间的压缩传输;利用克隆插件来复制数据库操作的压缩传输等等。
从下面结果可以看到 MySQL 支持的压缩算法为 zlib 和 zstd,MySQL 默认压缩算法为 zlib,当然你也可以选择非 zlib 算法,比如 zstd。至于哪种压缩算法最优,暂时没办法简单量化,依赖表中的数据分布或者业务请求。
阿里云RDS服务器报硬盘磁盘空间不足(100G的磁盘空间),登录后台查看,使用了130G,使用 SELECT file_name, concat(TOTAL_EXTENTS,'M') as 'FIle_size' FROM INFORMATION_SCHEMA.FILES order by TOTAL_EXTENTS DESC 查看,只使用了60G左右。那么还有70G是怎么用了呢?
查看问题:
查询 information_schema.innodb_trx ,看是哪些语句导致的。
原因:
ibdata文件很大,MySQL实例可能会 由于长时间不结束的查询导致 ibdata1 文件过大且无法收缩,导致实例空间满 ,为避免数据丢失,RDS会对实例进行自动锁定,磁盘锁定之后,将无法进行写入操作
解决方案:
重启实例即可
以前的小应用没有注意这个问题,现在遇到了mysql表中删除了100W数据,但是体检只有一点点变小,删除前是4.7G,删除后是4.6G。优化以后2.2G,哼哼哼哼。。。
查资料知道原因是mysql默认是不自动收缩的,所以删除数据体积不会变小。
我们需要手动优化来收缩数据。
方法一:使用Navicat的最优化功能
因为我是使用Navicat作为工具,所以推荐使用这个功能。选中需要优化的表,最优化即可。
方法二:运行命令优化
optimizetable数据表名称
方法三:自动批处理。说白了,还是运行命令
建议一个自动运行任务,每隔一段时间自动运行一下。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流