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).
This commit is contained in:
parent
ff8676e0e1
commit
bfec9c64b8
@ -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,
|
||||||
|
(is_artificial_event() &&
|
||||||
IF_DBUG(debug_not_change_ts_if_art_event > 0, 1) ?
|
IF_DBUG(debug_not_change_ts_if_art_event > 0, 1) ?
|
||||||
0 : when);
|
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)
|
|||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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'",
|
|||||||
|
|
||||||
end:
|
end:
|
||||||
if (sub_id && !thd->is_slave_error)
|
if (sub_id && !thd->is_slave_error)
|
||||||
update_slave_gtid_state_hash(sub_id, >id);
|
rpl_global_gtid_slave_state.update_state_hash(sub_id, >id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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, >id);
|
rpl_global_gtid_slave_state.update_state_hash(sub_id, >id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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;
|
|||||||
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)
|
|||||||
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
|
|||||||
|
|
||||||
|
|
||||||
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,
|
|||||||
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 @@ public:
|
|||||||
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);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
17
sql/slave.cc
17
sql/slave.cc
@ -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,
|
|
||||||
>id, sub_id, false))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
update_slave_gtid_state_hash(sub_id, >id);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|||||||
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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user