### 15.8.9 Purge Configuration

[]()[]()[]()

`InnoDB` does not physically remove a row from the database immediately when you delete it with an SQL statement. A row and its index records are only physically removed when `InnoDB` discards the undo log record written for the deletion. This removal operation, which only occurs after the row is no longer required for multi-version concurrency control (MVCC) or rollback, is called a purge.

 Purge runs on a periodic schedule. It parses and processes undo log pages from the history list, which is a list of undo log pages for committed transactions that is maintained by the `InnoDB` transaction system. Purge frees the undo log pages from the history list after processing them.

#### Configuring Purge Threads

 Purge operations are performed in the background by one or more purge threads. The number of purge threads is controlled by the [`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads) variable. The default value is 4.

 If DML action is concentrated on a single table, purge operations for the table are performed by a single purge thread, which can result in slowed purge operations, increased purge lag, and increased tablespace file size if the DML operations involve large object values. From MySQL 8.0.26, if the [`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag) setting is exceeded, purge work is automatically redistributed among available purge threads. Too many active purge threads in this scenario can cause contention with user threads, so manage the [`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads) setting accordingly. The [`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag) variable is set to 0 by default, which means that there is no maximum purge lag by default.

 If DML action is concentrated on few tables, keep the [`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads) setting low so that the threads do not contend with each other for access to the busy tables. If DML operations are spread across many tables, consider a higher [`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads) setting. The maximum number of purge threads is 32.

 The [`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads) setting is the maximum number of purge threads permitted. The purge system automatically adjusts the number of purge threads that are used.

#### Configuring Purge Batch Size

 The [`innodb_purge_batch_size`](innodb-parameters.html#sysvar_innodb_purge_batch_size) variable defines the number of undo log pages that purge parses and processes in one batch from the history list. The default value is 300. In a multithreaded purge configuration, the coordinator purge thread divides [`innodb_purge_batch_size`](innodb-parameters.html#sysvar_innodb_purge_batch_size) by [`innodb_purge_threads`](innodb-parameters.html#sysvar_innodb_purge_threads) and assigns that number of pages to each purge thread.

 The purge system also frees the undo log pages that are no longer required. It does so every 128 iterations through the undo logs. In addition to defining the number of undo log pages parsed and processed in a batch, the [`innodb_purge_batch_size`](innodb-parameters.html#sysvar_innodb_purge_batch_size) variable defines the number of undo log pages that purge frees every 128 iterations through the undo logs.

 The [`innodb_purge_batch_size`](innodb-parameters.html#sysvar_innodb_purge_batch_size) variable is intended for advanced performance tuning and experimentation. Most users need not change [`innodb_purge_batch_size`](innodb-parameters.html#sysvar_innodb_purge_batch_size) from its default value.

#### Configuring the Maximum Purge Lag

 The [`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag) variable defines the desired maximum purge lag. When the purge lag exceeds the [`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag) threshold, a delay is imposed on [`INSERT`](insert.html), [`UPDATE`](update.html), and [`DELETE`](delete.html) operations to allow time for purge operations to catch up. The default value is 0, which means there is no maximum purge lag and no delay.

 The `InnoDB` transaction system maintains a list of transactions that have index records delete-marked by [`UPDATE`](update.html) or [`DELETE`](delete.html) operations. The length of the list is the purge lag. Prior to MySQL 8.0.14, the purge lag delay is calculated by the following formula, which results in a minimum delay of 5000 microseconds:

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

 As of MySQL 8.0.14, the purge lag delay is calculated by the following revised formula, which reduces the minimum delay to 5 microseconds. A delay of 5 microseconds is more appropriate for modern systems.

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

 The delay is calculated at the beginning of a purge batch.

 A typical [`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag) setting for a problematic workload might be 1000000 (1 million), assuming that transactions are small, only 100 bytes in size, and it is permissible to have 100MB of unpurged table rows.

 The purge lag is presented as the `History list length` value in the `TRANSACTIONS` section of [`SHOW ENGINE INNODB STATUS`](show-engine.html) output.

```
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
```

 The `History list length` is typically a low value, usually less than a few thousand, but a write-heavy workload or long running transactions can cause it to increase, even for transactions that are read only. The reason that a long running transaction can cause the `History list length` to increase is that under a consistent read transaction isolation level such as `REPEATABLE READ`, a transaction must return the same result as when the read view for that transaction was created. Consequently, the `InnoDB` multi-version concurrency control (MVCC) system must keep a copy of the data in the undo log until all transactions that depend on that data have completed. The following are examples of long running transactions that could cause the `History list length` to increase:

* A [**mysqldump**](mysqldump.html) operation that uses the [`--single-transaction`](mysqldump.html#option_mysqldump_single-transaction) option while there is a significant amount of concurrent DML.

* Running a [`SELECT`](select.html) query after disabling [`autocommit`](server-system-variables.html#sysvar_autocommit), and forgetting to issue an explicit `COMMIT` or `ROLLBACK`.

 To prevent excessive delays in extreme situations where the purge lag becomes huge, you can limit the delay by setting the [`innodb_max_purge_lag_delay`](innodb-parameters.html#sysvar_innodb_max_purge_lag_delay) variable. The [`innodb_max_purge_lag_delay`](innodb-parameters.html#sysvar_innodb_max_purge_lag_delay) variable specifies the maximum delay in microseconds for the delay imposed when the [`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag) threshold is exceeded. The specified [`innodb_max_purge_lag_delay`](innodb-parameters.html#sysvar_innodb_max_purge_lag_delay) value is an upper limit on the delay period calculated by the [`innodb_max_purge_lag`](innodb-parameters.html#sysvar_innodb_max_purge_lag) formula.

#### Purge and Undo Tablespace Truncation

 The purge system is also responsible for truncating undo tablespaces. You can configure the [`innodb_purge_rseg_truncate_frequency`](innodb-parameters.html#sysvar_innodb_purge_rseg_truncate_frequency) variable to control the frequency with which the purge system looks for undo tablespaces to truncate. For more information, see [Truncating Undo Tablespaces](innodb-undo-tablespaces.html#truncate-undo-tablespace).

