InnoDBStatus.comMySQL InnoDB Diagnostic Tool

Analyzing InnoDB Rollback Progress in MySQL

When InnoDB rolls back a large transaction, it reports progress in the TRANSACTIONS section of SHOW ENGINE INNODB STATUS with a line such as "ROLLING BACK 12345 lock struct(s), heap size 1024, 9876 row lock(s), undo log entries 56789". This information lets you estimate how long the rollback will take and whether it is safe to restart MySQL or whether doing so will only extend the recovery time. InnoDB rollback is performed at the same speed as the original transaction — it cannot be paused, cancelled, or accelerated — so understanding what drives its duration is critical for capacity planning and incident management. This guide explains every rollback progress field, how to estimate completion time, and how to architect transactions to minimise future rollback durations.

Reading the Rollback Progress Indicator

Interpreting the "Rolling Back" Status Line

The "ROLLING BACK" line appears in the TRANSACTIONS section only for the specific transaction currently being rolled back. The "lock struct(s)" count shows how many lock structures (groups of row locks on the same page) need to be released, while "undo log entries" shows the total number of row versions that must be reversed. Rollback progress is not displayed as a percentage natively, but you can approximate it by sampling undo log entries at two points in time: progress% ≈ (1 - current_undo_entries / initial_undo_entries) × 100. This requires capturing the initial count when rollback begins. The InnoDB monitor output refreshes every ~30 seconds by default; run SHOW ENGINE INNODB STATUS in a loop with a 5-second interval via a shell script or pt-mext to track progress accurately.

Do NOT restart MySQL while a rollback is in progress. If you restart the server, InnoDB must perform Crash Recovery on startup: it first replays the redo log, then restarts the rollback from the beginning using the undo log. The total downtime will be doubled or tripled compared to simply waiting for the current rollback to complete. If a rollback is running, your only safe option is to wait for it to finish.

Undo Log Rows Remaining and Estimated Completion

To estimate rollback completion time, record the undo log entry count at two timestamps separated by 60 seconds and compute the rollback rate as (count_t1 - count_t2) / 60 undo entries per second. Dividing the remaining entries by this rate gives an estimated time to completion. For a transaction that inserted 10 million rows at an undo processing rate of 50,000 entries/second, expect approximately 200 seconds of rollback. The undo processing rate is bounded by I/O throughput to the undo tablespace, which is why placing undo tablespaces on the fastest available storage (NVMe) is recommended for systems that regularly run large batch transactions. In MySQL 8.0+, you can query the estimated rollback progress from performance_schema.events_transactions_current for instrumented threads.

Causes of Large Rollbacks

Long-Running Transactions and Batch Operations

Long-running transactions that touch millions of rows are the primary cause of multi-hour InnoDB rollbacks. A batch DELETE or UPDATE that modifies 50 million rows without intermediate commits creates 50 million undo log entries that must all be reversed on rollback. The undo log segments grow on disk during the transaction, potentially filling the undo tablespace and triggering "Undo log has grown too large" errors. Best practice: commit every 1,000–10,000 rows in batch operations using a cursor loop or "chunked DML" pattern (WHERE pk > last_processed_pk LIMIT 1000). Percona Toolkit's pt-archiver and pt-online-schema-change implement safe chunked processing automatically. Even if the operation needs to be retried from a checkpoint after a failure, the maximum rollback work is bounded to a single chunk.

Application Crash and Implicit Rollback on Connection Drop

An implicit rollback is triggered automatically by InnoDB when: (1) a client connection drops mid-transaction due to network failure or application crash, (2) a deadlock victim is selected, (3) innodb_lock_wait_timeout fires with rollback_on_timeout=ON, or (4) the MySQL server detects an error in the transaction that cannot be retried (e.g., a duplicate key violation in a non-ignorable context). From MySQL's perspective, all four cases are identical — InnoDB must undo all changes in reverse order from the undo log. The most dangerous scenario is scenario 1: a long-running import or ETL job that loses its connection after 99% completion. Implement application-level checkpointing with explicit COMMIT calls so that a connection drop only loses work since the last checkpoint, not the entire operation.

Minimizing Rollback Impact

Breaking Large Transactions into Smaller Batches

Choosing the right batch size and commit interval for large DML operations requires balancing three competing concerns: rollback cost (smaller batches = shorter rollback), redo log write amplification (larger batches = fewer fsync() calls), and replication lag (smaller batches = more binary log events = more replica apply work). A batch size of 1,000–5,000 rows typically provides the best balance for most OLTP workloads. Measure the actual throughput with different batch sizes using SHOW STATUS LIKE 'Innodb_rows_%' before and after each batch. Set innodb_flush_log_at_trx_commit=2 temporarily during non-critical bulk loads to batch redo log fsyncs to once per second, reducing write latency by 5–10× at the cost of up to 1 second of data loss exposure.

innodb_force_recovery for Post-Crash Scenarios

After a server crash, InnoDB automatically rolls back uncommitted transactions during crash recovery using the undo log. The duration of crash recovery is proportional to the undo log size of the largest incomplete transaction at crash time. Use innodb_force_recovery to control recovery aggressiveness: level 1 (SRV_FORCE_IGNORE_CORRUPT) ignores corrupted pages, level 3 (SRV_FORCE_NO_TRX_UNDO) skips the undo rollback phase entirely to make the server start faster in an emergency. Levels 4–6 progressively disable more InnoDB subsystems and should be used only to dump data out of a damaged instance before rebuilding. After using innodb_force_recovery > 0, the instance must be treated as read-only and the data exported and re-imported into a clean instance.

Ready to Diagnose Your MySQL Instance?

Paste your SHOW ENGINE INNODB STATUS output and get an instant visual analysis — 100% in your browser, no data sent anywhere.

Analyze my status now →