### 15.8.9 清除配置

[](<>)[](<>)[](<>)

`InnoDB`当您使用 SQL 语句删除某行时，它不会立即从数据库中物理删除该行。行及其索引记录仅在以下情况下被物理删除`InnoDB`丢弃为删除而写的撤消日志记录。这种删除操作仅在多版本并发控制 (MVCC) 或回滚不再需要该行之后发生，称为清除。

清除定期运行。它解析和处理历史列表中的撤消日志页面，历史列表是已提交事务的撤消日志页面列表，由`InnoDB`交易系统。清除处理后从历史列表中释放撤消日志页面。

#### 配置清除线程

清除操作由一个或多个清除线程在后台执行。清除线程的数量由[`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads)多变的。默认值为 4。

如果 DML 操作集中在单个表上，则表的清除操作由单个清除线程执行，如果 DML 操作涉及较大的对象值，这可能会导致清除操作变慢、清除延迟增加和表空间文件大小增加。从 MySQL 8.0.26 开始，如果[`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag)超出设置，清除工作会自动在可用的清除线程之间重新分配。在这种情况下，过多的活动清除线程可能会导致与用户线程的争用，因此请管理[`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads)相应地设置。这[`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag)变量默认设置为 0，这意味着默认情况下没有最大清除延迟。

如果 DML 操作集中在几个表上，请保留[`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads)设置为低，以便线程不会相互竞争访问繁忙的表。如果 DML 操作分布在许多表中，请考虑更高[`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads)环境。清洗线程的最大数量为 32。

这[`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads)设置是允许的最大清除线程数。清洗系统会自动调整使用的清洗线程数。

#### 配置清除批量大小

这[`innodb_清除_批量_大小`](innodb-parameters.html#sysvar_innodb_purge_batch_size)变量定义从历史记录列表中一批清除解析和进程的撤消日志页数。默认值为300。在多线程清除配置中，协调器清除线程将[`innodb_清除_批量_大小`](innodb-parameters.html#sysvar_innodb_purge_batch_size)通过[`innodb_清除_线程`](innodb-parameters.html#sysvar_innodb_purge_threads)并将该页数分配给每个清除线程。

清除系统还会释放不再需要的撤消日志页。它通过撤销日志每128次迭代执行一次。除了定义批处理中解析和处理的撤消日志页的数量外[`innodb_清除_批量_大小`](innodb-parameters.html#sysvar_innodb_purge_batch_size)变量定义每128次通过撤销日志清除释放的撤销日志页数。

这个[`innodb_清除_批量_大小`](innodb-parameters.html#sysvar_innodb_purge_batch_size)变量用于高级性能调整和实验。大多数用户不需要改变[`innodb_清除_批量_大小`](innodb-parameters.html#sysvar_innodb_purge_batch_size)从其默认值。

#### 配置最大清除延迟

这个[`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag)变量定义所需的最大净化滞后时间。当净化滞后超过[`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag)阈值，则对[`插入`](insert.html),[`使现代化`](update.html)和[`删去`](delete.html)为净化操作留出时间。默认值为0，这意味着没有最大清除滞后和延迟。

这个`InnoDB`事务处理系统维护一个事务列表，其中索引记录由delete标记[`使现代化`](update.html)或[`删去`](delete.html)操作。列表的长度是清除延迟。在MySQL 8.0.14之前，清除滞后延迟是通过以下公式计算的，这导致最小延迟为5000微秒：

```
(purge lag/innodb_max_purge_lag - 0.5) * 10000
```

从MySQL 8.0.14开始，清除延迟通过以下修订公式计算，该公式将最小延迟减少到5微秒。5微秒的延迟更适合现代系统。

```
(purge_lag/innodb_max_purge_lag - 0.9995) * 10000
```

延迟在吹扫批次开始时计算。

典型的[`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag)有问题的工作负载的设置可能是1000000（100万），假设事务很小，大小只有100字节，并且允许有100MB的未敦促表行。

吹扫滞后时间表示为`历史记录列表长度`价值观`交易`部分[`显示引擎INNODB状态`](show-engine.html)输出

```
mysql> SHOW ENGINE INNODB STATUS;
...
------------
TRANSACTIONS
------------
Trx id counter 0 290328385
Purge done for trx's n:o < 0 290315608 undo n:o < 0 17
History list length 20
```

这个`历史记录列表长度`通常是一个较低的值，通常不到几千个，但写繁重的工作负载或长时间运行的事务可能会导致它增加，即使对于只读事务也是如此。长时间运行的事务可能导致`历史记录列表长度`增加的是在一致的读事务隔离级别下，例如`可重复读取`，事务必须返回与创建该事务的读取视图时相同的结果。因此`InnoDB`多版本并发控制（MVCC）系统必须在撤销日志中保留一份数据副本，直到依赖该数据的所有事务完成。以下是可能导致`历史记录列表长度`增加：

-   A.[**mysqldump**](mysqldump.html)使用[`--单笔交易`](mysqldump.html#option_mysqldump_single-transaction)选项，同时存在大量并发DML。

-   经营一家[`选择`](select.html)禁用后的查询[`自动提交`](server-system-variables.html#sysvar_autocommit)，忘记发出明确的`犯罪`或`回降`.

    为了防止在吹扫滞后变得巨大的极端情况下出现过度延迟，可以通过设置[`innodb_max_purge_lag_delay`](innodb-parameters.html#sysvar_innodb_max_purge_lag_delay)变量这个[`innodb_max_purge_lag_delay`](innodb-parameters.html#sysvar_innodb_max_purge_lag_delay)变量指定当[`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag)超过阈值。指定的[`innodb_max_purge_lag_delay`](innodb-parameters.html#sysvar_innodb_max_purge_lag_delay)值是由[`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag)公式

#### 清除并撤消表空间截断

清除系统还负责截断撤消表空间。您可以配置[`innodb_purge_rseg_truncate_频率`](innodb-parameters.html#sysvar_innodb_purge_rseg_truncate_frequency)变量，以控制清除系统查找要截断的撤消表空间的频率。有关更多信息，请参阅[截断撤消表空间](innodb-undo-tablespaces.html#truncate-undo-tablespace).
