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
7ab62d4b
Commit
7ab62d4b
authored
Aug 05, 2019
by
antirez
Browse files
Replication: clarify why repl_put_online_on_ack exists at all.
parent
495dd0da
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/replication.c
View file @
7ab62d4b
...
...
@@ -823,7 +823,9 @@ void replconfCommand(client *c) {
c
->
repl_ack_time
=
server
.
unixtime
;
/* If this was a diskless replication, we need to really put
* the slave online when the first ACK is received (which
* confirms slave is online and ready to get more data). */
* confirms slave is online and ready to get more data). This
* allows for simpler and less CPU intensive EOF detection
* when streaming RDB files. */
if
(
c
->
repl_put_online_on_ack
&&
c
->
replstate
==
SLAVE_STATE_ONLINE
)
putSlaveOnline
(
c
);
/* Note: this command does not reply anything! */
...
...
@@ -842,18 +844,20 @@ void replconfCommand(client *c) {
addReply
(
c
,
shared
.
ok
);
}
/* This function puts a
slave
in the online state, and should be called just
* after a
slave
received the RDB file for the initial synchronization, and
/* This function puts a
replica
in the online state, and should be called just
* after a
replica
received the RDB file for the initial synchronization, and
* we are finally ready to send the incremental stream of commands.
*
* It does a few things:
*
* 1) Put the slave in ONLINE state (useless when the function is called
* because state is already ONLINE but repl_put_online_on_ack is true).
* 1) Put the slave in ONLINE state. Note that the function may also be called
* for a replicas that are already in ONLINE state, but having the flag
* repl_put_online_on_ack set to true: we still have to install the write
* handler in that case. This function will take care of that.
* 2) Make sure the writable event is re-installed, since calling the SYNC
* command disables it, so that we can accumulate output buffer without
* sending it to the
slave
.
* 3) Update the count of good
slaves
. */
* sending it to the
replica
.
* 3) Update the count of
"
good
replicas"
. */
void
putSlaveOnline
(
client
*
slave
)
{
slave
->
replstate
=
SLAVE_STATE_ONLINE
;
slave
->
repl_put_online_on_ack
=
0
;
...
...
@@ -965,11 +969,31 @@ void updateSlavesWaitingBgsave(int bgsaveerr, int type) {
serverLog
(
LL_NOTICE
,
"Streamed RDB transfer with replica %s succeeded (socket). Waiting for REPLCONF ACK from slave to enable streaming"
,
replicationGetSlaveName
(
slave
));
/* Note: we wait for a REPLCONF ACK message from
slave
in
/* Note: we wait for a REPLCONF ACK message from
the replica
in
* order to really put it online (install the write handler
* so that the accumulated data can be transferred). However
* we change the replication state ASAP, since our slave
* is technically online now. */
* is technically online now.
*
* So things work like that:
*
* 1. We end trasnferring the RDB file via socket.
* 2. The replica is put ONLINE but the write handler
* is not installed.
* 3. The replica however goes really online, and pings us
* back via REPLCONF ACK commands.
* 4. Now we finally install the write handler, and send
* the buffers accumulated so far to the replica.
*
* But why we do that? Because the replica, when we stream
* the RDB directly via the socket, must detect the RDB
* EOF (end of file), that is a special random string at the
* end of the RDB (for streamed RDBs we don't know the length
* in advance). Detecting such final EOF string is much
* simpler and less CPU intensive if no more data is sent
* after such final EOF. So we don't want to glue the end of
* the RDB trasfer with the start of the other replication
* data. */
slave
->
replstate
=
SLAVE_STATE_ONLINE
;
slave
->
repl_put_online_on_ack
=
1
;
slave
->
repl_ack_time
=
server
.
unixtime
;
/* Timeout otherwise. */
...
...
src/server.h
View file @
7ab62d4b
...
...
@@ -748,7 +748,7 @@ typedef struct client {
int
flags
;
/* Client flags: CLIENT_* macros. */
int
authenticated
;
/* When requirepass is non-NULL. */
int
replstate
;
/* Replication state if this is a slave. */
int
repl_put_online_on_ack
;
/* Install slave write handler on ACK. */
int
repl_put_online_on_ack
;
/* Install slave write handler on
first
ACK. */
int
repldbfd
;
/* Replication DB file descriptor. */
off_t
repldboff
;
/* Replication DB file offset. */
off_t
repldbsize
;
/* Replication DB file size. */
...
...
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