diff options
Diffstat (limited to 'storage/xtradb/row/row0upd.c')
-rw-r--r-- | storage/xtradb/row/row0upd.c | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c index e1c78949603..a6fb266c4ed 100644 --- a/storage/xtradb/row/row0upd.c +++ b/storage/xtradb/row/row0upd.c @@ -439,6 +439,12 @@ row_upd_changes_field_size_or_external( 0); } + if (srv_use_sys_stats_table + && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes) + && upd_field->field_no >= rec_offs_n_fields(offsets)) { + return(TRUE); + } + old_len = rec_offs_nth_size(offsets, upd_field->field_no); if (rec_offs_comp(offsets) @@ -844,6 +850,18 @@ row_upd_build_difference_binary( for (i = 0; i < dtuple_get_n_fields(entry); i++) { + if (srv_use_sys_stats_table + && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes) + && i >= rec_offs_n_fields(offsets)) { + dfield = dtuple_get_nth_field(entry, i); + + upd_field = upd_get_nth_field(update, n_diff); + dfield_copy(&(upd_field->new_val), dfield); + upd_field_set_field_no(upd_field, i, index, trx); + n_diff++; + goto skip_compare; + } + data = rec_get_nth_field(rec, offsets, i, &len); dfield = dtuple_get_nth_field(entry, i); @@ -1192,25 +1210,31 @@ NOTE: we compare the fields as binary strings! @return TRUE if update vector changes an ordering field in the index record */ UNIV_INTERN ibool -row_upd_changes_ord_field_binary( -/*=============================*/ +row_upd_changes_ord_field_binary_func( +/*==================================*/ + dict_index_t* index, /*!< in: index of the record */ + const upd_t* update, /*!< in: update vector for the row; NOTE: the + field numbers in this MUST be clustered index + positions! */ +#ifdef UNIV_DEBUG + const que_thr_t*thr, /*!< in: query thread */ +#endif /* UNIV_DEBUG */ const dtuple_t* row, /*!< in: old value of row, or NULL if the row and the data values in update are not known when this function is called, e.g., at compile time */ - const row_ext_t*ext, /*!< NULL, or prefixes of the externally + const row_ext_t*ext) /*!< NULL, or prefixes of the externally stored columns in the old row */ - dict_index_t* index, /*!< in: index of the record */ - const upd_t* update) /*!< in: update vector for the row; NOTE: the - field numbers in this MUST be clustered index - positions! */ { ulint n_unique; ulint i; const dict_index_t* clust_index; - ut_ad(update); ut_ad(index); + ut_ad(update); + ut_ad(thr); + ut_ad(thr->graph); + ut_ad(thr->graph->trx); n_unique = dict_index_get_n_unique(index); @@ -1252,6 +1276,10 @@ row_upd_changes_ord_field_binary( || dfield_is_null(dfield)) { /* do nothing special */ } else if (UNIV_LIKELY_NULL(ext)) { + /* Silence a compiler warning without + silencing a Valgrind error. */ + dfield_len = 0; + UNIV_MEM_INVALID(&dfield_len, sizeof dfield_len); /* See if the column is stored externally. */ buf = row_ext_lookup(ext, col_no, &dfield_len); @@ -1259,9 +1287,14 @@ row_upd_changes_ord_field_binary( if (UNIV_LIKELY_NULL(buf)) { if (UNIV_UNLIKELY(buf == field_ref_zero)) { - /* This should never happen, but - we try to fail safe here. */ - ut_ad(0); + /* The externally stored field + was not written yet. This + record should only be seen by + recv_recovery_rollback_active(), + when the server had crashed before + storing the field. */ + ut_ad(thr->graph->trx->is_recovered); + ut_ad(trx_is_recv(thr->graph->trx)); return(TRUE); } @@ -1608,8 +1641,8 @@ row_upd_sec_step( ut_ad(!dict_index_is_clust(node->index)); if (node->state == UPD_NODE_UPDATE_ALL_SEC - || row_upd_changes_ord_field_binary(node->row, node->ext, - node->index, node->update)) { + || row_upd_changes_ord_field_binary(node->index, node->update, + thr, node->row, node->ext)) { return(row_upd_sec_index_entry(node, thr)); } @@ -1937,7 +1970,7 @@ row_upd_clust_rec( index, btr_cur_get_block(btr_cur), rec, rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap), - big_rec, mtr); + mtr, TRUE, big_rec); mtr_commit(mtr); } @@ -2136,8 +2169,8 @@ exit_func: row_upd_store_row(node); - if (row_upd_changes_ord_field_binary(node->row, node->ext, index, - node->update)) { + if (row_upd_changes_ord_field_binary(index, node->update, thr, + node->row, node->ext)) { /* Update causes an ordering field (ordering fields within the B-tree) of the clustered index record to change: perform |