# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: rohit.kalhans@gmail.com-20140324112050-be9nyakv5debgvzo # target_branch: file:///work/mariadb/mariadb/mariadb10/ # testament_sha1: b10123115431579b7b0ea0d9311efc5c8ac702fb # timestamp: 2014-03-24 16:52:42 +0530 # base_revision_id: elenst@wheezy-64.home-20140315125635-\ # 4mv83huc3dntadur # # Begin patch === modified file 'mysql-test/suite/rpl/r/rpl_gtid_basic.result' --- mysql-test/suite/rpl/r/rpl_gtid_basic.result 2014-02-11 13:21:48 +0000 +++ mysql-test/suite/rpl/r/rpl_gtid_basic.result 2014-03-24 11:20:50 +0000 @@ -248,6 +248,9 @@ -1 SELECT * FROM t1 ORDER BY a; a +SELECT master_gtid_wait("1-99-1", 2); +master_gtid_wait("1-99-1", 2) +-1 SELECT master_gtid_wait(@pos); include/start_slave.inc master_gtid_wait(@pos) === modified file 'mysql-test/suite/rpl/t/rpl_gtid_basic.test' --- mysql-test/suite/rpl/t/rpl_gtid_basic.test 2014-02-11 13:06:03 +0000 +++ mysql-test/suite/rpl/t/rpl_gtid_basic.test 2014-03-24 11:20:50 +0000 @@ -243,6 +243,13 @@ # Let's check that we get a timeout SELECT master_gtid_wait(@pos, 0.5); SELECT * FROM t1 ORDER BY a; + +# MDEV-5873 +# We use a gtid with the same domain and seq no as one of the trx already +# applied but with an impossible server id. +# This should return with a timeout (returns -1) +SELECT master_gtid_wait("1-99-1", 2); + # Now actually wait until the slave reaches the position send SELECT master_gtid_wait(@pos); === modified file 'sql/rpl_gtid.cc' --- sql/rpl_gtid.cc 2014-02-10 14:12:17 +0000 +++ sql/rpl_gtid.cc 2014-03-24 11:20:50 +0000 @@ -90,12 +90,21 @@ my_free(elem); } +static void +rpl_slave_state_free_dom_element(void *arg) +{ + struct rpl_slave_state::dom_element *elem= + (struct rpl_slave_state::dom_element *)arg; + my_hash_free(&elem->hash); + my_free(elem); +} rpl_slave_state::rpl_slave_state() : last_sub_id(0), inited(false), loaded(false) { - my_hash_init(&hash, &my_charset_bin, 32, offsetof(element, domain_id), - sizeof(uint32), NULL, rpl_slave_state_free_element, HASH_UNIQUE); + my_hash_init(&hash, &my_charset_bin, 32, offsetof(dom_element, domain_id), + sizeof(uint32), NULL, rpl_slave_state_free_dom_element, + HASH_UNIQUE); } @@ -112,17 +121,16 @@ inited= true; } - -void -rpl_slave_state::truncate_hash() +void truncate_server_id_hash(HASH *hash) { uint32 i; - for (i= 0; i < hash.records; ++i) + for (i= 0; i < hash->records; ++i) { - element *e= (element *)my_hash_element(&hash, i); - list_element *l= e->list; - list_element *next; + rpl_slave_state::element *e= (rpl_slave_state::element *) + my_hash_element(hash, i); + rpl_slave_state::list_element *l= e->list; + rpl_slave_state::list_element *next; while (l) { next= l->next; @@ -131,6 +139,18 @@ } /* The element itself is freed by the hash element free function. */ } + my_hash_reset(hash); +} + +void +rpl_slave_state::truncate_hash() +{ + uint32 i; + for (i= 0; i < hash.records; ++i) + { + dom_element *de= (dom_element *)my_hash_element(&hash, i); + truncate_server_id_hash(&de->hash); + } my_hash_reset(&hash); } @@ -152,7 +172,7 @@ element *elem= NULL; list_element *list_elem= NULL; - if (!(elem= get_element(domain_id))) + if (!(elem= get_element(domain_id, server_id))) return 1; if (seq_no > elem->highest_seq_no) @@ -185,35 +205,67 @@ struct rpl_slave_state::element * -rpl_slave_state::get_element(uint32 domain_id) +rpl_slave_state::get_element(uint32 domain_id, uint32 server_id) { - struct element *elem; + struct element *elem= 0; + struct dom_element *d_elem= 0; + bool domain_exists= false;// assuming domain does not exist already - elem= (element *)my_hash_search(&hash, (const uchar *)&domain_id, 0); + d_elem= (dom_element *)my_hash_search(&hash, (const uchar *)&domain_id, 0); + if (d_elem) + { + domain_exists= true; // domain exists + elem= (element *)my_hash_search(&d_elem->hash, (const uchar *)&server_id, 0); + } if (elem) return elem; - - if (!(elem= (element *)my_malloc(sizeof(*elem), MYF(MY_WME)))) + // creare new domain element. + if (!domain_exists) + { + if (!(d_elem= (dom_element *)my_malloc(sizeof(*d_elem), MYF(MY_WME)))) + return NULL; + + my_hash_init(&d_elem->hash, &my_charset_bin, 32, + offsetof(element, server_id), sizeof(uint32), + NULL, rpl_slave_state_free_element, HASH_UNIQUE); + // set domain id + d_elem->domain_id= domain_id; + // insert this domain in the hash. + if (my_hash_insert(&hash, (uchar *)d_elem)) + { + my_free(d_elem); + return NULL; + } + } + + if (!(elem=(element*)my_malloc(sizeof(*elem), MYF(MY_WME)))) return NULL; + + mysql_cond_init(key_COND_wait_gtid, &elem->COND_wait_gtid, 0); elem->list= NULL; - elem->domain_id= domain_id; + elem->server_id= server_id; elem->highest_seq_no= 0; elem->gtid_waiter= NULL; - mysql_cond_init(key_COND_wait_gtid, &elem->COND_wait_gtid, 0); - if (my_hash_insert(&hash, (uchar *)elem)) + + if(my_hash_insert(&d_elem->hash, (uchar *)elem)) { my_free(elem); return NULL; } + return elem; } int -rpl_slave_state::put_back_list(uint32 domain_id, list_element *list) +rpl_slave_state::put_back_list(uint32 domain_id, uint32 server_id, + list_element *list) { + dom_element* de; element *e; - if (!(e= (element *)my_hash_search(&hash, (const uchar *)&domain_id, 0))) + if (!(de= (dom_element *)my_hash_search(&hash, (const uchar *)&domain_id, 0))) + return 1; + if (!(e=(element *)my_hash_search(&de->hash,(const uchar*)&server_id, 0))) return 1; while (list) { @@ -407,7 +459,7 @@ } mysql_mutex_lock(&LOCK_slave_state); - if ((elem= get_element(gtid->domain_id)) == NULL) + if ((elem= get_element(gtid->domain_id, gtid->server_id)) == NULL) { mysql_mutex_unlock(&LOCK_slave_state); my_error(ER_OUT_OF_RESOURCES, MYF(0)); @@ -499,7 +551,7 @@ if (elist) { mysql_mutex_lock(&LOCK_slave_state); - put_back_list(gtid->domain_id, elist); + put_back_list(gtid->domain_id, gtid->server_id, elist); mysql_mutex_unlock(&LOCK_slave_state); } @@ -556,7 +608,7 @@ rpl_slave_state::iterate(int (*cb)(rpl_gtid *, void *), void *data, rpl_gtid *extra_gtids, uint32 num_extra) { - uint32 i; + uint32 i, j; HASH gtid_hash; uchar *rec; rpl_gtid *gtid; @@ -573,25 +625,34 @@ for (i= 0; i < hash.records; ++i) { - uint64 best_sub_id; + uint64 best_sub_id= 0; rpl_gtid best_gtid; - element *e= (element *)my_hash_element(&hash, i); - list_element *l= e->list; - - if (!l) - continue; /* Nothing here */ - - best_gtid.domain_id= e->domain_id; - best_gtid.server_id= l->server_id; - best_gtid.seq_no= l->seq_no; - best_sub_id= l->sub_id; - while ((l= l->next)) + bool first= true; + dom_element *de= (dom_element *)my_hash_element(&hash, i); + for ( j= 0; j < de->hash.records; ++j) { - if (l->sub_id > best_sub_id) + element* e= (element *)my_hash_element(&de->hash, j); + list_element *l= e->list; + + if (!l) + continue; /* Nothing here */ + if (first) // executed once per domain. { best_sub_id= l->sub_id; + best_gtid.domain_id= de->domain_id; best_gtid.server_id= l->server_id; best_gtid.seq_no= l->seq_no; + first= false; + } + while(l) + { + if (l->sub_id > best_sub_id) + { + best_sub_id= l->sub_id; + best_gtid.server_id= l->server_id; + best_gtid.seq_no= l->seq_no; + } + l = l->next; } } @@ -683,30 +744,48 @@ bool rpl_slave_state::domain_to_gtid(uint32 domain_id, rpl_gtid *out_gtid) { - element *elem; + dom_element *d_elem; + element* elem; list_element *list; uint64 best_sub_id; + uint32 i; + bool first= true; mysql_mutex_lock(&LOCK_slave_state); - elem= (element *)my_hash_search(&hash, (const uchar *)&domain_id, 0); - if (!elem || !(list= elem->list)) + d_elem= (dom_element *)my_hash_search(&hash, (const uchar *)&domain_id, 0); + if (!d_elem) { mysql_mutex_unlock(&LOCK_slave_state); return false; } - - out_gtid->domain_id= domain_id; - out_gtid->server_id= list->server_id; - out_gtid->seq_no= list->seq_no; - best_sub_id= list->sub_id; - - while ((list= list->next)) + for (i= 0; i < d_elem->hash.records; ++i) { - if (best_sub_id > list->sub_id) - continue; - best_sub_id= list->sub_id; - out_gtid->server_id= list->server_id; - out_gtid->seq_no= list->seq_no; + elem= (element*)my_hash_element(&d_elem->hash, i); + if (!elem || !(list= elem->list)) + { + mysql_mutex_unlock(&LOCK_slave_state); + return false; + } + if (first) + { + out_gtid->domain_id= domain_id; + out_gtid->server_id= list->server_id; + out_gtid->seq_no= list->seq_no; + best_sub_id= list->sub_id; + first= false; + } + while (list) + { + if (best_sub_id > list->sub_id) + { + list= list->next; + continue; + } + best_sub_id= list->sub_id; + out_gtid->server_id= list->server_id; + out_gtid->seq_no= list->seq_no; + list= list->next; + } } mysql_mutex_unlock(&LOCK_slave_state); @@ -836,18 +915,23 @@ bool rpl_slave_state::is_empty() { - uint32 i; + uint32 i, j; bool result= true; mysql_mutex_lock(&LOCK_slave_state); for (i= 0; i < hash.records; ++i) { - element *e= (element *)my_hash_element(&hash, i); - if (e->list) + dom_element *de= (dom_element *)my_hash_element(&hash, i); + for (j= 0; j < de->hash.records; ++j) { - result= false; - break; + element *e= (element *)my_hash_element(&de->hash, j); + if (e->list) + { + result= false; + break; + } } + if(!result) break; } mysql_mutex_unlock(&LOCK_slave_state); @@ -986,7 +1070,7 @@ gtid->server_id= server_id; mysql_mutex_lock(&LOCK_binlog_state); - if ((elem= (element *)my_hash_search(&hash, (const uchar *)(&domain_id), 0))) + if ((elem= (element*)my_hash_search(&hash, (const uchar *)(&domain_id), 0))) { gtid->seq_no= ++elem->seq_no_counter; if (!elem->update_element(gtid)) @@ -1807,6 +1891,7 @@ #ifdef HAVE_REPLICATION queue_element elem; uint32 domain_id= wait_gtid->domain_id; + uint32 server_id= wait_gtid->server_id; uint64 seq_no= wait_gtid->seq_no; hash_element *he; rpl_slave_state::element *slave_state_elem= NULL; @@ -1858,7 +1943,7 @@ and re-aquiring the lock. */ if (!slave_state_elem && - !(slave_state_elem= rpl_global_gtid_slave_state.get_element(domain_id))) + !(slave_state_elem= rpl_global_gtid_slave_state.get_element(domain_id, server_id))) { mysql_mutex_unlock(&rpl_global_gtid_slave_state.LOCK_slave_state); remove_from_wait_queue(he, &elem); === modified file 'sql/rpl_gtid.h' --- sql/rpl_gtid.h 2014-02-08 21:28:41 +0000 +++ sql/rpl_gtid.h 2014-03-24 11:20:50 +0000 @@ -112,11 +112,18 @@ }; /* Elements in the HASH that hold the state for one domain_id. */ + struct dom_element + { + uint32 domain_id; + HASH hash; + }; + + /* Elements in the HASH that hold the state for one server_id. */ struct element { struct list_element *list; - uint32 domain_id; - /* Highest seq_no seen so far in this domain. */ + uint32 server_id; + /* Highest seq_no seen so far in this (domain,server_id). */ uint64 highest_seq_no; /* If this is non-NULL, then it is the waiter responsible for the small @@ -168,8 +175,8 @@ bool in_statement); bool is_empty(); - element *get_element(uint32 domain_id); - int put_back_list(uint32 domain_id, list_element *list); + element *get_element(uint32 domain_id, uint32 server_id); + int put_back_list(uint32 domain_id, uint32 server_id, list_element *list); void update_state_hash(uint64 sub_id, rpl_gtid *gtid); int record_and_update_gtid(THD *thd, struct rpl_group_info *rgi); # Begin bundle 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 gpE//i7kinChICyW/NY=