diff --git a/include/row0ext.h b/include/row0ext.h index 377c500d5a4..b015bcc176d 100644 --- a/include/row0ext.h +++ b/include/row0ext.h @@ -27,8 +27,11 @@ row_ext_create( dict_col_get_no(); NOT relative to the records in the clustered index */ const dtuple_t* tuple, /* in: data tuple containing the field - references of the externally stored columns; - must be indexed by col_no */ + references of the externally stored + columns; must be indexed by col_no; + the clustered index record must be + covered by a lock or a page latch + to prevent deletion (rollback or purge). */ ulint zip_size,/* compressed page size in bytes, or 0 */ mem_heap_t* heap); /* in: heap where created */ diff --git a/include/row0upd.h b/include/row0upd.h index 17236709a2b..eceafc40f72 100644 --- a/include/row0upd.h +++ b/include/row0upd.h @@ -185,7 +185,10 @@ given. */ void row_upd_index_replace_new_col_vals_index_pos( /*=========================================*/ - dtuple_t* entry, /* in/out: index entry where replaced */ + dtuple_t* entry, /* in/out: index entry where replaced; + the clustered index record must be + covered by a lock or a page latch to + prevent deletion (rollback or purge) */ dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ const upd_t* update, /* in: an update vector built for the index so @@ -210,7 +213,10 @@ given. */ void row_upd_index_replace_new_col_vals( /*===============================*/ - dtuple_t* entry, /* in/out: index entry where replaced */ + dtuple_t* entry, /* in/out: index entry where replaced; + the clustered index record must be + covered by a lock or a page latch to + prevent deletion (rollback or purge) */ dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ const upd_t* update, /* in: an update vector built for the diff --git a/row/row0ext.c b/row/row0ext.c index 6be079818c0..89db822e8ac 100644 --- a/row/row0ext.c +++ b/row/row0ext.c @@ -60,8 +60,11 @@ row_ext_create( dict_col_get_no(); NOT relative to the records in the clustered index */ const dtuple_t* tuple, /* in: data tuple containing the field - references of the externally stored columns; - must be indexed by col_no */ + references of the externally stored + columns; must be indexed by col_no; + the clustered index record must be + covered by a lock or a page latch + to prevent deletion (rollback or purge). */ ulint zip_size,/* compressed page size in bytes, or 0 */ mem_heap_t* heap) /* in: heap where created */ { diff --git a/row/row0sel.c b/row/row0sel.c index 87e8af41b57..8e73ef8b8fc 100644 --- a/row/row0sel.c +++ b/row/row0sel.c @@ -67,10 +67,13 @@ row_sel_sec_rec_is_for_blob( ulint mbminlen, /* in: minimum length of a multi-byte character */ ulint mbmaxlen, /* in: maximum length of a - multi-byte character */ + multi-byte character */ const byte* clust_field, /* in: the locally stored part of - the clustered index column, including - the BLOB pointer */ + the clustered index column, including + the BLOB pointer; the clustered + index record must be covered by + a lock or a page latch to protect it + against deletion (rollback or purge) */ ulint clust_len, /* in: length of clust_field */ const byte* sec_field, /* in: column in secondary index */ ulint sec_len, /* in: length of sec_field */ @@ -104,7 +107,10 @@ row_sel_sec_rec_is_for_clust_rec( when compared with collation */ const rec_t* sec_rec, /* in: secondary index record */ dict_index_t* sec_index, /* in: secondary index */ - const rec_t* clust_rec, /* in: clustered index record */ + const rec_t* clust_rec, /* in: clustered index record; + must be protected by a lock or + a page latch against deletion + in rollback or purge */ dict_index_t* clust_index) /* in: clustered index */ { const byte* sec_field; @@ -2990,8 +2996,8 @@ row_sel_get_clust_rec_for_mysql( && !row_sel_sec_rec_is_for_clust_rec( rec, sec_index, clust_rec, clust_index)) { clust_rec = NULL; - } else { #ifdef UNIV_SEARCH_DEBUG + } else { ut_a(clust_rec == NULL || row_sel_sec_rec_is_for_clust_rec( rec, sec_index, clust_rec, clust_index)); diff --git a/row/row0umod.c b/row/row0umod.c index 684d123cc75..b9483d1f438 100644 --- a/row/row0umod.c +++ b/row/row0umod.c @@ -637,6 +637,8 @@ row_undo_mod_upd_exist_sec( but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. */ + /* TODO: lock the clustered index record + before fetching BLOBs */ row_upd_index_replace_new_col_vals(entry, index, node->update, NULL, heap); diff --git a/row/row0upd.c b/row/row0upd.c index 82139726d99..1a9322e92f1 100644 --- a/row/row0upd.c +++ b/row/row0upd.c @@ -868,7 +868,10 @@ given. */ void row_upd_index_replace_new_col_vals_index_pos( /*=========================================*/ - dtuple_t* entry, /* in/out: index entry where replaced */ + dtuple_t* entry, /* in/out: index entry where replaced; + the clustered index record must be + covered by a lock or a page latch to + prevent deletion (rollback or purge) */ dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ const upd_t* update, /* in: an update vector built for the index so @@ -986,7 +989,10 @@ given. */ void row_upd_index_replace_new_col_vals( /*===============================*/ - dtuple_t* entry, /* in/out: index entry where replaced */ + dtuple_t* entry, /* in/out: index entry where replaced; + the clustered index record must be + covered by a lock or a page latch to + prevent deletion (rollback or purge) */ dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ const upd_t* update, /* in: an update vector built for the @@ -1440,6 +1446,7 @@ row_upd_sec_index_entry( } /* Build a new index entry */ + /* TODO: lock the clustered index record before fetching BLOBs */ row_upd_index_replace_new_col_vals(entry, index, node->update, NULL, heap); @@ -1562,6 +1569,7 @@ row_upd_clust_rec_by_insert( entry = row_build_index_entry(node->row, node->ext, index, heap); ut_a(entry); + /* TODO: lock the clustered index record before fetching BLOBs */ row_upd_index_replace_new_col_vals(entry, index, node->update, NULL, heap);