Skip to content

Commit 00f2d0b

Browse files
committed
Broadcast newmaster from watcher-thread
Acquire generation under rep_mutexp Signed-off-by: Mark Hannum <[email protected]>
1 parent c4d6db0 commit 00f2d0b

File tree

6 files changed

+96
-15
lines changed

6 files changed

+96
-15
lines changed

bdb/rep.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ int gbl_prefault_latency = 0;
6868
int gbl_long_log_truncation_warn_thresh_sec = INT_MAX;
6969
int gbl_long_log_truncation_abort_thresh_sec = INT_MAX;
7070
int gbl_debug_drop_nth_rep_message = 0;
71+
int gbl_broadcast_newmaster = 1;
7172
extern int gbl_debug_stat4dump_loop;
7273

7374
extern struct thdpool *gbl_udppfault_thdpool;
@@ -4838,6 +4839,10 @@ void berkdb_receive_msg(void *ack_handle, void *usr_ptr, char *from_host,
48384839

48394840
bdb_state->dbenv->rep_flush(bdb_state->dbenv);
48404841

4842+
if (gbl_broadcast_newmaster) {
4843+
bdb_state->dbenv->rep_newmaster(bdb_state->dbenv);
4844+
}
4845+
48414846
logmsg(LOGMSG_INFO, "USER_TYPE_LSNCMP %d %d %d %d host:%s\n", lsn_cmp.lsn.file,
48424847
cur_lsn.file, lsn_cmp.lsn.offset, cur_lsn.offset, from_host);
48434848

berkdb/build/db.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,6 +2592,7 @@ struct __db_env {
25922592
void *rep_handle; /* Replication handle and methods. */
25932593
int (*rep_elect) __P((DB_ENV *, int, int, u_int32_t, u_int32_t *, int *, char **));
25942594
int (*rep_flush) __P((DB_ENV *));
2595+
int (*rep_newmaster) __P((DB_ENV *));
25952596
int (*rep_process_message) __P((DB_ENV *, DBT *, DBT *,
25962597
char **, DB_LSN *, uint32_t *, uint32_t *, char **, int));
25972598
int (*rep_verify_will_recover) __P((DB_ENV *, DBT *, DBT *));

berkdb/rep/rep_method.c

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static int __rep_elect __P((DB_ENV *, int, int, u_int32_t, u_int32_t *, int *, c
5151
static int __rep_elect_init
5252
__P((DB_ENV *, DB_LSN *, int, int, int *, u_int32_t *));
5353
static int __rep_flush __P((DB_ENV *));
54+
static int __rep_newmaster __P((DB_ENV *));
5455
static int __rep_restore_prepared __P((DB_ENV *));
5556
static int __rep_get_limit __P((DB_ENV *, u_int32_t *, u_int32_t *));
5657
static int __rep_set_limit __P((DB_ENV *, u_int32_t, u_int32_t));
@@ -116,6 +117,7 @@ __rep_dbenv_create(dbenv)
116117
{
117118
dbenv->rep_elect = __rep_elect;
118119
dbenv->rep_flush = __rep_flush;
120+
dbenv->rep_newmaster = __rep_newmaster;
119121
dbenv->rep_process_message = __rep_process_message;
120122
dbenv->rep_verify_will_recover = __rep_verify_will_recover;
121123
dbenv->rep_start = __rep_start;
@@ -129,13 +131,13 @@ __rep_dbenv_create(dbenv)
129131
dbenv->set_rep_request = __rep_set_request;
130132
dbenv->set_rep_transport = __rep_set_rep_transport;
131133
dbenv->set_rep_ignore = __rep_set_ignore;
132-
dbenv->set_log_trigger = __rep_set_log_trigger;
134+
dbenv->set_log_trigger = __rep_set_log_trigger;
133135
dbenv->set_truncate_sc_callback = __rep_set_truncate_sc_callback;
134136
dbenv->set_rep_truncate_callback = __rep_set_rep_truncate_callback;
135137
dbenv->set_rep_recovery_cleanup = __rep_set_rep_recovery_cleanup;
136138
dbenv->rep_set_gen = __rep_set_gen_pp;
137139
dbenv->wrlock_recovery_lock = __rep_wrlock_recovery_lock;
138-
dbenv->wrlock_recovery_blocked = __rep_wrlock_recovery_blocked;
140+
dbenv->wrlock_recovery_blocked = __rep_wrlock_recovery_blocked;
139141
dbenv->lock_recovery_lock = __rep_lock_recovery_lock;
140142
dbenv->unlock_recovery_lock = __rep_unlock_recovery_lock;
141143
dbenv->set_check_standalone = __rep_set_check_standalone;
@@ -407,8 +409,8 @@ __rep_start(dbenv, dbt, gen, flags)
407409
*/
408410
logmsg(LOGMSG_DEBUG, "%s line %d sending REP_NEWMASTER\n",
409411
__func__, __LINE__);
410-
(void)__rep_send_message(dbenv,
411-
db_eid_broadcast, REP_NEWMASTER, &lsn, NULL, 0, NULL);
412+
(void)__rep_send_message_gen(dbenv,
413+
db_eid_broadcast, REP_NEWMASTER, &lsn, NULL, 0, gen, NULL);
412414
ret = 0;
413415
if (role_chg) {
414416
ret = __txn_reset(dbenv);
@@ -1640,6 +1642,8 @@ __rep_elect_init(dbenv, lsnp, nsites, priority, beginp, otally)
16401642
DB_REP *db_rep;
16411643
REP *rep;
16421644
int ret;
1645+
u_int32_t gen;
1646+
int ismaster = 0;
16431647

16441648
db_rep = dbenv->rep_handle;
16451649
rep = db_rep->region;
@@ -1648,14 +1652,18 @@ __rep_elect_init(dbenv, lsnp, nsites, priority, beginp, otally)
16481652

16491653
/* We may miscount, as we don't hold the replication mutex here. */
16501654
rep->stat.st_elections++;
1655+
MUTEX_LOCK(dbenv, db_rep->rep_mutexp);
1656+
ismaster = F_ISSET(rep, REP_F_MASTER);
1657+
gen = rep->gen;
1658+
MUTEX_UNLOCK(dbenv, db_rep->rep_mutexp);
16511659

16521660
/* If we are already a master; simply broadcast that fact and return. */
1653-
if (F_ISSET(rep, REP_F_MASTER)) {
1661+
if (ismaster) {
16541662
logmsg(LOGMSG_USER,
16551663
"%s line %d sending REP_NEWMASTER\n",
16561664
__func__, __LINE__);
1657-
(void)__rep_send_message(dbenv,
1658-
db_eid_broadcast, REP_NEWMASTER, lsnp, NULL, 0, NULL);
1665+
(void)__rep_send_message_gen(dbenv,
1666+
db_eid_broadcast, REP_NEWMASTER, lsnp, NULL, 0, gen, NULL);
16591667
rep->stat.st_elections_won++;
16601668
return (DB_REP_NEWMASTER);
16611669
}
@@ -1824,6 +1832,41 @@ err: if ((t_ret = __log_c_close(logc)) != 0 && ret == 0)
18241832
return (ret);
18251833
}
18261834

1835+
static int
1836+
__rep_newmaster(dbenv)
1837+
DB_ENV *dbenv;
1838+
{
1839+
REP *rep;
1840+
DB_LSN lsn;
1841+
DB_REP *db_rep;
1842+
DB_LOG *dblp;
1843+
int ismaster = 0;
1844+
u_int32_t gen;
1845+
1846+
PANIC_CHECK(dbenv);
1847+
ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, "rep_newmaster", DB_INIT_REP);
1848+
db_rep = dbenv->rep_handle;
1849+
rep = db_rep->region;
1850+
1851+
MUTEX_LOCK(dbenv, db_rep->rep_mutexp);
1852+
ismaster = F_ISSET(rep, REP_F_MASTER);
1853+
gen = rep->gen;
1854+
MUTEX_UNLOCK(dbenv, db_rep->rep_mutexp);
1855+
if (ismaster) {
1856+
dblp = (DB_LOG *)dbenv->lg_handle;
1857+
R_LOCK(dbenv, &dblp->reginfo);
1858+
lsn = ((LOG *)dblp->reginfo.primary)->lsn;
1859+
R_UNLOCK(dbenv, &dblp->reginfo);
1860+
1861+
logmsg(LOGMSG_DEBUG, "%s line %d sending REP_NEWMASTER\n",
1862+
__func__, __LINE__);
1863+
(void)__rep_send_message_gen(dbenv,
1864+
db_eid_broadcast, REP_NEWMASTER, &lsn, NULL, 0, gen, NULL);
1865+
}
1866+
1867+
return 0;
1868+
}
1869+
18271870
int
18281871
__rep_get_eid(dbenv, eid_out)
18291872
DB_ENV *dbenv;

berkdb/rep/rep_util.c

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,23 @@ static inline int is_logput(int type) {
102102
}
103103

104104
/*
105-
* __rep_send_message --
105+
* __rep_send_message_gen --
106106
* This is a wrapper for sending a message. It takes care of constructing
107107
* the REP_CONTROL structure and calling the user's specified send function.
108108
*
109-
* PUBLIC: int __rep_send_message __P((DB_ENV *, char*,
109+
* PUBLIC: int __rep_send_message_gen __P((DB_ENV *, char*,
110110
* PUBLIC: u_int32_t, DB_LSN *, const DBT *, u_int32_t,
111-
* PUBLIC: void *usr_ptr));
111+
* PUBLIC: u_int32_t, void *usr_ptr));
112112
*/
113113
int
114-
__rep_send_message(dbenv, eid, rtype, lsnp, dbtp, flags, usr_ptr)
114+
__rep_send_message_gen(dbenv, eid, rtype, lsnp, dbtp, flags, gen, usr_ptr)
115115
DB_ENV *dbenv;
116116
char *eid;
117117
u_int32_t rtype;
118118
DB_LSN *lsnp;
119119
const DBT *dbtp;
120120
u_int32_t flags;
121+
u_int32_t gen;
121122
void *usr_ptr;
122123
{
123124
DB_REP *db_rep;
@@ -158,10 +159,7 @@ __rep_send_message(dbenv, eid, rtype, lsnp, dbtp, flags, usr_ptr)
158159
cntrl.flags = flags;
159160
cntrl.rep_version = DB_REPVERSION;
160161
cntrl.log_version = DB_LOGVERSION;
161-
MUTEX_LOCK(dbenv, db_rep->rep_mutexp);
162-
cntrl.gen = rep->gen;
163-
MUTEX_UNLOCK(dbenv, db_rep->rep_mutexp);
164-
162+
cntrl.gen = gen;
165163

166164
memset(&cdbt, 0, sizeof(cdbt));
167165
cdbt.data = &cntrl;
@@ -281,6 +279,36 @@ __rep_send_message(dbenv, eid, rtype, lsnp, dbtp, flags, usr_ptr)
281279
return (ret);
282280
}
283281

282+
283+
/*
284+
* __rep_send_message --
285+
* This is a wrapper for sending a message. It takes care of constructing
286+
* the REP_CONTROL structure and calling the user's specified send function.
287+
*
288+
* PUBLIC: int __rep_send_message __P((DB_ENV *, char*,
289+
* PUBLIC: u_int32_t, DB_LSN *, const DBT *, u_int32_t,
290+
* PUBLIC: void *usr_ptr));
291+
*/
292+
int
293+
__rep_send_message(dbenv, eid, rtype, lsnp, dbtp, flags, usr_ptr)
294+
DB_ENV *dbenv;
295+
char *eid;
296+
u_int32_t rtype;
297+
DB_LSN *lsnp;
298+
const DBT *dbtp;
299+
u_int32_t flags;
300+
void *usr_ptr;
301+
{
302+
u_int32_t gen;
303+
DB_REP *db_rep = dbenv->rep_handle;
304+
REP *rep = db_rep->region;
305+
MUTEX_LOCK(dbenv, db_rep->rep_mutexp);
306+
gen = rep->gen;
307+
MUTEX_UNLOCK(dbenv, db_rep->rep_mutexp);
308+
return __rep_send_message_gen(dbenv, eid, rtype, lsnp, dbtp, flags, gen, usr_ptr);
309+
}
310+
311+
284312
/*
285313
* __rep_send_log_more --
286314
* This is a wrapper for sending a REP_LOG message.

db/db_tunables.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ extern int gbl_ufid_dbreg_test;
344344
extern int gbl_debug_add_replication_latency;
345345
extern int gbl_javasp_early_release;
346346
extern int gbl_debug_drop_nth_rep_message;
347+
extern int gbl_broadcast_newmaster;
347348
extern int gbl_fdb_emulate_old;
348349

349350
extern long long sampling_threshold;

db/db_tunables.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,9 @@ REGISTER_TUNABLE("debug_drop_nth_rep_message", "Drop the Nth replication message
14961496
"for testing purposes (Default: 0)", TUNABLE_INTEGER,
14971497
&gbl_debug_drop_nth_rep_message, EXPERIMENTAL | INTERNAL, NULL,
14981498
NULL, NULL, NULL);
1499+
REGISTER_TUNABLE("broadcast_newmaster", "Broadcast new-master periodically. "
1500+
"(Default: on)", TUNABLE_BOOLEAN, &gbl_broadcast_newmaster,
1501+
EXPERIMENTAL | INTERNAL, NULL, NULL, NULL, NULL);
14991502
REGISTER_TUNABLE(
15001503
"max_clientstats",
15011504
"Max number of client stats stored in comdb2_clientstats. (Default: 10000)",

0 commit comments

Comments
 (0)