@@ -3843,6 +3843,7 @@ dberr_t btr_cur_pessimistic_update(
38433843 ulint n_reserved = 0 ;
38443844 ulint n_ext;
38453845 ulint max_ins_size = 0 ;
3846+ trx_t *const trx = (thr == nullptr ) ? nullptr : thr_get_trx (thr);
38463847
38473848 *offsets = NULL ;
38483849 *big_rec = NULL ;
@@ -3925,31 +3926,6 @@ dberr_t btr_cur_pessimistic_update(
39253926 ut_ad (rec_offs_validate (rec, index, *offsets));
39263927 n_ext += lob::btr_push_update_extern_fields (new_entry, update, entry_heap);
39273928
3928- /* UNDO logging is also turned-off during normal operation on intrinsic
3929- table so condition needs to ensure that table is not intrinsic. */
3930- if ((flags & BTR_NO_UNDO_LOG_FLAG) && rec_offs_any_extern (*offsets) &&
3931- !index->table ->is_intrinsic ()) {
3932- /* We are in a transaction rollback undoing a row
3933- update: we must free possible externally stored fields
3934- which got new values in the update, if they are not
3935- inherited values. They can be inherited if we have
3936- updated the primary key to another value, and then
3937- update it back again. */
3938-
3939- ut_ad (big_rec_vec == NULL );
3940- ut_ad (index->is_clustered ());
3941- ut_ad ((flags & ~BTR_KEEP_POS_FLAG) ==
3942- (BTR_NO_LOCKING_FLAG | BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG) ||
3943- thr_get_trx (thr)->id == trx_id);
3944-
3945- DBUG_EXECUTE_IF (" ib_blob_update_rollback" , DBUG_SUICIDE (););
3946- RECOVERY_CRASH (99 );
3947-
3948- lob::BtrContext ctx (mtr, nullptr , index, rec, *offsets, block);
3949-
3950- ctx.free_updated_extern_fields (trx_id, undo_no, update, true );
3951- }
3952-
39533929 if (page_zip_rec_needs_ext (rec_get_converted_size (index, new_entry, n_ext),
39543930 page_is_comp (page), dict_index_get_n_fields (index),
39553931 block->page .size )) {
@@ -3982,6 +3958,34 @@ dberr_t btr_cur_pessimistic_update(
39823958 goto err_exit;
39833959 }
39843960
3961+ /* Check for an update that moved an ext field to inline */
3962+ lob::mark_not_partially_updatable (trx, index, update, mtr);
3963+
3964+ /* UNDO logging is also turned-off during normal operation on intrinsic
3965+ table so condition needs to ensure that table is not intrinsic. */
3966+ if ((flags & BTR_NO_UNDO_LOG_FLAG) && rec_offs_any_extern (*offsets) &&
3967+ !index->table ->is_intrinsic ()) {
3968+ /* We are in a transaction rollback undoing a row
3969+ update: we must free possible externally stored fields
3970+ which got new values in the update, if they are not
3971+ inherited values. They can be inherited if we have
3972+ updated the primary key to another value, and then
3973+ update it back again. */
3974+
3975+ ut_ad (big_rec_vec == NULL );
3976+ ut_ad (index->is_clustered ());
3977+ ut_ad ((flags & ~BTR_KEEP_POS_FLAG) ==
3978+ (BTR_NO_LOCKING_FLAG | BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG) ||
3979+ thr_get_trx (thr)->id == trx_id);
3980+
3981+ DBUG_EXECUTE_IF (" ib_blob_update_rollback" , DBUG_SUICIDE (););
3982+ RECOVERY_CRASH (99 );
3983+
3984+ lob::BtrContext ctx (mtr, nullptr , index, rec, *offsets, block);
3985+
3986+ ctx.free_updated_extern_fields (trx_id, undo_no, update, true );
3987+ }
3988+
39853989 if (optim_err == DB_OVERFLOW) {
39863990 /* First reserve enough free space for the file segments
39873991 of the index tree, so that the update will not fail because
0 commit comments