diff options
author | unknown <knielsen@knielsen-hq.org> | 2013-06-21 11:53:46 +0200 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2013-06-21 11:53:46 +0200 |
commit | 6e7d7f9bcd25b475b0f399d77e80eee05471cb5c (patch) | |
tree | 9e9d774dbd35a390bf8c2f174f9adba6b857ad42 /sql/rpl_gtid.cc | |
parent | 03fb90f3a770bceca743c26533af4d99c8fa9549 (diff) | |
download | mariadb-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.cc | 40 |
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) |