summaryrefslogtreecommitdiff
path: root/sql/rpl_gtid.cc
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2013-06-21 11:53:46 +0200
committerunknown <knielsen@knielsen-hq.org>2013-06-21 11:53:46 +0200
commit6e7d7f9bcd25b475b0f399d77e80eee05471cb5c (patch)
tree9e9d774dbd35a390bf8c2f174f9adba6b857ad42 /sql/rpl_gtid.cc
parent03fb90f3a770bceca743c26533af4d99c8fa9549 (diff)
downloadmariadb-git-6e7d7f9bcd25b475b0f399d77e80eee05471cb5c.tar.gz
MDEV-4688: empty @@gtid_slave_pos during slave commit.
In record_gtid(), too many rows were deleted from the slave position hash - we need to always keep on to the most recent committed row, so we have a valid slave position at all times.
Diffstat (limited to 'sql/rpl_gtid.cc')
-rw-r--r--sql/rpl_gtid.cc40
1 files changed, 33 insertions, 7 deletions
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index d8e79c1e002..4783fb763c8 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -363,6 +363,14 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
goto end;
}
+ if(opt_bin_log &&
+ (err= mysql_bin_log.bump_seq_no_counter_if_needed(gtid->domain_id,
+ gtid->seq_no)))
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ goto end;
+ }
+
lock();
if ((elem= get_element(gtid->domain_id)) == NULL)
{
@@ -371,7 +379,30 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
err= 1;
goto end;
}
- elist= elem->grab_list();
+ if ((elist= elem->grab_list()) != NULL)
+ {
+ /* Delete any old stuff, but keep around the most recent one. */
+ list_element *cur= elist;
+ uint64 best_sub_id= cur->sub_id;
+ list_element **best_ptr_ptr= &elist;
+ while ((next= cur->next))
+ {
+ if (next->sub_id > best_sub_id)
+ {
+ best_sub_id= next->sub_id;
+ best_ptr_ptr= &cur->next;
+ }
+ cur= next;
+ }
+ /*
+ Delete the highest sub_id element from the old list, and put it back as
+ the single-element new list.
+ */
+ cur= *best_ptr_ptr;
+ *best_ptr_ptr= cur->next;
+ cur->next= NULL;
+ elem->list= cur;
+ }
unlock();
if (!elist)
@@ -393,7 +424,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
DBUG_EXECUTE_IF("gtid_slave_pos_simulate_failed_delete",
{ err= ENOENT;
table->file->print_error(err, MYF(0));
- /* `break' does not work in DBUG_EXECUTE_IF */
+ /* `break' does not work inside DBUG_EXECUTE_IF */
goto dbug_break; });
next= elist->next;
@@ -420,11 +451,6 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
IF_DBUG(dbug_break:, )
table->file->ha_index_end();
- if(!err && opt_bin_log &&
- (err= mysql_bin_log.bump_seq_no_counter_if_needed(gtid->domain_id,
- gtid->seq_no)))
- my_error(ER_OUT_OF_RESOURCES, MYF(0));
-
end:
if (table_opened)