傻大方


首页 > 潮·科技 > >

删除|什么?还在用delete删除数据《死磕MySQL系列 九》( 二 )

傻大方提要:【删除|什么?还在用delete删除数据《死磕MySQL系列 九》( 二 )】结论 在项目开始阶段 , 切记将innodb_file_per_table设置为on , 这是正确的做法 。 二、数据删除流程现在你应该知道Innodb存储引擎用的是B+树数据结构 , 如...



按关键词阅读: 数据库 删除 InnoDB



结论
在项目开始阶段 , 切记将innodb_file_per_table设置为on , 这是正确的做法 。
二、数据删除流程现在你应该知道Innodb存储引擎用的是B+树数据结构 , 如下图 。

如果现在删了主键ID为4的这条记录 , Innodb引擎会把ID为4的这条记录标记为删除 , 如果之后再插入ID为4的记录 , 可能会复用这个位置 , 但磁盘文件大小并不会缩小 。
隐式字段
这里就牵扯到了mvcc中的一个知识点 , MVCC实现原理是由俩个隐式字段、undo日志、Read view来实现的 。
上文说的标记删除就是隐式字段中的delete flag , 即记录被更新或删除 , 这里的删除并不代表真的删除 , 而是将这条记录的delete flag改为true 。

在MVCC:听说有人好奇我的底层实现这篇文章中也给大家留下了一个伏笔 , 数据库的删除是真的删除吗?问题:删了一个数据页的所有数据会怎么样
跟单条数据是一样的 , 整个数据页都是可以复用的 。
记录的复用是仅限于符合范围条件的数据 , 例如上文删除的ID为4这条记录 , 如果在插入ID为4就会复用 。
这里需要给大家再聊一个新的知识点页合并 , 若相邻的两个数据页利用率都很低 , 系统就会把这两个数据页合并到一个页上 , 另一个数据页就会标记为可复用 。
问题:使用delete把整个表的数据都删除了会怎么样
答案是 , 所有的数据页都会标记为可复用 , 但是磁盘文件大小是不会改变的 。
三、实践全表删除表文件大小不改变
经过添加数据后表数据已经达到近100W了 , 文件大小已经达到108M 。
扩展
这里大家应该能看见stopped , 就是执行命令ctrl + z来的 , 作用是开始我们在MySQL窗口里边 , 但不想退出MySQL窗口查看MySQL表文件大小 , 然后就可以执行这个命令结束任务 。
查看完后可以在执行fg返回到MySQL窗口 。

问题:Linux如何把文件单位显示为M
假设刚刚直接执行ll命令查看文件 , 那么就需要手动计算文件大小 , 很不方便 。
执行ll -h命令则可以直观的看到文件大小 。

删除数据查看磁盘文件是否缩小

为了直观看大文件大小变化 , 咔咔直接把表里边的数据全部删了 , 再看文件大小 , 还是108M 。 文件大小是没有变化的 。 四、如何正确的减少磁盘文件在第三小节中 , 我们演示了删除了100W数据后文件大小是没有改变的 , 也就是空洞问题影响的 , 接下来就解决这种问题 。
问题:空洞是如何产生的?
到了这里都应该知道空洞是因为大量的增删改造成的 。
解决思路
你可以新建一个evt_sms_copy表 , 然后根据主键ID递增的顺序 , 把数据从evt_sms读入evt_sms1中 。
这样就可以达到因为空洞造成的磁盘文件大小无法收缩问题 。
问题:为什么能解决呢?
因为evt_sms_copy是一张新的表 , 并且数据是以主键ID递增的 , 索引是紧促的 , 数据页利用率已经达到了最高峰状态 , 这样就起到了磁盘文件无法收缩问题 。
上干货
直接执行alter table evt_sms engine = Innodb 命令来达到磁盘文件收缩 。
这里需要跟大家聊一下不同版本处理不同 。
在MySQL5.5之前 , 这个命令做的事情跟我们解决思路是一样的 , 不同的是evt_sms_copy是不用自己创建的 。
在执行命令期间如有新增数据的话 , 会造成数据丢失 , 因为在MySQL5.5之前版本的DDL不是Online的 。 因此不能有数据的改动 。
现在MySQL都已经更新到8版本了 , 如果你是新项目就直接用8版本 , 不要在用5.6以前的老版本了 , 咔咔在18年开始就已经在使用MySQL8.0版本了 。
在锁那一期文章中跟大家聊了MySQL5.6在DDL操作做了优化 , 引入了Online DDL 。
优化后的执行流程

  • 建立临时文件tmp_file , 把表的B+树存储到临时文件中 。 若此时有对表的操作 , 则会记录在row log文件中 。
  • 把数据从原表全部刷到临时文件后 , 此时临时文件的数据就跟原表的数据一致 。
  • 最后用临时文件替换表A的数据文件 。
Online DDL的由来
可以看到在收缩磁盘文件时有数据更新会记录在row log中 , 意思就是在收缩磁盘空间时是可以对表进行增删改查的 。
注意点
在进行磁盘文件收缩的过程中 , 都会全表扫描原数据和新增临时文件 , 如果你的表非常大 , 会非常消耗IO和CPU 。
因此 , 你要安全的做这个操作 , 可以使用开源的gh-ost来进行 。


稿源:(原来是咔咔)

【傻大方】网址:http://www.shadafang.com/c/111395UW2021.html

标题:删除|什么?还在用delete删除数据《死磕MySQL系列 九》( 二 )


上一篇:双十一|双十一七大厂商终极战报汇总 魅族不再惨兮兮,小米破193亿元

下一篇:微博|双11手机战绩盘点:红米成最大赢家,消费者对价格愈发敏感