mysql 优化——磁盘空间优化

前言

有的时候,表的数据太多,为了提高查询以及存储,就把历史数据放到一个历史表里,在把历史数据删除,发现虽然历史数据删除,表的大小并没有发生改变。

Innodb 表有两部分,即:表结构定义和数据。在 MySQL 8.0 版本以前,表结构是存在以.frm 为后缀的文件里。而 MySQL 8.0 版本,则已经允许把表结构定义放在系统数据表中了。因为表结构定义占用的空间很小,所以我们今天主要讨论的是表数据。

drop table 为什么无法回收表空间

在上面我们已经说过innodb 表有两部分,即:表结构定义和数据。如果表结构定义和数据在一个文件,那么drop table 就无法回收表的空间,如果表结构是存在以.frm 为后缀的文件里,那么drop table 就可以回收表的空间,直接删除就可以了。

这种行为可以通过 innodb_file_per_table 控制,在mysql 日志可以看到, innodb_file_per_table=ON 表数据存储在一个以 .ibd 为后缀的文件中,表结构存储在.frm 为后缀的文件里。innodb_file_per_table=OFF 表的数据放在系统共享表空间,也就是跟数据字典放在一起;

从 MySQL 5.6.6 版本开始,它的默认值就是 ON 了,不管任何版本都设置成ON。

Delete 删除数据内部机制

Innodb 数据都是用B+树的结构,下面图,表示的就是聚簇索引的数据结构:

图A

如果我们删除了R3 的数据,数据的磁盘空间并不会删除,只会在R3 标记已经删除,如果下次要出入400,直接用R3的数据空间,如果是700就用到了,索引必须保证顺序性

如果pageA 这个页被删除了,那么整个页都会被标记为已删除,下次新增数据时,需要使用新页时,不管数据大小都是可以被复用的

如果两个数据页的利用率都很小,系统就会把这两个数据页上的数据合并到其中一个页上,另一个数据页标记可复用

如果delete 删除表的所有记录,那么整个表的所有页标记都可以被复用

总之,delete 删除,之后标记成可复用,磁盘文件大小不会有任何变化。这些可以复用,而没有复用的空间,就是碎片

不仅删除可能造成碎片话,插入也可能。

图A上,我们插入ID是550,又会怎么样呢?看图B

图B

可以看到由于pageA 满了,在插入一个ID 是550的数据,需要申请新页pageB保存数据,也分裂后,pageA 就有碎片化了。

为啥会这样,500后面的空间为啥用不上?那是由于页分裂策略决定的:

非递增情况innodb的页分裂策略就是50%分裂,在整个页中前50%的不动,后百分之50%的移动到新的页。 50%分裂策略的优势: 分裂之后,两个页面的空间利用率是一样的;如果新的插入是随机在两个页面中挑选进行,那么下一次分裂的操作就会更晚触发; 50%分裂策略的劣势: 空间利用率不高:按照传统50%的页面分裂策略,索引页面的空间利用率在50%左右; 分裂频率较大:针对如上所示的递增插入(递减插入),每新插入两条记录,就会导致最右的叶页面再次发生分裂;

那么更新索引上的值,可以理解为删除一个旧值然后插入一个新值,也会造成碎片。

综上可以看出,一张表经过大量的DML操作都会有碎片化,同时也可以看出delete 并不会减少磁盘大小,那么就必须重新建表

重建表

现在表有大量的操作,表的碎片比较多,这些占据了表的磁盘空间,影响查询性能。那么我们该怎么办呢。我们有几种方案

方案一:

  1. 我们新建一张表B

  2. 把原表A的数据,通过sql 插入到表B

  3. 完成了,用表B替换表A

这个方案解决了表的碎片问题,但是会有业务数据的丢失,在数据插入表B时,有其他数据写入表A,这个是在server 认为操作的。

方案二:

以使用 alter table A engine=InnoDB 命令来重建表。这个命令在 MySQL 5.5 版本之前,会先加上MDL 写锁,其他的步骤和方案一是一样的,只不过表B是mysql 自己建的,此时业务是不能做DML操作的。所以说DDL不是online DDL

那么MySQL 5.5版本后有哪些变化呢?

那么在这个版本后,alter table A engine=InnoDB 成为online DDL,它是怎么做的呢?

  1. 建立一个临时文件,扫描表 A 主键的所有数据页;

  2. 用数据页中表 A 的记录生成 B+ 树,存储到临时文件中;

  3. 生成临时文件的过程中,将所有对 A 的操作记录在一个日志文件(row log)中

  4. 临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与表 A 相同的数据文件

  5. 用临时文件替换表 A 的数据文件。

