From 405c5c2d992a954988b80e3b75163af54691802b Mon Sep 17 00:00:00 2001 From: greypilgrim-083 Date: Fri, 4 Sep 2026 15:15:56 +0530 Subject: [PATCH] MDEV-40995 concurrent INSERT ... SELECT on a partitioned InnoDB table can leave the table-level AUTO_INCREMENT counter behind MAX(pk), so later inserts are handed ids that already exist and fail with ER_DUP_ENTRY on the PRIMARY KEY For a partitioned InnoDB table with AUTO_INCREMENT as the leftmost PK column, values are issued by the partitioning layer from the shared counter Partition_share::next_auto_inc_val, reserved in doubling blocks (1, 2, 4, 8 ... values per reservation). At end-of-statement, ha_partition::release_auto_increment() returns unused tail values to the shared counter. When a row fails mid-statement, handler::restore_auto_increment() rolls next_insert_id back to the boundary of an earlier block. The guard in release_auto_increment() inspects only the last interval, so it passes even when the returned value is already in use by concurrent sessions. Fix: extend the guard to also verify that next_insert_id is within the statement's own reservation interval, rejecting a lowering caused by restore_auto_increment() rolling back across a block boundary.# --- sql/ha_partition.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index e1e04c359211b..499a0d84b6290 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -11139,7 +11139,8 @@ void ha_partition::release_auto_increment() we can lower the reserved value. */ if (next_insert_id < next_auto_inc_val && - auto_inc_interval_for_cur_row.maximum() >= next_auto_inc_val) + auto_inc_interval_for_cur_row.maximum() >= next_auto_inc_val && + next_insert_id >= auto_inc_interval_for_cur_row.minimum()) { THD *thd= ha_thd(); /*