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
967a98f5
Unverified
Commit
967a98f5
authored
Feb 21, 2019
by
Salvatore Sanfilippo
Committed by
GitHub
Feb 21, 2019
Browse files
Merge pull request #4811 from oranagra/cli-diskless-repl
Add redis-cli support for diskless replication (CAPA EOF)
parents
a8921c06
d56f4b41
Changes
1
Show whitespace changes
Inline
Side-by-side
src/redis-cli.c
View file @
967a98f5
...
@@ -6152,9 +6152,31 @@ static void latencyDistMode(void) {
...
@@ -6152,9 +6152,31 @@ static void latencyDistMode(void) {
* Slave mode
* Slave mode
*--------------------------------------------------------------------------- */
*--------------------------------------------------------------------------- */
#define RDB_EOF_MARK_SIZE 40
void
sendReplconf
(
const
char
*
arg1
,
const
char
*
arg2
)
{
printf
(
"sending REPLCONF %s %s
\n
"
,
arg1
,
arg2
);
redisReply
*
reply
=
redisCommand
(
context
,
"REPLCONF %s %s"
,
arg1
,
arg2
);
/* Handle any error conditions */
if
(
reply
==
NULL
)
{
fprintf
(
stderr
,
"
\n
I/O error
\n
"
);
exit
(
1
);
}
else
if
(
reply
->
type
==
REDIS_REPLY_ERROR
)
{
fprintf
(
stderr
,
"REPLCONF %s error: %s
\n
"
,
arg1
,
reply
->
str
);
/* non fatal, old versions may not support it */
}
freeReplyObject
(
reply
);
}
void
sendCapa
()
{
sendReplconf
(
"capa"
,
"eof"
);
}
/* Sends SYNC and reads the number of bytes in the payload. Used both by
/* Sends SYNC and reads the number of bytes in the payload. Used both by
* slaveMode() and getRDB(). */
* slaveMode() and getRDB().
unsigned
long
long
sendSync
(
int
fd
)
{
* returns 0 in case an EOF marker is used. */
unsigned
long
long
sendSync
(
int
fd
,
char
*
out_eof
)
{
/* To start we need to send the SYNC command and return the payload.
/* To start we need to send the SYNC command and return the payload.
* The hiredis client lib does not understand this part of the protocol
* The hiredis client lib does not understand this part of the protocol
* and we don't want to mess with its buffers, so everything is performed
* and we don't want to mess with its buffers, so everything is performed
...
@@ -6184,17 +6206,33 @@ unsigned long long sendSync(int fd) {
...
@@ -6184,17 +6206,33 @@ unsigned long long sendSync(int fd) {
printf
(
"SYNC with master failed: %s
\n
"
,
buf
);
printf
(
"SYNC with master failed: %s
\n
"
,
buf
);
exit
(
1
);
exit
(
1
);
}
}
if
(
strncmp
(
buf
+
1
,
"EOF:"
,
4
)
==
0
&&
strlen
(
buf
+
5
)
>=
RDB_EOF_MARK_SIZE
)
{
memcpy
(
out_eof
,
buf
+
5
,
RDB_EOF_MARK_SIZE
);
return
0
;
}
return
strtoull
(
buf
+
1
,
NULL
,
10
);
return
strtoull
(
buf
+
1
,
NULL
,
10
);
}
}
static
void
slaveMode
(
void
)
{
static
void
slaveMode
(
void
)
{
int
fd
=
context
->
fd
;
int
fd
=
context
->
fd
;
unsigned
long
long
payload
=
sendSync
(
fd
);
static
char
eofmark
[
RDB_EOF_MARK_SIZE
];
static
char
lastbytes
[
RDB_EOF_MARK_SIZE
];
static
int
usemark
=
0
;
unsigned
long
long
payload
=
sendSync
(
fd
,
eofmark
);
char
buf
[
1024
];
char
buf
[
1024
];
int
original_output
=
config
.
output
;
int
original_output
=
config
.
output
;
if
(
payload
==
0
)
{
payload
=
ULLONG_MAX
;
memset
(
lastbytes
,
0
,
RDB_EOF_MARK_SIZE
);
usemark
=
1
;
fprintf
(
stderr
,
"SYNC with master, discarding "
"bytes of bulk transfer until EOF marker...
\n
"
);
}
else
{
fprintf
(
stderr
,
"SYNC with master, discarding %llu "
fprintf
(
stderr
,
"SYNC with master, discarding %llu "
"bytes of bulk transfer...
\n
"
,
payload
);
"bytes of bulk transfer...
\n
"
,
payload
);
}
/* Discard the payload. */
/* Discard the payload. */
while
(
payload
)
{
while
(
payload
)
{
...
@@ -6206,7 +6244,28 @@ static void slaveMode(void) {
...
@@ -6206,7 +6244,28 @@ static void slaveMode(void) {
exit
(
1
);
exit
(
1
);
}
}
payload
-=
nread
;
payload
-=
nread
;
if
(
usemark
)
{
/* Update the last bytes array, and check if it matches our delimiter.*/
if
(
nread
>=
RDB_EOF_MARK_SIZE
)
{
memcpy
(
lastbytes
,
buf
+
nread
-
RDB_EOF_MARK_SIZE
,
RDB_EOF_MARK_SIZE
);
}
else
{
int
rem
=
RDB_EOF_MARK_SIZE
-
nread
;
memmove
(
lastbytes
,
lastbytes
+
nread
,
rem
);
memcpy
(
lastbytes
+
rem
,
buf
,
nread
);
}
if
(
memcmp
(
lastbytes
,
eofmark
,
RDB_EOF_MARK_SIZE
)
==
0
)
break
;
}
}
}
if
(
usemark
)
{
unsigned
long
long
offset
=
ULLONG_MAX
-
payload
;
fprintf
(
stderr
,
"SYNC done after %llu bytes. Logging commands from master.
\n
"
,
offset
);
/* put the slave online */
sleep
(
1
);
sendReplconf
(
"ACK"
,
"0"
);
}
else
fprintf
(
stderr
,
"SYNC done. Logging commands from master.
\n
"
);
fprintf
(
stderr
,
"SYNC done. Logging commands from master.
\n
"
);
/* Now we can use hiredis to read the incoming protocol. */
/* Now we can use hiredis to read the incoming protocol. */
...
@@ -6224,11 +6283,22 @@ static void slaveMode(void) {
...
@@ -6224,11 +6283,22 @@ static void slaveMode(void) {
static
void
getRDB
(
void
)
{
static
void
getRDB
(
void
)
{
int
s
=
context
->
fd
;
int
s
=
context
->
fd
;
int
fd
;
int
fd
;
unsigned
long
long
payload
=
sendSync
(
s
);
static
char
eofmark
[
RDB_EOF_MARK_SIZE
];
static
char
lastbytes
[
RDB_EOF_MARK_SIZE
];
static
int
usemark
=
0
;
unsigned
long
long
payload
=
sendSync
(
s
,
eofmark
);
char
buf
[
4096
];
char
buf
[
4096
];
if
(
payload
==
0
)
{
payload
=
ULLONG_MAX
;
memset
(
lastbytes
,
0
,
RDB_EOF_MARK_SIZE
);
usemark
=
1
;
fprintf
(
stderr
,
"SYNC sent to master, writing bytes of bulk transfer until EOF marker to '%s'
\n
"
,
config
.
rdb_filename
);
}
else
{
fprintf
(
stderr
,
"SYNC sent to master, writing %llu bytes to '%s'
\n
"
,
fprintf
(
stderr
,
"SYNC sent to master, writing %llu bytes to '%s'
\n
"
,
payload
,
config
.
rdb_filename
);
payload
,
config
.
rdb_filename
);
}
/* Write to file. */
/* Write to file. */
if
(
!
strcmp
(
config
.
rdb_filename
,
"-"
))
{
if
(
!
strcmp
(
config
.
rdb_filename
,
"-"
))
{
...
@@ -6257,11 +6327,31 @@ static void getRDB(void) {
...
@@ -6257,11 +6327,31 @@ static void getRDB(void) {
exit
(
1
);
exit
(
1
);
}
}
payload
-=
nread
;
payload
-=
nread
;
if
(
usemark
)
{
/* Update the last bytes array, and check if it matches our delimiter.*/
if
(
nread
>=
RDB_EOF_MARK_SIZE
)
{
memcpy
(
lastbytes
,
buf
+
nread
-
RDB_EOF_MARK_SIZE
,
RDB_EOF_MARK_SIZE
);
}
else
{
int
rem
=
RDB_EOF_MARK_SIZE
-
nread
;
memmove
(
lastbytes
,
lastbytes
+
nread
,
rem
);
memcpy
(
lastbytes
+
rem
,
buf
,
nread
);
}
if
(
memcmp
(
lastbytes
,
eofmark
,
RDB_EOF_MARK_SIZE
)
==
0
)
break
;
}
}
if
(
usemark
)
{
payload
=
ULLONG_MAX
-
payload
-
RDB_EOF_MARK_SIZE
;
if
(
ftruncate
(
fd
,
payload
)
==
-
1
)
fprintf
(
stderr
,
"ftruncate failed: %s.
\n
"
,
strerror
(
errno
));
fprintf
(
stderr
,
"Transfer finished with success after %llu bytes
\n
"
,
payload
);
}
else
{
fprintf
(
stderr
,
"Transfer finished with success.
\n
"
);
}
}
close
(
s
);
/* Close the file descriptor ASAP as fsync() may take time. */
close
(
s
);
/* Close the file descriptor ASAP as fsync() may take time. */
fsync
(
fd
);
fsync
(
fd
);
close
(
fd
);
close
(
fd
);
fprintf
(
stderr
,
"Transfer finished with success.
\n
"
);
exit
(
0
);
exit
(
0
);
}
}
...
@@ -7314,12 +7404,14 @@ int main(int argc, char **argv) {
...
@@ -7314,12 +7404,14 @@ int main(int argc, char **argv) {
/* Slave mode */
/* Slave mode */
if
(
config
.
slave_mode
)
{
if
(
config
.
slave_mode
)
{
if
(
cliConnect
(
0
)
==
REDIS_ERR
)
exit
(
1
);
if
(
cliConnect
(
0
)
==
REDIS_ERR
)
exit
(
1
);
sendCapa
();
slaveMode
();
slaveMode
();
}
}
/* Get RDB mode. */
/* Get RDB mode. */
if
(
config
.
getrdb_mode
)
{
if
(
config
.
getrdb_mode
)
{
if
(
cliConnect
(
0
)
==
REDIS_ERR
)
exit
(
1
);
if
(
cliConnect
(
0
)
==
REDIS_ERR
)
exit
(
1
);
sendCapa
();
getRDB
();
getRDB
();
}
}
...
...
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