数据库系统原理及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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • php 5 与7有什么区别

    php 5 与7有什么区别

    2021年11月10日
    40
  • 如何使用Journalctl查看并操作Systemd日志

    如何使用Journalctl查看并操作Systemd日志提供:ZStack云计算内容简介作为最具吸引力的优势,systemd拥有强大的处理与系统日志记录功能。在使用其它工具时,日志往往被分散在整套系统当中,由不同的守护进程及进程负责处理,这意味着我们很难跨越多种应用程序对其内容进行解读。相比之下,systemd尝试提供一套集中化管理方案,从而统一打理全部内核及用户级进程的日志信息。这套系统能够收集并管理日志内容,而这也就是我们所熟知的journal。J

    2022年5月23日
    49
  • C#实现QQ(高仿版)聊天窗口

    C#实现QQ(高仿版)聊天窗口一.编程思想(1).考虑聊天功能的实现,文本的获取以及显示;(2).窗体制作时需要的控件;(3).考虑是否可以发送空格以及空字符;(4).刚开始进入界面时焦点的位置;(5).获取输入内容鼠标光标跟踪最后一个字符处;(6).窗口抖动依赖位置的变化进行实现;(6).点击按钮对应的触发事件;二.代码的实现1.需要的控件简介:TextBox:允许用户输入文本,并提供多行编辑和密码字符掩……

    2022年7月24日
    6
  • kali 目录扫描_kali扫描命令

    kali 目录扫描_kali扫描命令1、简介dirsearch是一个基于python3的命令行工具,常用于暴力扫描页面结构,包括网页中的目录和文件。相比其他扫描工具disearch的特点是:支持HTTP代理多线程支持多种形式的网页(asp,php)生成报告(纯文本,JSON)启发式检测无效的网页递归扫描用户代理随机化批量处理扫描器与字典(注:字典必须是文本文件)2、下载及安装GitHub的下载地址为:https://github.com/maurosoria/dirsearchWindows10安装方式点击c

    2022年9月26日
    0
  • 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    2022年3月7日
    28
  • 离散数学传递闭包_传递闭包一定等于自身的是

    离散数学传递闭包_传递闭包一定等于自身的是给定 n 个变量和 m 个不等式。其中 n 小于等于 26,变量分别用前 n 的大写英文字母表示。不等式之间具有传递性,即若 A>B 且 B>C,则 A>C。请从前往后遍历每对关系,每次遍历时判断:如果能够确定全部关系且无矛盾,则结束循环,输出确定的次序;如果发生矛盾,则结束循环,输出有矛盾;如果循环结束时没有发生上述两种情况,则输出无定解。输入格式输入包含多组测试数据。每组测试数据,第一行包含两个整数 n 和 m。接下来 m 行,每行包含一个不等式,不等式全部为小于关系

    2022年8月9日
    3

发表回复

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

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