[MDEV-33213] History list is not shrunk unless there is a pause in the workload Created: 2024-01-10 Updated: 2024-02-07 Resolved: 2024-01-17 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Affects Version/s: | 10.6, 10.11, 11.0, 11.1, 11.2, 11.3, 11.4 |
| Fix Version/s: | 10.10.7, 10.6.17, 10.11.7, 11.0.5, 11.1.4, 11.2.3, 11.3.2, 11.4.1 |
| Type: | Bug | Priority: | Blocker |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 1 |
| Labels: | performance | ||
| Attachments: |
|
||||||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||||||
| Description |
|
While testing Some initial debugging indicates that the purge_truncation_task (which was added in |
| Comments |
| Comment by Axel Schwenke [ 2024-01-10 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
This is the same build from branch 10.6- | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2024-01-10 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I instrumented a 11.x server with the following patch:
I see output like this:
The workload script is based on something that I used for I tried again oltp_update_non_index, which should allow purge to work around MDEV-17598. Same thing there, despite a 3-second sleep between two 60-second workloads:
Roughly coinciding with the 3-second sleep, we see some reduction of the history list, followed by a steady growth to the end of the run. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2024-01-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
During the busy part of my test workload, purge_sys.sees(rseg.needs_purge) would never hold in purge_sys_t::iterator::free_history(). Occasionally, rseg.is_referenced() would hold. Only when trx_purge_truncate_rseg_history() is invoked with all=true, the history would be shrunk. When all=false, I observed the difference trx_sys.get_max_trx_id()-rseg.needs_purge to be between 0 and 3379. The type of the field trx_rseg_t::needs_purge was changed from a Boolean to a transaction identifier in | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2024-01-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The following patch, which will prevent the reuse of undo pages by multiple small transactions (TRX_UNDO_CACHED), will allow the history list to shrink during my test workload:
If this change turns out to improve performance in a broad selection of benchmarks, we might want to introduce a configuration parameter for this. Back when I was working on Note: In | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2024-01-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I think that the only practical way to prevent rseg.needs_purge from blocking the cleanup action is to temporarily disable one rollback segment at a time, by invoking trx_rseg_t::skip_allocation(). Adding more rollback segments is not practical, because the current file format (especially the format of DB_ROLL_PTR) limits us to only 128 rollback segments, or 127 when innodb_undo_tablespaces>0 because the first one is hard-coded in the system tablespace. When transactions are started, they can choose any of the other rollback 127 or 126 segments while the purge subsystem is preparing to free the undo log pages that stored the already purged history in one rollback segment. For innodb_undo_log_truncate=ON we already disable all rollback segments (trx_rseg_t::set_skip_allocation()) that belong to the purge_sys.truncate.current tablespace. The reason why this logic does not work during a heavy workload is that we are “too shy” to prepare for the truncation. If we allow purge_coordinator_state::do_purge() to invoke that part of trx_purge_truncate_history() directly, then undo tablespace truncation will work during the workload. I have implemented this, and it seems to work with my simple benchmark script, without too much disruption on the throughput. If we also invoked trx_rseg_t::set_skip_allocation() for one rollback segment at a time in the innodb_undo_log_truncate=OFF case, the need for undo tablespace truncation should be reduced. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Axel Schwenke [ 2024-01-12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The commit 4799e4efee2 in branch mariadb-10.6- Attachments: 12x5.pdf | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Axel Schwenke [ 2024-01-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I repeated now the TPC-C regression tests. They run on cheetah01 and include tests with innodb_undo_log_truncate=OFF (default) as well as innodb_undo_log_truncate=ON. The results also look good. Attached; 10.6-MDEV-33213.pdf | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Matthias Leich [ 2024-01-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
10.6- | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Matthias Leich [ 2024-01-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
RQG testing etc. |