summaryrefslogtreecommitdiff
path: root/storage/innobase/trx/trx0rec.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/trx/trx0rec.cc')
-rw-r--r--storage/innobase/trx/trx0rec.cc91
1 files changed, 58 insertions, 33 deletions
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 86fe7758626..ce291b7add9 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -1191,14 +1191,43 @@ trx_undo_page_report_modify(
const dict_col_t* col
= dict_table_get_nth_col(table, col_no);
- const char* col_name = dict_table_get_col_name(table,
- col_no);
if (!col->ord_part) {
continue;
}
- if (update) {
+ const ulint pos = dict_index_get_nth_col_pos(
+ index, col_no, NULL);
+ /* All non-virtual columns must be present in
+ the clustered index. */
+ ut_ad(pos != ULINT_UNDEFINED);
+
+ const bool is_ext = rec_offs_nth_extern(offsets, pos);
+ const spatial_status_t spatial_status = is_ext
+ ? dict_col_get_spatial_status(col)
+ : SPATIAL_NONE;
+
+ switch (spatial_status) {
+ case SPATIAL_UNKNOWN:
+ ut_ad(0);
+ /* fall through */
+ case SPATIAL_MIXED:
+ case SPATIAL_ONLY:
+ /* Externally stored spatially indexed
+ columns will be (redundantly) logged
+ again, because we did not write the
+ MBR yet, that is, the previous call to
+ trx_undo_page_report_modify_ext()
+ was with SPATIAL_UNKNOWN. */
+ break;
+ case SPATIAL_NONE:
+ if (!update) {
+ /* This is a DELETE operation. */
+ break;
+ }
+ /* Avoid redundantly logging indexed
+ columns that were updated. */
+
for (i = 0; i < update->n_fields; i++) {
const ulint field_no
= upd_get_nth_field(update, i)
@@ -1213,37 +1242,19 @@ trx_undo_page_report_modify(
}
if (true) {
- ulint pos;
- spatial_status_t spatial_status;
-
- spatial_status = SPATIAL_NONE;
-
/* Write field number to undo log */
if (trx_undo_left(undo_page, ptr) < 5 + 15) {
return(0);
}
- pos = dict_index_get_nth_col_pos(index,
- col_no,
- NULL);
- if (pos == ULINT_UNDEFINED) {
- ib::error() << "Column " << col_no
- << " name " << col_name
- << " not found from index " << index->name
- << " table. " << table->name.m_name
- << " Table has " << dict_table_get_n_cols(table)
- << " and index has " << dict_index_get_n_fields(index)
- << " fields.";
- }
-
ptr += mach_write_compressed(ptr, pos);
/* Save the old value of field */
field = rec_get_nth_cfield(
rec, index, offsets, pos, &flen);
- if (rec_offs_nth_extern(offsets, pos)) {
+ if (is_ext) {
const dict_col_t* col =
dict_index_get_nth_col(
index, pos);
@@ -1253,10 +1264,6 @@ trx_undo_page_report_modify(
ut_a(prefix_len < sizeof ext_buf);
- spatial_status =
- dict_col_get_spatial_status(
- col);
-
/* If there is a spatial index on it,
log its MBR */
if (spatial_status != SPATIAL_NONE) {
@@ -1655,6 +1662,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
@@ -1685,6 +1693,16 @@ trx_undo_rec_get_partial_row(
dtuple_init_v_fld(*row);
+ for (const upd_field_t* uf = update->fields, * const ue
+ = update->fields + update->n_fields;
+ uf != ue; uf++) {
+ if (uf->old_v_val) {
+ continue;
+ }
+ ulint c = dict_index_get_nth_col(index, uf->field_no)->ind;
+ *dtuple_get_nth_field(*row, c) = uf->new_val;
+ }
+
end_ptr = ptr + mach_read_from_2(ptr);
ptr += 2;
@@ -1730,6 +1748,13 @@ trx_undo_rec_get_partial_row(
col = dict_index_get_nth_col(index, field_no);
col_no = dict_col_get_no(col);
dfield = dtuple_get_nth_field(*row, col_no);
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dict_col_type_assert_equal(col,
+ &dfield->type));
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dfield->len == len
+ || (len != UNIV_SQL_NULL
+ && len >= UNIV_EXTERN_STORAGE_FIELD));
dict_col_copy_type(
dict_table_get_nth_col(index->table, col_no),
dfield_get_type(dfield));
@@ -1829,8 +1854,9 @@ ulint
trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
buf_block_t* block, mtr_t* mtr)
{
- ulint first_free = mach_read_from_2(block->frame + TRX_UNDO_PAGE_HDR
- + TRX_UNDO_PAGE_FREE);
+ byte* ptr_first_free = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
+ + block->frame;
+ ulint first_free = mach_read_from_2(ptr_first_free);
ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
ut_ad(first_free <= UNIV_PAGE_SIZE);
byte* start = block->frame + first_free;
@@ -1858,11 +1884,10 @@ trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
ptr += 2;
ulint offset = page_offset(ptr);
mach_write_to_2(start, offset);
- mach_write_to_2(block->frame + TRX_UNDO_PAGE_HDR
- + TRX_UNDO_PAGE_FREE, offset);
+ mach_write_to_2(ptr_first_free, offset);
trx_undof_page_add_undo_rec_log(block->frame, first_free, offset, mtr);
- return offset;
+ return first_free;
}
/** Report a RENAME TABLE operation.
@@ -1956,8 +1981,8 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index; NULL if insert */
const ulint* offsets, /*!< in: rec_get_offsets(rec) */
- roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the
- inserted undo log record */
+ roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
+ undo log record */
{
trx_t* trx;
ulint page_no;