这个过程中增加一个日子文件,记录用数据页中表 A 的记录生成 B+ 树时,数据的变化,避免数据丢失。这个是在Innodb 引擎自己操作的。 需要说明的是在MySQL 5.5版本后的DDL操作也是需要加MDL锁的,不够对MDL锁进行了优化:

  1. MDL写锁

  2. 退化MDL读锁

  3. 拷贝数据

  4. MDL写锁

  5. 退化MDL读锁

锁相对于业务时间非常短,所以就叫online DDL

需要补充说明的是,上述的这些重建方法都会扫描原表数据和构建临时文件。对于很大的表来说,这个操作是很消耗 IO 和 CPU 资源的。因此,如果是线上服务,你要很小心地控制操作时间。如果想要比较安全的操作的话,我推荐你使用 GitHub 开源的 gh-ost 来做。

Online 和 inplace 比较

inplace 是原地操作,就是把数据挪动到临时表。对于方案二来说,虽然建立了临时文件,但这个临时文件是inodb 建的,server 层是没有显现的,就相当于原地,也就是一个inplace 操作,方案一就不是。

alter table t engine=InnoDB 相当于 alter table t engine=innodb,ALGORITHM=inplace;

如果这个语句写成这样 alter table t engine=innodb,ALGORITHM=copy; 表示强制拷贝表,就不是 inplace

是不是所有的alter 一定是 Online 吗?当然不一定是的

alter table t add FULLTEXT(field_name);

这个加全文索引是要阻塞增删改操作,非Online。但是inplace

综上所述,他们的关系可以概括为

  1. DDL 过程如果是 Online 的,就一定是 inplace 的;

  2. 反过来未必,也就是说 inplace 的 DDL,有可能不是 Online 的。截止到 MySQL 8.0,添加全文索引(FULLTEXT index)和空间索引 (SPATIAL index) 就属于这种情况。

最后我在说明下 optimize table、analyze table 和 alter table 这三种方式重建表的区

  1. 从 MySQL 5.6 版本开始,alter table t engine = InnoDB(也就是 recreate)就是方法二流程;

  2. analyze table t 其实不是重建表,只是对表的索引信息做重新统计,没有修改数据,这个过程中加了 MDL 读锁;

  3. optimize table t 等于 recreate+analyze。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/447177.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Emgu CV教程】9.1、形态学常用操作之腐蚀

文章目录 一、相关概念1.什么叫形态学2.形态学操作的目的3.形态学都包含哪些操作4.结构元素StructuringElement 二、腐蚀1.什么叫腐蚀2.腐蚀的作用3.腐蚀的函数 三、演示1.原始素材2.代码3.运行结果 一、相关概念 1.什么叫形态学 形态学,英文名称morphology&#…

【C++】了解一下STL

个人主页 : zxctscl 如有转载请先通知 STL 1. 什么是STL2. STL的版本3. STL的六大组件4. STL的重要性5. 如何学习STL6. STL的缺陷 1. 什么是STL STL(standard template libaray-标准模板库):是C标准库的重要组成部分,不仅是一个可复用的组件…

C语言:基于单链表实现的泊车管理系统

一、需求 (1)管理员方账号登录; (2)车位管理显示:车位状态; (3)收费管理:小轿车 5元/小时,面包车6元/小时,大货车或客车7元/小时&a…

vulhub中Weblogic 管理控制台未授权远程命令执行漏洞复现(CVE-2020-14882,CVE-2020-14883)

Weblogic是Oracle公司推出的J2EE应用服务器。在2020年10月的更新中,Oracle官方修复了两个长亭科技安全研究员voidfyoo 提交的安全漏洞,分别是CVE-2020-14882和CVE-2020-14883。 CVE-2020-14882允许未授权的用户绕过管理控制台的权限验证访问后台&#x…

【Flutter 面试题】dart是值传递还是引用传递?

【Flutter 面试题】dart是值传递还是引用传递? 文章目录 写在前面解答补充说明值传递示例引用传递示例总结 写在前面 关于我 ,小雨青年 👉 CSDN博客专家,GitChat专栏作者,阿里云社区专家博主,51CTO专家博主…

vs2022的下载及安装教程(Visual Studio 2022)

vs简介 Visual Studio在团队项目开发中使用非常多且功能强大,支持开发人员编写跨平台的应用程序;Microsoft Visual C 2022正式版(VC2022运行库),具有程序框架自动生成,灵活方便的类管理,强大的代码编写等功能,可提供编…

信息系统项目管理师008:两化融合与智能制造(1信息化发展—1.3现代化创新发展—1.3.2两化融合与智能制造)

文章目录 1.3.2 两化融合与智能制造1.两化融合2.智能制造 记忆要点总结 1.3.2 两化融合与智能制造 “坚持自主可控、安全高效,推进产业基础高级化、产业链现代化,保持制造业比重基本稳定,增强制造业竞争优势,推动制造业高质量发展…

[云原生] k8s配置资源管理

一、Secret的资源配置 1.1 Secret配置的相关说明 Secret 是用来保存密码、token、密钥等敏感数据的 k8s 资源,这类数据虽然也可以存放在 Pod 或者镜像中,但是放在 Secret 中是为了更方便的控制如何使用数据,并减少暴露的风险。 Secret 有…

钉钉如何通过AppLink快速连接仓储系统

一、什么是APPlink? APPlink是RestCloud打造的一款简单易用的零代码自动化集成平台,为业务流程提供自动化的解决方案,将企业内部的核心系统以及第三方应用程序和云服务等进行集成。无论是开发人员还是业务人员,都可以使用APPlink…

HTML静态网页成品作业(HTML+CSS)——阜阳剪纸介绍设计制作(1个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…

打破界限,释放创新:一键将HTML转化为PDF

在互联网时代,HTML作为网页的标准语言,承载着无数的信息与创意。然而,有时我们需要将这些在线内容转化为可打印、可分享的PDF格式。这时,一款高效、便捷的转换工具就显得尤为重要。 首先,我们要进入首助编辑高手主页面…

《IEEE Transactions on Robotics》发表!北京大学研究团队推出具有多种运动模态的软体两栖机器人

两栖机器人以其在复杂水陆混合环境中的卓越适应性而脱颖而出,成为非结构化场景下信息监测、资源勘探和灾难救援等多元化任务的理想选择。凭借能够在水生和陆生环境中自如切换的优势,两栖机器人在如上任务执行过程中展现出对多变环境的惊人适应能力。 在…

springboot实现国际化

引言 今天在开发过程中,遇到国外客户,要求项目一些返回msg中,不能再有中文,于是便有了国际化需求。 How to do 1.在项目resources下创建i18n文件夹以及messages.properties文件 messages.properties 国际化主文件 phoneErr.ms…

easyexcel文件上传

easyexcel文件上传 前言&#xff1a;功能开发中&#xff0c;难免碰到数据上传下载功能&#xff0c;excel上传常见用于报表上传&#xff0c;绩效上传&#xff0c;考勤上传… 使用步骤&#xff1a; 1&#xff0c;编写业务层&#xff1a; 1&#xff0c;添加easyexcel依赖 <…

Langchain-Chatchat本地部署

1.前言&#xff1a; 最近AI爆发式的火&#xff0c;忆往昔尤记得16,17那会移动互联网是特别火热的&#xff0c;也造富了一批公司和个人&#xff0c;出来了很多精妙的app应用。现在轮到AI发力了&#xff0c;想想自己也应该参与到这场时代的浪潮之中&#xff0c;所以就找了开源的…

割点原理及封装好的割点类

作者推荐 视频算法专题 预备知识 本分析针对&#xff1a;连通无向图G。 搜索树 节点的父子关系&#xff1a;任意 节点的邻接 节点除了已处理 节点&#xff0c;都是它的子 节点。 以任意一点为根开始DFS&#xff0c;计算所有 节点的父子关系。只保留个子 节点到父 节点形成…

linux:线程的控制

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、线程的总结1. 线程的优点2. 线程的缺点3. 线程异常4.线程和进程 二、线程的控制创建线程线程终止线程等待获取返回值 线程分离 总结 前言 本文作为我对于线程的…

git远程仓库使用

赋值这个地址clone 克隆之后 cd slam_oncloud/ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/slam_oncloud.git 查看一下 linuxchenxiao:/media/linux/mydisk/cloud_slam/slam_oncloud$ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/sla…

GitHub Desktop的常用操作【图形化】

文章目录 【1】仓库的创建和删除【2】文件操作【3】分支原理与分支操作1.分支创建2.分支合并 【4】标签 【1】仓库的创建和删除 在本地创建一个新的仓库&#xff1a; 然后输入仓库的名称&#xff0c;描述&#xff0c;并选择路径&#xff1a; 点击完后就发现我们的仓库创建好…

明日周刊-第1期

打算开一个新的专栏&#xff0c;专门记录一周发生的事情以及资源共享&#xff0c;那么就从第一期开始吧。 1. 一周热点 人工智能技术突破&#xff1a;可能会有关于人工智能领域的最新研究成果&#xff0c;例如新算法的开发、机器学习模型的提升或者AI在不同行业的应用案例。 量…
最新文章