diff --git a/mysql-8.0.32/storage/innobase/handler/ha_innopart.cc b/mysql-8.0.32/storage/innobase/handler/ha_innopart.cc index 97a2066..e5d0c56 100644 --- a/mysql-8.0.32/storage/innobase/handler/ha_innopart.cc +++ b/mysql-8.0.32/storage/innobase/handler/ha_innopart.cc @@ -931,6 +931,7 @@ int ha_innopart::open(const char *name, int, uint, const dd::Table *table_def) { assert(table != nullptr); m_prebuilt->m_mysql_table = table; m_prebuilt->m_mysql_handler = this; + m_prebuilt->blob_in_use = false; if (ib_table->n_v_cols > 0) { dict_sys_mutex_enter(); @@ -1294,6 +1295,7 @@ void ha_innopart::set_partition(uint part_id) { DBUG_PRINT("ha_innopart", ("validating blob_heap: %p", m_prebuilt->blob_heap)); mem_heap_validate(m_prebuilt->blob_heap); + ut_a(m_prebuilt->blob_in_use); } #endif @@ -1332,6 +1334,7 @@ void ha_innopart::update_partition(uint part_id) { DBUG_PRINT("ha_innopart", ("validating blob_heap: %p", m_prebuilt->blob_heap)); mem_heap_validate(m_prebuilt->blob_heap); + ut_a(m_prebuilt->blob_in_use); } #endif @@ -4125,6 +4128,16 @@ void ha_innopart::clear_blob_heaps() { return; } + if (m_prebuilt->blob_in_use == false) { +#ifdef UNIV_DEBUG + for (uint i = 0; i < m_tot_parts; i++) { + auto &part{m_parts[i]}; + ut_a(part.m_blob_heap == nullptr); + } +#endif + return; + } + for (uint i = 0; i < m_tot_parts; i++) { auto &part{m_parts[i]}; if (part.m_blob_heap != nullptr) { @@ -4134,6 +4147,7 @@ void ha_innopart::clear_blob_heaps() { } } + m_prebuilt->blob_in_use = false; /* Reset blob_heap in m_prebuilt after freeing all heaps. It is set in ha_innopart::set_partition to the blob heap of current partition. */ m_prebuilt->blob_heap = nullptr; diff --git a/mysql-8.0.32/storage/innobase/handler/handler0alter.cc b/mysql-8.0.32/storage/innobase/handler/handler0alter.cc index e7f98cb..e4f8028 100644 --- a/mysql-8.0.32/storage/innobase/handler/handler0alter.cc +++ b/mysql-8.0.32/storage/innobase/handler/handler0alter.cc @@ -7904,6 +7904,9 @@ rollback_trx: prebuilt. Blob heaps of all the partitions will be freed later in the ha_innopart::clear_blob_heaps() */ ctx->prebuilt->blob_heap = nullptr; + + /* force to scan */ + ctx->prebuilt->blob_in_use = true; } row_prebuilt_free(ctx->prebuilt, true); @@ -7923,6 +7926,9 @@ rollback_trx: } user_trx->will_lock++; m_prebuilt->trx = user_trx; + + /* force to scan */ + m_prebuilt->blob_in_use = dict_table_is_partition(ctx->new_table); } DBUG_INJECT_CRASH("ib_commit_inplace_crash", crash_inject_count++); } @@ -10370,6 +10376,7 @@ bool ha_innopart::prepare_inplace_alter_table(TABLE *altered_table, for (uint i = 0; i < m_tot_parts; ++oldp, ++newp) { m_prebuilt = ctx_parts->prebuilt_array[i]; + m_prebuilt->blob_in_use = true; set_partition(i); const dd::Partition *old_part = *oldp; @@ -10410,6 +10417,7 @@ bool ha_innopart::prepare_inplace_alter_table(TABLE *altered_table, } m_prebuilt = ctx_parts->prebuilt_array[0]; + m_prebuilt->blob_in_use = true; ha_alter_info->handler_ctx = ctx_parts; ha_alter_info->group_commit_ctx = ctx_parts->ctx_array; ha_alter_info->create_info->tablespace = save_tablespace; diff --git a/mysql-8.0.32/storage/innobase/include/row0mysql.h b/mysql-8.0.32/storage/innobase/include/row0mysql.h index 07473a6..431ad8b 100644 --- a/mysql-8.0.32/storage/innobase/include/row0mysql.h +++ b/mysql-8.0.32/storage/innobase/include/row0mysql.h @@ -730,6 +730,7 @@ struct row_prebuilt_t { fetched row in fetch_cache */ ulint n_fetch_cached; /*!< number of not yet fetched rows in fetch_cache */ + bool blob_in_use; /*!< indicate if blob_heap is used */ mem_heap_t *blob_heap; /*!< in SELECTS BLOB fields are copied to this heap */ mem_heap_t *old_vers_heap; /*!< memory heap where a previous diff --git a/mysql-8.0.32/storage/innobase/row/row0mysql.cc b/mysql-8.0.32/storage/innobase/row/row0mysql.cc index 571f4ef..8629100 100644 --- a/mysql-8.0.32/storage/innobase/row/row0mysql.cc +++ b/mysql-8.0.32/storage/innobase/row/row0mysql.cc @@ -916,6 +916,7 @@ row_prebuilt_t *row_create_prebuilt( prebuilt->fts_doc_id_in_read_set = false; prebuilt->blob_heap = nullptr; + prebuilt->blob_in_use = false; prebuilt->no_read_locking = false; prebuilt->no_autoinc_locking = false; diff --git a/mysql-8.0.32/storage/innobase/row/row0sel.cc b/mysql-8.0.32/storage/innobase/row/row0sel.cc index c1c82b5..f4ab372 100644 --- a/mysql-8.0.32/storage/innobase/row/row0sel.cc +++ b/mysql-8.0.32/storage/innobase/row/row0sel.cc @@ -2752,6 +2752,10 @@ void row_sel_field_store_in_mysql_format_func( blob_heap = mem_heap_create(UNIV_PAGE_SIZE, UT_LOCATION_HERE); } + if (blob_heap == prebuilt->blob_heap) { + prebuilt->blob_in_use = true; + } + heap = blob_heap; } else { heap = mem_heap_create(UNIV_PAGE_SIZE, UT_LOCATION_HERE); @@ -2854,6 +2858,10 @@ void row_sel_field_store_in_mysql_format_func( blob_heap = mem_heap_create(UNIV_PAGE_SIZE, UT_LOCATION_HERE); } + if (blob_heap == prebuilt->blob_heap) { + prebuilt->blob_in_use = true; + } + heap = blob_heap; data = static_cast(mem_heap_dup(heap, data, len)); } @@ -2899,6 +2907,10 @@ bool row_sel_store_mysql_rec(byte *mysql_rec, row_prebuilt_t *prebuilt, mem_heap_empty(blob_heap); } + if (prebuilt->blob_heap != nullptr) { + prebuilt->blob_in_use = true; + } + if (clust_templ_for_sec) { /* Store all clustered index column of secondary index record. */ for (ulint i = 0; i < dict_index_get_n_fields(prebuilt_index); i++) {