mysql数据删除策略

本文详细介绍了InnoDB存储引擎中表数据的存放方式,以及innodb_file_per_table参数的作用。在数据删除流程中,讨论了记录和数据页的复用机制,并指出磁盘文件大小不会因删除而减小。接着,阐述了重建表的过程,包括在线与非在线执行的区别,以及MySQL如何通过重建表来优化磁盘空间。重建表过程中,InnoDB会预留部分空间以备后续更新,因此重建后的表并非最紧凑。最后,提到了online和inplace操作的概念及其区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先我们表数据的存放,他可以存在共享空间里面,也可以是单独的文件,这个行为是由参数innodb_file_per_table控制的。它有以下两个值:

OFF:表的数据存放在系统共享表空间。

ON:每个InnoDB表数据存储在一个以.ibd为后缀的文件中。默认是ON

数据删除流程

接下来删除流程的讲解时基于innodb_file_per_table是ON来描述的。下面我们看看一个索引结构图

现在如果我们要删除R4这个记录,那么就把R4这个记录成删除,之后如果要插入一个ID在300和600之间的记录时,可能会复用这个位置。如此,磁盘文件的大小不会减少。

如果删除了整个数据页上所有的数据,那么整个数据页就可以复用了,数据页的复用和记录的复用是不同的。

 

  1. 记录的复用,只限于符合范围的数据,如上面R4的位置被删除后,如果插入一个ID是400的行,那么可以直接复用,如果是800的,那么不能。

  2. 数据页的复用,如果选择需要插入一条ID为50的记录,需要另外申请一个数据页,那么可能这个数据页就会被复用。

以上两种情况,磁盘上的文件都不会变小。

还有一种情况,插入数据也可能会造成数据的留空,如下插入一个550的数据,而一页上的数据已经满了,那么就会申请新的一页。

这个时候pageA页就会留下空白。如果要把这些空白去掉,就可以采用重建表的操作。

重建表

使用alter table A engine=InnoDB命令来重建表,MySQL会自动完成转存数据、交换表名、删除旧表的操作。

上面是一个改锁表的过程,这个会创建一个临时表。

花时间最多的是往临时表插入数据的过程,有新的数据要写入到表A,造成数据丢失,所以在整个执行语句的过程中,A表不能有更新,所以整个执行时不能在线执行的。在后面的版本mysql做了优化,这个叫online执行:

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

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

3. 生成临时文件的过程中,将所有对A的操作记录在一个日志文件(row log)中,对应的是图中state2的状态;

4. 临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与表A相同的数据文件,对应的就是图中state3的状态;

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

 

在以上的流程中,alter语句在启动的时候需要获取MDL写锁,但是这个写锁在真正拷贝数据之前就退化成读锁了。这样子,就不会阻塞增删改的操作了。但是也不能直接解锁,因为怕有其他的线程也在执行相同的指令。

Online和inplace

在上面的第一个重建表方案中,会创建出来一个临时表,这个是在server层创建的。表A重建出来的数据时放在tmp_file中的,这个临时文件是InnoDB在内部创建出来的。整个语句执行过程都是在InnoDB中完成的,即使在引擎层完成的,对于server层来说,他并没有把数据移动到临时表,是一个inplace操作。

所以说online操作一定是inplace的。但是inplace的不一定是online的,如加一个全文索引,它会阻塞增删改操作,是非online的。

最后说一句,在重建表的时候,InnoDB不会把整张表占满,每个页留了1/16给后续的更新用。也就是说,其实重建表之后不是“最”紧凑的。

### 如何设置或更改 MySQL 删除 Binlog 的策略MySQL 中,Binlog 是二进制日志文件,用于记录数据库中的事务操作。这些日志对于数据恢复、主从复制以及增量备份非常重要。然而,随着时间推移,Binlog 文件会占用大量磁盘空间。因此,合理配置删除 Binlog 的策略至关重要。 #### 自动清理机制 MySQL 提供了一个内置参数 `expire_logs_days` 来自动管理 Binlog 的保留周期。该参数定义了 Binlog 文件保存的最大天数。超过指定天数的 Binlog 将被自动删除[^1]。 可以通过修改 MySQL 配置文件(通常是 my.cnf 或 my.ini)来调整此参数: ```ini [mysqld] expire_logs_days = 7 ``` 上述配置表示 Binlog 文件将在创建后 7 天内有效,之后会被自动清除。如果希望禁用自动清理功能,则可以将值设为 0。 #### 手动删除 Binlog 除了依赖于 `expire_logs_days` 参数外,还可以手动执行命令以删除不再需要的 Binlog 文件。以下是常用的两种方法: 1. **PURGE BINARY LOGS 命令** 使用 SQL 查询方式删除特定日期之前的 Binlog 文件: ```sql PURGE BINARY LOGS BEFORE 'YYYY-MM-DD HH:MM:SS'; ``` 此语句会删除所有早于此时间戳的日志文件。例如,要删除截至前一天的所有 Binlog 日志,可运行如下命令: ```sql PURUGE BINARY LOGS BEFORE DATE_SUB(CURDATE(), INTERVAL 1 DAY); ``` 2. **RESET MASTER 命令** 如果确认不需要任何历史 Binlog 数据,可以直接重置 Master 日志状态并清空现有日志列表: ```sql RESET MASTER; ``` 这一操作不可逆,应谨慎使用。 #### 注意事项 当涉及 Apache NiFi 同步 Mysql 到 HBase 场景时,需特别注意 Binlog 清理可能带来的影响[^2]。由于 NiFi 取决于 Binlog 记录的数据变更事件,在设定删除策略前务必确保下游消费者已完全处理完毕相关日志内容。否则可能导致同步失败或者丢失部分更新信息。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值