DEV Community

dkelxldk
dkelxldk

Posted on

MariaDB 12 Broke Our Concurrent Updates: Debugging ERROR 1020 After an Upgrade

We recently deployed a new environment using MariaDB 12.3, while our older environments were still running MariaDB 10.11.

Soon after deployment, some concurrent UPDATE operations started failing with:

ERROR 1020 (HY000): Record has changed since last read in table
Enter fullscreen mode Exit fullscreen mode

The interesting part: the same application logic had been running fine on MariaDB 10.11.

Finding the Difference

After comparing both environments, we found this:

Environment MariaDB innodb_snapshot_isolation
Existing 10.11.x OFF
New 12.3.x ON

You can check it with:

SHOW VARIABLES LIKE 'innodb_snapshot_isolation';
Enter fullscreen mode Exit fullscreen mode

MariaDB changed the default of innodb_snapshot_isolation to ON starting from newer releases.

With it enabled, MariaDB performs stricter write-conflict detection under REPEATABLE READ.

A simplified scenario:

Transaction A reads row
        ↓
Transaction B updates and commits row
        ↓
Transaction A tries to update same row
        ↓
ERROR 1020
Enter fullscreen mode Exit fullscreen mode

So the concurrent access pattern was not necessarily new.

What changed was how MariaDB handled it.

The Compatibility Fix

Our existing production environments were already running successfully with:

innodb_snapshot_isolation = OFF
Enter fullscreen mode Exit fullscreen mode

So for the new environment, we aligned the configuration:

SET GLOBAL innodb_snapshot_isolation = OFF;
Enter fullscreen mode Exit fullscreen mode

After changing it, the ERROR 1020 failures disappeared under our workload.

Is Disabling It Always the Right Solution?

No.

ERROR 1020 can indicate a legitimate concurrency conflict.

Longer term, applications may want to handle this using approaches such as:

transaction retries
SELECT ... FOR UPDATE
atomic UPDATE statements
optimistic locking
shorter transactions
Enter fullscreen mode Exit fullscreen mode

For us, disabling it was mainly a compatibility decision so the upgraded environment behaved consistently with the existing production system.

Takeaway

The main lesson wasn't the one-line config change.

It was this:

When application behavior changes after a database upgrade, compare database defaults and configuration — not just application code.

A major database upgrade can expose concurrency assumptions that have existed unnoticed for years.

In our case, the difference came down to one setting:

MariaDB 10.11 → innodb_snapshot_isolation = OFF
MariaDB 12.3  → innodb_snapshot_isolation = ON
Enter fullscreen mode Exit fullscreen mode

Sometimes a production issue that looks like an application regression is actually a database behavior change.

Top comments (2)

Collapse
 
raknaos profile image
Raknaos

The takeaway about comparing server defaults rather than app code is the one most upgrade postmortems miss. innodb_snapshot_isolation=ON turns a silently-lost-update race into a hard error, which is arguably MariaDB doing you a favour — the conflict was always there on 10.11, it just resolved last-writer-wins without telling anyone.

Worth noting for anyone hitting this: the retry path matters more than the flag. If your UPDATE is idempotent, catching ERROR 1020 and retrying the transaction keeps the safety on. We went the same config-alignment route during a version jump and it worked, but we tracked it as debt precisely because the stricter mode was flagging a real race.

Collapse
 
dkelxldk profile image
dkelxldk

Yeah, that’s a fair point.

For us, disabling innodb_snapshot_isolation was mostly about keeping the new environment consistent with the existing 10.11 setup first, rather than treating it as the final fix.

But I agree that the stricter behavior is exposing a race that was already there. The retry approach is probably the better long-term direction, especially for operations that are safe to retry.

Good call on treating the config change as debt rather than considering the issue fully solved.