天天看点

为什么明明表数据删掉一半,表文件大小不变?

1)表结构和表数据是怎样放置的?

  • 8.0之前啊,表结构是放在.frm为后缀的文件中。8.0之后呢,可以放在了系统数据表中。

2)先来 看看参数innodb_file_per_table的含义是怎么?

  • 当值为off的时候,表示我的文件数据是放在共享表中的。
  • 当值为on的时候,那文件数据就是单独放在一个文件中的,每个数据表都有一个对应的文件。
  • 从mysql5.6.6开始,默认值 就是on了。

3)数据的删除流程是怎样的?

为什么明明表数据删掉一半,表文件大小不变?
  • 假如要 删R4这一行数据 ,仅仅是打个标记,代表 删除了 ,是逻辑上的删除,并不会实际的把这部分地址空间移除。那以后要插入新的数据的话还得看满足范围不。
  • 那如果是删除整页的话,那就是标记整个页都是被删除的了,你要插什么范围的数据进来都是可以的。

4)页合并的过程中还发生了什么?

  • 如果两个页的利用率都很低,那数据合并到其中一页之后,剩下的一页就被标记为可复用状态。

5)如果我们用delete命令删除整个表数据,会发生什么?

  • 标记一下所有的数据页上的数据都被删除了,大家想用的话就用。仅仅是逻辑上的删除。但是磁盘上的文件还是实实在在存在的。

6)delete删除的时候,是标记 我们的数据页为可复用状态,但是实际上我们有一些内存是利用不到的,这个就是内存碎片,在随机插入的时候也会造成内存碎片,那如何去解决内存碎片这个问题呢?

  • 用alter table 表名 engine = innoDB命令重建表
  • 5.5之前,是把A表的东一行西一行的数据整齐的码放到一个临时表,临时表中数据是挨着的,然后用这张临时表 来替换A表。这种方式的话需要停摆我们的业务 ,因为重建过程中如果有新的数据到A上,那到不了临时表上,会造成数据丢失 。
  • 5.6之后,优化了我们重建表的细节 ,A表的数据生成一颗B+树,然后数据整齐码放到一个临时文件(注意这里不再表是文件)的时候,如果有新的业务插进来数据,我把这些数据记录到一个日志上row log,然后等我把数据码放到我们的临时文件上后,再把日志中的数据添加到临时文件。最后临时文件和A表 交换。