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
c2fa4b8a
Unverified
Commit
c2fa4b8a
authored
Jan 11, 2018
by
Salvatore Sanfilippo
Committed by
GitHub
Jan 11, 2018
Browse files
Merge pull request #4568 from oranagra/restore_size_limit
fix RESTORE command size limits
parents
e954742f
b509a14c
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/config.c
View file @
c2fa4b8a
...
...
@@ -328,6 +328,10 @@ void loadServerConfigFromString(char *config) {
err
=
"maxmemory-samples must be 1 or greater"
;
goto
loaderr
;
}
}
else
if
((
!
strcasecmp
(
argv
[
0
],
"max-bulk-len"
))
&&
argc
==
2
)
{
server
.
max_bulk_len
=
memtoll
(
argv
[
1
],
NULL
);
}
else
if
((
!
strcasecmp
(
argv
[
0
],
"max-querybuf-len"
))
&&
argc
==
2
)
{
server
.
client_max_querybuf_len
=
memtoll
(
argv
[
1
],
NULL
);
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"lfu-log-factor"
)
&&
argc
==
2
)
{
server
.
lfu_log_factor
=
atoi
(
argv
[
1
]);
if
(
server
.
lfu_log_factor
<
0
)
{
...
...
@@ -1132,6 +1136,10 @@ void configSetCommand(client *c) {
}
freeMemoryIfNeeded
();
}
}
config_set_memory_field
(
"max-bulk-len"
,
server
.
max_bulk_len
)
{
}
config_set_memory_field
(
"max-querybuf-len"
,
server
.
client_max_querybuf_len
)
{
}
config_set_memory_field
(
"repl-backlog-size"
,
ll
)
{
resizeReplicationBacklog
(
ll
);
}
config_set_memory_field
(
"auto-aof-rewrite-min-size"
,
ll
)
{
...
...
@@ -1220,6 +1228,8 @@ void configGetCommand(client *c) {
/* Numerical values */
config_get_numerical_field
(
"maxmemory"
,
server
.
maxmemory
);
config_get_numerical_field
(
"max-bulk-len"
,
server
.
max_bulk_len
);
config_get_numerical_field
(
"max-querybuf-len"
,
server
.
client_max_querybuf_len
);
config_get_numerical_field
(
"maxmemory-samples"
,
server
.
maxmemory_samples
);
config_get_numerical_field
(
"lfu-log-factor"
,
server
.
lfu_log_factor
);
config_get_numerical_field
(
"lfu-decay-time"
,
server
.
lfu_decay_time
);
...
...
@@ -1992,6 +2002,8 @@ int rewriteConfig(char *path) {
rewriteConfigStringOption
(
state
,
"requirepass"
,
server
.
requirepass
,
NULL
);
rewriteConfigNumericalOption
(
state
,
"maxclients"
,
server
.
maxclients
,
CONFIG_DEFAULT_MAX_CLIENTS
);
rewriteConfigBytesOption
(
state
,
"maxmemory"
,
server
.
maxmemory
,
CONFIG_DEFAULT_MAXMEMORY
);
rewriteConfigBytesOption
(
state
,
"max-bulk-len"
,
server
.
max_bulk_len
,
CONFIG_DEFAULT_MAX_BULK_LEN
);
rewriteConfigBytesOption
(
state
,
"max-querybuf-len"
,
server
.
client_max_querybuf_len
,
PROTO_MAX_QUERYBUF_LEN
);
rewriteConfigEnumOption
(
state
,
"maxmemory-policy"
,
server
.
maxmemory_policy
,
maxmemory_policy_enum
,
CONFIG_DEFAULT_MAXMEMORY_POLICY
);
rewriteConfigNumericalOption
(
state
,
"maxmemory-samples"
,
server
.
maxmemory_samples
,
CONFIG_DEFAULT_MAXMEMORY_SAMPLES
);
rewriteConfigNumericalOption
(
state
,
"lfu-log-factor"
,
server
.
lfu_log_factor
,
CONFIG_DEFAULT_LFU_LOG_FACTOR
);
...
...
src/module.c
View file @
c2fa4b8a
...
...
@@ -3024,7 +3024,7 @@ int64_t RM_LoadSigned(RedisModuleIO *io) {
void
RM_SaveString
(
RedisModuleIO
*
io
,
RedisModuleString
*
s
)
{
if
(
io
->
error
)
return
;
/* Save opcode. */
in
t
retval
=
rdbSaveLen
(
io
->
rio
,
RDB_MODULE_OPCODE_STRING
);
ssize_
t
retval
=
rdbSaveLen
(
io
->
rio
,
RDB_MODULE_OPCODE_STRING
);
if
(
retval
==
-
1
)
goto
saveerr
;
io
->
bytes
+=
retval
;
/* Save value. */
...
...
@@ -3042,7 +3042,7 @@ saveerr:
void
RM_SaveStringBuffer
(
RedisModuleIO
*
io
,
const
char
*
str
,
size_t
len
)
{
if
(
io
->
error
)
return
;
/* Save opcode. */
in
t
retval
=
rdbSaveLen
(
io
->
rio
,
RDB_MODULE_OPCODE_STRING
);
ssize_
t
retval
=
rdbSaveLen
(
io
->
rio
,
RDB_MODULE_OPCODE_STRING
);
if
(
retval
==
-
1
)
goto
saveerr
;
io
->
bytes
+=
retval
;
/* Save value. */
...
...
src/networking.c
View file @
c2fa4b8a
...
...
@@ -33,7 +33,7 @@
#include <math.h>
#include <ctype.h>
static
void
setProtocolError
(
const
char
*
errstr
,
client
*
c
,
int
pos
);
static
void
setProtocolError
(
const
char
*
errstr
,
client
*
c
,
long
pos
);
/* Return the size consumed from the allocator, for the specified SDS string,
* including internal fragmentation. This function is used in order to compute
...
...
@@ -1140,7 +1140,7 @@ int processInlineBuffer(client *c) {
/* Helper function. Trims query buffer to make the function that processes
* multi bulk requests idempotent. */
#define PROTO_DUMP_LEN 128
static
void
setProtocolError
(
const
char
*
errstr
,
client
*
c
,
int
pos
)
{
static
void
setProtocolError
(
const
char
*
errstr
,
client
*
c
,
long
pos
)
{
if
(
server
.
verbosity
<=
LL_VERBOSE
)
{
sds
client
=
catClientInfoString
(
sdsempty
(),
c
);
...
...
@@ -1181,7 +1181,8 @@ static void setProtocolError(const char *errstr, client *c, int pos) {
* to be '*'. Otherwise for inline commands processInlineBuffer() is called. */
int
processMultibulkBuffer
(
client
*
c
)
{
char
*
newline
=
NULL
;
int
pos
=
0
,
ok
;
long
pos
=
0
;
int
ok
;
long
long
ll
;
if
(
c
->
multibulklen
==
0
)
{
...
...
@@ -1253,7 +1254,7 @@ int processMultibulkBuffer(client *c) {
}
ok
=
string2ll
(
c
->
querybuf
+
pos
+
1
,
newline
-
(
c
->
querybuf
+
pos
+
1
),
&
ll
);
if
(
!
ok
||
ll
<
0
||
ll
>
512
*
1024
*
1024
)
{
if
(
!
ok
||
ll
<
0
||
ll
>
server
.
max_bulk_len
)
{
addReplyError
(
c
,
"Protocol error: invalid bulk length"
);
setProtocolError
(
"invalid bulk length"
,
c
,
pos
);
return
C_ERR
;
...
...
@@ -1279,7 +1280,7 @@ int processMultibulkBuffer(client *c) {
}
/* Read bulk argument */
if
(
sdslen
(
c
->
querybuf
)
-
pos
<
(
unsigned
)(
c
->
bulklen
+
2
))
{
if
(
sdslen
(
c
->
querybuf
)
-
pos
<
(
size_t
)(
c
->
bulklen
+
2
))
{
/* Not enough data (+2 == trailing \r\n) */
break
;
}
else
{
...
...
@@ -1288,7 +1289,7 @@ int processMultibulkBuffer(client *c) {
* just use the current sds string. */
if
(
pos
==
0
&&
c
->
bulklen
>=
PROTO_MBULK_BIG_ARG
&&
(
signed
)
sdslen
(
c
->
querybuf
)
==
c
->
bulklen
+
2
)
sdslen
(
c
->
querybuf
)
==
(
size_t
)(
c
->
bulklen
+
2
)
)
{
c
->
argv
[
c
->
argc
++
]
=
createObject
(
OBJ_STRING
,
c
->
querybuf
);
sdsIncrLen
(
c
->
querybuf
,
-
2
);
/* remove CRLF */
...
...
@@ -1399,7 +1400,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
if
(
c
->
reqtype
==
PROTO_REQ_MULTIBULK
&&
c
->
multibulklen
&&
c
->
bulklen
!=
-
1
&&
c
->
bulklen
>=
PROTO_MBULK_BIG_ARG
)
{
in
t
remaining
=
(
unsigned
)(
c
->
bulklen
+
2
)
-
sdslen
(
c
->
querybuf
);
ssize_
t
remaining
=
(
size_t
)(
c
->
bulklen
+
2
)
-
sdslen
(
c
->
querybuf
);
if
(
remaining
<
readlen
)
readlen
=
remaining
;
}
...
...
src/rdb.c
View file @
c2fa4b8a
...
...
@@ -425,7 +425,7 @@ ssize_t rdbSaveLongLongAsStringObject(rio *rdb, long long value) {
}
/* Like rdbSaveRawString() gets a Redis object instead. */
in
t
rdbSaveStringObject
(
rio
*
rdb
,
robj
*
obj
)
{
ssize_
t
rdbSaveStringObject
(
rio
*
rdb
,
robj
*
obj
)
{
/* Avoid to decode the object, then encode it again, if the
* object is already integer encoded. */
if
(
obj
->
encoding
==
OBJ_ENCODING_INT
)
{
...
...
@@ -861,21 +861,25 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val,
}
/* Save an AUX field. */
int
rdbSaveAuxField
(
rio
*
rdb
,
void
*
key
,
size_t
keylen
,
void
*
val
,
size_t
vallen
)
{
if
(
rdbSaveType
(
rdb
,
RDB_OPCODE_AUX
)
==
-
1
)
return
-
1
;
if
(
rdbSaveRawString
(
rdb
,
key
,
keylen
)
==
-
1
)
return
-
1
;
if
(
rdbSaveRawString
(
rdb
,
val
,
vallen
)
==
-
1
)
return
-
1
;
return
1
;
ssize_t
rdbSaveAuxField
(
rio
*
rdb
,
void
*
key
,
size_t
keylen
,
void
*
val
,
size_t
vallen
)
{
ssize_t
ret
,
len
=
0
;
if
((
ret
=
rdbSaveType
(
rdb
,
RDB_OPCODE_AUX
))
==
-
1
)
return
-
1
;
len
+=
ret
;
if
((
ret
=
rdbSaveRawString
(
rdb
,
key
,
keylen
)
==
-
1
))
return
-
1
;
len
+=
ret
;
if
((
ret
=
rdbSaveRawString
(
rdb
,
val
,
vallen
)
==
-
1
))
return
-
1
;
len
+=
ret
;
return
len
;
}
/* Wrapper for rdbSaveAuxField() used when key/val length can be obtained
* with strlen(). */
in
t
rdbSaveAuxFieldStrStr
(
rio
*
rdb
,
char
*
key
,
char
*
val
)
{
ssize_
t
rdbSaveAuxFieldStrStr
(
rio
*
rdb
,
char
*
key
,
char
*
val
)
{
return
rdbSaveAuxField
(
rdb
,
key
,
strlen
(
key
),
val
,
strlen
(
val
));
}
/* Wrapper for strlen(key) + integer type (up to long long range). */
in
t
rdbSaveAuxFieldStrInt
(
rio
*
rdb
,
char
*
key
,
long
long
val
)
{
ssize_
t
rdbSaveAuxFieldStrInt
(
rio
*
rdb
,
char
*
key
,
long
long
val
)
{
char
buf
[
LONG_STR_SIZE
];
int
vlen
=
ll2string
(
buf
,
sizeof
(
buf
),
val
);
return
rdbSaveAuxField
(
rdb
,
key
,
strlen
(
key
),
buf
,
vlen
);
...
...
src/rdb.h
View file @
c2fa4b8a
...
...
@@ -141,7 +141,7 @@ robj *rdbLoadObject(int type, rio *rdb);
void
backgroundSaveDoneHandler
(
int
exitcode
,
int
bysignal
);
int
rdbSaveKeyValuePair
(
rio
*
rdb
,
robj
*
key
,
robj
*
val
,
long
long
expiretime
,
long
long
now
);
robj
*
rdbLoadStringObject
(
rio
*
rdb
);
in
t
rdbSaveStringObject
(
rio
*
rdb
,
robj
*
obj
);
ssize_
t
rdbSaveStringObject
(
rio
*
rdb
,
robj
*
obj
);
ssize_t
rdbSaveRawString
(
rio
*
rdb
,
unsigned
char
*
s
,
size_t
len
);
void
*
rdbGenericLoadStringObject
(
rio
*
rdb
,
int
flags
,
size_t
*
lenptr
);
int
rdbSaveBinaryDoubleValue
(
rio
*
rdb
,
double
val
);
...
...
src/rio.c
View file @
c2fa4b8a
...
...
@@ -310,7 +310,7 @@ void rioSetAutoSync(rio *r, off_t bytes) {
* generating the Redis protocol for the Append Only File. */
/* Write multi bulk count in the format: "*<count>\r\n". */
size_t
rioWriteBulkCount
(
rio
*
r
,
char
prefix
,
int
count
)
{
size_t
rioWriteBulkCount
(
rio
*
r
,
char
prefix
,
long
count
)
{
char
cbuf
[
128
];
int
clen
;
...
...
src/rio.h
View file @
c2fa4b8a
...
...
@@ -130,7 +130,7 @@ void rioInitWithFdset(rio *r, int *fds, int numfds);
void
rioFreeFdset
(
rio
*
r
);
size_t
rioWriteBulkCount
(
rio
*
r
,
char
prefix
,
int
count
);
size_t
rioWriteBulkCount
(
rio
*
r
,
char
prefix
,
long
count
);
size_t
rioWriteBulkString
(
rio
*
r
,
const
char
*
buf
,
size_t
len
);
size_t
rioWriteBulkLongLong
(
rio
*
r
,
long
long
l
);
size_t
rioWriteBulkDouble
(
rio
*
r
,
double
d
);
...
...
src/sds.c
View file @
c2fa4b8a
...
...
@@ -175,7 +175,7 @@ void sdsfree(sds s) {
* the output will be "6" as the string was modified but the logical length
* remains 6 bytes. */
void
sdsupdatelen
(
sds
s
)
{
in
t
reallen
=
strlen
(
s
);
size_
t
reallen
=
strlen
(
s
);
sdssetlen
(
s
,
reallen
);
}
...
...
@@ -319,7 +319,7 @@ void *sdsAllocPtr(sds s) {
* ... check for nread <= 0 and handle it ...
* sdsIncrLen(s, nread);
*/
void
sdsIncrLen
(
sds
s
,
in
t
incr
)
{
void
sdsIncrLen
(
sds
s
,
ssize_
t
incr
)
{
unsigned
char
flags
=
s
[
-
1
];
size_t
len
;
switch
(
flags
&
SDS_TYPE_MASK
)
{
...
...
@@ -589,7 +589,7 @@ sds sdscatprintf(sds s, const char *fmt, ...) {
sds
sdscatfmt
(
sds
s
,
char
const
*
fmt
,
...)
{
size_t
initlen
=
sdslen
(
s
);
const
char
*
f
=
fmt
;
int
i
;
long
i
;
va_list
ap
;
va_start
(
ap
,
fmt
);
...
...
@@ -721,7 +721,7 @@ sds sdstrim(sds s, const char *cset) {
* s = sdsnew("Hello World");
* sdsrange(s,1,-1); => "ello World"
*/
void
sdsrange
(
sds
s
,
in
t
start
,
in
t
end
)
{
void
sdsrange
(
sds
s
,
ssize_
t
start
,
ssize_
t
end
)
{
size_t
newlen
,
len
=
sdslen
(
s
);
if
(
len
==
0
)
return
;
...
...
@@ -735,9 +735,9 @@ void sdsrange(sds s, int start, int end) {
}
newlen
=
(
start
>
end
)
?
0
:
(
end
-
start
)
+
1
;
if
(
newlen
!=
0
)
{
if
(
start
>=
(
s
igned
)
len
)
{
if
(
start
>=
(
s
size_t
)
len
)
{
newlen
=
0
;
}
else
if
(
end
>=
(
s
igned
)
len
)
{
}
else
if
(
end
>=
(
s
size_t
)
len
)
{
end
=
len
-
1
;
newlen
=
(
start
>
end
)
?
0
:
(
end
-
start
)
+
1
;
}
...
...
@@ -751,14 +751,14 @@ void sdsrange(sds s, int start, int end) {
/* Apply tolower() to every character of the sds string 's'. */
void
sdstolower
(
sds
s
)
{
in
t
len
=
sdslen
(
s
),
j
;
size_
t
len
=
sdslen
(
s
),
j
;
for
(
j
=
0
;
j
<
len
;
j
++
)
s
[
j
]
=
tolower
(
s
[
j
]);
}
/* Apply toupper() to every character of the sds string 's'. */
void
sdstoupper
(
sds
s
)
{
in
t
len
=
sdslen
(
s
),
j
;
size_
t
len
=
sdslen
(
s
),
j
;
for
(
j
=
0
;
j
<
len
;
j
++
)
s
[
j
]
=
toupper
(
s
[
j
]);
}
...
...
@@ -782,7 +782,7 @@ int sdscmp(const sds s1, const sds s2) {
l2
=
sdslen
(
s2
);
minlen
=
(
l1
<
l2
)
?
l1
:
l2
;
cmp
=
memcmp
(
s1
,
s2
,
minlen
);
if
(
cmp
==
0
)
return
l1
-
l2
;
if
(
cmp
==
0
)
return
l1
>
l2
?
1
:
(
l1
<
l2
?
-
1
:
0
)
;
return
cmp
;
}
...
...
@@ -802,8 +802,9 @@ int sdscmp(const sds s1, const sds s2) {
* requires length arguments. sdssplit() is just the
* same function but for zero-terminated strings.
*/
sds
*
sdssplitlen
(
const
char
*
s
,
int
len
,
const
char
*
sep
,
int
seplen
,
int
*
count
)
{
int
elements
=
0
,
slots
=
5
,
start
=
0
,
j
;
sds
*
sdssplitlen
(
const
char
*
s
,
ssize_t
len
,
const
char
*
sep
,
int
seplen
,
int
*
count
)
{
int
elements
=
0
,
slots
=
5
;
long
start
=
0
,
j
;
sds
*
tokens
;
if
(
seplen
<
1
||
len
<
0
)
return
NULL
;
...
...
src/sds.h
View file @
c2fa4b8a
...
...
@@ -236,11 +236,11 @@ sds sdscatprintf(sds s, const char *fmt, ...);
sds
sdscatfmt
(
sds
s
,
char
const
*
fmt
,
...);
sds
sdstrim
(
sds
s
,
const
char
*
cset
);
void
sdsrange
(
sds
s
,
in
t
start
,
in
t
end
);
void
sdsrange
(
sds
s
,
ssize_
t
start
,
ssize_
t
end
);
void
sdsupdatelen
(
sds
s
);
void
sdsclear
(
sds
s
);
int
sdscmp
(
const
sds
s1
,
const
sds
s2
);
sds
*
sdssplitlen
(
const
char
*
s
,
in
t
len
,
const
char
*
sep
,
int
seplen
,
int
*
count
);
sds
*
sdssplitlen
(
const
char
*
s
,
ssize_
t
len
,
const
char
*
sep
,
int
seplen
,
int
*
count
);
void
sdsfreesplitres
(
sds
*
tokens
,
int
count
);
void
sdstolower
(
sds
s
);
void
sdstoupper
(
sds
s
);
...
...
@@ -253,7 +253,7 @@ sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
/* Low level functions exposed to the user API */
sds
sdsMakeRoomFor
(
sds
s
,
size_t
addlen
);
void
sdsIncrLen
(
sds
s
,
in
t
incr
);
void
sdsIncrLen
(
sds
s
,
ssize_
t
incr
);
sds
sdsRemoveFreeSpace
(
sds
s
);
size_t
sdsAllocSize
(
sds
s
);
void
*
sdsAllocPtr
(
sds
s
);
...
...
src/server.c
View file @
c2fa4b8a
...
...
@@ -1388,6 +1388,7 @@ void initServerConfig(void) {
server
.
active_defrag_threshold_upper
=
CONFIG_DEFAULT_DEFRAG_THRESHOLD_UPPER
;
server
.
active_defrag_cycle_min
=
CONFIG_DEFAULT_DEFRAG_CYCLE_MIN
;
server
.
active_defrag_cycle_max
=
CONFIG_DEFAULT_DEFRAG_CYCLE_MAX
;
server
.
max_bulk_len
=
CONFIG_DEFAULT_MAX_BULK_LEN
;
server
.
client_max_querybuf_len
=
PROTO_MAX_QUERYBUF_LEN
;
server
.
saveparams
=
NULL
;
server
.
loading
=
0
;
...
...
src/server.h
View file @
c2fa4b8a
...
...
@@ -161,6 +161,7 @@ typedef long long mstime_t; /* millisecond time type. */
#define CONFIG_DEFAULT_DEFRAG_IGNORE_BYTES (100<<20)
/* don't defrag if frag overhead is below 100mb */
#define CONFIG_DEFAULT_DEFRAG_CYCLE_MIN 25
/* 25% CPU min (at lower threshold) */
#define CONFIG_DEFAULT_DEFRAG_CYCLE_MAX 75
/* 75% CPU max (at upper threshold) */
#define CONFIG_DEFAULT_MAX_BULK_LEN (512ll*1024*1024)
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 20
/* Loopkups per loop. */
#define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000
/* Microseconds */
...
...
@@ -1132,6 +1133,7 @@ struct redisServer {
int
maxmemory_samples
;
/* Pricision of random sampling */
int
lfu_log_factor
;
/* LFU logarithmic counter factor. */
int
lfu_decay_time
;
/* LFU counter decay factor. */
long
long
max_bulk_len
;
/* Blocked clients */
unsigned
int
blocked_clients
;
/* # of clients executing a blocking cmd.*/
unsigned
int
blocked_clients_by_type
[
BLOCKED_NUM
];
...
...
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