不知道大家有没有想过下面这件事?

我们平时调用 DELETE 在 MySQL 中删除的数据都去哪儿了?

这还用问吗?当然是被删除了啊

那么这里又有个新的问题了,如果在 InnoDB 下,多事务并发的情况下,如果事务A删除了 id=1 的数据,同时事务B又去读取 id=1 的数据,如果这条数据真的被删除了,那 MVCC 拿啥数据返回给用户呢?

没错,这就需要了解一下 MySQL 的多版本并发的原理相关的东西,感兴趣的可以去看我之前写的这篇文章

所以,实际情况中,调用了 DELETE 语句删除的数据并不会真正的被物理删除,这条数据其实还在那,只不过被打上了一个标记,标记已删除

这其实跟我们日常的操作——软删除,差不多是一个意思

在 MySQL 中, UPDATEDELETE 操作本质上是一样的, 都属于更新操作,删除操作只不过是把某行数据中的一个特定的比特位标记为已删除,仅此而已。

那么问题又来了,那这些删除的数据如果一直这么堆下去,那不早晚把硬盘撑爆?

如果都玩儿成这样了,那 MySQL 还能像现在这样被大规模的用于生产环境中吗?那 MySQL 到底是怎么玩的?

这就需要提到 Purge 操作了。

Purge操作是啥?

Purge 操作才是真正将数据(已被标记为已删除)物理删除的操作。

Purge 操作针对的数据对象,不仅仅是某一行,还有其对应的索引数据和 Undo Log。

好的那么问题又来了。

问题是,Purge 操作什么时候会执行呢?实际上,你可以将执行 Purge 操作的线程(简称 Purge 线程)理解成一个后台周期性执行的线程。

Purge 线程可以有一个,也可以有多个,具体的线程数量可以由 MySQL 的配置项 innodb_purge_threads 来进行配置。当然,我相信你肯定不记得在使用 MySQL 的时候配置过这个,因为 innodb_purge_threads 有个默认值,值为 4

InnoDB 会根据 MySQL 中表的数量和 Purge 线程的数量进行分配。

但正是因为有这种特性,Purge 线程的数量才需要根据业务的实际情况来做调整。举个例子,假设 DML 操作都集中在某张表,比如表1上...

你先等等,我打断一下......

什么叫 DML 操作?总喜欢搞些复杂的名词...DML(Data Manipulation Language)数据操作语句,实际上就是CRUD增删改查...

与之类似的概念还有DDL(Data Definition Language)数据定义语句,也就是CREATEDROPALTER等等.

以及DCL(Data Control Language)数据控制语句,也就是GRANTREVOKE等等...

继续说回来,虽然 Purge 线程的数量是可配置的,但是也不是你想配多少就配多少的。不然你给它干个 10000 个线程,那不就直接原地 OOM 了吗?

innodb_purge_threads 的最大值为 32,而且并不是我们配了 32 InnoDB 就真的会启动 32 个 Purge 线程,为啥呢?举个很简单的例子,假设此时只有一张表,然后我们配置了 32 个 Purge 线程。

你看着上面这个图问问自己,这「河里」吗?这样不仅浪费了系统的资源,同时还使得不同的 Purge 线程之间发生了数据竞争。不仅如此,Purge 线程还可能跟用户线程产生竞争。

但是当系统中真的有 32 张表的时候,情况又不一样了,一个 Purge 线程对应一张表,线程与线程之间就不会存在数据竞争,并且没有浪费系统资源,还能够提升执行 Purge 操作的性能。

这就是为啥 InnoDB 会根据实际情况来调整 MySQL 中 Purge 线程的数量,所以我们在配置的时候也要按照实际情况来设置。

举个例子,如果你的数据库中,增删改 的操作只集中在某几张表上,则可以考虑将 innodb_purge_threads 设置的稍微低一点。相反,如果 增删改 的操作几乎每张表都有,那么 innodb_purge_threads 就可以设置的大一些。

了解完 Purge 线程本身之后,我们就可以来了解 Purge 线程所针对的对象了。Purge 线程主要清理的对象是 Undo Logs,其次是行记录。

因为 Undo Log 可以分为:

  • Insert Undo Log
  • Update Undo Log

所以更准确的说法是,Purge 线程清理的对象是 Update Undo Log 和 行记录,因为 Insert Undo Log 会在事务提交之后就会被删除。

我们都知道 InnoDB 的 MVCC 的数据来源是一个一个 Undo Log 形成的单链表,而 Purge 线程就是用于定期清理 Undo Log 的,并且在清理完 删除数据所生成的 Undo Log 的时候,就会把对应的行记录给移除了。

那么问题又来了,Purge 线程每次会读取多少条件 Undo Log 记录呢?

很明显,它不是看当时的心情来决定取多少条的。它是通过配置项 innodb_purge_batch_size 来控制的,默认是 300。然后InnoDB会将这300条 Undo Log 分给innodb_purge_threads个 Purge 线程。在清理的过程中,Purge 线程还会释放 Undo Log 表空间内的文件。

