summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/innobase/btr/btr0cur.c30
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c18
-rw-r--r--storage/innobase/include/btr0cur.h15
3 files changed, 54 insertions, 9 deletions
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index 81a482e2854..16d5016a9b5 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -1631,7 +1631,7 @@ btr_cur_upd_lock_and_undo(
/***********************************************************//**
Writes a redo log record of updating a record in-place. */
-UNIV_INLINE
+UNIV_INTERN
void
btr_cur_update_in_place_log(
/*========================*/
@@ -1659,18 +1659,30 @@ btr_cur_update_in_place_log(
return;
}
- /* The code below assumes index is a clustered index: change index to
- the clustered index if we are updating a secondary index record (or we
- could as well skip writing the sys col values to the log in this case
- because they are not needed for a secondary index record update) */
-
- index = dict_table_get_first_index(index->table);
+ /* For secondary indexes, we could skip writing the dummy system fields
+ to the redo log but we have to change redo log parsing of
+ MLOG_REC_UPDATE_IN_PLACE/MLOG_COMP_REC_UPDATE_IN_PLACE or we have to add
+ new redo log record. For now, just write dummy sys fields to the redo
+ log if we are updating a secondary index record.
+ */
mach_write_to_1(log_ptr, flags);
log_ptr++;
- log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,
- mtr);
+ if (dict_index_is_clust(index)) {
+ log_ptr = row_upd_write_sys_vals_to_log(
+ index, trx, roll_ptr, log_ptr, mtr);
+ } else {
+ /* Dummy system fields for a secondary index */
+ /* TRX_ID Position */
+ log_ptr += mach_write_compressed(log_ptr, 0);
+ /* ROLL_PTR */
+ trx_write_roll_ptr(log_ptr, 0);
+ log_ptr += DATA_ROLL_PTR_LEN;
+ /* TRX_ID */
+ log_ptr += mach_ull_write_compressed(log_ptr, 0);
+ }
+
mach_write_to_2(log_ptr, page_offset(rec));
log_ptr += 2;
diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index 306cdefc304..59403bc599c 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -4016,6 +4016,24 @@ updated_in_place:
to btr_cur_update_in_place(). */
row_upd_rec_in_place(rec, index, offsets,
update, page_zip);
+
+ /* Log the update in place operation. During recovery
+ MLOG_COMP_REC_UPDATE_IN_PLACE/MLOG_REC_UPDATE_IN_PLACE
+ expects trx_id, roll_ptr for secondary indexes. So we
+ just write dummy trx_id(0), roll_ptr(0) */
+ btr_cur_update_in_place_log(BTR_KEEP_SYS_FLAG, rec,
+ index, update,
+ NULL, 0, mtr);
+ DBUG_EXECUTE_IF(
+ "crash_after_log_ibuf_upd_inplace",
+ log_buffer_flush_to_disk();
+ fprintf(stderr,
+ "InnoDB: Wrote log record for ibuf "
+ "update in place operation\n");
+ DBUG_SUICIDE();
+ );
+
+
goto updated_in_place;
}
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 283a6eec852..78637ea7295 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -636,6 +636,21 @@ btr_cur_set_deleted_flag_for_ibuf(
uncompressed */
ibool val, /*!< in: value to set */
mtr_t* mtr); /*!< in/out: mini-transaction */
+
+/***********************************************************//**
+Writes a redo log record of updating a record in-place. */
+UNIV_INTERN
+void
+btr_cur_update_in_place_log(
+/*========================*/
+ ulint flags, /*!< in: flags */
+ rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: index where cursor positioned */
+ const upd_t* update, /*!< in: update vector */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr, /*!< in: roll ptr */
+ mtr_t* mtr); /*!< in: mtr */
+
/*######################################################################*/
/** In the pessimistic delete, if the page data size drops below this