Skip to content

Commit 4e90b9d

Browse files
author
Nisha Gopalakrishnan
committed
Bug#37189985: Crashing and widespread corruption of spatial indexes
after INPLACE alter table ANALYSIS ALTER TABLE, INPLACE operation on a table containing both a spatial index and an auto increment column can cause corruption or trigger debug assert in debug builds. This is due to auto increment column value getting overwritten in the old records of spatial index while preparing the new record. Per-thread memory is allocated for a single dtuple (row) in while processing the records. Records are accessed through a cursor, cached into a tuple vector m_dtuples in the RTree_inserter::add_to_batch() that is called through bulk_inserter. The row is built with shallow copying of fields, and the auto-increment value is prepared locally and copied. This process repeats until page traversal is complete. In subsequent iterations, shallow-copied pointers are overwritten, but since the source record remains intact and page is latched, they stay valid. The row continues to reference the old auto-incremented value, causing only the auto-increment field to be overwritten, and older rows to point to the latest auto-incremented value. FIX Perform deep copy of the auto-increment field while processing the index records. Change-Id: I9c1b6bc4eab321d3421c12e8ee17882d25f46a4a
1 parent 5b55e2e commit 4e90b9d

File tree

4 files changed

+13
-3
lines changed

4 files changed

+13
-3
lines changed

storage/innobase/ddl/ddl0ctx.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,16 @@ bool Context::has_virtual_columns() const noexcept {
236236
return false;
237237
}
238238

239-
dberr_t Context::handle_autoinc(const dtuple_t *dtuple) noexcept {
239+
dberr_t Context::handle_autoinc(const dtuple_t *dtuple,
240+
mem_heap_t *heap) noexcept {
240241
ut_ad(m_add_autoinc != ULINT_UNDEFINED);
241242
ut_ad(m_add_autoinc < m_new_table->get_n_user_cols());
242243

243244
const auto dfield = dtuple_get_nth_field(dtuple, m_add_autoinc);
245+
/* Perform a deep copy of the field because for spatial indexes,
246+
the default tuple allocation is overwritten, as tuples are
247+
processed at the end of the page. */
248+
dfield_dup(dfield, heap);
244249

245250
if (dfield_is_null(dfield)) {
246251
return DB_SUCCESS;

storage/innobase/ddl/ddl0ddl.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ dberr_t Row::build(ddl::Context &ctx, dict_index_t *index, mem_heap_t *heap,
515515
}
516516

517517
if (ctx.m_add_autoinc != ULINT_UNDEFINED) {
518-
auto err = ctx.handle_autoinc(m_ptr);
518+
auto err = ctx.handle_autoinc(m_ptr, heap);
519519

520520
if (err != DB_SUCCESS) {
521521
return err;

storage/innobase/ddl/ddl0rtree.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ dberr_t RTree_inserter::batch_insert(trx_id_t trx_id,
106106

107107
ut_ad(dtuple != nullptr);
108108

109+
/* If there is no sufficient space in the redo logs then deep copy the
110+
cached records and release the page(s) latches as that would be required to
111+
commit the mini-transaction. */
109112
if (log_free_check_is_required() IF_DEBUG(|| force_log_free_check)) {
110113
if (!latches_released) {
111114
deep_copy_tuples(it);

storage/innobase/include/ddl0ddl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,10 @@ struct Context {
550550

551551
/** Handle auto increment.
552552
@param[in] row Row with autoinc column.
553+
@param[in] heap Heap to use for allocation of autoinc column.
553554
@return DB_SUCCESS or error code. */
554-
[[nodiscard]] dberr_t handle_autoinc(const dtuple_t *row) noexcept;
555+
[[nodiscard]] dberr_t handle_autoinc(const dtuple_t *row,
556+
mem_heap_t *heap) noexcept;
555557

556558
/** @return true if any virtual columns are involved. */
557559
[[nodiscard]] bool has_virtual_columns() const noexcept;

0 commit comments

Comments
 (0)