本篇文章已放到我的 Github github.com/sh-blog 中,欢迎 Star。微信搜索关注【SH的全栈笔记】,回复【队列】获取MQ学习资料,包含基础概念解析和RocketMQ详细的源码解析,持续更新中。

如果你觉得这篇文章对你有帮助,还麻烦点个赞关个注分个享留个言

MySQL 中删除的数据都去哪儿了?的更多相关文章

  1. mysql中删除重复数据

    //首先我们需要知道我们重复的都有哪些数据, //第一步:进行对数据表进行分组,group by. //第二步:进行后通过having进行限制筛选,条数大于等于2的 //第三步:进行多表删除. //案 ...

  2. MySQL中删除重复数据的简单方法,mysql删除重复数据

    MYSQL里有五百万数据,但大多是重复的,真实的就180万,于是想怎样把这些重复的数据搞出来,在网上找了一圈,好多是用NOT IN这样的代码,这样效率很低,自己琢磨组合了一下,找到一个高效的处理方式, ...

  3. Mysql 中删除重复数据(保留一条)

    sql去重 先根据需要去重的字段进行分组,取到主键值最小的记录(id 是主键,删除重复的 record_id 的记录) select min(id) from tb_traffic_wf_record ...

  4. MySQL中删除重复数据只保留一条

    用SQL语句,删除掉重复项只保留一条 在几千条记录里,存在着些相同的记录,如何能用SQL语句,删除掉重复的呢 1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 SELECT ...

  5. sql语句中----删除表数据drop、truncate和delete的用法

    sql语句中----删除表数据drop.truncate和delete的用法 --drop drop table  tb   --tb表示数据表的名字,下同 删除内容和定义,释放空间.简单来说就是把整 ...

  6. from表单上提交的数据都去了哪里呢?

    from表单上提交的数据都去了哪里呢? 一个简单的from案例如下: <form> 姓名:<br> <input type="text" name=& ...

  7. MySQL_(Java)使用JDBC向数据库中删除(delete)数据

    MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC向数据库中插入(insert)数据 传送门 MySQL_(Java)使用JDBC向数据库中删除(d ...

  8. mySQL中删除unique key的语法 (删除某个字段的唯一性)

    mySQL中删除unique key的语法 CREATE TABLE `good_booked` (  `auto_id` int(10) NOT NULL auto_increment,  `goo ...

  9. mysql进阶(十五) mysql批量删除大量数据

    mysql批量删除大量数据 假设有一个表(syslogs)有1000万条记录,需要在业务不停止的情况下删除其中statusid=1的所有记录,差不多有600万条, 直接执行 DELETE FROM s ...

随机推荐

  1. 用python+pyqt5语言编写的扫雷小游戏软件

    github源码地址:https://github.com/richenyunqi/Mine-game ,撒娇打滚求star哦~~ღ( ´・ᴗ・` )比心 扫雷主界面模块 整个扫雷界面使用大量的白色方 ...

  2. 即时通信之 SignalR

    即时通信在日常的web开发场景中经常使用,本篇主要回顾一下SignalR的实现原理和通过例子说明如何在.NET Core 中使用. SingnalR 应用 需要从服务器进行高频更新的应用程序.例如游戏 ...

  3. 使用 Docker 秒速搭建多版本 PHP 开发环境

    目录 目标 下载 代理设置 配置环境 PHP 7.2.x,占用本地端口 8081 PHP 5.6.x,占用本地端口 8082 端口映射 local.php72.com -> 127.0.0.1: ...

  4. hadoop学习(三)HDFS常用命令以及java操作HDFS

    一.HDFS的常用命令 1.查看根目录下的信息:./hadoop dfs -ls 2.查看根目录下的in目录中的内容:./hadoop dfs -ls in或者./hadoop dfs -ls ./i ...

  5. Redis 高级面试题

    Redis 持久化机制 Redis 是一个支持持久化的内存数据库,通过持久化机制把内存中的数据同步到硬盘文件来 保证数据持久化.当 Redis 重启后通过把硬盘文件重新加载到内存,就能达到恢复数据的目 ...

  6. 详解Docker 端口映射与容器互联

    详解Docker 端口映射与容器互联 1.端口映射实现访问容器 1.从外部访问容器应用 在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内部的网络应用和服务的. 当容器中运行 ...

  7. buu 达芬奇 && ROT

    一.达芬奇 百度了下电影简介,发现了斐波那契数列,同时发现密文是由斐波那契数列移动而来的,有点像base64变种 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 ...

  8. 字符串中的第一个唯一字符 python

    给定一个字符串,找到它的第一个不重复的字符,并返回它的索引.如果不存在,则返回 -1. s = "leetcode" 返回 0. s = "loveleetcode&qu ...

  9. SFC style CSS variable injection

    摘要 在单文件组件样式中支持使用组件状态驱动的 CSS 变量( CSS 自定义属性). 基础示例 <template> <div class="text"> ...

  10. 手写系列-实现一个铂金段位的 React

    一.前言 本文基于 https://pomb.us/build-your-own-react/ 实现简单版 React. 本文学习思路来自 卡颂-b站-React源码,你在第几层. 模拟的版本为 Re ...