Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
-
Unexpected results
-
Description
Summary
MariaDB ROW replication can preserve identical committed rows while leaving
the replica's implicit InnoDB AUTO_INCREMENT allocator below the primary after
an ignored duplicate-key allocation. A subsequent local insert therefore receives a different identifier on the two endpoints.
Environment
- MariaDB 12.2.2 → MariaDB 12.2.2: 15/15 executions showed the allocator
mismatch across five repetitions and three stress cases, with one clean control per repetition. - MariaDB 10.3 → MariaDB 12.2.2: 9/9 executions showed the allocator mismatch
across three repetitions; the sequential and `TRUNCATE` controls were clean. - MariaDB 10.6 → MariaDB 12.2.2: 9/9 executions showed the allocator mismatch
across three repetitions. - Engine: InnoDB.
- Replication: file/position, `binlog_format=ROW`.
Minimal reproduction
Run on an empty primary after the replica has caught up with the empty schema:
DROP TABLE IF EXISTS d; |
CREATE TABLE d( |
id INT AUTO_INCREMENT PRIMARY KEY, |
uk INT UNIQUE, |
v INT NOT NULL |
) ENGINE=InnoDB;
|
|
|
INSERT INTO d(uk,v) VALUES (1,10); |
INSERT IGNORE INTO d(uk,v) VALUES |
(2,20), -- inserted |
(1,30), -- duplicate uk; ignored |
(4,40); -- inserted |
Wait until the replica has executed the transaction. Do not execute any
follow-up write before recording the allocator state:
SELECT id,uk,v FROM d ORDER BY id; |
SELECT AUTO_INCREMENT |
FROM information_schema.tables |
WHERE table_schema = DATABASE() AND table_name = 'd'; |
Expected result
The table rows must match, and the implicit allocator state should describe the
same next value on both endpoints. A clean sequential insert control has next
value `4` on both endpoints.
Observed result
MariaDB 12.2.2 → 12.2.2, repeated 5 times:
primary rows:
|
(1,1,10), (2,2,20), (3,4,40)
|
primary AUTO_INCREMENT: 5
|
|
|
replica rows:
|
(1,1,10), (2,2,20), (3,4,40)
|
replica AUTO_INCREMENT: 4
|
The same cursor mismatch reproduces for MariaDB 10.3 → 12.2.2 and
10.6 → 12.2.2. The no-conflict sequential control and `TRUNCATE` control do
not mismatch.
The difference comes from the primary reserving an auto-increment value for
the ignored middle row, while ROW apply reconstructs the explicit committed
row ids and leaves the replica allocator at the maximum applied id plus one.
Failover-relevant witness
In a disposable same-version pair, stop the replica SQL thread immediately
after the initial transaction has applied, then execute:
INSERT INTO d(uk,v) VALUES (999,999); |
SELECT LAST_INSERT_ID(); |
The primary allocates `5`; the replica allocates `4`. Thus promotion or local
writes on the replica can reuse an id that the primary intentionally skipped,
even though the replicated table rows were byte-for-byte equal before the
write.
Repetition and related behavior
The minimal schedule reproduced the cursor mismatch 15/15 times on MariaDB
12.2.2 to 12.2.2, 9/9 times on MariaDB 10.3 to 12.2.2, and 9/9 times on
MariaDB 10.6 to 12.2.2. Every execution completed without an inconclusive
setup or replication-health result. Sequential-insert and TRUNCATE controls
held equality on both endpoints. Related MIXED/routine/AUTO_INCREMENT issues
were reviewed; none describes this ROW-applier reconstruction of the implicit
allocator after an ignored or reserved allocation.