diff --git a/sql/binlog.cc b/sql/binlog.cc index 593ef91637e0..af466d34772a 100644 --- a/sql/binlog.cc +++ b/sql/binlog.cc @@ -14246,6 +14246,29 @@ void MYSQL_BIN_LOG::finish_transaction_in_engines(THD *thd, bool all, bool run_a } } +int trim_logged_gtid(const std::vector &trimmed_gtids) { + if (trimmed_gtids.empty()) return 0; + + global_tsid_lock->rdlock(); + int error = gtid_state->remove_logged_gtid_on_trim(trimmed_gtids); + Master_info *active_mi = nullptr; + if (!get_and_lock_master_info(&active_mi)) { + // NO_LINT_DEBUG + sql_print_information( + "active_mi or rli is not set. Hence not trimming " + "logged gtids from rli"); + } + if (active_mi && active_mi->rli) { + // Remove rli logged gtids. Note that retrieved gtid is not cleared here + // since it is going to be updated when the next gtid is fetched + error = active_mi->rli->remove_logged_gtids(trimmed_gtids); + unlock_master_info(active_mi); + } + global_tsid_lock->unlock(); + + return error; +} + struct st_mysql_storage_engine binlog_storage_engine = { MYSQL_HANDLERTON_INTERFACE_VERSION}; diff --git a/sql/binlog.h b/sql/binlog.h index e81ae7a7d1a9..6f6eaba0923d 100644 --- a/sql/binlog.h +++ b/sql/binlog.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "my_dbug.h" #include "my_inttypes.h" @@ -1643,6 +1644,7 @@ int query_error_code(const THD *thd, bool not_killed); bool show_raft_status(THD *thd); bool get_and_lock_master_info(Master_info **master_info); void unlock_master_info(Master_info *master_info); +int trim_logged_gtid(const std::vector &trimmed_gtids); void set_valid_pos(my_off_t *valid_pos, const std::string &cur_binlog_file, my_off_t first_gtid_start, char *engine_binlog_file, diff --git a/sql/rpl_gtid.h b/sql/rpl_gtid.h index 246477cbedaa..cabe652c36f2 100644 --- a/sql/rpl_gtid.h +++ b/sql/rpl_gtid.h @@ -3161,6 +3161,13 @@ class Gtid_state { */ int32 get_gtid_wait_count() { return atomic_gtid_wait_count; } + /** + Remove gtid from logged_gtid when binlog gets trimmed. + @param trimmed_gtids The gtids to remove from logged_gtids + */ + enum_return_status remove_logged_gtid_on_trim( + const std::vector &trimmed_gtids); + #endif // ifdef MYSQL_SERVER /** Computes the next available GNO. diff --git a/sql/rpl_gtid_state.cc b/sql/rpl_gtid_state.cc index cc2b1c72448c..bf6a4cb6efaa 100644 --- a/sql/rpl_gtid_state.cc +++ b/sql/rpl_gtid_state.cc @@ -22,6 +22,9 @@ #include #include +#include +#include +#include #include "lex_string.h" #include "my_compiler.h" @@ -38,6 +41,7 @@ #include "sql/binlog.h" #include "sql/current_thd.h" #include "sql/debug_sync.h" // DEBUG_SYNC +#include "sql/log.h" #include "sql/mdl.h" #include "sql/mysqld.h" // opt_bin_log #include "sql/rpl_context.h" @@ -964,3 +968,47 @@ enum_return_status Gtid_state::ensure_commit_group_sidnos(rpl_sidno sidno) { BINLOG_ERROR(("Out of memory."), (ER_OUT_OF_RESOURCES, MYF(0))); RETURN_REPORTED_ERROR; } + +enum_return_status Gtid_state::remove_logged_gtid_on_trim( + const std::vector &trimmed_gtids) { + DBUG_TRACE; + global_tsid_lock->assert_some_lock(); + + if (trimmed_gtids.empty()) RETURN_OK; + + const auto &first_gtid = trimmed_gtids.front(); + + Gtid gtid; + if (gtid.parse(global_tsid_map, first_gtid.c_str()) != + mysql::utils::Return_status::ok) { + // NO_LINT_DEBUG + sql_print_error("Failed to parse gtid %s", first_gtid.c_str()); + RETURN_REPORTED_ERROR; + } + + rpl_sidno first_sidno = gtid.sidno; + tsid_locks.lock(first_sidno); + + for (const auto &trimmed_gtid : trimmed_gtids) { + if (gtid.parse(global_tsid_map, trimmed_gtid.c_str()) != + mysql::utils::Return_status::ok) { + // NO_LINT_DEBUG + sql_print_error("Failed to parse gtid %s", trimmed_gtid.c_str()); + tsid_locks.unlock(first_sidno); + RETURN_REPORTED_ERROR; + } + assert(first_sidno == gtid.sidno); + if (gtid.sidno > 0) { + /* Remove Gtid from logged_gtid set. */ + DBUG_PRINT("info", + ("Removing gtid(sidno:%d, gno:%" PRId64 ") from logged gtids", + gtid.sidno, gtid.gno)); + // TODO(pgl) - confirm once if the below code is good? + executed_gtids._remove_gtid(gtid); + gtids_only_in_table._remove_gtid(gtid); + } + } + + tsid_locks.unlock(first_sidno); + RETURN_OK; +} diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc index 16f6447d863e..4cc009cbe579 100644 --- a/sql/rpl_handler.cc +++ b/sql/rpl_handler.cc @@ -83,6 +83,7 @@ extern int raft_stop_io_thread(THD *thd); extern int raft_start_sql_thread(THD *thd); extern int rli_relay_log_raft_reset( std::pair raft_log_applied_upto_pos); +extern int trim_logged_gtid(const std::vector &trimmed_gtids); /** end of raft related extern funtion declarations **/ Trans_delegate *transaction_delegate; @@ -1769,6 +1770,10 @@ extern "C" void *process_raft_queue(void *) { result.error = handle_read_only(element.arg.val_sys_var_uint); break; } + case RaftListenerCallbackType::TRIM_LOGGED_GTIDS: { + result.error = trim_logged_gtid(element.arg.trim_gtids); + break; + } case RaftListenerCallbackType::ROTATE_BINLOG: { result.error = rotate_binlog_file(current_thd); break; diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 0824db3f5067..2eaccb139055 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include "mutex_lock.h" // Mutex_lock #include "my_bitmap.h" @@ -1902,6 +1903,34 @@ int Relay_log_info::rli_init_info(bool skip_received_gtid_set_recovery) { return error; } +int Relay_log_info::remove_logged_gtids( + const std::vector &trimmed_gtids) { + DBUG_TRACE; + global_tsid_lock->assert_some_lock(); + + if (trimmed_gtids.empty()) RETURN_OK; + + Gtid gtid; + for (const auto &trimmed_gtid : trimmed_gtids) { + if (gtid.parse(global_tsid_map, trimmed_gtid.c_str()) != + mysql::utils::Return_status::ok) { + // NO_LINT_DEBUG + sql_print_error("Failed to parse gtid %s", trimmed_gtid.c_str()); + RETURN_REPORTED_ERROR; + } + + if (gtid.sidno > 0) { + /* Remove Gtid from logged_gtid set. */ + DBUG_PRINT("info", ("Removing gtid(sidno:%d, gno:%" PRId64 + ") from rli logged gtids", + gtid.sidno, gtid.gno)); + gtid_set->_remove_gtid(gtid); + } + } + + RETURN_OK; +} + void Relay_log_info::end_info() { DBUG_TRACE; diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 73724224a7cd..14784b55889f 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -862,6 +862,8 @@ class Relay_log_info : public Rpl_info { */ enum_return_status add_gtid_set(const Gtid_set *gtid_set); + int remove_logged_gtids(const std::vector &trimmed_gtids); + const Gtid_set *get_gtid_set() const { return gtid_set; } bool reinit_sql_thread_io_cache(const char *log, bool need_data_lock);