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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL DuckDB 分析主实例,集群系列 8核16GB
简介: 什么?还在用delete删除数据《死磕MySQL系列 九》

别再用delete删除数据



参与了好几个项目开发,每个项目随着业务量的增大,MySQL数据日益剧增,例如其中一个项目中得用户足迹表,那是非常的疯狂,只怪我大意了,没有闪。


这篇文章我会从delete对性能的影响,以及如何以正确的姿势来删除数据。


在MySQL中Innodb存储引擎的表存在两部分,一部分是表结构,另一部分是表数据。


在MySQL8.0之前/var/lib/mysql下都会存在.frm文件,在MySQL8.0之后就不存在了。这是因为MySQL8.0中已经允许把表结构定义放到数据字典中了,是用参数innodb_file_per_table来决定的。


一、表空间

表空间分为几种,系统表空间、用户表空间、undo空间。


系统表空间:MySQL内部的数据字典,如information_schema库下的数据。


用户表空间:自己建立的表结构数据


undo空间:存储Undo信息,用于快速回滚。


MySQL8.0之前表结构是在系统表空间存储的,在MySQL5.6.6后可以使用参数innodb_file_per_table来控制。


设置为off时,表数据是放在系统表空间中,也就是MySQL的数据字典放在一起。


设置为on时,innodb存储引擎的表数据存储在.idb文件中。


你知道表定义存储在哪里吗?


来到死磕MySQL系列的专用数据库kaka,新建一张表evt_sms。


image.png


猜一下创建的evt_sms表结构定义存储在哪里呢?


在information_schema库里边的TABLES中,执行查询SELECT TABLE_NAME,TABLE_COMMENT FROM TABLES WHERE TABLE_TYPE='BASE TABLE';


我们自定义的表类型是TABLE_TYPE。


image.png



说了这么是为了解释如果把innodb_file_per_table设置为off,则表数据也会存放在这里。


问题:如果数据存在放共享表空间中,表删除了,空间会删除吗?


答案是不会的。


参数innodb_file_per_table设置为on数据存储在哪里呢?


一般情况下是在var/lib/mysql中,会看到你创建的数据库,进入到数据库中就能看到一张表对应一个ibd文件。


数据就是存储在这里。


image.png


结论


在项目开始阶段,切记将innodb_file_per_table设置为on,这是正确的做法。


二、数据删除流程

现在你应该知道Innodb存储引擎用的是B+树数据结构,如下图。


image.png


如果现在删了主键ID为4的这条记录,Innodb引擎会把ID为4的这条记录标记为删除,如果之后再插入ID为4的记录,可能会复用这个位置,但磁盘文件大小并不会缩小。


隐式字段


这里就牵扯到了mvcc中的一个知识点,MVCC实现原理是由俩个隐式字段、undo日志、Read view来实现的。


上文说的标记删除就是隐式字段中的delete flag,即记录被更新或删除,这里的删除并不代表真的删除,而是将这条记录的delete flag改为true。


在MVCC:听说有人好奇我的底层实现这篇文章中也给大家留下了一个伏笔,数据库的删除是真的删除吗?


image.png


问题:删了一个数据页的所有数据会怎么样


跟单条数据是一样的,整个数据页都是可以复用的。


记录的复用是仅限于符合范围条件的数据,例如上文删除的ID为4这条记录,如果在插入ID为4就会复用。


这里需要给大家再聊一个新的知识点页合并,若相邻的两个数据页利用率都很低,系统就会把这两个数据页合并到一个页上,另一个数据页就会标记为可复用。


问题:使用delete把整个表的数据都删除了会怎么样


答案是,所有的数据页都会标记为可复用,但是磁盘文件大小是不会改变的。


三、实践全表删除表文件大小不改变


image.png


经过添加数据后表数据已经达到近100W了,文件大小已经达到108M。


扩展


这里大家应该能看见stopped,就是执行命令ctrl + z来的,作用是开始我们在MySQL窗口里边,但不想退出MySQL窗口查看MySQL表文件大小,然后就可以执行这个命令结束任务。


查看完后可以在执行fg返回到MySQL窗口。


image.png


问题:Linux如何把文件单位显示为M


假设刚刚直接执行ll命令查看文件,那么就需要手动计算文件大小,很不方便。


执行ll -h命令则可以直观的看到文件大小。


image.png


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


image.png


为了直观看大文件大小变化,咔咔直接把表里边的数据全部删了,再看文件大小,还是108M。文件大小是没有变化的。



相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
Mysql数据恢复—Mysql数据库delete删除后数据恢复案例
本地服务器,操作系统为windows server。服务器上部署mysql单实例,innodb引擎,独立表空间。未进行数据库备份,未开启binlog。 人为误操作使用Delete命令删除数据时未添加where子句,导致全表数据被删除。删除后未对该表进行任何操作。需要恢复误删除的数据。 在本案例中的mysql数据库未进行备份,也未开启binlog日志,无法直接还原数据库。
|
关系型数据库 MySQL Shell
MySQL回滚脚本: 误操作delete binlog回滚shell脚本
MySQL回滚脚本: 误操作delete binlog回滚shell脚本
|
存储 关系型数据库 MySQL
MySQL删除数据 文件大小不变的原因以及处理空洞问题
总之,MySQL中删除数据后文件大小不变的现象是由于InnoDB存储引擎的设计决策,旨在优化性能和空间的重用。处理这一问题需要综合考量数据库的使用场景以及可能的性能影响,选择合适的策略
1336 6
|
SQL 关系型数据库 MySQL
MySQL删除表数据、清空表命令(truncate、drop、delete 区别)
MySQL删除表数据、清空表命令(truncate、drop、delete区别) 使用原则总结如下: 当你不需要该表时(删除数据和结构),用drop; 当你仍要保留该表、仅删除所有数据表内容时,用truncate; 当你要删除部分记录、且希望能回滚的话,用delete;
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用问题之 MySQL数据库中,执行delete命令删除数据后,存储空间通常不会立即释放,该如何优化
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
424 2
|
SQL Oracle 关系型数据库
实时计算 Flink版产品使用问题之在从MySQL同步数据到Doris时,delete语句无法同步,是什么原因
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
关系型数据库 MySQL 数据库
mysql,归零,无法自动排序,删除id,表单的数据没有从零开始出现怎样解决?删除数据仍然从删除的地方该怎样解决?表单的数据没有从2开始,而是从之前的删除的序号开始自增。
mysql,归零,无法自动排序,删除id,表单的数据没有从零开始出现怎样解决?删除数据仍然从删除的地方该怎样解决?表单的数据没有从2开始,而是从之前的删除的序号开始自增。
|
关系型数据库 MySQL 数据库
DELETE、TRUNCATE 和 DROP 在MySQL中的区别及使用示例
DELETE、TRUNCATE 和 DROP 在MySQL中的区别及使用示例
819 0
|
3月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
155 3
|
3月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。