Commit bfec9c64 authored by unknown's avatar unknown

MDEV-26: Global transaction ID, intermediate commit.

 - Fix that slave GTID state was updated from the wrong place in the code,
   causing random crashing and other misery.

 - Fix updates to mysql.rpl_slave_state to not go to binlog (this would cause
   duplicate key errors on the slave and is generally the wrong thing to do).
parent ff8676e0
...@@ -911,9 +911,11 @@ int Log_event::do_update_pos(Relay_log_info *rli) ...@@ -911,9 +911,11 @@ int Log_event::do_update_pos(Relay_log_info *rli)
if (debug_not_change_ts_if_art_event == 1 if (debug_not_change_ts_if_art_event == 1
&& is_artificial_event()) && is_artificial_event())
debug_not_change_ts_if_art_event= 0; ); debug_not_change_ts_if_art_event= 0; );
rli->stmt_done(log_pos, is_artificial_event() && rli->stmt_done(log_pos,
IF_DBUG(debug_not_change_ts_if_art_event > 0, 1) ? (is_artificial_event() &&
0 : when); IF_DBUG(debug_not_change_ts_if_art_event > 0, 1) ?
0 : when),
thd);
DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp", DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
if (debug_not_change_ts_if_art_event == 0) if (debug_not_change_ts_if_art_event == 0)
debug_not_change_ts_if_art_event= 2; ); debug_not_change_ts_if_art_event= 2; );
...@@ -3725,7 +3727,7 @@ bool test_if_equal_repl_errors(int expected_error, int actual_error) ...@@ -3725,7 +3727,7 @@ bool test_if_equal_repl_errors(int expected_error, int actual_error)
void void
update_slave_gtid_state_hash(uint64 sub_id, rpl_gtid *gtid) rpl_slave_state::update_state_hash(uint64 sub_id, rpl_gtid *gtid)
{ {
int err; int err;
/* /*
...@@ -3735,10 +3737,9 @@ update_slave_gtid_state_hash(uint64 sub_id, rpl_gtid *gtid) ...@@ -3735,10 +3737,9 @@ update_slave_gtid_state_hash(uint64 sub_id, rpl_gtid *gtid)
there will not be an attempt to delete the corresponding table row before there will not be an attempt to delete the corresponding table row before
it is even committed. it is even committed.
*/ */
rpl_global_gtid_slave_state.lock(); lock();
err= rpl_global_gtid_slave_state.update(gtid->domain_id, gtid->server_id, err= update(gtid->domain_id, gtid->server_id, sub_id, gtid->seq_no);
sub_id, gtid->seq_no); unlock();
rpl_global_gtid_slave_state.unlock();
if (err) if (err)
{ {
sql_print_warning("Slave: Out of memory during slave state maintenance. " sql_print_warning("Slave: Out of memory during slave state maintenance. "
...@@ -3753,6 +3754,26 @@ update_slave_gtid_state_hash(uint64 sub_id, rpl_gtid *gtid) ...@@ -3753,6 +3754,26 @@ update_slave_gtid_state_hash(uint64 sub_id, rpl_gtid *gtid)
} }
int
rpl_slave_state::record_and_update_gtid(THD *thd, Relay_log_info *rli)
{
uint64 sub_id;
/*
Update the GTID position, if we have it and did not already update
it in a GTID transaction.
*/
if ((sub_id= rli->gtid_sub_id))
{
rli->gtid_sub_id= 0;
if (record_gtid(thd, &rli->current_gtid, sub_id, false))
return 1;
update_state_hash(sub_id, &rli->current_gtid);
}
return 0;
}
/** /**
@todo @todo
Compare the values of "affected rows" around here. Something Compare the values of "affected rows" around here. Something
...@@ -4171,7 +4192,7 @@ Default database: '%s'. Query: '%s'", ...@@ -4171,7 +4192,7 @@ Default database: '%s'. Query: '%s'",
end: end:
if (sub_id && !thd->is_slave_error) if (sub_id && !thd->is_slave_error)
update_slave_gtid_state_hash(sub_id, &gtid); rpl_global_gtid_slave_state.update_state_hash(sub_id, &gtid);
/* /*
Probably we have set thd->query, thd->db, thd->catalog to point to places Probably we have set thd->query, thd->db, thd->catalog to point to places
...@@ -5982,6 +6003,7 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli) ...@@ -5982,6 +6003,7 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli)
rli->group_master_log_name, rli->group_master_log_name,
(ulong) rli->group_master_log_pos)); (ulong) rli->group_master_log_pos));
mysql_mutex_unlock(&rli->data_lock); mysql_mutex_unlock(&rli->data_lock);
rpl_global_gtid_slave_state.record_and_update_gtid(thd, rli);
flush_relay_log_info(rli); flush_relay_log_info(rli);
/* /*
...@@ -6226,6 +6248,7 @@ rpl_slave_state::truncate_state_table(THD *thd) ...@@ -6226,6 +6248,7 @@ rpl_slave_state::truncate_state_table(THD *thd)
if (!(err= open_and_lock_tables(thd, &tlist, FALSE, 0))) if (!(err= open_and_lock_tables(thd, &tlist, FALSE, 0)))
{ {
table= tlist.table; table= tlist.table;
table->no_replicate= 1;
err= table->file->ha_truncate(); err= table->file->ha_truncate();
if (err) if (err)
...@@ -6281,6 +6304,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, ...@@ -6281,6 +6304,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
goto end; goto end;
table_opened= true; table_opened= true;
table= tlist.table; table= tlist.table;
table->no_replicate= 1;
/* /*
ToDo: Check the table definition, error if not as expected. ToDo: Check the table definition, error if not as expected.
...@@ -7805,7 +7829,7 @@ int Xid_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -7805,7 +7829,7 @@ int Xid_log_event::do_apply_event(Relay_log_info const *rli)
thd->mdl_context.release_transactional_locks(); thd->mdl_context.release_transactional_locks();
if (sub_id) if (sub_id)
update_slave_gtid_state_hash(sub_id, &gtid); rpl_global_gtid_slave_state.update_state_hash(sub_id, &gtid);
/* /*
Increment the global status commit count variable Increment the global status commit count variable
...@@ -8553,6 +8577,7 @@ int Stop_log_event::do_update_pos(Relay_log_info *rli) ...@@ -8553,6 +8577,7 @@ int Stop_log_event::do_update_pos(Relay_log_info *rli)
rli->inc_event_relay_log_pos(); rli->inc_event_relay_log_pos();
else else
{ {
rpl_global_gtid_slave_state.record_and_update_gtid(thd, rli);
rli->inc_group_relay_log_pos(0); rli->inc_group_relay_log_pos(0);
flush_relay_log_info(rli); flush_relay_log_info(rli);
} }
...@@ -10354,7 +10379,7 @@ Rows_log_event::do_update_pos(Relay_log_info *rli) ...@@ -10354,7 +10379,7 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
Step the group log position if we are not in a transaction, Step the group log position if we are not in a transaction,
otherwise increase the event log position. otherwise increase the event log position.
*/ */
rli->stmt_done(log_pos, when); rli->stmt_done(log_pos, when, thd);
/* /*
Clear any errors in thd->net.last_err*. It is not known if this is Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in needed or not. It is believed that any errors that may exist in
......
...@@ -3018,6 +3018,9 @@ struct rpl_slave_state ...@@ -3018,6 +3018,9 @@ struct rpl_slave_state
void unlock() { DBUG_ASSERT(inited); mysql_mutex_unlock(&LOCK_slave_state); } void unlock() { DBUG_ASSERT(inited); mysql_mutex_unlock(&LOCK_slave_state); }
element *get_element(uint32 domain_id); element *get_element(uint32 domain_id);
void update_state_hash(uint64 sub_id, rpl_gtid *gtid);
int record_and_update_gtid(THD *thd, Relay_log_info *rli);
}; };
...@@ -4721,7 +4724,6 @@ extern TYPELIB binlog_checksum_typelib; ...@@ -4721,7 +4724,6 @@ extern TYPELIB binlog_checksum_typelib;
them once the fate of the Query is determined for execution. them once the fate of the Query is determined for execution.
*/ */
bool slave_execute_deferred_events(THD *thd); bool slave_execute_deferred_events(THD *thd);
void update_slave_gtid_state_hash(uint64 sub_id, rpl_gtid *gtid);
#endif #endif
/** /**
......
...@@ -1847,7 +1847,7 @@ Old_rows_log_event::do_update_pos(Relay_log_info *rli) ...@@ -1847,7 +1847,7 @@ Old_rows_log_event::do_update_pos(Relay_log_info *rli)
Step the group log position if we are not in a transaction, Step the group log position if we are not in a transaction,
otherwise increase the event log position. otherwise increase the event log position.
*/ */
rli->stmt_done(log_pos, when); rli->stmt_done(log_pos, when, thd);
/* /*
Clear any errors in thd->net.last_err*. It is not known if this is Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in needed or not. It is believed that any errors that may exist in
......
...@@ -1200,7 +1200,7 @@ bool Relay_log_info::cached_charset_compare(char *charset) const ...@@ -1200,7 +1200,7 @@ bool Relay_log_info::cached_charset_compare(char *charset) const
void Relay_log_info::stmt_done(my_off_t event_master_log_pos, void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
time_t event_creation_time) time_t event_creation_time, THD *thd)
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
extern uint debug_not_change_ts_if_art_event; extern uint debug_not_change_ts_if_art_event;
...@@ -1235,6 +1235,7 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos, ...@@ -1235,6 +1235,7 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
else else
{ {
inc_group_relay_log_pos(event_master_log_pos); inc_group_relay_log_pos(event_master_log_pos);
rpl_global_gtid_slave_state.record_and_update_gtid(thd, this);
flush_relay_log_info(this); flush_relay_log_info(this);
/* /*
Note that Rotate_log_event::do_apply_event() does not call this Note that Rotate_log_event::do_apply_event() does not call this
......
...@@ -453,7 +453,7 @@ class Relay_log_info : public Slave_reporting_capability ...@@ -453,7 +453,7 @@ class Relay_log_info : public Slave_reporting_capability
the <code>Seconds_behind_master</code> field. the <code>Seconds_behind_master</code> field.
*/ */
void stmt_done(my_off_t event_log_pos, void stmt_done(my_off_t event_log_pos,
time_t event_creation_time); time_t event_creation_time, THD *thd);
/** /**
......
...@@ -5151,25 +5151,8 @@ MYSQL *rpl_connect_master(MYSQL *mysql) ...@@ -5151,25 +5151,8 @@ MYSQL *rpl_connect_master(MYSQL *mysql)
bool flush_relay_log_info(Relay_log_info* rli) bool flush_relay_log_info(Relay_log_info* rli)
{ {
bool error=0; bool error=0;
uint64 sub_id;
rpl_gtid gtid;
DBUG_ENTER("flush_relay_log_info"); DBUG_ENTER("flush_relay_log_info");
/*
Update the GTID position, if we have it and did not already update
it in a GTID transaction.
*/
if ((sub_id= rli->gtid_sub_id))
{
rli->gtid_sub_id= 0;
gtid= rli->current_gtid;
if (rpl_global_gtid_slave_state.record_gtid(rli->sql_thd,
&gtid, sub_id, false))
error= 1;
else
update_slave_gtid_state_hash(sub_id, &gtid);
}
if (unlikely(rli->no_storage)) if (unlikely(rli->no_storage))
DBUG_RETURN(0); DBUG_RETURN(0);
......
...@@ -3062,6 +3062,7 @@ rpl_load_gtid_slave_state(THD *thd) ...@@ -3062,6 +3062,7 @@ rpl_load_gtid_slave_state(THD *thd)
goto end; goto end;
table_opened= true; table_opened= true;
table= tlist.table; table= tlist.table;
table->no_replicate= 1;
/* /*
ToDo: Check the table definition, error if not as expected. ToDo: Check the table definition, error if not as expected.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment