数据库系统原理及MySQL应用教程_三十讲之第三讲读后感

数据库系统原理及MySQL应用教程_三十讲之第三讲读后感此文为极客时间MySQL实战45讲第13节的笔记一、表数据的存放位置表数据既可以存在共享表空间里,也可以是单独的文件。这个行为是由参数innodb_file_per_table控制的:OFF

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

此文为极客时间MySQL实战45讲第13节的笔记

一、表数据的存放位置

表数据既可以存在共享表空间里,也可以是单独的文件。这个行为是由参数 innodb_file_per_table 控制的:

  1. OFF :表的数据放在系统共享表空间,即跟数据字典放在一起;
  2. ON :表数据存储在一个以 .ibd 为后缀的文件中。(MySQL 5.6.6 默认为 ON)

一般情况下,表单独存放的时候,可以通过 drop table 语句直接删除,而如果放在共享表空间,及时删除了表也无法回收空间。

二、表数据的删除

一般情况下,很少有直接连结构带数据直接删掉表的情况,更多时候是只删除一些数据,但是这样往往会遇到这样的问题:表中的数据被删除了,但是表空间却没有被回收。

实际上,这与 innodb 中数据都以 B+ 树的结构存储有关:

image-20201105203027271

以上图为例,如果我们删除 R4 这条数据,则 innodb 会把 R4 这个位置标记为删除,之后如果插入一个在 300~600 的记录的时候,就会直接使用现在 R4 的位置。同理,如果我们清除这个 PageA,那么这个数据页都会被标记删除,等到下一个数据页加载的时候就可以直接使用这个空间。而当两个相邻的数据页上被删除了记录很多,也就是页的利用率都很低的时候,系统就会自动合并两个页的数据,并且标记其中一个为可复用。

值得一提的是,记录的空间被复用,必须限定位置,比如 R4 的空间被复用,就不能插入300 ~ 600之外的数据;而数据页的空间则可以被任意一页新加载的页复用。

综上所述,不难理解,我们使用 delete 删除的数据只是把这块空间标记为可复用,是一种逻辑上的删除,并没有实际减少磁盘空间的占用。

实际上,不止是删除数据会造成空洞,插入数据也会。

如果数据是按照索引递增顺序插入的,那么索引是紧凑的。但如果数据是随机插入的,就可能造成索引的数据页分裂。

image-20201105204359077

假如 PageA 已满,再插入一条550,PageA 就会不得不分离成两页,这就是页的分裂。当分裂完以后,PageA 就会留下一个空洞,新页 PageB 一样没有占满。

另外,更新索引上的值,可以理解为删除一个旧的值,再插入一个新值。不难理解,这很有可能破坏了索引的有序性,也是会造成空洞的

也就是说,经过大量增删改的表,都是可能是存在空洞的。所以,如果能够把这些空洞去掉,就能达到收缩表空间的目的。

而重建表,就可以达到这样的目的。

三、重建表

1.重建表的流程

为了去掉表中的空洞,我们可以新建一个与表 A 结构相同的表 B,然后按照主键 ID 递增的顺序,把数据一行一行地从表 A 里读出来再插入到表 B 中。

由于表 B 是新建的表,所以表 A 主键索引上的空洞,在表 B 中就都不存在了。显然地,表 B 的主键索引更紧凑,数据页的利用率也更高。如果我们把表 B 作为临时表,数据从表 A 导入表 B 的操作完成后,用表 B 替换 A,从效果上看,就起到了收缩表 A 空间的作用。

可以使用 alter table A engine=InnoDB 命令来重建表。在 MySQL 5.5 版本之前,这个命令的执行流程跟我们前面描述的差不多,mysql 会自动完成全部操作。

2.优化

但是这个 DDL 语句不是 online 的,也就说,如果过程中有新的数据往 A 表插入,有可能不会被读到并且一起转移到 B 表,导致最后丢失更新。因此,在 5.6 版本以后,引入的 online DDL 对这个流程做了优化。

新的流程如下:

  1. 建立一个临时文件,扫描表 A 主键的所有数据页;
  2. 用数据页中表 A 的记录生成 B+ 树,存储到临时文件中;
  3. 生成临时文件的过程中,将所有对 A 的操作记录在一个日志文件中;
  4. 临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与表 A 相同的数据文件;
  5. 用临时文件替换表 A 的数据文件。

因为过程中对表 A 的操作最后都会通过日志同步到临时文件,所以在整个 DDL 执行的过程不会影响对表 A 的增删改查。

3.inplace

我们可以注意到,5.6 之前是创建临时表,而 5.6 以后则是创建了临时文件。这两者的区别在于:临时表是创建在 server 层的,临时文件是创建在 innodb 内部的,整个 DDL 过程都在 innodb 内部完成。对于 server 层来说,后者没有把数据移到临时表,相当于一个原地操作,所以叫 inplace。

也就是说,alter table t engine=InnoDB 这个 DDL 实际上相当于:

alter table t engine=innodb,ALGORITHM=inplace;

相对于创建临时表:

alter table t engine=innodb,ALGORITHM=copy;

4.三种重建表方式的区别

  1. 从 MySQL 5.6 版本开始,alter table t engine = InnoDB(也就是 recreate)默认的就是上面图 4 的流程了;
  2. analyze table t 其实不是重建表,只是对表的索引信息做重新统计,没有修改数据,这个过程中加了 MDL 读锁;
  3. optimize table t 等于 recreate + analyze。

四、总结

数据库表文件可以存在共享表空间里;也可以单独以 .ibd 文件存储。共享表空间中的表使用 drop table 无法清除。通过innodb_file_per_table参数的 off/on 可以控制存放策略。mysql 5.6.6 以后默认为 on。

innodb 中的删除只是标记空间为可复用,没有实际删除数据。当非有序的插增删改影响了索引上的数据的有序性时,可能产生“空洞”降低空间利用率。当内存中相邻表空间利用率都很低的时候,可能引起页的合并,反之,过满或者无序插入会引发页分裂。

通过拷贝数据到临时表,再有序将数据插入原表,即重建表可以收缩空间。可以使用 alter table A engine=InnoDB的 sql 实现。

5.5 之前版本拷贝过程中原表的正删改可能在重建后丢失,5.6 之后将对原表的正删改写入临时日志后再同步,实现了 online DDL。

5.6 之前重建操作为在server 层创建临时表,5.6 之后为在 innodb 内创建临时文件,他们的写法如下:

# 默认为inplace
alter table t engine=innodb(,ALGORITHM=inplace);
alter table t engine=innodb,ALGORITHM=copy;
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/170784.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 语音信号处理概念

    语音信号处理概念语音交互你知道苹果手机有几个麦克风吗?·语音交互(VUI)是指人与人/设备通过自然语音进行信息传递的过程。语音交互的优势:输入效率高。语音输入的速度是传统键盘输入方式的3倍以上。例如:语音电视选台、远场语音交互、语音支持组合指令输出(“播放周星驰电影、要免费的、4星以上的”)使用门槛低。人类本就是先有语音再有文字,对于那些无法用文字交互的人来说,语…

    2022年5月20日
  • StringUtils的isBlank(), isEmpty(), isNotBlank(), isNotEmpety(), isNoneBlank(), isNoneEmpty()[通俗易懂]

    StringUtils的isBlank(), isEmpty(), isNotBlank(), isNotEmpety(), isNoneBlank(), isNoneEmpty()[通俗易懂]isBlank()方法把空格当做没有,而isEmpty()认可空格的存在.StringUtils.isEmpty(null)=trueStringUtils.isEmpty(“”)=trueStringUtils.isEmpty(”“)=false//注意在StringUtils中空格作非空处理StringUtils.isEmpty(”“)=fal……

    2022年8月12日
  • CDH6.1.0环境搭建 完成后 登录admin账户失败

    CDH6.1.0环境搭建 完成后 登录admin账户失败CDH环境搭建完成,启动cloudera-manager-server成功,下面是启动日志[root@node-1~]#sudosystemctlstartcloudera-scm-server[root@node-1~]#sudotail-f/var/log/cloudera-scm-server/cloudera-scm-server.log2019-02-14…

    2022年5月12日
  • struts2拦截器和过滤器的区别_ExecuteNonQuery

    struts2拦截器和过滤器的区别_ExecuteNonQuery转自:http://blog.csdn.net/lifuxiangcaohui/article/details/8172956在Struts2开发中,很多人问到,声明过滤器的时候,为什么有的时候用"FilterDispatcher",而有的时候用"StrutsPrepareAndExecuteFilter"?两者都可以正常工作,那区别是什么呢?1.FilterDispatcher例子 …&…

    2022年8月16日
  • arcgis二次开发python-ArcGIS 二次开发专题 序「建议收藏」

    arcgis二次开发python-ArcGIS 二次开发专题 序「建议收藏」依据ArcGIS组件式开发及应用的目录结构,将系统性的学习ArcGIS二次开发的道路分为三个部分。这个系列包含以下三个部分:Part1基础1.前言1.1组件式GIS1.2ArcObject开发的特点与历史2.使用ArcGISEngine控件编程3.几何形体对象Geometry4.地图组成5.空间数据符号化6.空间数据管理7.空间分析8.空间数据编辑9.地图输出10…

    2022年7月23日
  • 华为服务器安装nas系统,服务器 nas 配置[通俗易懂]

    华为服务器安装nas系统,服务器 nas 配置[通俗易懂]服务器nas配置内容精选换一换为了确保DBService日常数据安全,或者系统管理员需要对DBService进行重大操作(如升级或迁移等)时,需要对DBService数据进行备份,从而保证系统在出现异常或未达到预期结果时可以及时进行数据恢复,将对业务的影响降到最低。系统管理员可以通过FusionInsightManager创建备份DBService任务并备份数据。支表1列出了云备份CBR的…

    2022年6月23日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号