Skip to content

Commit

Permalink
Bug#36526369 MySQL server crashes on UPDATE after ALTER TABLE
Browse files Browse the repository at this point in the history
Issue:
 In bug#35183686 fix, we started logging the fields whose column order
 changed. But while calculating size needed in redo to log index information
 these columns were missing from calculation.

Fix
 Make sure these colums are also considered while calculating size
 needed to log index entry.

Change-Id: Ic8752c72a8f5beddfc5739688068b9c32b02a700
  • Loading branch information
Mayank Prasad committed May 29, 2024
1 parent 71ae8c6 commit e6248f5
Showing 1 changed file with 39 additions and 26 deletions.
65 changes: 39 additions & 26 deletions storage/innobase/mtr/mtr0log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,15 @@ constexpr size_t inst_col_info_size = 6;
@param[in] is_comp true if COMP
@param[in] is_versioned if table has row versions
@param[in] is_instant true if table has INSTANT cols
@param[in] fields_with_changed_order bitmap to indicate fields with changed
order
@param[out] size_needed total size needed on REDO LOG */
static void log_index_get_size_needed(const dict_index_t *index, size_t size,
uint16_t n, bool is_comp,
bool is_versioned, bool is_instant,
const bool *fields_with_changed_order,
size_t &size_needed) {
auto size_for_versioned_fields = [](const dict_index_t *ind) {
auto size_for_versioned_fields = [&](const dict_index_t *ind) {
size_t _size = 0;
/* 2 bytes for number of columns with version */
_size += 2;
Expand All @@ -530,6 +533,16 @@ static void log_index_get_size_needed(const dict_index_t *index, size_t size,
ut_ad(n_versioned_fields != 0);

_size += n_versioned_fields * inst_col_info_size;

/* For fields with changed order */
size_t n_changed_order_fields = 0;
for (size_t i = 0; i < n; i++) {
if (fields_with_changed_order[i]) {
n_changed_order_fields++;
}
}
_size += n_changed_order_fields * inst_col_info_size;

return (_size);
};

Expand Down Expand Up @@ -799,9 +812,33 @@ bool mlog_open_and_write_index(mtr_t *mtr, const byte *rec,
n = DICT_INDEX_SPATIAL_NODEPTR_SIZE;
}

/* Ordinal position of an existing field can't be changed with INSTANT
algorithm. But when it is combined with ADD/DROP COLUMN, ordinal position
of a filed can be changed. This bool array of size #fields in index,
represents if ordinal position of an existing filed is changed. */
bool *fields_with_changed_order = nullptr;
if (is_versioned) {
fields_with_changed_order = new bool[n];
memset(fields_with_changed_order, false, (sizeof(bool) * n));

uint16_t phy_pos = 0;
for (size_t i = 0; i < n; i++) {
dict_field_t *field = index->get_field(i);
const dict_col_t *col = field->col;

if (col->is_instant_added() || col->is_instant_dropped()) {
continue;
} else if (field->get_phy_pos() >= phy_pos) {
phy_pos = field->get_phy_pos();
} else {
fields_with_changed_order[i] = true;
}
}
}

size_t size_needed = 0;
log_index_get_size_needed(index, size, n, is_comp, is_versioned, is_instant,
size_needed);
fields_with_changed_order, size_needed);
size_t total = size_needed;
size_t alloc = total;
if (alloc > mtr_buf_t::MAX_DATA_SIZE) {
Expand Down Expand Up @@ -846,30 +883,6 @@ bool mlog_open_and_write_index(mtr_t *mtr, const byte *rec,
return true;
};

/* Ordinal position of an existing field can't be changed with INSTANT
algorithm. But when it is combined with ADD/DROP COLUMN, ordinal position
of a filed can be changed. This bool array of size #fields in index,
represents if ordinal position of an existing filed is changed. */
bool *fields_with_changed_order = nullptr;
if (is_versioned) {
fields_with_changed_order = new bool[n];
memset(fields_with_changed_order, false, (sizeof(bool) * n));

uint16_t phy_pos = 0;
for (size_t i = 0; i < n; i++) {
dict_field_t *field = index->get_field(i);
const dict_col_t *col = field->col;

if (col->is_instant_added() || col->is_instant_dropped()) {
continue;
} else if (field->get_phy_pos() >= phy_pos) {
phy_pos = field->get_phy_pos();
} else {
fields_with_changed_order[i] = true;
}
}
}

if (is_comp) {
/* Write fields info. */
if (!log_index_fields(index, n, is_versioned, instant_fields_to_log,
Expand Down

0 comments on commit e6248f5

Please sign in to comment.