diff options
-rw-r--r-- | storage/innobase/btr/btr0cur.c | 30 | ||||
-rw-r--r-- | storage/innobase/ibuf/ibuf0ibuf.c | 18 | ||||
-rw-r--r-- | storage/innobase/include/btr0cur.h | 15 |
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 |