一:概念

  - 这里,我们还是针对 MySQL 中应用最广泛的 InnoDB 引擎展开讨论。

  - 一个 InnoDB 表包含两部分,即:表结构定义和数据。

    - 在 MySQL 8.0 版本以前,表结构是存在以.frm 为后缀的文件里。

    - 而 MySQL 8.0 版本,则已经允许把表结构定义放在系统数据表中了。

    - 因为表结构定义占用的空间很小,所以我们今天主要讨论的是表数据。

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

  - 概念

    - 这个参数设置为 OFF 表示的是,表的数据放在系统共享表空间,也就是跟数据字典放在一起。

    - 这个参数设置为 ON 表示的是,每个 InnoDB 表数据存储在一个以 .ibd 为后缀的文件中。

  - 从 MySQL 5.6.6 版本开始,它的默认值就是 ON 了。

    - 因为,一个表单独存储为一个文件更容易管理,而且在你不需要这个表的时候,通过 drop table 命令,系统就会直接删除这个文件。

    - 而如果是放在共享表空间中,即使表删掉了,空间也是不会回收的。 

三:数据删除流程

  - 数据

    - 

  - 删除

    - 假设,我们要删掉 300 的记录,InnoDB 引擎只会把 300 这个记录标记为删除。

    - 但是, 如果之后要再插入一个 在 300-500 之间的记录时,可能会复用这个位置。(磁盘文件的大小并不会缩小)。

    - 如果我们删掉了一个数据页上的所有记录,整个数据页就可以被复用了。(如果相邻的两个数据页利用率都很小,会整合两个数据页,一个数据页就被标记为可复用。)

  - 如果我们用 delete 命令把整个表的数据删除呢?

    - 结果就是,所有的数据页都会被标记为可复用。但是磁盘上,文件不会变小。

  - 结论

    - Delete 命令其实只是把记录的位置,或者数据页标记为了“可复用”,但磁盘文件的大小是不会变的。

    - 也就是说,通过 Delete 命令是不能回收表空间的。

    - 这些可以复用,而没有被使用的空间,看起来就像是“空洞”。

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

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

      - 假设我要写入的 page A 已经满了,在插入一行数据,也会导致页分裂。

      - 另外,更新索引上的值,可以理解为删除一个旧的值,再插入一个新值。不难理解,这也是会造成空洞的。

    - 也就是说,经过大量增删改的表,都是可能是存在空洞的。

    - 所以,如果能够把这些空洞去掉,就能达到收缩表空间的目的。

四:重建表(去除空洞)

  - 如果需要重建表,那么你能想出他是如何构建表的?

    - 建立 临时表B,把 A 表数据根据递增的关系,放入 B 中,最后用 B 替换 A。完成重构。(A 的空间收缩,空洞消失)

  - 而在MySQL 5.6 版本开始引入的 Online DDL,对这个重建操作流程做了优化。

    - 流程

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

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

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

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

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

    - 区别

      - 不同之处在于,由于日志文件记录和重放操作这个功能的存在,这个方案在重建表的过程中,允许对表 A 做增删改操作。

      - 这也就是 Online DDL 名字的来源。

五:如何重建表?

  - alter table t engine = InnoDB(也就是 recreate)

    - OnLine DDL

  - analyze table t

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

  - optimize table t

    - 等于 recreate+analyze。

《Mysql - 为什么表数据删掉一半,表文件大小不变?》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. ERROR: node with name "rabbit" already running on "localhost"

    rabbitmqctl start_app启动没有这个问题

  2. CF2B The least round way(贪心+动规)

    题目 CF2B The least round way 做法 后面\(0\)的个数,\(2\)和\(5\)是\(10\)分解质因数 则把方格中的每个数分解成\(2\)和\(5\),对\(2\)和\(5 ...

  3. zabbix (二)安装

    一.centos7源码安装zabbix3.x 1.安装前环境搭建 下载最新的yum源 #wget -P /etc/yum.repos.d http://mirrors.aliyun.com/repo/ ...

  4. meshing-划分圆柱结构化网格

    原视频下载地址:https://yunpan.cn/cqjeckrzEpVkY  访问密码 eb5d

  5. ICEM-带死角弯管

    原视频下载地址:https://yunpan.cn/cqRiHaQiLi8I7  访问密码 b5c6

  6. Gitlab 服务器搭建

    一.官网地址 首页:https://about.gitlab.com/ 安装说明:https://about.gitlab.com/installation/ 二.安装命令摘录 实际问题:yum 安装 ...

  7. 【Canvas】勾画调和级数Harmonic series 曲线 y=1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+....

    相关资料:https://baike.baidu.com/item/%E8%B0%83%E5%92%8C%E7%BA%A7%E6%95%B0/8019971?fr=aladdin 调和级数(英语:Ha ...

  8. PEP 442 -- Safe object finalization

    https://www.python.org/dev/peps/pep-0442/ PEP 442 -- Safe object finalization PEP: 442 Title: Safe o ...

  9. 浅谈TextView Ellipsize效果与Marquee跑马灯无效果问题

    说到TextView 效果,相信大家一定熟悉跑马灯. 先来看看 Ellipsize是什么,Ellipsize 从开发技术上翻译为省略效果.故名思议,就是当文本无法显示全部时,用什么效果来显示未显示的部 ...

  10. 003-结构型-01-适配器模式(Adapter)

    一.概述 将一个类的接口转换成客户期望的另一个接口.适配器模式让那些接口不兼容的类可以一起工作. 1.1.适用场景 已经存在的类,它的方法和需求不匹配时(方法结果相同或相似) 不是软件设计阶段考虑的设 ...