Databases 9 min read

How MySQL InnoDB Allocates Undo Segments

This article explains the internal process MySQL 8.0.32 InnoDB uses to allocate, create, and manage Undo segments—including cached segment retrieval, new segment creation, insertion into rollback segment lists, conflict avoidance through mutexes, and a concise step‑by‑step summary of the entire workflow.

Aikesheng Open Source Community
Aikesheng Open Source Community
Aikesheng Open Source Community
How MySQL InnoDB Allocates Undo Segments

Based on the MySQL 8.0.32 source code with the InnoDB storage engine, this article details how Undo segments are allocated, created, and linked to rollback segments.

1. Allocating Cached Undo Segments

The Undo segment memory structure contains two linked‑list properties:

insert_undo_cached : caches Insert Undo segments.

update_undo_cached : caches Update Undo segments.

These cached lists serve two purposes: speeding up Undo segment allocation and reusing the space of Undo pages managed by the Undo segment, thereby improving space utilization.

When allocating an Insert Undo segment, the system first tries to obtain a segment from the insert_undo_cached list head. If successful, the segment is removed from the list; otherwise a new Undo segment is created.

The same logic applies to Update Undo segments, using the update_undo_cached list.

2. Creating a New Undo Segment

If no cached segment is available, a new Undo segment must be created. Both Insert and Update Undo segments share the same structure; they are distinguished by the type field, which can be TRX_UNDO_INSERT or TRX_UNDO_UPDATE .

A rollback segment can manage up to 1024 Undo segments. To allocate a new segment, the system scans the 1024 slots on the rollback segment’s header page to find a free slot (value 4294967295 , defined as FIL_NULL ). The allocation steps are:

Iterate over the 1024 slots from the first one.

Read the integer stored in each slot.

If the integer equals 4294967295 ( FIL_NULL ), the slot is free and the search stops.

Otherwise continue to the next slot.

Once a free slot is found, the system:

Allocates a page from the Undo tablespace; this page becomes both the Undo segment’s header page and an Undo log page.

Initializes the header page fields.

Writes the newly allocated page number into the free slot.

Creates the in‑memory Undo segment structure and initializes its attributes.

If no free slot is found after scanning all 1024 entries, MySQL returns error (1637, 'Too many active concurrent transactions') and logs a message indicating that the system has run out of free slots for Undo logs.

3. Adding the Undo Segment to the List

Whether the Undo segment comes from a cached list or is newly created, it is inserted at the head of the appropriate list in the rollback segment:

Insert Undo segments go to insert_undo_list .

Update Undo segments go to update_undo_list .

When a new segment is created, its header page number is written into the previously found free slot in the rollback segment; the list insertion itself is an in‑memory operation.

4. How to Avoid Conflicts

The number of Undo tablespaces for regular user tables is controlled by the system variable innodb_undo_tablespaces (default 2). Each tablespace contains a number of rollback segments defined by innodb_rollback_segments (default 128), giving a total of 256 rollback segments.

If 256 or more concurrent read‑write transactions try to allocate Undo segments, multiple transactions may contend for the same rollback segment. To prevent this, a mutex is acquired on the rollback segment before accessing either insert_undo_cached or update_undo_cached . After obtaining or creating an Undo segment and inserting it into the appropriate list, the mutex is released, ensuring exclusive access during allocation.

5. Summary

The overall workflow for allocating an Undo segment, given an already assigned rollback segment, is:

Acquire the rollback segment’s mutex.

Try to fetch an Undo segment from the cached lists insert_undo_cached or update_undo_cached .

If a cached segment is found, remove it from the list.

If not, create a new Undo segment following the steps described above.

Insert the segment at the head of insert_undo_list or update_undo_list as appropriate.

Release the rollback segment’s mutex.

TransactionDatabaseInnoDBMySQLRollbackundo
Aikesheng Open Source Community
Written by

Aikesheng Open Source Community

The Aikesheng Open Source Community provides stable, enterprise‑grade MySQL open‑source tools and services, releases a premium open‑source component each year (1024), and continuously operates and maintains them.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.