Skip to content

Commit 7269603

Browse files
author
Mohammad Tafzeel Shams
committed
Bug #36993445 : virtual index unstable after rollback when index_id is
greater than max uint32 SYMPTOM: When performing an insert operation on a table with a virtual index, re-inserting the same row after rolling back the previous insert causes unexpected behaviour failure if the index_id is greater than or equal to 2^32. ROOT CAUSE: The function used to log and read the index_id for virtual indexes in the undo record does not support 64-bit integers, causing issues when the index_id exceeds the maximum value of a 32-bit unsigned integer. FIX: Replace the existing logging and reading functions with mach_u64_write_much_compressed() and mach_read_next_much_compressed(), which support 64-bit integers. Change-Id: I4831a3c979a4a797185e37318999af83132d58d5
1 parent dc0f623 commit 7269603

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

storage/innobase/dict/dict0boot.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1996, 2023, Oracle and/or its affiliates.
3+
Copyright (c) 1996, 2025, Oracle and/or its affiliates.
44
55
This program is free software; you can redistribute it and/or modify
66
it under the terms of the GNU General Public License, version 2.0,
@@ -135,6 +135,8 @@ dict_hdr_get_new_id(
135135
if (index_id) {
136136
id = mach_read_from_8(dict_hdr + DICT_HDR_INDEX_ID);
137137
id++;
138+
const ib_id_t max_uint32 = 0xFFFFFFFF;
139+
DBUG_EXECUTE_IF("simulate_index_id_exceed_uint32", if(id < max_uint32) { id = max_uint32; });
138140
mlog_write_ull(dict_hdr + DICT_HDR_INDEX_ID, id, &mtr);
139141
*index_id = id;
140142
}

storage/innobase/trx/trx0rec.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1996, 2023, Oracle and/or its affiliates.
3+
Copyright (c) 1996, 2025, Oracle and/or its affiliates.
44
55
This program is free software; you can redistribute it and/or modify
66
it under the terms of the GNU General Public License, version 2.0,
@@ -243,10 +243,10 @@ trx_undo_log_v_idx(
243243

244244
ut_ad(n_idx > 0);
245245

246-
/* Size to reserve, max 5 bytes for each index id and position, plus
246+
/* Size to reserve, max (11 + 5) bytes for each index id and position, plus
247247
5 bytes for num of indexes, 2 bytes for write total length.
248248
1 byte for undo log record format version marker */
249-
ulint size = n_idx * (5 + 5) + 5 + 2 + (first_v_col ? 1 : 0);
249+
ulint size = n_idx * (11 + 5) + 5 + 2 + (first_v_col ? 1 : 0);
250250

251251
if (trx_undo_left(undo_page, ptr) < size) {
252252
return(NULL);
@@ -271,7 +271,7 @@ trx_undo_log_v_idx(
271271
it != vcol->v_indexes->end(); ++it) {
272272
dict_v_idx_t v_index = *it;
273273

274-
ptr += mach_write_compressed(
274+
ptr += mach_u64_write_much_compressed(
275275
ptr, static_cast<ulint>(v_index.index->id));
276276

277277
ptr += mach_write_compressed(ptr, v_index.nth_field);
@@ -310,7 +310,7 @@ trx_undo_read_v_idx_low(
310310
dict_index_t* clust_index = dict_table_get_first_index(table);
311311

312312
for (ulint i = 0; i < num_idx; i++) {
313-
index_id_t id = mach_read_next_compressed(&ptr);
313+
index_id_t id = mach_read_next_much_compressed(&ptr);
314314
ulint pos = mach_read_next_compressed(&ptr);
315315
dict_index_t* index = dict_table_get_next_index(clust_index);
316316

0 commit comments

Comments
 (0)