summaryrefslogtreecommitdiff
path: root/storage/innobase/trx/trx0rec.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-08-25 15:32:15 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-08-25 15:32:15 +0300
commit8cf8ad86d4b6f3479d80f3d8e8c2bcf463966924 (patch)
tree06a28427160063d99649650adfbadc2d77bd63a2 /storage/innobase/trx/trx0rec.cc
parentc0e5cf79ad13fad4b34fa7d0777cc90035db93c1 (diff)
downloadmariadb-git-8cf8ad86d4b6f3479d80f3d8e8c2bcf463966924.tar.gz
MDEV-23547 InnoDB: Failing assertion: *len in row_upd_ext_fetch
This bug was originally repeated on 10.4 after defining a UNIQUE KEY on a TEXT column, which is implemented by MDEV-371 by creating the index on a hidden virtual column. While row_vers_vc_matches_cluster() is executing in a purge thread to find out if an index entry may be removed in a secondary index that comprises a virtual column, another purge thread may process the undo log record that this check is interested in, and write a null BLOB pointer in that record. This would trip the assertion. To prevent this from occurring, we must propagate the 'missing BLOB' error up the call stack. row_upd_ext_fetch(): Return NULL when the error occurs. row_upd_index_replace_new_col_val(): Return whether the previous version was built successfully. row_upd_index_replace_new_col_vals_index_pos(): Check the error result. Yes, we would intentionally crash on this error if it occurs outside the purge thread. row_upd_index_replace_new_col_vals(): Check for the error condition, and simplify the logic. trx_undo_prev_version_build(): Check for the error condition.
Diffstat (limited to 'storage/innobase/trx/trx0rec.cc')
-rw-r--r--storage/innobase/trx/trx0rec.cc6
1 files changed, 5 insertions, 1 deletions
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index ee022b4f1fd..623d8990381 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -2446,7 +2446,11 @@ trx_undo_prev_version_build(
/* The page containing the clustered index record
corresponding to entry is latched in mtr. Thus the
following call is safe. */
- row_upd_index_replace_new_col_vals(entry, index, update, heap);
+ if (!row_upd_index_replace_new_col_vals(entry, *index, update,
+ heap)) {
+ ut_a(v_status & TRX_UNDO_PREV_IN_PURGE);
+ return false;
+ }
/* Get number of externally stored columns in updated record */
const ulint n_ext = dtuple_get_n_ext(entry);