diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 7fa7d42320a..8db12a0bbb8 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -3484,9 +3484,10 @@ btr_cur_set_ownership_of_extern_field( Marks not updated extern fields as not-owned by this record. The ownership is transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. */ +to free the field. +@return TRUE if BLOB ownership was transferred */ UNIV_INTERN -void +ibool btr_cur_mark_extern_inherited_fields( /*=================================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed @@ -3500,13 +3501,14 @@ btr_cur_mark_extern_inherited_fields( ulint n; ulint j; ulint i; + ibool change_ownership = FALSE; ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); if (!rec_offs_any_extern(offsets)) { - return; + return(FALSE); } n = rec_offs_n_fields(offsets); @@ -3529,10 +3531,14 @@ btr_cur_mark_extern_inherited_fields( btr_cur_set_ownership_of_extern_field( page_zip, rec, index, offsets, i, FALSE, mtr); + + change_ownership = TRUE; updated: ; } } + + return(change_ownership); } /*******************************************************************//** diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h index 7dc2eb63cf5..e151fdcb563 100644 --- a/storage/innodb_plugin/include/btr0cur.h +++ b/storage/innodb_plugin/include/btr0cur.h @@ -468,9 +468,10 @@ btr_estimate_number_of_different_key_vals( Marks not updated extern fields as not-owned by this record. The ownership is transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. */ +to free the field. +@return TRUE if BLOB ownership was transferred */ UNIV_INTERN -void +ibool btr_cur_mark_extern_inherited_fields( /*=================================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 397b117c067..04c3139fcc7 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -1598,6 +1598,7 @@ row_upd_clust_rec_by_insert( dict_table_t* table; dtuple_t* entry; ulint err; + ibool change_ownership = FALSE; ut_ad(node); ut_ad(dict_index_is_clust(index)); @@ -1630,9 +1631,9 @@ row_upd_clust_rec_by_insert( index = dict_table_get_first_index(table); offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); - btr_cur_mark_extern_inherited_fields( - btr_cur_get_page_zip(btr_cur), - rec, index, offsets, node->update, mtr); + change_ownership = btr_cur_mark_extern_inherited_fields( + btr_cur_get_page_zip(btr_cur), rec, index, offsets, + node->update, mtr); if (check_ref) { /* NOTE that the following call loses the position of pcur ! */ @@ -1661,10 +1662,11 @@ row_upd_clust_rec_by_insert( row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id); - if (node->upd_ext) { + if (change_ownership) { /* If we return from a lock wait, for example, we may have extern fields marked as not-owned in entry (marked in the - if-branch above). We must unmark them. */ + if-branch above). We must unmark them, take the ownership + back. */ btr_cur_unmark_dtuple_extern_fields(entry);