Hi Marko, Thanks for the patch. It looks good, just a few small comments inline. Approved after fixing the check for !is_relay_log. I have pushed an extra commit on top of bb-10.4-MDEV-32673 with a testcase (feel free to squash it onto your commit). The tests pass with your patch (but fails without it). - Kristian.
diff --git a/sql/handler.h b/sql/handler.h index 6085111bc25..134212a0ad7 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1438,6 +1438,7 @@ struct handlerton enum_binlog_command binlog_command, const char *query, uint query_length, const char *db, const char *table_name); + void (*reset_binlog_pos)(const char *name, uint64_t pos);
I think there should be a comment describing what this new call does. Suggestion: /* Called at server startup or RESET MASTER when the new binlog is opened. Informs the storage engine of the change in binlog file name and position. */
diff --git a/sql/log.cc b/sql/log.cc index 59730c3205a..e46f3796b63 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4327,6 +4327,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, err: if (error == 1) name= const_cast<char*>(save_name); + else + ha_reset_binlog_pos(get_log_fname(), BIN_LOG_HEADER_SIZE);
Sorry, I forgot something when we discussed this. This function is also used for resetting the relay logs. So it needs a check for !is_relay_log. For example: --- a/sql/log.cc +++ b/sql/log.cc @@ -4331,6 +4331,10 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, if (!is_relay_log) { xid_count_per_binlog *b; + + if (!error) + ha_reset_binlog_pos(get_log_fname(), BIN_LOG_HEADER_SIZE); + /* Remove all entries in the xid_count list except the last. Normally we will just be deleting all the entries that we waited for to
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index be52373d03b..3ffa003588d 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -826,3 +826,52 @@ trx_rseg_update_binlog_offset(byte* rseg_header, const trx_t* trx, mtr_t* mtr) mlog_write_string(p, binlog_name, len, mtr); } } + +void trx_rseg_reset_binlog_pos(const char *name, uint64_t pos) +{ + mtr_t mtr; + /* Invalidate the information on the TRX_SYS page. */ + mtr.start(); + if (buf_block_t *sys= trx_sysf_get(&mtr, true)) + { + byte *magic= TRX_SYS + TRX_SYS_MYSQL_LOG_INFO + + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD + sys->frame; + if (mach_read_from_4(magic)) + mlog_memset(magic, + TRX_SYS_MYSQL_LOG_NAME + TRX_SYS_MYSQL_LOG_NAME_LEN, 0, + &mtr); + + const uint32_t page_no= trx_sysf_rseg_get_page_no(sys, 0); + if (page_no != FIL_NULL) + { + const uint32_t space_id= trx_sysf_rseg_get_space(sys, 0); + ut_ad(space_id == TRX_SYS_SPACE); + buf_block_t *block= buf_page_get(page_id_t(space_id, page_no), + 0, RW_X_LATCH, &mtr); + mlog_write_ull(TRX_RSEG + TRX_RSEG_BINLOG_OFFSET + block->frame, + pos, &mtr); + byte *p= TRX_RSEG + TRX_RSEG_BINLOG_NAME + block->frame; + const size_t len= strlen(name) + 1; + if (memcmp(name, p, len)) + mlog_write_string(p, reinterpret_cast<const byte*>(name), len, &mtr); + } + + /* Invalidate the information in the other rollback segment headers. */ + for (ulint rseg_id= 1; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) + { + const uint32_t page_no= trx_sysf_rseg_get_page_no(sys, rseg_id); + if (page_no != FIL_NULL) + { + const uint32_t space_id= trx_sysf_rseg_get_space(sys, rseg_id); + buf_block_t *block= buf_page_get(page_id_t(space_id, page_no), + 0, RW_X_LATCH, &mtr); + byte *name= TRX_RSEG + TRX_RSEG_BINLOG_NAME + block->frame; + if (*name) + mlog_write_ulint(name, 0, MLOG_1BYTE, &mtr); + } + } + } + mtr.commit(); + /* Durably write the change. */ + log_write_up_to(mtr.commit_lsn(), true); +}