diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h index 63d0b11..f3db4fb 100644 --- a/storage/innobase/include/row0vers.h +++ b/storage/innobase/include/row0vers.h @@ -136,6 +136,17 @@ void row_vers_build_for_semi_consistent_read( mem_heap_t **offset_heap, mem_heap_t *in_heap, const rec_t **old_vers, const dtuple_t **vrow); +/**build the value of virtual column in the index, base on current cluster index + record data from log record of table operations during online ddl + @param[in,out] row the cluster index row in dtuple form + @param[in] clust_index clustered index + @param[in] index the secondary index + @param[in] mysql_table mysql table object + @param[in] heap heap used to build virtual dtuple */ +void row_vers_build_clust_v_col_from_log_table( + const dtuple_t *row, dict_index_t *clust_index, dict_index_t *index, TABLE *mysql_table, + mem_heap_t *heap); + #include "row0vers.ic" #endif diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 783f7e7..89a3657 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -49,6 +49,7 @@ this program; if not, write to the Free Software Foundation, Inc., #include "row0mysql.h" #include "row0row.h" #include "row0upd.h" +#include "row0vers.h" #include "srv0mon.h" #include "trx0rec.h" #include "ut0new.h" @@ -1555,6 +1556,8 @@ It is then unmarked. Otherwise, the entry is just inserted to the index. return (error); } + dict_index_t *clust_index = index; + do { n_index++; index = index->next(); @@ -1566,6 +1569,11 @@ It is then unmarked. Otherwise, the entry is just inserted to the index. continue; } + // fix or build the values of virtual columns in the index, which had been not change + if(dup->m_table) { + row_vers_build_clust_v_col_from_log_table(row, clust_index, index, dup->m_table, heap); + } + entry = row_build_index_entry(row, nullptr, index, heap); if (index->is_multi_value()) { @@ -1724,6 +1732,7 @@ flag_ok: const dtuple_t *ventry, /*!< in: dtuple holding virtual column info */ const ulint *offsets, /*!< in: offsets on pcur */ + TABLE *mysql_table, /*!< mysql table object */ mem_heap_t *heap, /*!< in/out: memory heap */ mtr_t *mtr) /*!< in/out: mini-transaction, will be committed */ @@ -1734,6 +1743,7 @@ flag_ok: dict_index_t *index = pcur->get_btr_cur()->index; ut_ad(index->is_clustered()); + dict_index_t *clust_index = index; DBUG_PRINT( "ib_alter_table", @@ -1765,6 +1775,11 @@ flag_ok: continue; } + // fix or build the values of virtual columns in the index, which had been not change + if(mysql_table) { + row_vers_build_clust_v_col_from_log_table(row, clust_index, index, mysql_table, heap); + } + if (index->is_multi_value()) { error = apply_delete_multi_value(row, ext, index, pcur, heap); if (error == DB_INDEX_CORRUPT) { @@ -1903,7 +1918,7 @@ flag_ok: &(log->col_map[log->n_old_col]), heap); } - return (row_log_table_apply_delete_low(&pcur, old_pk, offsets, heap, &mtr)); + return (row_log_table_apply_delete_low(&pcur, old_pk, offsets, nullptr, heap, &mtr)); } /** Replays an update operation on the multi-value index. @@ -2187,7 +2202,7 @@ flag_ok: /* Some BLOBs are missing, so we are interpreting this ROW_T_UPDATE as ROW_T_DELETE (see *1). */ error = - row_log_table_apply_delete_low(&pcur, old_pk, cur_offsets, heap, &mtr); + row_log_table_apply_delete_low(&pcur, old_pk, cur_offsets, nullptr, heap, &mtr); goto func_exit_committed; } @@ -2229,7 +2244,7 @@ flag_ok: } error = - row_log_table_apply_delete_low(&pcur, old_pk, cur_offsets, heap, &mtr); + row_log_table_apply_delete_low(&pcur, old_pk, cur_offsets, dup->m_table, heap, &mtr); ut_ad(mtr.has_committed()); if (error == DB_SUCCESS) { diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 41608b2..346704b 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -68,6 +68,15 @@ static bool row_vers_non_vc_index_entry_match(dict_index_t *index, const dtuple_t *ientry2, ulint *n_non_v_col); +/** build virtual column value from current cluster index record data + @param[in,out] row the cluster index row in dtuple form + @param[in] clust_index clustered index + @param[in] index the secondary index + @param[in] mysql_table mysql table object + @param[in] heap heap used to build virtual dtuple */ +static void row_vers_build_clust_v_col_low(const dtuple_t *row, dict_index_t *clust_index, + dict_index_t *index, TABLE *mysql_table, mem_heap_t *heap); + /** Checks if a particular version of a record from clustered index matches the secondary index record. The match occurs if and only if two condition hold: 1) the clust_rec exists and is not delete marked @@ -639,6 +648,17 @@ static bool row_vers_non_vc_index_entry_match(dict_index_t *index, @param[in] heap heap used to build virtual dtuple */ static void row_vers_build_clust_v_col(dtuple_t *row, dict_index_t *clust_index, dict_index_t *index, mem_heap_t *heap) { + row_vers_build_clust_v_col_low(row, clust_index, index, nullptr, heap); +} + +/** build virtual column value from current cluster index record data + * @param[in,out] row the cluster index row in dtuple form + * @param[in] clust_index clustered index + * @param[in] index the secondary index + * @param[in] mysql_table mysql table object + * @param[in] heap heap used to build virtual dtuple */ +static void row_vers_build_clust_v_col_low(const dtuple_t *row, dict_index_t *clust_index, + dict_index_t *index, TABLE *mysql_table, mem_heap_t *heap) { mem_heap_t *local_heap = nullptr; for (ulint i = 0; i < dict_index_get_n_fields(index); i++) { const dict_field_t *ind_field = index->get_field(i); @@ -649,7 +669,7 @@ static void row_vers_build_clust_v_col(dtuple_t *row, dict_index_t *clust_index, col = reinterpret_cast(ind_field->col); innobase_get_computed_value(row, col, clust_index, &local_heap, heap, - nullptr, current_thd, nullptr, nullptr, + nullptr, current_thd, mysql_table, nullptr, nullptr, nullptr); } } @@ -1466,3 +1486,18 @@ void row_vers_build_for_semi_consistent_read( mem_heap_free(heap); } } + +/**build the value of virtual column in the index, base on current cluster index + * record data from log record of table operations during online ddl + * @param[in,out] row the cluster index row in dtuple form + * @param[in] clust_index clustered index + * @param[in] index the secondary index + * @param[in] mysql_table mysql table object + * @param[in] heap heap used to build virtual dtuple */ +void row_vers_build_clust_v_col_from_log_table(const dtuple_t *row, dict_index_t *clust_index, + dict_index_t *index, TABLE *mysql_table, mem_heap_t *heap) { + + row_vers_build_clust_v_col_low(row, clust_index, index, mysql_table, heap); + +} +