Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
bac29c8b
You need to sign in or sign up before continuing.
Commit
bac29c8b
authored
Apr 19, 2013
by
antirez
Browse files
Sentinel: turn old master into a slave when it comes back.
parent
4848af1b
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/sentinel.c
View file @
bac29c8b
...
@@ -74,6 +74,8 @@ typedef struct sentinelAddr {
...
@@ -74,6 +74,8 @@ typedef struct sentinelAddr {
#define SRI_RECONF_DONE (1<<13)
/* Slave synchronized with new master. */
#define SRI_RECONF_DONE (1<<13)
/* Slave synchronized with new master. */
#define SRI_FORCE_FAILOVER (1<<14)
/* Force failover with master up. */
#define SRI_FORCE_FAILOVER (1<<14)
/* Force failover with master up. */
#define SRI_SCRIPT_KILL_SENT (1<<15)
/* SCRIPT KILL already sent on -BUSY */
#define SRI_SCRIPT_KILL_SENT (1<<15)
/* SCRIPT KILL already sent on -BUSY */
#define SRI_DEMOTE (1<<16)
/* If the instance claims to be a master, demote
it into a slave sending SLAVEOF. */
#define SENTINEL_INFO_PERIOD 10000
#define SENTINEL_INFO_PERIOD 10000
#define SENTINEL_PING_PERIOD 1000
#define SENTINEL_PING_PERIOD 1000
...
@@ -1401,7 +1403,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
...
@@ -1401,7 +1403,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
* otherwise add it. */
* otherwise add it. */
if
(
sentinelRedisInstanceLookupSlave
(
ri
,
ip
,
atoi
(
port
))
==
NULL
)
{
if
(
sentinelRedisInstanceLookupSlave
(
ri
,
ip
,
atoi
(
port
))
==
NULL
)
{
if
((
slave
=
createSentinelRedisInstance
(
NULL
,
SRI_SLAVE
,
ip
,
if
((
slave
=
createSentinelRedisInstance
(
NULL
,
SRI_SLAVE
,
ip
,
atoi
(
port
),
ri
->
quorum
,
ri
))
!=
NULL
)
atoi
(
port
),
ri
->
quorum
,
ri
))
!=
NULL
)
{
{
sentinelEvent
(
REDIS_NOTICE
,
"+slave"
,
slave
,
"%@"
);
sentinelEvent
(
REDIS_NOTICE
,
"+slave"
,
slave
,
"%@"
);
}
}
...
@@ -1467,7 +1469,19 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
...
@@ -1467,7 +1469,19 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
/* Act if a slave turned into a master. */
/* Act if a slave turned into a master. */
if
((
ri
->
flags
&
SRI_SLAVE
)
&&
role
==
SRI_MASTER
)
{
if
((
ri
->
flags
&
SRI_SLAVE
)
&&
role
==
SRI_MASTER
)
{
if
(
!
(
ri
->
master
->
flags
&
SRI_FAILOVER_IN_PROGRESS
)
&&
if
(
ri
->
flags
&
SRI_DEMOTE
)
{
int
retval
;
/* Old master returned back? Turn it into a slave ASAP.
* We'll clear this flag only when we have the acknowledge
* that it's a slave again. */
retval
=
redisAsyncCommand
(
ri
->
cc
,
sentinelDiscardReplyCallback
,
NULL
,
"SLAVEOF %s %d"
,
ri
->
master
->
addr
->
ip
,
ri
->
master
->
addr
->
port
);
if
(
retval
==
REDIS_OK
)
sentinelEvent
(
REDIS_NOTICE
,
"+demote-old-slave"
,
ri
,
"%@"
);
}
else
if
(
!
(
ri
->
master
->
flags
&
SRI_FAILOVER_IN_PROGRESS
)
&&
(
runid_changed
||
first_runid
))
(
runid_changed
||
first_runid
))
{
{
/* If a slave turned into master but:
/* If a slave turned into master but:
...
@@ -1564,6 +1578,12 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
...
@@ -1564,6 +1578,12 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
ri
->
failover_state_change_time
=
mstime
();
ri
->
failover_state_change_time
=
mstime
();
}
}
}
}
/* Detect if the old master was demoted as slave. */
if
(
role
==
SRI_SLAVE
&&
ri
->
flags
&
SRI_DEMOTE
)
{
sentinelEvent
(
REDIS_NOTICE
,
"+slave"
,
ri
,
"%@"
);
ri
->
flags
&=
~
SRI_DEMOTE
;
}
}
}
void
sentinelInfoReplyCallback
(
redisAsyncContext
*
c
,
void
*
reply
,
void
*
privdata
)
{
void
sentinelInfoReplyCallback
(
redisAsyncContext
*
c
,
void
*
reply
,
void
*
privdata
)
{
...
@@ -1835,6 +1855,7 @@ void addReplySentinelRedisInstance(redisClient *c, sentinelRedisInstance *ri) {
...
@@ -1835,6 +1855,7 @@ void addReplySentinelRedisInstance(redisClient *c, sentinelRedisInstance *ri) {
if
(
ri
->
flags
&
SRI_RECONF_SENT
)
flags
=
sdscat
(
flags
,
"reconf_sent,"
);
if
(
ri
->
flags
&
SRI_RECONF_SENT
)
flags
=
sdscat
(
flags
,
"reconf_sent,"
);
if
(
ri
->
flags
&
SRI_RECONF_INPROG
)
flags
=
sdscat
(
flags
,
"reconf_inprog,"
);
if
(
ri
->
flags
&
SRI_RECONF_INPROG
)
flags
=
sdscat
(
flags
,
"reconf_inprog,"
);
if
(
ri
->
flags
&
SRI_RECONF_DONE
)
flags
=
sdscat
(
flags
,
"reconf_done,"
);
if
(
ri
->
flags
&
SRI_RECONF_DONE
)
flags
=
sdscat
(
flags
,
"reconf_done,"
);
if
(
ri
->
flags
&
SRI_DEMOTE
)
flags
=
sdscat
(
flags
,
"demote,"
);
if
(
sdslen
(
flags
)
!=
0
)
flags
=
sdsrange
(
flags
,
0
,
-
2
);
/* remove last "," */
if
(
sdslen
(
flags
)
!=
0
)
flags
=
sdsrange
(
flags
,
0
,
-
2
);
/* remove last "," */
addReplyBulkCString
(
c
,
flags
);
addReplyBulkCString
(
c
,
flags
);
...
@@ -2592,6 +2613,7 @@ sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) {
...
@@ -2592,6 +2613,7 @@ sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) {
mstime_t
info_validity_time
=
mstime
()
-
SENTINEL_INFO_VALIDITY_TIME
;
mstime_t
info_validity_time
=
mstime
()
-
SENTINEL_INFO_VALIDITY_TIME
;
if
(
slave
->
flags
&
(
SRI_S_DOWN
|
SRI_O_DOWN
|
SRI_DISCONNECTED
))
continue
;
if
(
slave
->
flags
&
(
SRI_S_DOWN
|
SRI_O_DOWN
|
SRI_DISCONNECTED
))
continue
;
if
(
slave
->
flags
&
SRI_DEMOTE
)
continue
;
/* Old master not yet ready. */
if
(
slave
->
last_avail_time
<
info_validity_time
)
continue
;
if
(
slave
->
last_avail_time
<
info_validity_time
)
continue
;
if
(
slave
->
slave_priority
==
0
)
continue
;
if
(
slave
->
slave_priority
==
0
)
continue
;
...
@@ -2837,12 +2859,28 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) {
...
@@ -2837,12 +2859,28 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) {
void
sentinelFailoverSwitchToPromotedSlave
(
sentinelRedisInstance
*
master
)
{
void
sentinelFailoverSwitchToPromotedSlave
(
sentinelRedisInstance
*
master
)
{
sentinelRedisInstance
*
ref
=
master
->
promoted_slave
?
sentinelRedisInstance
*
ref
=
master
->
promoted_slave
?
master
->
promoted_slave
:
master
;
master
->
promoted_slave
:
master
;
sds
old_master_ip
;
int
old_master_port
;
sentinelEvent
(
REDIS_WARNING
,
"+switch-master"
,
master
,
"%s %s %d %s %d"
,
sentinelEvent
(
REDIS_WARNING
,
"+switch-master"
,
master
,
"%s %s %d %s %d"
,
master
->
name
,
master
->
addr
->
ip
,
master
->
addr
->
port
,
master
->
name
,
master
->
addr
->
ip
,
master
->
addr
->
port
,
ref
->
addr
->
ip
,
ref
->
addr
->
port
);
ref
->
addr
->
ip
,
ref
->
addr
->
port
);
old_master_ip
=
sdsdup
(
master
->
addr
->
ip
);
old_master_port
=
master
->
addr
->
port
;
sentinelResetMasterAndChangeAddress
(
master
,
ref
->
addr
->
ip
,
ref
->
addr
->
port
);
sentinelResetMasterAndChangeAddress
(
master
,
ref
->
addr
->
ip
,
ref
->
addr
->
port
);
/* If this is a real switch, that is, we have master->promoted_slave not
* NULL, then we want to add the old master as a slave of the new master,
* but flagging it with SRI_DEMOTE so that we know we'll need to send
* SLAVEOF once the old master is reachable again. */
if
(
master
!=
ref
)
{
/* Add the new slave, but don't generate a Sentinel event as it will
* happen later when finally the instance will claim to be a slave
* in the INFO output. */
createSentinelRedisInstance
(
NULL
,
SRI_SLAVE
|
SRI_DEMOTE
,
old_master_ip
,
old_master_port
,
master
->
quorum
,
master
);
}
sdsfree
(
old_master_ip
);
}
}
void
sentinelFailoverStateMachine
(
sentinelRedisInstance
*
ri
)
{
void
sentinelFailoverStateMachine
(
sentinelRedisInstance
*
ri
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment