mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 08:08:53 -05:00
RDMF: More consistent define names.
This commit is contained in:
parent
40eb548a80
commit
32f80e2f1b
180
src/aof.c
180
src/aof.c
@ -95,10 +95,10 @@ void aofChildWriteDiffData(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
listNode *ln;
|
listNode *ln;
|
||||||
aofrwblock *block;
|
aofrwblock *block;
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(fd);
|
UNUSED(fd);
|
||||||
REDIS_NOTUSED(privdata);
|
UNUSED(privdata);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
ln = listFirst(server.aof_rewrite_buf_blocks);
|
ln = listFirst(server.aof_rewrite_buf_blocks);
|
||||||
@ -150,8 +150,8 @@ void aofRewriteBufferAppend(unsigned char *s, unsigned long len) {
|
|||||||
* as a notice or warning. */
|
* as a notice or warning. */
|
||||||
numblocks = listLength(server.aof_rewrite_buf_blocks);
|
numblocks = listLength(server.aof_rewrite_buf_blocks);
|
||||||
if (((numblocks+1) % 10) == 0) {
|
if (((numblocks+1) % 10) == 0) {
|
||||||
int level = ((numblocks+1) % 100) == 0 ? REDIS_WARNING :
|
int level = ((numblocks+1) % 100) == 0 ? LL_WARNING :
|
||||||
REDIS_NOTICE;
|
LL_NOTICE;
|
||||||
serverLog(level,"Background AOF buffer size: %lu MB",
|
serverLog(level,"Background AOF buffer size: %lu MB",
|
||||||
aofRewriteBufferSize()/(1024*1024));
|
aofRewriteBufferSize()/(1024*1024));
|
||||||
}
|
}
|
||||||
@ -204,19 +204,19 @@ void aof_background_fsync(int fd) {
|
|||||||
/* Called when the user switches from "appendonly yes" to "appendonly no"
|
/* Called when the user switches from "appendonly yes" to "appendonly no"
|
||||||
* at runtime using the CONFIG command. */
|
* at runtime using the CONFIG command. */
|
||||||
void stopAppendOnly(void) {
|
void stopAppendOnly(void) {
|
||||||
serverAssert(server.aof_state != REDIS_AOF_OFF);
|
serverAssert(server.aof_state != AOF_OFF);
|
||||||
flushAppendOnlyFile(1);
|
flushAppendOnlyFile(1);
|
||||||
aof_fsync(server.aof_fd);
|
aof_fsync(server.aof_fd);
|
||||||
close(server.aof_fd);
|
close(server.aof_fd);
|
||||||
|
|
||||||
server.aof_fd = -1;
|
server.aof_fd = -1;
|
||||||
server.aof_selected_db = -1;
|
server.aof_selected_db = -1;
|
||||||
server.aof_state = REDIS_AOF_OFF;
|
server.aof_state = AOF_OFF;
|
||||||
/* rewrite operation in progress? kill it, wait child exit */
|
/* rewrite operation in progress? kill it, wait child exit */
|
||||||
if (server.aof_child_pid != -1) {
|
if (server.aof_child_pid != -1) {
|
||||||
int statloc;
|
int statloc;
|
||||||
|
|
||||||
serverLog(REDIS_NOTICE,"Killing running AOF rewrite child: %ld",
|
serverLog(LL_NOTICE,"Killing running AOF rewrite child: %ld",
|
||||||
(long) server.aof_child_pid);
|
(long) server.aof_child_pid);
|
||||||
if (kill(server.aof_child_pid,SIGUSR1) != -1)
|
if (kill(server.aof_child_pid,SIGUSR1) != -1)
|
||||||
wait3(&statloc,0,NULL);
|
wait3(&statloc,0,NULL);
|
||||||
@ -235,19 +235,19 @@ void stopAppendOnly(void) {
|
|||||||
int startAppendOnly(void) {
|
int startAppendOnly(void) {
|
||||||
server.aof_last_fsync = server.unixtime;
|
server.aof_last_fsync = server.unixtime;
|
||||||
server.aof_fd = open(server.aof_filename,O_WRONLY|O_APPEND|O_CREAT,0644);
|
server.aof_fd = open(server.aof_filename,O_WRONLY|O_APPEND|O_CREAT,0644);
|
||||||
serverAssert(server.aof_state == REDIS_AOF_OFF);
|
serverAssert(server.aof_state == AOF_OFF);
|
||||||
if (server.aof_fd == -1) {
|
if (server.aof_fd == -1) {
|
||||||
serverLog(REDIS_WARNING,"Redis needs to enable the AOF but can't open the append only file: %s",strerror(errno));
|
serverLog(LL_WARNING,"Redis needs to enable the AOF but can't open the append only file: %s",strerror(errno));
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
if (rewriteAppendOnlyFileBackground() == C_ERR) {
|
if (rewriteAppendOnlyFileBackground() == C_ERR) {
|
||||||
close(server.aof_fd);
|
close(server.aof_fd);
|
||||||
serverLog(REDIS_WARNING,"Redis needs to enable the AOF but can't trigger a background AOF rewrite operation. Check the above logs for more info about the error.");
|
serverLog(LL_WARNING,"Redis needs to enable the AOF but can't trigger a background AOF rewrite operation. Check the above logs for more info about the error.");
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
/* We correctly switched on AOF, now wait for the rewrite to be complete
|
/* We correctly switched on AOF, now wait for the rewrite to be complete
|
||||||
* in order to append data on disk. */
|
* in order to append data on disk. */
|
||||||
server.aof_state = REDIS_AOF_WAIT_REWRITE;
|
server.aof_state = AOF_WAIT_REWRITE;
|
||||||
return C_OK;
|
return C_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ void flushAppendOnlyFile(int force) {
|
|||||||
/* Otherwise fall trough, and go write since we can't wait
|
/* Otherwise fall trough, and go write since we can't wait
|
||||||
* over two seconds. */
|
* over two seconds. */
|
||||||
server.aof_delayed_fsync++;
|
server.aof_delayed_fsync++;
|
||||||
serverLog(REDIS_NOTICE,"Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.");
|
serverLog(LL_NOTICE,"Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* We want to perform a single write. This should be guaranteed atomic
|
/* We want to perform a single write. This should be guaranteed atomic
|
||||||
@ -340,13 +340,13 @@ void flushAppendOnlyFile(int force) {
|
|||||||
/* Log the AOF write error and record the error code. */
|
/* Log the AOF write error and record the error code. */
|
||||||
if (nwritten == -1) {
|
if (nwritten == -1) {
|
||||||
if (can_log) {
|
if (can_log) {
|
||||||
serverLog(REDIS_WARNING,"Error writing to the AOF file: %s",
|
serverLog(LL_WARNING,"Error writing to the AOF file: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
server.aof_last_write_errno = errno;
|
server.aof_last_write_errno = errno;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (can_log) {
|
if (can_log) {
|
||||||
serverLog(REDIS_WARNING,"Short write while writing to "
|
serverLog(LL_WARNING,"Short write while writing to "
|
||||||
"the AOF file: (nwritten=%lld, "
|
"the AOF file: (nwritten=%lld, "
|
||||||
"expected=%lld)",
|
"expected=%lld)",
|
||||||
(long long)nwritten,
|
(long long)nwritten,
|
||||||
@ -355,7 +355,7 @@ void flushAppendOnlyFile(int force) {
|
|||||||
|
|
||||||
if (ftruncate(server.aof_fd, server.aof_current_size) == -1) {
|
if (ftruncate(server.aof_fd, server.aof_current_size) == -1) {
|
||||||
if (can_log) {
|
if (can_log) {
|
||||||
serverLog(REDIS_WARNING, "Could not remove short write "
|
serverLog(LL_WARNING, "Could not remove short write "
|
||||||
"from the append-only file. Redis may refuse "
|
"from the append-only file. Redis may refuse "
|
||||||
"to load the AOF the next time it starts. "
|
"to load the AOF the next time it starts. "
|
||||||
"ftruncate: %s", strerror(errno));
|
"ftruncate: %s", strerror(errno));
|
||||||
@ -374,7 +374,7 @@ void flushAppendOnlyFile(int force) {
|
|||||||
* reply for the client is already in the output buffers, and we
|
* reply for the client is already in the output buffers, and we
|
||||||
* have the contract with the user that on acknowledged write data
|
* have the contract with the user that on acknowledged write data
|
||||||
* is synced on disk. */
|
* is synced on disk. */
|
||||||
serverLog(REDIS_WARNING,"Can't recover from AOF write error when the AOF fsync policy is 'always'. Exiting...");
|
serverLog(LL_WARNING,"Can't recover from AOF write error when the AOF fsync policy is 'always'. Exiting...");
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
/* Recover from failed write leaving data into the buffer. However
|
/* Recover from failed write leaving data into the buffer. However
|
||||||
@ -394,7 +394,7 @@ void flushAppendOnlyFile(int force) {
|
|||||||
/* Successful write(2). If AOF was in error state, restore the
|
/* Successful write(2). If AOF was in error state, restore the
|
||||||
* OK state and log the event. */
|
* OK state and log the event. */
|
||||||
if (server.aof_last_write_status == C_ERR) {
|
if (server.aof_last_write_status == C_ERR) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"AOF write error looks solved, Redis can write again.");
|
"AOF write error looks solved, Redis can write again.");
|
||||||
server.aof_last_write_status = C_OK;
|
server.aof_last_write_status = C_OK;
|
||||||
}
|
}
|
||||||
@ -531,7 +531,7 @@ void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int a
|
|||||||
/* Append to the AOF buffer. This will be flushed on disk just before
|
/* Append to the AOF buffer. This will be flushed on disk just before
|
||||||
* of re-entering the event loop, so before the client will get a
|
* of re-entering the event loop, so before the client will get a
|
||||||
* positive reply about the operation performed. */
|
* positive reply about the operation performed. */
|
||||||
if (server.aof_state == REDIS_AOF_ON)
|
if (server.aof_state == AOF_ON)
|
||||||
server.aof_buf = sdscatlen(server.aof_buf,buf,sdslen(buf));
|
server.aof_buf = sdscatlen(server.aof_buf,buf,sdslen(buf));
|
||||||
|
|
||||||
/* If a background append only file rewriting is in progress we want to
|
/* If a background append only file rewriting is in progress we want to
|
||||||
@ -562,10 +562,10 @@ struct client *createFakeClient(void) {
|
|||||||
c->argv = NULL;
|
c->argv = NULL;
|
||||||
c->bufpos = 0;
|
c->bufpos = 0;
|
||||||
c->flags = 0;
|
c->flags = 0;
|
||||||
c->btype = REDIS_BLOCKED_NONE;
|
c->btype = BLOCKED_NONE;
|
||||||
/* We set the fake client as a slave waiting for the synchronization
|
/* We set the fake client as a slave waiting for the synchronization
|
||||||
* so that Redis will not try to send replies to this client. */
|
* so that Redis will not try to send replies to this client. */
|
||||||
c->replstate = REDIS_REPL_WAIT_BGSAVE_START;
|
c->replstate = SLAVE_STATE_WAIT_BGSAVE_START;
|
||||||
c->reply = listCreate();
|
c->reply = listCreate();
|
||||||
c->reply_bytes = 0;
|
c->reply_bytes = 0;
|
||||||
c->obuf_soft_limit_reached_time = 0;
|
c->obuf_soft_limit_reached_time = 0;
|
||||||
@ -611,13 +611,13 @@ int loadAppendOnlyFile(char *filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
serverLog(REDIS_WARNING,"Fatal error: can't open the append log file for reading: %s",strerror(errno));
|
serverLog(LL_WARNING,"Fatal error: can't open the append log file for reading: %s",strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporarily disable AOF, to prevent EXEC from feeding a MULTI
|
/* Temporarily disable AOF, to prevent EXEC from feeding a MULTI
|
||||||
* to the same file we're about to read. */
|
* to the same file we're about to read. */
|
||||||
server.aof_state = REDIS_AOF_OFF;
|
server.aof_state = AOF_OFF;
|
||||||
|
|
||||||
fakeClient = createFakeClient();
|
fakeClient = createFakeClient();
|
||||||
startLoading(fp);
|
startLoading(fp);
|
||||||
@ -677,7 +677,7 @@ int loadAppendOnlyFile(char *filename) {
|
|||||||
/* Command lookup */
|
/* Command lookup */
|
||||||
cmd = lookupCommand(argv[0]->ptr);
|
cmd = lookupCommand(argv[0]->ptr);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
serverLog(REDIS_WARNING,"Unknown command '%s' reading the append only file", (char*)argv[0]->ptr);
|
serverLog(LL_WARNING,"Unknown command '%s' reading the append only file", (char*)argv[0]->ptr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ int loadAppendOnlyFile(char *filename) {
|
|||||||
/* The fake client should not have a reply */
|
/* The fake client should not have a reply */
|
||||||
serverAssert(fakeClient->bufpos == 0 && listLength(fakeClient->reply) == 0);
|
serverAssert(fakeClient->bufpos == 0 && listLength(fakeClient->reply) == 0);
|
||||||
/* The fake client should never get blocked */
|
/* The fake client should never get blocked */
|
||||||
serverAssert((fakeClient->flags & REDIS_BLOCKED) == 0);
|
serverAssert((fakeClient->flags & CLIENT_BLOCKED) == 0);
|
||||||
|
|
||||||
/* Clean up. Command code may have changed argv/argc so we use the
|
/* Clean up. Command code may have changed argv/argc so we use the
|
||||||
* argv/argc of the client instead of the local variables. */
|
* argv/argc of the client instead of the local variables. */
|
||||||
@ -697,7 +697,7 @@ int loadAppendOnlyFile(char *filename) {
|
|||||||
|
|
||||||
/* This point can only be reached when EOF is reached without errors.
|
/* This point can only be reached when EOF is reached without errors.
|
||||||
* If the client is in the middle of a MULTI/EXEC, log error and quit. */
|
* If the client is in the middle of a MULTI/EXEC, log error and quit. */
|
||||||
if (fakeClient->flags & REDIS_MULTI) goto uxeof;
|
if (fakeClient->flags & CLIENT_MULTI) goto uxeof;
|
||||||
|
|
||||||
loaded_ok: /* DB loaded, cleanup and return C_OK to the caller. */
|
loaded_ok: /* DB loaded, cleanup and return C_OK to the caller. */
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -710,40 +710,40 @@ loaded_ok: /* DB loaded, cleanup and return C_OK to the caller. */
|
|||||||
|
|
||||||
readerr: /* Read error. If feof(fp) is true, fall through to unexpected EOF. */
|
readerr: /* Read error. If feof(fp) is true, fall through to unexpected EOF. */
|
||||||
if (!feof(fp)) {
|
if (!feof(fp)) {
|
||||||
serverLog(REDIS_WARNING,"Unrecoverable error reading the append only file: %s", strerror(errno));
|
serverLog(LL_WARNING,"Unrecoverable error reading the append only file: %s", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uxeof: /* Unexpected AOF end of file. */
|
uxeof: /* Unexpected AOF end of file. */
|
||||||
if (server.aof_load_truncated) {
|
if (server.aof_load_truncated) {
|
||||||
serverLog(REDIS_WARNING,"!!! Warning: short read while loading the AOF file !!!");
|
serverLog(LL_WARNING,"!!! Warning: short read while loading the AOF file !!!");
|
||||||
serverLog(REDIS_WARNING,"!!! Truncating the AOF at offset %llu !!!",
|
serverLog(LL_WARNING,"!!! Truncating the AOF at offset %llu !!!",
|
||||||
(unsigned long long) valid_up_to);
|
(unsigned long long) valid_up_to);
|
||||||
if (valid_up_to == -1 || truncate(filename,valid_up_to) == -1) {
|
if (valid_up_to == -1 || truncate(filename,valid_up_to) == -1) {
|
||||||
if (valid_up_to == -1) {
|
if (valid_up_to == -1) {
|
||||||
serverLog(REDIS_WARNING,"Last valid command offset is invalid");
|
serverLog(LL_WARNING,"Last valid command offset is invalid");
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,"Error truncating the AOF file: %s",
|
serverLog(LL_WARNING,"Error truncating the AOF file: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Make sure the AOF file descriptor points to the end of the
|
/* Make sure the AOF file descriptor points to the end of the
|
||||||
* file after the truncate call. */
|
* file after the truncate call. */
|
||||||
if (server.aof_fd != -1 && lseek(server.aof_fd,0,SEEK_END) == -1) {
|
if (server.aof_fd != -1 && lseek(server.aof_fd,0,SEEK_END) == -1) {
|
||||||
serverLog(REDIS_WARNING,"Can't seek the end of the AOF file: %s",
|
serverLog(LL_WARNING,"Can't seek the end of the AOF file: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"AOF loaded anyway because aof-load-truncated is enabled");
|
"AOF loaded anyway because aof-load-truncated is enabled");
|
||||||
goto loaded_ok;
|
goto loaded_ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serverLog(REDIS_WARNING,"Unexpected end of file reading the append only file. You can: 1) Make a backup of your AOF file, then use ./redis-check-aof --fix <filename>. 2) Alternatively you can set the 'aof-load-truncated' configuration option to yes and restart the server.");
|
serverLog(LL_WARNING,"Unexpected end of file reading the append only file. You can: 1) Make a backup of your AOF file, then use ./redis-check-aof --fix <filename>. 2) Alternatively you can set the 'aof-load-truncated' configuration option to yes and restart the server.");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
fmterr: /* Format error. */
|
fmterr: /* Format error. */
|
||||||
serverLog(REDIS_WARNING,"Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>");
|
serverLog(LL_WARNING,"Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +761,7 @@ int rioWriteBulkObject(rio *r, robj *obj) {
|
|||||||
} else if (sdsEncodedObject(obj)) {
|
} else if (sdsEncodedObject(obj)) {
|
||||||
return rioWriteBulkString(r,obj->ptr,sdslen(obj->ptr));
|
return rioWriteBulkString(r,obj->ptr,sdslen(obj->ptr));
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown string encoding");
|
serverPanic("Unknown string encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,8 +777,8 @@ int rewriteListObject(rio *r, robj *key, robj *o) {
|
|||||||
|
|
||||||
while (quicklistNext(li,&entry)) {
|
while (quicklistNext(li,&entry)) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
int cmd_items = (items > REDIS_AOF_REWRITE_ITEMS_PER_CMD) ?
|
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
|
||||||
REDIS_AOF_REWRITE_ITEMS_PER_CMD : items;
|
AOF_REWRITE_ITEMS_PER_CMD : items;
|
||||||
if (rioWriteBulkCount(r,'*',2+cmd_items) == 0) return 0;
|
if (rioWriteBulkCount(r,'*',2+cmd_items) == 0) return 0;
|
||||||
if (rioWriteBulkString(r,"RPUSH",5) == 0) return 0;
|
if (rioWriteBulkString(r,"RPUSH",5) == 0) return 0;
|
||||||
if (rioWriteBulkObject(r,key) == 0) return 0;
|
if (rioWriteBulkObject(r,key) == 0) return 0;
|
||||||
@ -789,12 +789,12 @@ int rewriteListObject(rio *r, robj *key, robj *o) {
|
|||||||
} else {
|
} else {
|
||||||
if (rioWriteBulkLongLong(r,entry.longval) == 0) return 0;
|
if (rioWriteBulkLongLong(r,entry.longval) == 0) return 0;
|
||||||
}
|
}
|
||||||
if (++count == REDIS_AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
||||||
items--;
|
items--;
|
||||||
}
|
}
|
||||||
quicklistReleaseIterator(li);
|
quicklistReleaseIterator(li);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -810,15 +810,15 @@ int rewriteSetObject(rio *r, robj *key, robj *o) {
|
|||||||
|
|
||||||
while(intsetGet(o->ptr,ii++,&llval)) {
|
while(intsetGet(o->ptr,ii++,&llval)) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
int cmd_items = (items > REDIS_AOF_REWRITE_ITEMS_PER_CMD) ?
|
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
|
||||||
REDIS_AOF_REWRITE_ITEMS_PER_CMD : items;
|
AOF_REWRITE_ITEMS_PER_CMD : items;
|
||||||
|
|
||||||
if (rioWriteBulkCount(r,'*',2+cmd_items) == 0) return 0;
|
if (rioWriteBulkCount(r,'*',2+cmd_items) == 0) return 0;
|
||||||
if (rioWriteBulkString(r,"SADD",4) == 0) return 0;
|
if (rioWriteBulkString(r,"SADD",4) == 0) return 0;
|
||||||
if (rioWriteBulkObject(r,key) == 0) return 0;
|
if (rioWriteBulkObject(r,key) == 0) return 0;
|
||||||
}
|
}
|
||||||
if (rioWriteBulkLongLong(r,llval) == 0) return 0;
|
if (rioWriteBulkLongLong(r,llval) == 0) return 0;
|
||||||
if (++count == REDIS_AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
||||||
items--;
|
items--;
|
||||||
}
|
}
|
||||||
} else if (o->encoding == OBJ_ENCODING_HT) {
|
} else if (o->encoding == OBJ_ENCODING_HT) {
|
||||||
@ -828,20 +828,20 @@ int rewriteSetObject(rio *r, robj *key, robj *o) {
|
|||||||
while((de = dictNext(di)) != NULL) {
|
while((de = dictNext(di)) != NULL) {
|
||||||
robj *eleobj = dictGetKey(de);
|
robj *eleobj = dictGetKey(de);
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
int cmd_items = (items > REDIS_AOF_REWRITE_ITEMS_PER_CMD) ?
|
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
|
||||||
REDIS_AOF_REWRITE_ITEMS_PER_CMD : items;
|
AOF_REWRITE_ITEMS_PER_CMD : items;
|
||||||
|
|
||||||
if (rioWriteBulkCount(r,'*',2+cmd_items) == 0) return 0;
|
if (rioWriteBulkCount(r,'*',2+cmd_items) == 0) return 0;
|
||||||
if (rioWriteBulkString(r,"SADD",4) == 0) return 0;
|
if (rioWriteBulkString(r,"SADD",4) == 0) return 0;
|
||||||
if (rioWriteBulkObject(r,key) == 0) return 0;
|
if (rioWriteBulkObject(r,key) == 0) return 0;
|
||||||
}
|
}
|
||||||
if (rioWriteBulkObject(r,eleobj) == 0) return 0;
|
if (rioWriteBulkObject(r,eleobj) == 0) return 0;
|
||||||
if (++count == REDIS_AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
||||||
items--;
|
items--;
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -869,8 +869,8 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
|
|||||||
score = zzlGetScore(sptr);
|
score = zzlGetScore(sptr);
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
int cmd_items = (items > REDIS_AOF_REWRITE_ITEMS_PER_CMD) ?
|
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
|
||||||
REDIS_AOF_REWRITE_ITEMS_PER_CMD : items;
|
AOF_REWRITE_ITEMS_PER_CMD : items;
|
||||||
|
|
||||||
if (rioWriteBulkCount(r,'*',2+cmd_items*2) == 0) return 0;
|
if (rioWriteBulkCount(r,'*',2+cmd_items*2) == 0) return 0;
|
||||||
if (rioWriteBulkString(r,"ZADD",4) == 0) return 0;
|
if (rioWriteBulkString(r,"ZADD",4) == 0) return 0;
|
||||||
@ -883,7 +883,7 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
|
|||||||
if (rioWriteBulkLongLong(r,vll) == 0) return 0;
|
if (rioWriteBulkLongLong(r,vll) == 0) return 0;
|
||||||
}
|
}
|
||||||
zzlNext(zl,&eptr,&sptr);
|
zzlNext(zl,&eptr,&sptr);
|
||||||
if (++count == REDIS_AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
||||||
items--;
|
items--;
|
||||||
}
|
}
|
||||||
} else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
@ -896,8 +896,8 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
|
|||||||
double *score = dictGetVal(de);
|
double *score = dictGetVal(de);
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
int cmd_items = (items > REDIS_AOF_REWRITE_ITEMS_PER_CMD) ?
|
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
|
||||||
REDIS_AOF_REWRITE_ITEMS_PER_CMD : items;
|
AOF_REWRITE_ITEMS_PER_CMD : items;
|
||||||
|
|
||||||
if (rioWriteBulkCount(r,'*',2+cmd_items*2) == 0) return 0;
|
if (rioWriteBulkCount(r,'*',2+cmd_items*2) == 0) return 0;
|
||||||
if (rioWriteBulkString(r,"ZADD",4) == 0) return 0;
|
if (rioWriteBulkString(r,"ZADD",4) == 0) return 0;
|
||||||
@ -905,12 +905,12 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
|
|||||||
}
|
}
|
||||||
if (rioWriteBulkDouble(r,*score) == 0) return 0;
|
if (rioWriteBulkDouble(r,*score) == 0) return 0;
|
||||||
if (rioWriteBulkObject(r,eleobj) == 0) return 0;
|
if (rioWriteBulkObject(r,eleobj) == 0) return 0;
|
||||||
if (++count == REDIS_AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
||||||
items--;
|
items--;
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted zset encoding");
|
serverPanic("Unknown sorted zset encoding");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -941,7 +941,7 @@ static int rioWriteHashIteratorCursor(rio *r, hashTypeIterator *hi, int what) {
|
|||||||
return rioWriteBulkObject(r, value);
|
return rioWriteBulkObject(r, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,8 +954,8 @@ int rewriteHashObject(rio *r, robj *key, robj *o) {
|
|||||||
hi = hashTypeInitIterator(o);
|
hi = hashTypeInitIterator(o);
|
||||||
while (hashTypeNext(hi) != C_ERR) {
|
while (hashTypeNext(hi) != C_ERR) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
int cmd_items = (items > REDIS_AOF_REWRITE_ITEMS_PER_CMD) ?
|
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
|
||||||
REDIS_AOF_REWRITE_ITEMS_PER_CMD : items;
|
AOF_REWRITE_ITEMS_PER_CMD : items;
|
||||||
|
|
||||||
if (rioWriteBulkCount(r,'*',2+cmd_items*2) == 0) return 0;
|
if (rioWriteBulkCount(r,'*',2+cmd_items*2) == 0) return 0;
|
||||||
if (rioWriteBulkString(r,"HMSET",5) == 0) return 0;
|
if (rioWriteBulkString(r,"HMSET",5) == 0) return 0;
|
||||||
@ -964,7 +964,7 @@ int rewriteHashObject(rio *r, robj *key, robj *o) {
|
|||||||
|
|
||||||
if (rioWriteHashIteratorCursor(r, hi, OBJ_HASH_KEY) == 0) return 0;
|
if (rioWriteHashIteratorCursor(r, hi, OBJ_HASH_KEY) == 0) return 0;
|
||||||
if (rioWriteHashIteratorCursor(r, hi, OBJ_HASH_VALUE) == 0) return 0;
|
if (rioWriteHashIteratorCursor(r, hi, OBJ_HASH_VALUE) == 0) return 0;
|
||||||
if (++count == REDIS_AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
|
||||||
items--;
|
items--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,7 +993,7 @@ ssize_t aofReadDiffFromParent(void) {
|
|||||||
*
|
*
|
||||||
* In order to minimize the number of commands needed in the rewritten
|
* In order to minimize the number of commands needed in the rewritten
|
||||||
* log Redis uses variadic commands when possible, such as RPUSH, SADD
|
* log Redis uses variadic commands when possible, such as RPUSH, SADD
|
||||||
* and ZADD. However at max REDIS_AOF_REWRITE_ITEMS_PER_CMD items per time
|
* and ZADD. However at max AOF_REWRITE_ITEMS_PER_CMD items per time
|
||||||
* are inserted using a single command. */
|
* are inserted using a single command. */
|
||||||
int rewriteAppendOnlyFile(char *filename) {
|
int rewriteAppendOnlyFile(char *filename) {
|
||||||
dictIterator *di = NULL;
|
dictIterator *di = NULL;
|
||||||
@ -1011,14 +1011,14 @@ int rewriteAppendOnlyFile(char *filename) {
|
|||||||
snprintf(tmpfile,256,"temp-rewriteaof-%d.aof", (int) getpid());
|
snprintf(tmpfile,256,"temp-rewriteaof-%d.aof", (int) getpid());
|
||||||
fp = fopen(tmpfile,"w");
|
fp = fopen(tmpfile,"w");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
serverLog(REDIS_WARNING, "Opening the temp file for AOF rewrite in rewriteAppendOnlyFile(): %s", strerror(errno));
|
serverLog(LL_WARNING, "Opening the temp file for AOF rewrite in rewriteAppendOnlyFile(): %s", strerror(errno));
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
server.aof_child_diff = sdsempty();
|
server.aof_child_diff = sdsempty();
|
||||||
rioInitWithFile(&aof,fp);
|
rioInitWithFile(&aof,fp);
|
||||||
if (server.aof_rewrite_incremental_fsync)
|
if (server.aof_rewrite_incremental_fsync)
|
||||||
rioSetAutoSync(&aof,REDIS_AOF_AUTOSYNC_BYTES);
|
rioSetAutoSync(&aof,AOF_AUTOSYNC_BYTES);
|
||||||
for (j = 0; j < server.dbnum; j++) {
|
for (j = 0; j < server.dbnum; j++) {
|
||||||
char selectcmd[] = "*2\r\n$6\r\nSELECT\r\n";
|
char selectcmd[] = "*2\r\n$6\r\nSELECT\r\n";
|
||||||
redisDb *db = server.db+j;
|
redisDb *db = server.db+j;
|
||||||
@ -1066,7 +1066,7 @@ int rewriteAppendOnlyFile(char *filename) {
|
|||||||
} else if (o->type == OBJ_HASH) {
|
} else if (o->type == OBJ_HASH) {
|
||||||
if (rewriteHashObject(&aof,&key,o) == 0) goto werr;
|
if (rewriteHashObject(&aof,&key,o) == 0) goto werr;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown object type");
|
serverPanic("Unknown object type");
|
||||||
}
|
}
|
||||||
/* Save the expire time */
|
/* Save the expire time */
|
||||||
if (expiretime != -1) {
|
if (expiretime != -1) {
|
||||||
@ -1118,13 +1118,13 @@ int rewriteAppendOnlyFile(char *filename) {
|
|||||||
* the child will eventually get terminated. */
|
* the child will eventually get terminated. */
|
||||||
if (syncRead(server.aof_pipe_read_ack_from_parent,&byte,1,5000) != 1 ||
|
if (syncRead(server.aof_pipe_read_ack_from_parent,&byte,1,5000) != 1 ||
|
||||||
byte != '!') goto werr;
|
byte != '!') goto werr;
|
||||||
serverLog(REDIS_NOTICE,"Parent agreed to stop sending diffs. Finalizing AOF...");
|
serverLog(LL_NOTICE,"Parent agreed to stop sending diffs. Finalizing AOF...");
|
||||||
|
|
||||||
/* Read the final diff if any. */
|
/* Read the final diff if any. */
|
||||||
aofReadDiffFromParent();
|
aofReadDiffFromParent();
|
||||||
|
|
||||||
/* Write the received diff to the file. */
|
/* Write the received diff to the file. */
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Concatenating %.2f MB of AOF diff received from parent.",
|
"Concatenating %.2f MB of AOF diff received from parent.",
|
||||||
(double) sdslen(server.aof_child_diff) / (1024*1024));
|
(double) sdslen(server.aof_child_diff) / (1024*1024));
|
||||||
if (rioWrite(&aof,server.aof_child_diff,sdslen(server.aof_child_diff)) == 0)
|
if (rioWrite(&aof,server.aof_child_diff,sdslen(server.aof_child_diff)) == 0)
|
||||||
@ -1138,15 +1138,15 @@ int rewriteAppendOnlyFile(char *filename) {
|
|||||||
/* Use RENAME to make sure the DB file is changed atomically only
|
/* Use RENAME to make sure the DB file is changed atomically only
|
||||||
* if the generate DB file is ok. */
|
* if the generate DB file is ok. */
|
||||||
if (rename(tmpfile,filename) == -1) {
|
if (rename(tmpfile,filename) == -1) {
|
||||||
serverLog(REDIS_WARNING,"Error moving temp append only file on the final destination: %s", strerror(errno));
|
serverLog(LL_WARNING,"Error moving temp append only file on the final destination: %s", strerror(errno));
|
||||||
unlink(tmpfile);
|
unlink(tmpfile);
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_NOTICE,"SYNC append only file rewrite performed");
|
serverLog(LL_NOTICE,"SYNC append only file rewrite performed");
|
||||||
return C_OK;
|
return C_OK;
|
||||||
|
|
||||||
werr:
|
werr:
|
||||||
serverLog(REDIS_WARNING,"Write error writing append only file on disk: %s", strerror(errno));
|
serverLog(LL_WARNING,"Write error writing append only file on disk: %s", strerror(errno));
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
unlink(tmpfile);
|
unlink(tmpfile);
|
||||||
if (di) dictReleaseIterator(di);
|
if (di) dictReleaseIterator(di);
|
||||||
@ -1162,19 +1162,19 @@ werr:
|
|||||||
* parent sends a '!' as well to acknowledge. */
|
* parent sends a '!' as well to acknowledge. */
|
||||||
void aofChildPipeReadable(aeEventLoop *el, int fd, void *privdata, int mask) {
|
void aofChildPipeReadable(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
char byte;
|
char byte;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(privdata);
|
UNUSED(privdata);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
|
|
||||||
if (read(fd,&byte,1) == 1 && byte == '!') {
|
if (read(fd,&byte,1) == 1 && byte == '!') {
|
||||||
serverLog(REDIS_NOTICE,"AOF rewrite child asks to stop sending diffs.");
|
serverLog(LL_NOTICE,"AOF rewrite child asks to stop sending diffs.");
|
||||||
server.aof_stop_sending_diff = 1;
|
server.aof_stop_sending_diff = 1;
|
||||||
if (write(server.aof_pipe_write_ack_to_child,"!",1) != 1) {
|
if (write(server.aof_pipe_write_ack_to_child,"!",1) != 1) {
|
||||||
/* If we can't send the ack, inform the user, but don't try again
|
/* If we can't send the ack, inform the user, but don't try again
|
||||||
* since in the other side the children will use a timeout if the
|
* since in the other side the children will use a timeout if the
|
||||||
* kernel can't buffer our write, or, the children was
|
* kernel can't buffer our write, or, the children was
|
||||||
* terminated. */
|
* terminated. */
|
||||||
serverLog(REDIS_WARNING,"Can't send ACK to AOF child: %s",
|
serverLog(LL_WARNING,"Can't send ACK to AOF child: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1210,7 +1210,7 @@ int aofCreatePipes(void) {
|
|||||||
return C_OK;
|
return C_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
serverLog(REDIS_WARNING,"Error opening /setting AOF rewrite IPC pipes: %s",
|
serverLog(LL_WARNING,"Error opening /setting AOF rewrite IPC pipes: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
for (j = 0; j < 6; j++) if(fds[j] != -1) close(fds[j]);
|
for (j = 0; j < 6; j++) if(fds[j] != -1) close(fds[j]);
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
@ -1261,7 +1261,7 @@ int rewriteAppendOnlyFileBackground(void) {
|
|||||||
size_t private_dirty = zmalloc_get_private_dirty();
|
size_t private_dirty = zmalloc_get_private_dirty();
|
||||||
|
|
||||||
if (private_dirty) {
|
if (private_dirty) {
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"AOF rewrite: %zu MB of memory used by copy-on-write",
|
"AOF rewrite: %zu MB of memory used by copy-on-write",
|
||||||
private_dirty/(1024*1024));
|
private_dirty/(1024*1024));
|
||||||
}
|
}
|
||||||
@ -1275,12 +1275,12 @@ int rewriteAppendOnlyFileBackground(void) {
|
|||||||
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
|
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
|
||||||
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
|
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
|
||||||
if (childpid == -1) {
|
if (childpid == -1) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Can't rewrite append only file in background: fork: %s",
|
"Can't rewrite append only file in background: fork: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Background append only file rewriting started by pid %d",childpid);
|
"Background append only file rewriting started by pid %d",childpid);
|
||||||
server.aof_rewrite_scheduled = 0;
|
server.aof_rewrite_scheduled = 0;
|
||||||
server.aof_rewrite_time_start = time(NULL);
|
server.aof_rewrite_time_start = time(NULL);
|
||||||
@ -1327,7 +1327,7 @@ void aofUpdateCurrentSize(void) {
|
|||||||
|
|
||||||
latencyStartMonitor(latency);
|
latencyStartMonitor(latency);
|
||||||
if (redis_fstat(server.aof_fd,&sb) == -1) {
|
if (redis_fstat(server.aof_fd,&sb) == -1) {
|
||||||
serverLog(REDIS_WARNING,"Unable to obtain the AOF file length. stat: %s",
|
serverLog(LL_WARNING,"Unable to obtain the AOF file length. stat: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
server.aof_current_size = sb.st_size;
|
server.aof_current_size = sb.st_size;
|
||||||
@ -1345,7 +1345,7 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) {
|
|||||||
long long now = ustime();
|
long long now = ustime();
|
||||||
mstime_t latency;
|
mstime_t latency;
|
||||||
|
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Background AOF rewrite terminated with success");
|
"Background AOF rewrite terminated with success");
|
||||||
|
|
||||||
/* Flush the differences accumulated by the parent to the
|
/* Flush the differences accumulated by the parent to the
|
||||||
@ -1355,13 +1355,13 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) {
|
|||||||
(int)server.aof_child_pid);
|
(int)server.aof_child_pid);
|
||||||
newfd = open(tmpfile,O_WRONLY|O_APPEND);
|
newfd = open(tmpfile,O_WRONLY|O_APPEND);
|
||||||
if (newfd == -1) {
|
if (newfd == -1) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Unable to open the temporary AOF produced by the child: %s", strerror(errno));
|
"Unable to open the temporary AOF produced by the child: %s", strerror(errno));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aofRewriteBufferWrite(newfd) == -1) {
|
if (aofRewriteBufferWrite(newfd) == -1) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Error trying to flush the parent diff to the rewritten AOF: %s", strerror(errno));
|
"Error trying to flush the parent diff to the rewritten AOF: %s", strerror(errno));
|
||||||
close(newfd);
|
close(newfd);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -1369,7 +1369,7 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) {
|
|||||||
latencyEndMonitor(latency);
|
latencyEndMonitor(latency);
|
||||||
latencyAddSampleIfNeeded("aof-rewrite-diff-write",latency);
|
latencyAddSampleIfNeeded("aof-rewrite-diff-write",latency);
|
||||||
|
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Residual parent diff successfully flushed to the rewritten AOF (%.2f MB)", (double) aofRewriteBufferSize() / (1024*1024));
|
"Residual parent diff successfully flushed to the rewritten AOF (%.2f MB)", (double) aofRewriteBufferSize() / (1024*1024));
|
||||||
|
|
||||||
/* The only remaining thing to do is to rename the temporary file to
|
/* The only remaining thing to do is to rename the temporary file to
|
||||||
@ -1415,7 +1415,7 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) {
|
|||||||
* it exists, because we reference it with "oldfd". */
|
* it exists, because we reference it with "oldfd". */
|
||||||
latencyStartMonitor(latency);
|
latencyStartMonitor(latency);
|
||||||
if (rename(tmpfile,server.aof_filename) == -1) {
|
if (rename(tmpfile,server.aof_filename) == -1) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Error trying to rename the temporary AOF file: %s", strerror(errno));
|
"Error trying to rename the temporary AOF file: %s", strerror(errno));
|
||||||
close(newfd);
|
close(newfd);
|
||||||
if (oldfd != -1) close(oldfd);
|
if (oldfd != -1) close(oldfd);
|
||||||
@ -1448,25 +1448,25 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) {
|
|||||||
|
|
||||||
server.aof_lastbgrewrite_status = C_OK;
|
server.aof_lastbgrewrite_status = C_OK;
|
||||||
|
|
||||||
serverLog(REDIS_NOTICE, "Background AOF rewrite finished successfully");
|
serverLog(LL_NOTICE, "Background AOF rewrite finished successfully");
|
||||||
/* Change state from WAIT_REWRITE to ON if needed */
|
/* Change state from WAIT_REWRITE to ON if needed */
|
||||||
if (server.aof_state == REDIS_AOF_WAIT_REWRITE)
|
if (server.aof_state == AOF_WAIT_REWRITE)
|
||||||
server.aof_state = REDIS_AOF_ON;
|
server.aof_state = AOF_ON;
|
||||||
|
|
||||||
/* Asynchronously close the overwritten AOF. */
|
/* Asynchronously close the overwritten AOF. */
|
||||||
if (oldfd != -1) bioCreateBackgroundJob(REDIS_BIO_CLOSE_FILE,(void*)(long)oldfd,NULL,NULL);
|
if (oldfd != -1) bioCreateBackgroundJob(REDIS_BIO_CLOSE_FILE,(void*)(long)oldfd,NULL,NULL);
|
||||||
|
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"Background AOF rewrite signal handler took %lldus", ustime()-now);
|
"Background AOF rewrite signal handler took %lldus", ustime()-now);
|
||||||
} else if (!bysignal && exitcode != 0) {
|
} else if (!bysignal && exitcode != 0) {
|
||||||
server.aof_lastbgrewrite_status = C_ERR;
|
server.aof_lastbgrewrite_status = C_ERR;
|
||||||
|
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Background AOF rewrite terminated with error");
|
"Background AOF rewrite terminated with error");
|
||||||
} else {
|
} else {
|
||||||
server.aof_lastbgrewrite_status = C_ERR;
|
server.aof_lastbgrewrite_status = C_ERR;
|
||||||
|
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Background AOF rewrite terminated by signal %d", bysignal);
|
"Background AOF rewrite terminated by signal %d", bysignal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1478,6 +1478,6 @@ cleanup:
|
|||||||
server.aof_rewrite_time_last = time(NULL)-server.aof_rewrite_time_start;
|
server.aof_rewrite_time_last = time(NULL)-server.aof_rewrite_time_start;
|
||||||
server.aof_rewrite_time_start = -1;
|
server.aof_rewrite_time_start = -1;
|
||||||
/* Schedule a new rewrite if we are waiting for it to switch the AOF ON. */
|
/* Schedule a new rewrite if we are waiting for it to switch the AOF ON. */
|
||||||
if (server.aof_state == REDIS_AOF_WAIT_REWRITE)
|
if (server.aof_state == AOF_WAIT_REWRITE)
|
||||||
server.aof_rewrite_scheduled = 1;
|
server.aof_rewrite_scheduled = 1;
|
||||||
}
|
}
|
||||||
|
12
src/bio.c
12
src/bio.c
@ -116,7 +116,7 @@ void bioInit(void) {
|
|||||||
for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
|
for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
|
||||||
void *arg = (void*)(unsigned long) j;
|
void *arg = (void*)(unsigned long) j;
|
||||||
if (pthread_create(&thread,&attr,bioProcessBackgroundJobs,arg) != 0) {
|
if (pthread_create(&thread,&attr,bioProcessBackgroundJobs,arg) != 0) {
|
||||||
serverLog(REDIS_WARNING,"Fatal: Can't initialize Background Jobs.");
|
serverLog(LL_WARNING,"Fatal: Can't initialize Background Jobs.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
bio_threads[j] = thread;
|
bio_threads[j] = thread;
|
||||||
@ -144,7 +144,7 @@ void *bioProcessBackgroundJobs(void *arg) {
|
|||||||
|
|
||||||
/* Check that the type is within the right interval. */
|
/* Check that the type is within the right interval. */
|
||||||
if (type >= REDIS_BIO_NUM_OPS) {
|
if (type >= REDIS_BIO_NUM_OPS) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Warning: bio thread started with wrong type %lu",type);
|
"Warning: bio thread started with wrong type %lu",type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ void *bioProcessBackgroundJobs(void *arg) {
|
|||||||
sigemptyset(&sigset);
|
sigemptyset(&sigset);
|
||||||
sigaddset(&sigset, SIGALRM);
|
sigaddset(&sigset, SIGALRM);
|
||||||
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
|
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Warning: can't mask SIGALRM in bio.c thread: %s", strerror(errno));
|
"Warning: can't mask SIGALRM in bio.c thread: %s", strerror(errno));
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
@ -184,7 +184,7 @@ void *bioProcessBackgroundJobs(void *arg) {
|
|||||||
} else if (type == REDIS_BIO_AOF_FSYNC) {
|
} else if (type == REDIS_BIO_AOF_FSYNC) {
|
||||||
aof_fsync((long)job->arg1);
|
aof_fsync((long)job->arg1);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Wrong job type in bioProcessBackgroundJobs().");
|
serverPanic("Wrong job type in bioProcessBackgroundJobs().");
|
||||||
}
|
}
|
||||||
zfree(job);
|
zfree(job);
|
||||||
|
|
||||||
@ -215,11 +215,11 @@ void bioKillThreads(void) {
|
|||||||
for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
|
for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
|
||||||
if (pthread_cancel(bio_threads[j]) == 0) {
|
if (pthread_cancel(bio_threads[j]) == 0) {
|
||||||
if ((err = pthread_join(bio_threads[j],NULL)) != 0) {
|
if ((err = pthread_join(bio_threads[j],NULL)) != 0) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Bio thread for job type #%d can be joined: %s",
|
"Bio thread for job type #%d can be joined: %s",
|
||||||
j, strerror(err));
|
j, strerror(err));
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Bio thread for job type #%d terminated",j);
|
"Bio thread for job type #%d terminated",j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ long redisBitpos(void *s, unsigned long count, int bit) {
|
|||||||
|
|
||||||
/* If we reached this point, there is a bug in the algorithm, since
|
/* If we reached this point, there is a bug in the algorithm, since
|
||||||
* the case of no match is handled as a special case before. */
|
* the case of no match is handled as a special case before. */
|
||||||
redisPanic("End of redisBitpos() reached.");
|
serverPanic("End of redisBitpos() reached.");
|
||||||
return 0; /* Just to avoid warnings. */
|
return 0; /* Just to avoid warnings. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ void setbitCommand(client *c) {
|
|||||||
byteval |= ((on & 0x1) << bit);
|
byteval |= ((on & 0x1) << bit);
|
||||||
((uint8_t*)o->ptr)[byte] = byteval;
|
((uint8_t*)o->ptr)[byte] = byteval;
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"setbit",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"setbit",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c, bitval ? shared.cone : shared.czero);
|
addReply(c, bitval ? shared.cone : shared.czero);
|
||||||
}
|
}
|
||||||
@ -446,11 +446,11 @@ void bitopCommand(client *c) {
|
|||||||
if (maxlen) {
|
if (maxlen) {
|
||||||
o = createObject(OBJ_STRING,res);
|
o = createObject(OBJ_STRING,res);
|
||||||
setKey(c->db,targetkey,o);
|
setKey(c->db,targetkey,o);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"set",targetkey,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"set",targetkey,c->db->id);
|
||||||
decrRefCount(o);
|
decrRefCount(o);
|
||||||
} else if (dbDelete(c->db,targetkey)) {
|
} else if (dbDelete(c->db,targetkey)) {
|
||||||
signalModifiedKey(c->db,targetkey);
|
signalModifiedKey(c->db,targetkey);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",targetkey,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",targetkey,c->db->id);
|
||||||
}
|
}
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReplyLongLong(c,maxlen); /* Return the output string length in bytes. */
|
addReplyLongLong(c,maxlen); /* Return the output string length in bytes. */
|
||||||
|
@ -34,17 +34,17 @@
|
|||||||
* getTimeoutFromObjectOrReply() is just an utility function to parse a
|
* getTimeoutFromObjectOrReply() is just an utility function to parse a
|
||||||
* timeout argument since blocking operations usually require a timeout.
|
* timeout argument since blocking operations usually require a timeout.
|
||||||
*
|
*
|
||||||
* blockClient() set the REDIS_BLOCKED flag in the client, and set the
|
* blockClient() set the CLIENT_BLOCKED flag in the client, and set the
|
||||||
* specified block type 'btype' filed to one of REDIS_BLOCKED_* macros.
|
* specified block type 'btype' filed to one of BLOCKED_* macros.
|
||||||
*
|
*
|
||||||
* unblockClient() unblocks the client doing the following:
|
* unblockClient() unblocks the client doing the following:
|
||||||
* 1) It calls the btype-specific function to cleanup the state.
|
* 1) It calls the btype-specific function to cleanup the state.
|
||||||
* 2) It unblocks the client by unsetting the REDIS_BLOCKED flag.
|
* 2) It unblocks the client by unsetting the CLIENT_BLOCKED flag.
|
||||||
* 3) It puts the client into a list of just unblocked clients that are
|
* 3) It puts the client into a list of just unblocked clients that are
|
||||||
* processed ASAP in the beforeSleep() event loop callback, so that
|
* processed ASAP in the beforeSleep() event loop callback, so that
|
||||||
* if there is some query buffer to process, we do it. This is also
|
* if there is some query buffer to process, we do it. This is also
|
||||||
* required because otherwise there is no 'readable' event fired, we
|
* required because otherwise there is no 'readable' event fired, we
|
||||||
* already read the pending commands. We also set the REDIS_UNBLOCKED
|
* already read the pending commands. We also set the CLIENT_UNBLOCKED
|
||||||
* flag to remember the client is in the unblocked_clients list.
|
* flag to remember the client is in the unblocked_clients list.
|
||||||
*
|
*
|
||||||
* processUnblockedClients() is called inside the beforeSleep() function
|
* processUnblockedClients() is called inside the beforeSleep() function
|
||||||
@ -94,11 +94,11 @@ int getTimeoutFromObjectOrReply(client *c, robj *object, mstime_t *timeout, int
|
|||||||
return C_OK;
|
return C_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Block a client for the specific operation type. Once the REDIS_BLOCKED
|
/* Block a client for the specific operation type. Once the CLIENT_BLOCKED
|
||||||
* flag is set client query buffer is not longer processed, but accumulated,
|
* flag is set client query buffer is not longer processed, but accumulated,
|
||||||
* and will be processed when the client is unblocked. */
|
* and will be processed when the client is unblocked. */
|
||||||
void blockClient(client *c, int btype) {
|
void blockClient(client *c, int btype) {
|
||||||
c->flags |= REDIS_BLOCKED;
|
c->flags |= CLIENT_BLOCKED;
|
||||||
c->btype = btype;
|
c->btype = btype;
|
||||||
server.bpop_blocked_clients++;
|
server.bpop_blocked_clients++;
|
||||||
}
|
}
|
||||||
@ -115,13 +115,13 @@ void processUnblockedClients(void) {
|
|||||||
serverAssert(ln != NULL);
|
serverAssert(ln != NULL);
|
||||||
c = ln->value;
|
c = ln->value;
|
||||||
listDelNode(server.unblocked_clients,ln);
|
listDelNode(server.unblocked_clients,ln);
|
||||||
c->flags &= ~REDIS_UNBLOCKED;
|
c->flags &= ~CLIENT_UNBLOCKED;
|
||||||
|
|
||||||
/* Process remaining data in the input buffer, unless the client
|
/* Process remaining data in the input buffer, unless the client
|
||||||
* is blocked again. Actually processInputBuffer() checks that the
|
* is blocked again. Actually processInputBuffer() checks that the
|
||||||
* client is not blocked before to proceed, but things may change and
|
* client is not blocked before to proceed, but things may change and
|
||||||
* the code is conceptually more correct this way. */
|
* the code is conceptually more correct this way. */
|
||||||
if (!(c->flags & REDIS_BLOCKED)) {
|
if (!(c->flags & CLIENT_BLOCKED)) {
|
||||||
if (c->querybuf && sdslen(c->querybuf) > 0) {
|
if (c->querybuf && sdslen(c->querybuf) > 0) {
|
||||||
processInputBuffer(c);
|
processInputBuffer(c);
|
||||||
}
|
}
|
||||||
@ -132,22 +132,22 @@ void processUnblockedClients(void) {
|
|||||||
/* Unblock a client calling the right function depending on the kind
|
/* Unblock a client calling the right function depending on the kind
|
||||||
* of operation the client is blocking for. */
|
* of operation the client is blocking for. */
|
||||||
void unblockClient(client *c) {
|
void unblockClient(client *c) {
|
||||||
if (c->btype == REDIS_BLOCKED_LIST) {
|
if (c->btype == BLOCKED_LIST) {
|
||||||
unblockClientWaitingData(c);
|
unblockClientWaitingData(c);
|
||||||
} else if (c->btype == REDIS_BLOCKED_WAIT) {
|
} else if (c->btype == BLOCKED_WAIT) {
|
||||||
unblockClientWaitingReplicas(c);
|
unblockClientWaitingReplicas(c);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown btype in unblockClient().");
|
serverPanic("Unknown btype in unblockClient().");
|
||||||
}
|
}
|
||||||
/* Clear the flags, and put the client in the unblocked list so that
|
/* Clear the flags, and put the client in the unblocked list so that
|
||||||
* we'll process new commands in its query buffer ASAP. */
|
* we'll process new commands in its query buffer ASAP. */
|
||||||
c->flags &= ~REDIS_BLOCKED;
|
c->flags &= ~CLIENT_BLOCKED;
|
||||||
c->btype = REDIS_BLOCKED_NONE;
|
c->btype = BLOCKED_NONE;
|
||||||
server.bpop_blocked_clients--;
|
server.bpop_blocked_clients--;
|
||||||
/* The client may already be into the unblocked list because of a previous
|
/* The client may already be into the unblocked list because of a previous
|
||||||
* blocking operation, don't add back it into the list multiple times. */
|
* blocking operation, don't add back it into the list multiple times. */
|
||||||
if (!(c->flags & REDIS_UNBLOCKED)) {
|
if (!(c->flags & CLIENT_UNBLOCKED)) {
|
||||||
c->flags |= REDIS_UNBLOCKED;
|
c->flags |= CLIENT_UNBLOCKED;
|
||||||
listAddNodeTail(server.unblocked_clients,c);
|
listAddNodeTail(server.unblocked_clients,c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,12 +155,12 @@ void unblockClient(client *c) {
|
|||||||
/* This function gets called when a blocked client timed out in order to
|
/* This function gets called when a blocked client timed out in order to
|
||||||
* send it a reply of some kind. */
|
* send it a reply of some kind. */
|
||||||
void replyToBlockedClientTimedOut(client *c) {
|
void replyToBlockedClientTimedOut(client *c) {
|
||||||
if (c->btype == REDIS_BLOCKED_LIST) {
|
if (c->btype == BLOCKED_LIST) {
|
||||||
addReply(c,shared.nullmultibulk);
|
addReply(c,shared.nullmultibulk);
|
||||||
} else if (c->btype == REDIS_BLOCKED_WAIT) {
|
} else if (c->btype == BLOCKED_WAIT) {
|
||||||
addReplyLongLong(c,replicationCountAcksByOffset(c->bpop.reploffset));
|
addReplyLongLong(c,replicationCountAcksByOffset(c->bpop.reploffset));
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown btype in replyToBlockedClientTimedOut().");
|
serverPanic("Unknown btype in replyToBlockedClientTimedOut().");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,12 +179,12 @@ void disconnectAllBlockedClients(void) {
|
|||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
client *c = listNodeValue(ln);
|
client *c = listNodeValue(ln);
|
||||||
|
|
||||||
if (c->flags & REDIS_BLOCKED) {
|
if (c->flags & CLIENT_BLOCKED) {
|
||||||
addReplySds(c,sdsnew(
|
addReplySds(c,sdsnew(
|
||||||
"-UNBLOCKED force unblock from blocking operation, "
|
"-UNBLOCKED force unblock from blocking operation, "
|
||||||
"instance state changed (master -> slave?)\r\n"));
|
"instance state changed (master -> slave?)\r\n"));
|
||||||
unblockClient(c);
|
unblockClient(c);
|
||||||
c->flags |= REDIS_CLOSE_AFTER_REPLY;
|
c->flags |= CLIENT_CLOSE_AFTER_REPLY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
206
src/cluster.c
206
src/cluster.c
@ -97,7 +97,7 @@ int clusterLoadConfig(char *filename) {
|
|||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Loading the cluster node config from %s: %s",
|
"Loading the cluster node config from %s: %s",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -146,7 +146,7 @@ int clusterLoadConfig(char *filename) {
|
|||||||
server.cluster->lastVoteEpoch =
|
server.cluster->lastVoteEpoch =
|
||||||
strtoull(argv[j+1],NULL,10);
|
strtoull(argv[j+1],NULL,10);
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Skipping unknown cluster config variable '%s'",
|
"Skipping unknown cluster config variable '%s'",
|
||||||
argv[j]);
|
argv[j]);
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ int clusterLoadConfig(char *filename) {
|
|||||||
} else if (!strcasecmp(s,"noflags")) {
|
} else if (!strcasecmp(s,"noflags")) {
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown flag in redis cluster config file");
|
serverPanic("Unknown flag in redis cluster config file");
|
||||||
}
|
}
|
||||||
if (p) s = p+1;
|
if (p) s = p+1;
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ int clusterLoadConfig(char *filename) {
|
|||||||
zfree(line);
|
zfree(line);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
serverLog(REDIS_NOTICE,"Node configuration loaded, I'm %.40s", myself->name);
|
serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name);
|
||||||
|
|
||||||
/* Something that should never happen: currentEpoch smaller than
|
/* Something that should never happen: currentEpoch smaller than
|
||||||
* the max epoch found in the nodes configuration. However we handle this
|
* the max epoch found in the nodes configuration. However we handle this
|
||||||
@ -275,7 +275,7 @@ int clusterLoadConfig(char *filename) {
|
|||||||
return C_OK;
|
return C_OK;
|
||||||
|
|
||||||
fmterr:
|
fmterr:
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Unrecoverable error: corrupted cluster config file.");
|
"Unrecoverable error: corrupted cluster config file.");
|
||||||
zfree(line);
|
zfree(line);
|
||||||
if (fp) fclose(fp);
|
if (fp) fclose(fp);
|
||||||
@ -343,7 +343,7 @@ err:
|
|||||||
|
|
||||||
void clusterSaveConfigOrDie(int do_fsync) {
|
void clusterSaveConfigOrDie(int do_fsync) {
|
||||||
if (clusterSaveConfig(do_fsync) == -1) {
|
if (clusterSaveConfig(do_fsync) == -1) {
|
||||||
serverLog(REDIS_WARNING,"Fatal: can't update cluster config file.");
|
serverLog(LL_WARNING,"Fatal: can't update cluster config file.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -368,7 +368,7 @@ int clusterLockConfig(char *filename) {
|
|||||||
* processes. */
|
* processes. */
|
||||||
int fd = open(filename,O_WRONLY|O_CREAT,0644);
|
int fd = open(filename,O_WRONLY|O_CREAT,0644);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Can't open %s in order to acquire a lock: %s",
|
"Can't open %s in order to acquire a lock: %s",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
@ -376,13 +376,13 @@ int clusterLockConfig(char *filename) {
|
|||||||
|
|
||||||
if (flock(fd,LOCK_EX|LOCK_NB) == -1) {
|
if (flock(fd,LOCK_EX|LOCK_NB) == -1) {
|
||||||
if (errno == EWOULDBLOCK) {
|
if (errno == EWOULDBLOCK) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Sorry, the cluster configuration file %s is already used "
|
"Sorry, the cluster configuration file %s is already used "
|
||||||
"by a different Redis Cluster node. Please make sure that "
|
"by a different Redis Cluster node. Please make sure that "
|
||||||
"different nodes use different cluster configuration "
|
"different nodes use different cluster configuration "
|
||||||
"files.", filename);
|
"files.", filename);
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Impossible to lock %s: %s", filename, strerror(errno));
|
"Impossible to lock %s: %s", filename, strerror(errno));
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -429,7 +429,7 @@ void clusterInit(void) {
|
|||||||
* by the createClusterNode() function. */
|
* by the createClusterNode() function. */
|
||||||
myself = server.cluster->myself =
|
myself = server.cluster->myself =
|
||||||
createClusterNode(NULL,REDIS_NODE_MYSELF|REDIS_NODE_MASTER);
|
createClusterNode(NULL,REDIS_NODE_MYSELF|REDIS_NODE_MASTER);
|
||||||
serverLog(REDIS_NOTICE,"No cluster configuration found, I'm %.40s",
|
serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s",
|
||||||
myself->name);
|
myself->name);
|
||||||
clusterAddNode(myself);
|
clusterAddNode(myself);
|
||||||
saveconf = 1;
|
saveconf = 1;
|
||||||
@ -443,7 +443,7 @@ void clusterInit(void) {
|
|||||||
* The other handshake port check is triggered too late to stop
|
* The other handshake port check is triggered too late to stop
|
||||||
* us from trying to use a too-high cluster port number. */
|
* us from trying to use a too-high cluster port number. */
|
||||||
if (server.port > (65535-REDIS_CLUSTER_PORT_INCR)) {
|
if (server.port > (65535-REDIS_CLUSTER_PORT_INCR)) {
|
||||||
serverLog(REDIS_WARNING, "Redis port number too high. "
|
serverLog(LL_WARNING, "Redis port number too high. "
|
||||||
"Cluster communication port is 10,000 port "
|
"Cluster communication port is 10,000 port "
|
||||||
"numbers higher than your Redis port. "
|
"numbers higher than your Redis port. "
|
||||||
"Your Redis port number must be "
|
"Your Redis port number must be "
|
||||||
@ -461,7 +461,7 @@ void clusterInit(void) {
|
|||||||
for (j = 0; j < server.cfd_count; j++) {
|
for (j = 0; j < server.cfd_count; j++) {
|
||||||
if (aeCreateFileEvent(server.el, server.cfd[j], AE_READABLE,
|
if (aeCreateFileEvent(server.el, server.cfd[j], AE_READABLE,
|
||||||
clusterAcceptHandler, NULL) == AE_ERR)
|
clusterAcceptHandler, NULL) == AE_ERR)
|
||||||
redisPanic("Unrecoverable error creating Redis Cluster "
|
serverPanic("Unrecoverable error creating Redis Cluster "
|
||||||
"file event.");
|
"file event.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -522,7 +522,7 @@ void clusterReset(int hard) {
|
|||||||
server.cluster->currentEpoch = 0;
|
server.cluster->currentEpoch = 0;
|
||||||
server.cluster->lastVoteEpoch = 0;
|
server.cluster->lastVoteEpoch = 0;
|
||||||
myself->configEpoch = 0;
|
myself->configEpoch = 0;
|
||||||
serverLog(REDIS_WARNING, "configEpoch set to 0 via CLUSTER RESET HARD");
|
serverLog(LL_WARNING, "configEpoch set to 0 via CLUSTER RESET HARD");
|
||||||
|
|
||||||
/* To change the Node ID we need to remove the old name from the
|
/* To change the Node ID we need to remove the old name from the
|
||||||
* nodes table, change the ID, and re-add back with new name. */
|
* nodes table, change the ID, and re-add back with new name. */
|
||||||
@ -573,11 +573,11 @@ void freeClusterLink(clusterLink *link) {
|
|||||||
void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
int cport, cfd;
|
int cport, cfd;
|
||||||
int max = MAX_CLUSTER_ACCEPTS_PER_CALL;
|
int max = MAX_CLUSTER_ACCEPTS_PER_CALL;
|
||||||
char cip[REDIS_IP_STR_LEN];
|
char cip[NET_IP_STR_LEN];
|
||||||
clusterLink *link;
|
clusterLink *link;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
REDIS_NOTUSED(privdata);
|
UNUSED(privdata);
|
||||||
|
|
||||||
/* If the server is starting up, don't accept cluster connections:
|
/* If the server is starting up, don't accept cluster connections:
|
||||||
* UPDATE messages may interact with the database content. */
|
* UPDATE messages may interact with the database content. */
|
||||||
@ -587,7 +587,7 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
|
cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
|
||||||
if (cfd == ANET_ERR) {
|
if (cfd == ANET_ERR) {
|
||||||
if (errno != EWOULDBLOCK)
|
if (errno != EWOULDBLOCK)
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"Error accepting cluster node: %s", server.neterr);
|
"Error accepting cluster node: %s", server.neterr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -595,7 +595,7 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
anetEnableTcpNoDelay(NULL,cfd);
|
anetEnableTcpNoDelay(NULL,cfd);
|
||||||
|
|
||||||
/* Use non-blocking I/O for cluster messages. */
|
/* Use non-blocking I/O for cluster messages. */
|
||||||
serverLog(REDIS_VERBOSE,"Accepted cluster node %s:%d", cip, cport);
|
serverLog(LL_VERBOSE,"Accepted cluster node %s:%d", cip, cport);
|
||||||
/* Create a link object we use to handle the connection.
|
/* Create a link object we use to handle the connection.
|
||||||
* It gets passed to the readable handler when data is available.
|
* It gets passed to the readable handler when data is available.
|
||||||
* Initiallly the link->node pointer is set to NULL as we don't know
|
* Initiallly the link->node pointer is set to NULL as we don't know
|
||||||
@ -911,7 +911,7 @@ void clusterRenameNode(clusterNode *node, char *newname) {
|
|||||||
int retval;
|
int retval;
|
||||||
sds s = sdsnewlen(node->name, REDIS_CLUSTER_NAMELEN);
|
sds s = sdsnewlen(node->name, REDIS_CLUSTER_NAMELEN);
|
||||||
|
|
||||||
serverLog(REDIS_DEBUG,"Renaming node %.40s into %.40s",
|
serverLog(LL_DEBUG,"Renaming node %.40s into %.40s",
|
||||||
node->name, newname);
|
node->name, newname);
|
||||||
retval = dictDelete(server.cluster->nodes, s);
|
retval = dictDelete(server.cluster->nodes, s);
|
||||||
sdsfree(s);
|
sdsfree(s);
|
||||||
@ -980,7 +980,7 @@ int clusterBumpConfigEpochWithoutConsensus(void) {
|
|||||||
myself->configEpoch = server.cluster->currentEpoch;
|
myself->configEpoch = server.cluster->currentEpoch;
|
||||||
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|
|
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|
|
||||||
CLUSTER_TODO_FSYNC_CONFIG);
|
CLUSTER_TODO_FSYNC_CONFIG);
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"New configEpoch set to %llu",
|
"New configEpoch set to %llu",
|
||||||
(unsigned long long) myself->configEpoch);
|
(unsigned long long) myself->configEpoch);
|
||||||
return C_OK;
|
return C_OK;
|
||||||
@ -1045,7 +1045,7 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) {
|
|||||||
server.cluster->currentEpoch++;
|
server.cluster->currentEpoch++;
|
||||||
myself->configEpoch = server.cluster->currentEpoch;
|
myself->configEpoch = server.cluster->currentEpoch;
|
||||||
clusterSaveConfigOrDie(1);
|
clusterSaveConfigOrDie(1);
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"WARNING: configEpoch collision with node %.40s."
|
"WARNING: configEpoch collision with node %.40s."
|
||||||
" configEpoch set to %llu",
|
" configEpoch set to %llu",
|
||||||
sender->name,
|
sender->name,
|
||||||
@ -1163,7 +1163,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) {
|
|||||||
if (nodeIsMaster(myself)) failures++;
|
if (nodeIsMaster(myself)) failures++;
|
||||||
if (failures < needed_quorum) return; /* No weak agreement from masters. */
|
if (failures < needed_quorum) return; /* No weak agreement from masters. */
|
||||||
|
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Marking node %.40s as failing (quorum reached).", node->name);
|
"Marking node %.40s as failing (quorum reached).", node->name);
|
||||||
|
|
||||||
/* Mark the node as failing. */
|
/* Mark the node as failing. */
|
||||||
@ -1188,7 +1188,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) {
|
|||||||
/* For slaves we always clear the FAIL flag if we can contact the
|
/* For slaves we always clear the FAIL flag if we can contact the
|
||||||
* node again. */
|
* node again. */
|
||||||
if (nodeIsSlave(node) || node->numslots == 0) {
|
if (nodeIsSlave(node) || node->numslots == 0) {
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Clear FAIL state for node %.40s: %s is reachable again.",
|
"Clear FAIL state for node %.40s: %s is reachable again.",
|
||||||
node->name,
|
node->name,
|
||||||
nodeIsSlave(node) ? "slave" : "master without slots");
|
nodeIsSlave(node) ? "slave" : "master without slots");
|
||||||
@ -1204,7 +1204,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) {
|
|||||||
(now - node->fail_time) >
|
(now - node->fail_time) >
|
||||||
(server.cluster_node_timeout * REDIS_CLUSTER_FAIL_UNDO_TIME_MULT))
|
(server.cluster_node_timeout * REDIS_CLUSTER_FAIL_UNDO_TIME_MULT))
|
||||||
{
|
{
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.",
|
"Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.",
|
||||||
node->name);
|
node->name);
|
||||||
node->flags &= ~REDIS_NODE_FAIL;
|
node->flags &= ~REDIS_NODE_FAIL;
|
||||||
@ -1239,7 +1239,7 @@ int clusterHandshakeInProgress(char *ip, int port) {
|
|||||||
* EINVAL - IP or port are not valid. */
|
* EINVAL - IP or port are not valid. */
|
||||||
int clusterStartHandshake(char *ip, int port) {
|
int clusterStartHandshake(char *ip, int port) {
|
||||||
clusterNode *n;
|
clusterNode *n;
|
||||||
char norm_ip[REDIS_IP_STR_LEN];
|
char norm_ip[NET_IP_STR_LEN];
|
||||||
struct sockaddr_storage sa;
|
struct sockaddr_storage sa;
|
||||||
|
|
||||||
/* IP sanity check */
|
/* IP sanity check */
|
||||||
@ -1264,15 +1264,15 @@ int clusterStartHandshake(char *ip, int port) {
|
|||||||
|
|
||||||
/* Set norm_ip as the normalized string representation of the node
|
/* Set norm_ip as the normalized string representation of the node
|
||||||
* IP address. */
|
* IP address. */
|
||||||
memset(norm_ip,0,REDIS_IP_STR_LEN);
|
memset(norm_ip,0,NET_IP_STR_LEN);
|
||||||
if (sa.ss_family == AF_INET)
|
if (sa.ss_family == AF_INET)
|
||||||
inet_ntop(AF_INET,
|
inet_ntop(AF_INET,
|
||||||
(void*)&(((struct sockaddr_in *)&sa)->sin_addr),
|
(void*)&(((struct sockaddr_in *)&sa)->sin_addr),
|
||||||
norm_ip,REDIS_IP_STR_LEN);
|
norm_ip,NET_IP_STR_LEN);
|
||||||
else
|
else
|
||||||
inet_ntop(AF_INET6,
|
inet_ntop(AF_INET6,
|
||||||
(void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr),
|
(void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr),
|
||||||
norm_ip,REDIS_IP_STR_LEN);
|
norm_ip,NET_IP_STR_LEN);
|
||||||
|
|
||||||
if (clusterHandshakeInProgress(norm_ip,port)) {
|
if (clusterHandshakeInProgress(norm_ip,port)) {
|
||||||
errno = EAGAIN;
|
errno = EAGAIN;
|
||||||
@ -1304,7 +1304,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) {
|
|||||||
sds ci;
|
sds ci;
|
||||||
|
|
||||||
ci = representRedisNodeFlags(sdsempty(), flags);
|
ci = representRedisNodeFlags(sdsempty(), flags);
|
||||||
serverLog(REDIS_DEBUG,"GOSSIP %.40s %s:%d %s",
|
serverLog(LL_DEBUG,"GOSSIP %.40s %s:%d %s",
|
||||||
g->nodename,
|
g->nodename,
|
||||||
g->ip,
|
g->ip,
|
||||||
ntohs(g->port),
|
ntohs(g->port),
|
||||||
@ -1319,14 +1319,14 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) {
|
|||||||
if (sender && nodeIsMaster(sender) && node != myself) {
|
if (sender && nodeIsMaster(sender) && node != myself) {
|
||||||
if (flags & (REDIS_NODE_FAIL|REDIS_NODE_PFAIL)) {
|
if (flags & (REDIS_NODE_FAIL|REDIS_NODE_PFAIL)) {
|
||||||
if (clusterNodeAddFailureReport(node,sender)) {
|
if (clusterNodeAddFailureReport(node,sender)) {
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"Node %.40s reported node %.40s as not reachable.",
|
"Node %.40s reported node %.40s as not reachable.",
|
||||||
sender->name, node->name);
|
sender->name, node->name);
|
||||||
}
|
}
|
||||||
markNodeAsFailingIfNeeded(node);
|
markNodeAsFailingIfNeeded(node);
|
||||||
} else {
|
} else {
|
||||||
if (clusterNodeDelFailureReport(node,sender)) {
|
if (clusterNodeDelFailureReport(node,sender)) {
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"Node %.40s reported node %.40s is back online.",
|
"Node %.40s reported node %.40s is back online.",
|
||||||
sender->name, node->name);
|
sender->name, node->name);
|
||||||
}
|
}
|
||||||
@ -1365,7 +1365,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) {
|
|||||||
|
|
||||||
/* IP -> string conversion. 'buf' is supposed to at least be 46 bytes. */
|
/* IP -> string conversion. 'buf' is supposed to at least be 46 bytes. */
|
||||||
void nodeIp2String(char *buf, clusterLink *link) {
|
void nodeIp2String(char *buf, clusterLink *link) {
|
||||||
anetPeerToString(link->fd, buf, REDIS_IP_STR_LEN, NULL);
|
anetPeerToString(link->fd, buf, NET_IP_STR_LEN, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the node address to the IP address that can be extracted
|
/* Update the node address to the IP address that can be extracted
|
||||||
@ -1379,7 +1379,7 @@ void nodeIp2String(char *buf, clusterLink *link) {
|
|||||||
* The function returns 0 if the node address is still the same,
|
* The function returns 0 if the node address is still the same,
|
||||||
* otherwise 1 is returned. */
|
* otherwise 1 is returned. */
|
||||||
int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, int port) {
|
int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, int port) {
|
||||||
char ip[REDIS_IP_STR_LEN] = {0};
|
char ip[NET_IP_STR_LEN] = {0};
|
||||||
|
|
||||||
/* We don't proceed if the link is the same as the sender link, as this
|
/* We don't proceed if the link is the same as the sender link, as this
|
||||||
* function is designed to see if the node link is consistent with the
|
* function is designed to see if the node link is consistent with the
|
||||||
@ -1397,7 +1397,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, int port) {
|
|||||||
node->port = port;
|
node->port = port;
|
||||||
if (node->link) freeClusterLink(node->link);
|
if (node->link) freeClusterLink(node->link);
|
||||||
node->flags &= ~REDIS_NODE_NOADDR;
|
node->flags &= ~REDIS_NODE_NOADDR;
|
||||||
serverLog(REDIS_WARNING,"Address updated for node %.40s, now %s:%d",
|
serverLog(LL_WARNING,"Address updated for node %.40s, now %s:%d",
|
||||||
node->name, node->ip, node->port);
|
node->name, node->ip, node->port);
|
||||||
|
|
||||||
/* Check if this is our master and we have to change the
|
/* Check if this is our master and we have to change the
|
||||||
@ -1453,7 +1453,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc
|
|||||||
curmaster = nodeIsMaster(myself) ? myself : myself->slaveof;
|
curmaster = nodeIsMaster(myself) ? myself : myself->slaveof;
|
||||||
|
|
||||||
if (sender == myself) {
|
if (sender == myself) {
|
||||||
serverLog(REDIS_WARNING,"Discarding UPDATE message about myself.");
|
serverLog(LL_WARNING,"Discarding UPDATE message about myself.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1504,7 +1504,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc
|
|||||||
* 2) We are a slave and our master is left without slots. We need
|
* 2) We are a slave and our master is left without slots. We need
|
||||||
* to replicate to the new slots owner. */
|
* to replicate to the new slots owner. */
|
||||||
if (newmaster && curmaster->numslots == 0) {
|
if (newmaster && curmaster->numslots == 0) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Configuration change detected. Reconfiguring myself "
|
"Configuration change detected. Reconfiguring myself "
|
||||||
"as a replica of %.40s", sender->name);
|
"as a replica of %.40s", sender->name);
|
||||||
clusterSetMaster(sender);
|
clusterSetMaster(sender);
|
||||||
@ -1542,7 +1542,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
clusterNode *sender;
|
clusterNode *sender;
|
||||||
|
|
||||||
server.cluster->stats_bus_messages_received++;
|
server.cluster->stats_bus_messages_received++;
|
||||||
serverLog(REDIS_DEBUG,"--- Processing packet of type %d, %lu bytes",
|
serverLog(LL_DEBUG,"--- Processing packet of type %d, %lu bytes",
|
||||||
type, (unsigned long) totlen);
|
type, (unsigned long) totlen);
|
||||||
|
|
||||||
/* Perform sanity checks */
|
/* Perform sanity checks */
|
||||||
@ -1612,7 +1612,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
server.cluster->mf_master_offset == 0)
|
server.cluster->mf_master_offset == 0)
|
||||||
{
|
{
|
||||||
server.cluster->mf_master_offset = sender->repl_offset;
|
server.cluster->mf_master_offset = sender->repl_offset;
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Received replication offset for paused "
|
"Received replication offset for paused "
|
||||||
"master manual failover: %lld",
|
"master manual failover: %lld",
|
||||||
server.cluster->mf_master_offset);
|
server.cluster->mf_master_offset);
|
||||||
@ -1621,7 +1621,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
|
|
||||||
/* Initial processing of PING and MEET requests replying with a PONG. */
|
/* Initial processing of PING and MEET requests replying with a PONG. */
|
||||||
if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_MEET) {
|
if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_MEET) {
|
||||||
serverLog(REDIS_DEBUG,"Ping packet received: %p", (void*)link->node);
|
serverLog(LL_DEBUG,"Ping packet received: %p", (void*)link->node);
|
||||||
|
|
||||||
/* We use incoming MEET messages in order to set the address
|
/* We use incoming MEET messages in order to set the address
|
||||||
* for 'myself', since only other cluster nodes will send us
|
* for 'myself', since only other cluster nodes will send us
|
||||||
@ -1635,13 +1635,13 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
* even with a normal PING packet. If it's wrong it will be fixed
|
* even with a normal PING packet. If it's wrong it will be fixed
|
||||||
* by MEET later. */
|
* by MEET later. */
|
||||||
if (type == CLUSTERMSG_TYPE_MEET || myself->ip[0] == '\0') {
|
if (type == CLUSTERMSG_TYPE_MEET || myself->ip[0] == '\0') {
|
||||||
char ip[REDIS_IP_STR_LEN];
|
char ip[NET_IP_STR_LEN];
|
||||||
|
|
||||||
if (anetSockName(link->fd,ip,sizeof(ip),NULL) != -1 &&
|
if (anetSockName(link->fd,ip,sizeof(ip),NULL) != -1 &&
|
||||||
strcmp(ip,myself->ip))
|
strcmp(ip,myself->ip))
|
||||||
{
|
{
|
||||||
memcpy(myself->ip,ip,REDIS_IP_STR_LEN);
|
memcpy(myself->ip,ip,NET_IP_STR_LEN);
|
||||||
serverLog(REDIS_WARNING,"IP address for this node updated to %s",
|
serverLog(LL_WARNING,"IP address for this node updated to %s",
|
||||||
myself->ip);
|
myself->ip);
|
||||||
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG);
|
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG);
|
||||||
}
|
}
|
||||||
@ -1675,7 +1675,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_PONG ||
|
if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_PONG ||
|
||||||
type == CLUSTERMSG_TYPE_MEET)
|
type == CLUSTERMSG_TYPE_MEET)
|
||||||
{
|
{
|
||||||
serverLog(REDIS_DEBUG,"%s packet received: %p",
|
serverLog(LL_DEBUG,"%s packet received: %p",
|
||||||
type == CLUSTERMSG_TYPE_PING ? "ping" : "pong",
|
type == CLUSTERMSG_TYPE_PING ? "ping" : "pong",
|
||||||
(void*)link->node);
|
(void*)link->node);
|
||||||
if (link->node) {
|
if (link->node) {
|
||||||
@ -1683,7 +1683,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
/* If we already have this node, try to change the
|
/* If we already have this node, try to change the
|
||||||
* IP/port of the node with the new one. */
|
* IP/port of the node with the new one. */
|
||||||
if (sender) {
|
if (sender) {
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"Handshake: we already know node %.40s, "
|
"Handshake: we already know node %.40s, "
|
||||||
"updating the address if needed.", sender->name);
|
"updating the address if needed.", sender->name);
|
||||||
if (nodeUpdateAddressIfNeeded(sender,link,ntohs(hdr->port)))
|
if (nodeUpdateAddressIfNeeded(sender,link,ntohs(hdr->port)))
|
||||||
@ -1700,7 +1700,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
/* First thing to do is replacing the random name with the
|
/* First thing to do is replacing the random name with the
|
||||||
* right node name if this was a handshake stage. */
|
* right node name if this was a handshake stage. */
|
||||||
clusterRenameNode(link->node, hdr->sender);
|
clusterRenameNode(link->node, hdr->sender);
|
||||||
serverLog(REDIS_DEBUG,"Handshake with node %.40s completed.",
|
serverLog(LL_DEBUG,"Handshake with node %.40s completed.",
|
||||||
link->node->name);
|
link->node->name);
|
||||||
link->node->flags &= ~REDIS_NODE_HANDSHAKE;
|
link->node->flags &= ~REDIS_NODE_HANDSHAKE;
|
||||||
link->node->flags |= flags&(REDIS_NODE_MASTER|REDIS_NODE_SLAVE);
|
link->node->flags |= flags&(REDIS_NODE_MASTER|REDIS_NODE_SLAVE);
|
||||||
@ -1711,7 +1711,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
/* If the reply has a non matching node ID we
|
/* If the reply has a non matching node ID we
|
||||||
* disconnect this node and set it as not having an associated
|
* disconnect this node and set it as not having an associated
|
||||||
* address. */
|
* address. */
|
||||||
serverLog(REDIS_DEBUG,"PONG contains mismatching sender ID");
|
serverLog(LL_DEBUG,"PONG contains mismatching sender ID");
|
||||||
link->node->flags |= REDIS_NODE_NOADDR;
|
link->node->flags |= REDIS_NODE_NOADDR;
|
||||||
link->node->ip[0] = '\0';
|
link->node->ip[0] = '\0';
|
||||||
link->node->port = 0;
|
link->node->port = 0;
|
||||||
@ -1842,7 +1842,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
if (server.cluster->slots[j]->configEpoch >
|
if (server.cluster->slots[j]->configEpoch >
|
||||||
senderConfigEpoch)
|
senderConfigEpoch)
|
||||||
{
|
{
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"Node %.40s has old slots configuration, sending "
|
"Node %.40s has old slots configuration, sending "
|
||||||
"an UPDATE message about %.40s",
|
"an UPDATE message about %.40s",
|
||||||
sender->name, server.cluster->slots[j]->name);
|
sender->name, server.cluster->slots[j]->name);
|
||||||
@ -1877,7 +1877,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
if (failing &&
|
if (failing &&
|
||||||
!(failing->flags & (REDIS_NODE_FAIL|REDIS_NODE_MYSELF)))
|
!(failing->flags & (REDIS_NODE_FAIL|REDIS_NODE_MYSELF)))
|
||||||
{
|
{
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"FAIL message received from %.40s about %.40s",
|
"FAIL message received from %.40s about %.40s",
|
||||||
hdr->sender, hdr->data.fail.about.nodename);
|
hdr->sender, hdr->data.fail.about.nodename);
|
||||||
failing->flags |= REDIS_NODE_FAIL;
|
failing->flags |= REDIS_NODE_FAIL;
|
||||||
@ -1887,7 +1887,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
CLUSTER_TODO_UPDATE_STATE);
|
CLUSTER_TODO_UPDATE_STATE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Ignoring FAIL message from unknown node %.40s about %.40s",
|
"Ignoring FAIL message from unknown node %.40s about %.40s",
|
||||||
hdr->sender, hdr->data.fail.about.nodename);
|
hdr->sender, hdr->data.fail.about.nodename);
|
||||||
}
|
}
|
||||||
@ -1937,7 +1937,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
server.cluster->mf_end = mstime() + REDIS_CLUSTER_MF_TIMEOUT;
|
server.cluster->mf_end = mstime() + REDIS_CLUSTER_MF_TIMEOUT;
|
||||||
server.cluster->mf_slave = sender;
|
server.cluster->mf_slave = sender;
|
||||||
pauseClients(mstime()+(REDIS_CLUSTER_MF_TIMEOUT*2));
|
pauseClients(mstime()+(REDIS_CLUSTER_MF_TIMEOUT*2));
|
||||||
serverLog(REDIS_WARNING,"Manual failover requested by slave %.40s.",
|
serverLog(LL_WARNING,"Manual failover requested by slave %.40s.",
|
||||||
sender->name);
|
sender->name);
|
||||||
} else if (type == CLUSTERMSG_TYPE_UPDATE) {
|
} else if (type == CLUSTERMSG_TYPE_UPDATE) {
|
||||||
clusterNode *n; /* The node the update is about. */
|
clusterNode *n; /* The node the update is about. */
|
||||||
@ -1962,7 +1962,7 @@ int clusterProcessPacket(clusterLink *link) {
|
|||||||
clusterUpdateSlotsConfigWith(n,reportedConfigEpoch,
|
clusterUpdateSlotsConfigWith(n,reportedConfigEpoch,
|
||||||
hdr->data.update.nodecfg.slots);
|
hdr->data.update.nodecfg.slots);
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,"Received unknown packet type: %d", type);
|
serverLog(LL_WARNING,"Received unknown packet type: %d", type);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1983,12 +1983,12 @@ void handleLinkIOError(clusterLink *link) {
|
|||||||
void clusterWriteHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
void clusterWriteHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
clusterLink *link = (clusterLink*) privdata;
|
clusterLink *link = (clusterLink*) privdata;
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
|
|
||||||
nwritten = write(fd, link->sndbuf, sdslen(link->sndbuf));
|
nwritten = write(fd, link->sndbuf, sdslen(link->sndbuf));
|
||||||
if (nwritten <= 0) {
|
if (nwritten <= 0) {
|
||||||
serverLog(REDIS_DEBUG,"I/O error writing to node link: %s",
|
serverLog(LL_DEBUG,"I/O error writing to node link: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
handleLinkIOError(link);
|
handleLinkIOError(link);
|
||||||
return;
|
return;
|
||||||
@ -2007,8 +2007,8 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
clusterMsg *hdr;
|
clusterMsg *hdr;
|
||||||
clusterLink *link = (clusterLink*) privdata;
|
clusterLink *link = (clusterLink*) privdata;
|
||||||
unsigned int readlen, rcvbuflen;
|
unsigned int readlen, rcvbuflen;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
|
|
||||||
while(1) { /* Read as long as there is data to read. */
|
while(1) { /* Read as long as there is data to read. */
|
||||||
rcvbuflen = sdslen(link->rcvbuf);
|
rcvbuflen = sdslen(link->rcvbuf);
|
||||||
@ -2025,7 +2025,7 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
if (memcmp(hdr->sig,"RCmb",4) != 0 ||
|
if (memcmp(hdr->sig,"RCmb",4) != 0 ||
|
||||||
ntohl(hdr->totlen) < CLUSTERMSG_MIN_LEN)
|
ntohl(hdr->totlen) < CLUSTERMSG_MIN_LEN)
|
||||||
{
|
{
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Bad message length or signature received "
|
"Bad message length or signature received "
|
||||||
"from Cluster bus.");
|
"from Cluster bus.");
|
||||||
handleLinkIOError(link);
|
handleLinkIOError(link);
|
||||||
@ -2041,7 +2041,7 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
|
|
||||||
if (nread <= 0) {
|
if (nread <= 0) {
|
||||||
/* I/O error... */
|
/* I/O error... */
|
||||||
serverLog(REDIS_DEBUG,"I/O error reading from node link: %s",
|
serverLog(LL_DEBUG,"I/O error reading from node link: %s",
|
||||||
(nread == 0) ? "connection closed" : strerror(errno));
|
(nread == 0) ? "connection closed" : strerror(errno));
|
||||||
handleLinkIOError(link);
|
handleLinkIOError(link);
|
||||||
return;
|
return;
|
||||||
@ -2471,7 +2471,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
|
|||||||
* our currentEpoch was updated as a side effect of receiving this
|
* our currentEpoch was updated as a side effect of receiving this
|
||||||
* request, if the request epoch was greater. */
|
* request, if the request epoch was greater. */
|
||||||
if (requestCurrentEpoch < server.cluster->currentEpoch) {
|
if (requestCurrentEpoch < server.cluster->currentEpoch) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)",
|
"Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)",
|
||||||
node->name,
|
node->name,
|
||||||
(unsigned long long) requestCurrentEpoch,
|
(unsigned long long) requestCurrentEpoch,
|
||||||
@ -2481,7 +2481,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
|
|||||||
|
|
||||||
/* I already voted for this epoch? Return ASAP. */
|
/* I already voted for this epoch? Return ASAP. */
|
||||||
if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) {
|
if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Failover auth denied to %.40s: already voted for epoch %llu",
|
"Failover auth denied to %.40s: already voted for epoch %llu",
|
||||||
node->name,
|
node->name,
|
||||||
(unsigned long long) server.cluster->currentEpoch);
|
(unsigned long long) server.cluster->currentEpoch);
|
||||||
@ -2495,15 +2495,15 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
|
|||||||
(!nodeFailed(master) && !force_ack))
|
(!nodeFailed(master) && !force_ack))
|
||||||
{
|
{
|
||||||
if (nodeIsMaster(node)) {
|
if (nodeIsMaster(node)) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Failover auth denied to %.40s: it is a master node",
|
"Failover auth denied to %.40s: it is a master node",
|
||||||
node->name);
|
node->name);
|
||||||
} else if (master == NULL) {
|
} else if (master == NULL) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Failover auth denied to %.40s: I don't know its master",
|
"Failover auth denied to %.40s: I don't know its master",
|
||||||
node->name);
|
node->name);
|
||||||
} else if (!nodeFailed(master)) {
|
} else if (!nodeFailed(master)) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Failover auth denied to %.40s: its master is up",
|
"Failover auth denied to %.40s: its master is up",
|
||||||
node->name);
|
node->name);
|
||||||
}
|
}
|
||||||
@ -2515,7 +2515,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
|
|||||||
* of the algorithm but makes the base case more linear. */
|
* of the algorithm but makes the base case more linear. */
|
||||||
if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2)
|
if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2)
|
||||||
{
|
{
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Failover auth denied to %.40s: "
|
"Failover auth denied to %.40s: "
|
||||||
"can't vote about this master before %lld milliseconds",
|
"can't vote about this master before %lld milliseconds",
|
||||||
node->name,
|
node->name,
|
||||||
@ -2537,7 +2537,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
|
|||||||
/* If we reached this point we found a slot that in our current slots
|
/* If we reached this point we found a slot that in our current slots
|
||||||
* is served by a master with a greater configEpoch than the one claimed
|
* is served by a master with a greater configEpoch than the one claimed
|
||||||
* by the slave requesting our vote. Refuse to vote for this slave. */
|
* by the slave requesting our vote. Refuse to vote for this slave. */
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Failover auth denied to %.40s: "
|
"Failover auth denied to %.40s: "
|
||||||
"slot %d epoch (%llu) > reqEpoch (%llu)",
|
"slot %d epoch (%llu) > reqEpoch (%llu)",
|
||||||
node->name, j,
|
node->name, j,
|
||||||
@ -2550,7 +2550,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
|
|||||||
clusterSendFailoverAuth(node);
|
clusterSendFailoverAuth(node);
|
||||||
server.cluster->lastVoteEpoch = server.cluster->currentEpoch;
|
server.cluster->lastVoteEpoch = server.cluster->currentEpoch;
|
||||||
node->slaveof->voted_time = mstime();
|
node->slaveof->voted_time = mstime();
|
||||||
serverLog(REDIS_WARNING, "Failover auth granted to %.40s for epoch %llu",
|
serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu",
|
||||||
node->name, (unsigned long long) server.cluster->currentEpoch);
|
node->name, (unsigned long long) server.cluster->currentEpoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2641,7 +2641,7 @@ void clusterLogCantFailover(int reason) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lastlog_time = time(NULL);
|
lastlog_time = time(NULL);
|
||||||
serverLog(REDIS_WARNING,"Currently unable to failover: %s", msg);
|
serverLog(LL_WARNING,"Currently unable to failover: %s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function implements the final part of automatic and manual failovers,
|
/* This function implements the final part of automatic and manual failovers,
|
||||||
@ -2727,7 +2727,7 @@ void clusterHandleSlaveFailover(void) {
|
|||||||
|
|
||||||
/* Set data_age to the number of seconds we are disconnected from
|
/* Set data_age to the number of seconds we are disconnected from
|
||||||
* the master. */
|
* the master. */
|
||||||
if (server.repl_state == REDIS_REPL_CONNECTED) {
|
if (server.repl_state == REPL_STATE_CONNECTED) {
|
||||||
data_age = (mstime_t)(server.unixtime - server.master->lastinteraction)
|
data_age = (mstime_t)(server.unixtime - server.master->lastinteraction)
|
||||||
* 1000;
|
* 1000;
|
||||||
} else {
|
} else {
|
||||||
@ -2774,7 +2774,7 @@ void clusterHandleSlaveFailover(void) {
|
|||||||
server.cluster->failover_auth_time = mstime();
|
server.cluster->failover_auth_time = mstime();
|
||||||
server.cluster->failover_auth_rank = 0;
|
server.cluster->failover_auth_rank = 0;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Start of election delayed for %lld milliseconds "
|
"Start of election delayed for %lld milliseconds "
|
||||||
"(rank #%d, offset %lld).",
|
"(rank #%d, offset %lld).",
|
||||||
server.cluster->failover_auth_time - mstime(),
|
server.cluster->failover_auth_time - mstime(),
|
||||||
@ -2801,7 +2801,7 @@ void clusterHandleSlaveFailover(void) {
|
|||||||
(newrank - server.cluster->failover_auth_rank) * 1000;
|
(newrank - server.cluster->failover_auth_rank) * 1000;
|
||||||
server.cluster->failover_auth_time += added_delay;
|
server.cluster->failover_auth_time += added_delay;
|
||||||
server.cluster->failover_auth_rank = newrank;
|
server.cluster->failover_auth_rank = newrank;
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Slave rank updated to #%d, added %lld milliseconds of delay.",
|
"Slave rank updated to #%d, added %lld milliseconds of delay.",
|
||||||
newrank, added_delay);
|
newrank, added_delay);
|
||||||
}
|
}
|
||||||
@ -2823,7 +2823,7 @@ void clusterHandleSlaveFailover(void) {
|
|||||||
if (server.cluster->failover_auth_sent == 0) {
|
if (server.cluster->failover_auth_sent == 0) {
|
||||||
server.cluster->currentEpoch++;
|
server.cluster->currentEpoch++;
|
||||||
server.cluster->failover_auth_epoch = server.cluster->currentEpoch;
|
server.cluster->failover_auth_epoch = server.cluster->currentEpoch;
|
||||||
serverLog(REDIS_WARNING,"Starting a failover election for epoch %llu.",
|
serverLog(LL_WARNING,"Starting a failover election for epoch %llu.",
|
||||||
(unsigned long long) server.cluster->currentEpoch);
|
(unsigned long long) server.cluster->currentEpoch);
|
||||||
clusterRequestFailoverAuth();
|
clusterRequestFailoverAuth();
|
||||||
server.cluster->failover_auth_sent = 1;
|
server.cluster->failover_auth_sent = 1;
|
||||||
@ -2837,13 +2837,13 @@ void clusterHandleSlaveFailover(void) {
|
|||||||
if (server.cluster->failover_auth_count >= needed_quorum) {
|
if (server.cluster->failover_auth_count >= needed_quorum) {
|
||||||
/* We have the quorum, we can finally failover the master. */
|
/* We have the quorum, we can finally failover the master. */
|
||||||
|
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Failover election won: I'm the new master.");
|
"Failover election won: I'm the new master.");
|
||||||
|
|
||||||
/* Update my configEpoch to the epoch of the election. */
|
/* Update my configEpoch to the epoch of the election. */
|
||||||
if (myself->configEpoch < server.cluster->failover_auth_epoch) {
|
if (myself->configEpoch < server.cluster->failover_auth_epoch) {
|
||||||
myself->configEpoch = server.cluster->failover_auth_epoch;
|
myself->configEpoch = server.cluster->failover_auth_epoch;
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"configEpoch set to %llu after successful failover",
|
"configEpoch set to %llu after successful failover",
|
||||||
(unsigned long long) myself->configEpoch);
|
(unsigned long long) myself->configEpoch);
|
||||||
}
|
}
|
||||||
@ -2941,7 +2941,7 @@ void clusterHandleSlaveMigration(int max_slaves) {
|
|||||||
/* Step 4: perform the migration if there is a target, and if I'm the
|
/* Step 4: perform the migration if there is a target, and if I'm the
|
||||||
* candidate. */
|
* candidate. */
|
||||||
if (target && candidate == myself) {
|
if (target && candidate == myself) {
|
||||||
serverLog(REDIS_WARNING,"Migrating to orphaned master %.40s",
|
serverLog(LL_WARNING,"Migrating to orphaned master %.40s",
|
||||||
target->name);
|
target->name);
|
||||||
clusterSetMaster(target);
|
clusterSetMaster(target);
|
||||||
}
|
}
|
||||||
@ -2995,7 +2995,7 @@ void resetManualFailover(void) {
|
|||||||
/* If a manual failover timed out, abort it. */
|
/* If a manual failover timed out, abort it. */
|
||||||
void manualFailoverCheckTimeout(void) {
|
void manualFailoverCheckTimeout(void) {
|
||||||
if (server.cluster->mf_end && server.cluster->mf_end < mstime()) {
|
if (server.cluster->mf_end && server.cluster->mf_end < mstime()) {
|
||||||
serverLog(REDIS_WARNING,"Manual failover timed out.");
|
serverLog(LL_WARNING,"Manual failover timed out.");
|
||||||
resetManualFailover();
|
resetManualFailover();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3016,7 +3016,7 @@ void clusterHandleManualFailover(void) {
|
|||||||
/* Our replication offset matches the master replication offset
|
/* Our replication offset matches the master replication offset
|
||||||
* announced after clients were paused. We can start the failover. */
|
* announced after clients were paused. We can start the failover. */
|
||||||
server.cluster->mf_can_start = 1;
|
server.cluster->mf_can_start = 1;
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"All master replication stream processed, "
|
"All master replication stream processed, "
|
||||||
"manual failover can start.");
|
"manual failover can start.");
|
||||||
}
|
}
|
||||||
@ -3068,7 +3068,7 @@ void clusterCron(void) {
|
|||||||
clusterLink *link;
|
clusterLink *link;
|
||||||
|
|
||||||
fd = anetTcpNonBlockBindConnect(server.neterr, node->ip,
|
fd = anetTcpNonBlockBindConnect(server.neterr, node->ip,
|
||||||
node->port+REDIS_CLUSTER_PORT_INCR, REDIS_BIND_ADDR);
|
node->port+REDIS_CLUSTER_PORT_INCR, NET_FIRST_BIND_ADDR);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
/* We got a synchronous error from connect before
|
/* We got a synchronous error from connect before
|
||||||
* clusterSendPing() had a chance to be called.
|
* clusterSendPing() had a chance to be called.
|
||||||
@ -3076,7 +3076,7 @@ void clusterCron(void) {
|
|||||||
* so we claim we actually sent a ping now (that will
|
* so we claim we actually sent a ping now (that will
|
||||||
* be really sent as soon as the link is obtained). */
|
* be really sent as soon as the link is obtained). */
|
||||||
if (node->ping_sent == 0) node->ping_sent = mstime();
|
if (node->ping_sent == 0) node->ping_sent = mstime();
|
||||||
serverLog(REDIS_DEBUG, "Unable to connect to "
|
serverLog(LL_DEBUG, "Unable to connect to "
|
||||||
"Cluster Node [%s]:%d -> %s", node->ip,
|
"Cluster Node [%s]:%d -> %s", node->ip,
|
||||||
node->port+REDIS_CLUSTER_PORT_INCR,
|
node->port+REDIS_CLUSTER_PORT_INCR,
|
||||||
server.neterr);
|
server.neterr);
|
||||||
@ -3109,7 +3109,7 @@ void clusterCron(void) {
|
|||||||
* normal PING packets. */
|
* normal PING packets. */
|
||||||
node->flags &= ~REDIS_NODE_MEET;
|
node->flags &= ~REDIS_NODE_MEET;
|
||||||
|
|
||||||
serverLog(REDIS_DEBUG,"Connecting with Node %.40s at %s:%d",
|
serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d",
|
||||||
node->name, node->ip, node->port+REDIS_CLUSTER_PORT_INCR);
|
node->name, node->ip, node->port+REDIS_CLUSTER_PORT_INCR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3136,7 +3136,7 @@ void clusterCron(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (min_pong_node) {
|
if (min_pong_node) {
|
||||||
serverLog(REDIS_DEBUG,"Pinging node %.40s", min_pong_node->name);
|
serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name);
|
||||||
clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING);
|
clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3225,7 +3225,7 @@ void clusterCron(void) {
|
|||||||
/* Timeout reached. Set the node as possibly failing if it is
|
/* Timeout reached. Set the node as possibly failing if it is
|
||||||
* not already in this state. */
|
* not already in this state. */
|
||||||
if (!(node->flags & (REDIS_NODE_PFAIL|REDIS_NODE_FAIL))) {
|
if (!(node->flags & (REDIS_NODE_PFAIL|REDIS_NODE_FAIL))) {
|
||||||
serverLog(REDIS_DEBUG,"*** NODE %.40s possibly failing",
|
serverLog(LL_DEBUG,"*** NODE %.40s possibly failing",
|
||||||
node->name);
|
node->name);
|
||||||
node->flags |= REDIS_NODE_PFAIL;
|
node->flags |= REDIS_NODE_PFAIL;
|
||||||
update_state = 1;
|
update_state = 1;
|
||||||
@ -3488,7 +3488,7 @@ void clusterUpdateState(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Change the state and log the event. */
|
/* Change the state and log the event. */
|
||||||
serverLog(REDIS_WARNING,"Cluster state changed: %s",
|
serverLog(LL_WARNING,"Cluster state changed: %s",
|
||||||
new_state == REDIS_CLUSTER_OK ? "ok" : "fail");
|
new_state == REDIS_CLUSTER_OK ? "ok" : "fail");
|
||||||
server.cluster->state = new_state;
|
server.cluster->state = new_state;
|
||||||
}
|
}
|
||||||
@ -3546,11 +3546,11 @@ int verifyClusterConfigWithData(void) {
|
|||||||
update_config++;
|
update_config++;
|
||||||
/* Case A: slot is unassigned. Take responsibility for it. */
|
/* Case A: slot is unassigned. Take responsibility for it. */
|
||||||
if (server.cluster->slots[j] == NULL) {
|
if (server.cluster->slots[j] == NULL) {
|
||||||
serverLog(REDIS_WARNING, "I have keys for unassigned slot %d. "
|
serverLog(LL_WARNING, "I have keys for unassigned slot %d. "
|
||||||
"Taking responsibility for it.",j);
|
"Taking responsibility for it.",j);
|
||||||
clusterAddSlot(myself,j);
|
clusterAddSlot(myself,j);
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING, "I have keys for slot %d, but the slot is "
|
serverLog(LL_WARNING, "I have keys for slot %d, but the slot is "
|
||||||
"assigned to another node. "
|
"assigned to another node. "
|
||||||
"Setting it to importing state.",j);
|
"Setting it to importing state.",j);
|
||||||
server.cluster->importing_slots_from[j] = server.cluster->slots[j];
|
server.cluster->importing_slots_from[j] = server.cluster->slots[j];
|
||||||
@ -3978,7 +3978,7 @@ void clusterCommand(client *c) {
|
|||||||
* configEpoch collision resolution will fix it assigning
|
* configEpoch collision resolution will fix it assigning
|
||||||
* a different epoch to each node. */
|
* a different epoch to each node. */
|
||||||
if (clusterBumpConfigEpochWithoutConsensus() == C_OK) {
|
if (clusterBumpConfigEpochWithoutConsensus() == C_OK) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"configEpoch updated after importing slot %d", slot);
|
"configEpoch updated after importing slot %d", slot);
|
||||||
}
|
}
|
||||||
server.cluster->importing_slots_from[slot] = NULL;
|
server.cluster->importing_slots_from[slot] = NULL;
|
||||||
@ -4220,17 +4220,17 @@ void clusterCommand(client *c) {
|
|||||||
* generates a new configuration epoch for this node without
|
* generates a new configuration epoch for this node without
|
||||||
* consensus, claims the master's slots, and broadcast the new
|
* consensus, claims the master's slots, and broadcast the new
|
||||||
* configuration. */
|
* configuration. */
|
||||||
serverLog(REDIS_WARNING,"Taking over the master (user request).");
|
serverLog(LL_WARNING,"Taking over the master (user request).");
|
||||||
clusterBumpConfigEpochWithoutConsensus();
|
clusterBumpConfigEpochWithoutConsensus();
|
||||||
clusterFailoverReplaceYourMaster();
|
clusterFailoverReplaceYourMaster();
|
||||||
} else if (force) {
|
} else if (force) {
|
||||||
/* If this is a forced failover, we don't need to talk with our
|
/* If this is a forced failover, we don't need to talk with our
|
||||||
* master to agree about the offset. We just failover taking over
|
* master to agree about the offset. We just failover taking over
|
||||||
* it without coordination. */
|
* it without coordination. */
|
||||||
serverLog(REDIS_WARNING,"Forced failover user request accepted.");
|
serverLog(LL_WARNING,"Forced failover user request accepted.");
|
||||||
server.cluster->mf_can_start = 1;
|
server.cluster->mf_can_start = 1;
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,"Manual failover user request accepted.");
|
serverLog(LL_WARNING,"Manual failover user request accepted.");
|
||||||
clusterSendMFStart(myself->slaveof);
|
clusterSendMFStart(myself->slaveof);
|
||||||
}
|
}
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
@ -4257,7 +4257,7 @@ void clusterCommand(client *c) {
|
|||||||
addReplyError(c,"Node config epoch is already non-zero");
|
addReplyError(c,"Node config epoch is already non-zero");
|
||||||
} else {
|
} else {
|
||||||
myself->configEpoch = epoch;
|
myself->configEpoch = epoch;
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"configEpoch set to %llu via CLUSTER SET-CONFIG-EPOCH",
|
"configEpoch set to %llu via CLUSTER SET-CONFIG-EPOCH",
|
||||||
(unsigned long long) myself->configEpoch);
|
(unsigned long long) myself->configEpoch);
|
||||||
|
|
||||||
@ -4326,8 +4326,8 @@ void createDumpPayload(rio *payload, robj *o) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* RDB version */
|
/* RDB version */
|
||||||
buf[0] = REDIS_RDB_VERSION & 0xff;
|
buf[0] = RDB_VERSION & 0xff;
|
||||||
buf[1] = (REDIS_RDB_VERSION >> 8) & 0xff;
|
buf[1] = (RDB_VERSION >> 8) & 0xff;
|
||||||
payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,buf,2);
|
payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,buf,2);
|
||||||
|
|
||||||
/* CRC64 */
|
/* CRC64 */
|
||||||
@ -4352,7 +4352,7 @@ int verifyDumpPayload(unsigned char *p, size_t len) {
|
|||||||
|
|
||||||
/* Verify RDB version */
|
/* Verify RDB version */
|
||||||
rdbver = (footer[1] << 8) | footer[0];
|
rdbver = (footer[1] << 8) | footer[0];
|
||||||
if (rdbver != REDIS_RDB_VERSION) return C_ERR;
|
if (rdbver != RDB_VERSION) return C_ERR;
|
||||||
|
|
||||||
/* Verify CRC64 */
|
/* Verify CRC64 */
|
||||||
crc = crc64(0,p,len-8);
|
crc = crc64(0,p,len-8);
|
||||||
@ -4728,7 +4728,7 @@ void askingCommand(client *c) {
|
|||||||
addReplyError(c,"This instance has cluster support disabled");
|
addReplyError(c,"This instance has cluster support disabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c->flags |= REDIS_ASKING;
|
c->flags |= CLIENT_ASKING;
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4740,13 +4740,13 @@ void readonlyCommand(client *c) {
|
|||||||
addReplyError(c,"This instance has cluster support disabled");
|
addReplyError(c,"This instance has cluster support disabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c->flags |= REDIS_READONLY;
|
c->flags |= CLIENT_READONLY;
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The READWRITE command just clears the READONLY command state. */
|
/* The READWRITE command just clears the READONLY command state. */
|
||||||
void readwriteCommand(client *c) {
|
void readwriteCommand(client *c) {
|
||||||
c->flags &= ~REDIS_READONLY;
|
c->flags &= ~CLIENT_READONLY;
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4793,9 +4793,9 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
|
|||||||
/* We handle all the cases as if they were EXEC commands, so we have
|
/* We handle all the cases as if they were EXEC commands, so we have
|
||||||
* a common code path for everything */
|
* a common code path for everything */
|
||||||
if (cmd->proc == execCommand) {
|
if (cmd->proc == execCommand) {
|
||||||
/* If REDIS_MULTI flag is not set EXEC is just going to return an
|
/* If CLIENT_MULTI flag is not set EXEC is just going to return an
|
||||||
* error. */
|
* error. */
|
||||||
if (!(c->flags & REDIS_MULTI)) return myself;
|
if (!(c->flags & CLIENT_MULTI)) return myself;
|
||||||
ms = &c->mstate;
|
ms = &c->mstate;
|
||||||
} else {
|
} else {
|
||||||
/* In order to have a single codepath create a fake Multi State
|
/* In order to have a single codepath create a fake Multi State
|
||||||
@ -4906,7 +4906,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
|
|||||||
* involves multiple keys and we don't have them all, the only option is
|
* involves multiple keys and we don't have them all, the only option is
|
||||||
* to send a TRYAGAIN error. */
|
* to send a TRYAGAIN error. */
|
||||||
if (importing_slot &&
|
if (importing_slot &&
|
||||||
(c->flags & REDIS_ASKING || cmd->flags & REDIS_CMD_ASKING))
|
(c->flags & CLIENT_ASKING || cmd->flags & CMD_ASKING))
|
||||||
{
|
{
|
||||||
if (multiple_keys && missing_keys) {
|
if (multiple_keys && missing_keys) {
|
||||||
if (error_code) *error_code = REDIS_CLUSTER_REDIR_UNSTABLE;
|
if (error_code) *error_code = REDIS_CLUSTER_REDIR_UNSTABLE;
|
||||||
@ -4919,8 +4919,8 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
|
|||||||
/* Handle the read-only client case reading from a slave: if this
|
/* Handle the read-only client case reading from a slave: if this
|
||||||
* node is a slave and the request is about an hash slot our master
|
* node is a slave and the request is about an hash slot our master
|
||||||
* is serving, we can reply without redirection. */
|
* is serving, we can reply without redirection. */
|
||||||
if (c->flags & REDIS_READONLY &&
|
if (c->flags & CLIENT_READONLY &&
|
||||||
cmd->flags & REDIS_CMD_READONLY &&
|
cmd->flags & CMD_READONLY &&
|
||||||
nodeIsSlave(myself) &&
|
nodeIsSlave(myself) &&
|
||||||
myself->slaveof == n)
|
myself->slaveof == n)
|
||||||
{
|
{
|
||||||
@ -4960,7 +4960,7 @@ void clusterRedirectClient(client *c, clusterNode *n, int hashslot, int error_co
|
|||||||
(error_code == REDIS_CLUSTER_REDIR_ASK) ? "ASK" : "MOVED",
|
(error_code == REDIS_CLUSTER_REDIR_ASK) ? "ASK" : "MOVED",
|
||||||
hashslot,n->ip,n->port));
|
hashslot,n->ip,n->port));
|
||||||
} else {
|
} else {
|
||||||
redisPanic("getNodeByQuery() unknown error.");
|
serverPanic("getNodeByQuery() unknown error.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4976,7 +4976,7 @@ void clusterRedirectClient(client *c, clusterNode *n, int hashslot, int error_co
|
|||||||
* longer handles, the client is sent a redirection error, and the function
|
* longer handles, the client is sent a redirection error, and the function
|
||||||
* returns 1. Otherwise 0 is returned and no operation is performed. */
|
* returns 1. Otherwise 0 is returned and no operation is performed. */
|
||||||
int clusterRedirectBlockedClientIfNeeded(client *c) {
|
int clusterRedirectBlockedClientIfNeeded(client *c) {
|
||||||
if (c->flags & REDIS_BLOCKED && c->btype == REDIS_BLOCKED_LIST) {
|
if (c->flags & CLIENT_BLOCKED && c->btype == BLOCKED_LIST) {
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
dictIterator *di;
|
dictIterator *di;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ typedef struct clusterNode {
|
|||||||
mstime_t voted_time; /* Last time we voted for a slave of this master */
|
mstime_t voted_time; /* Last time we voted for a slave of this master */
|
||||||
mstime_t repl_offset_time; /* Unix time we received offset for this node */
|
mstime_t repl_offset_time; /* Unix time we received offset for this node */
|
||||||
long long repl_offset; /* Last known repl offset for this node. */
|
long long repl_offset; /* Last known repl offset for this node. */
|
||||||
char ip[REDIS_IP_STR_LEN]; /* Latest known IP address of this node */
|
char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */
|
||||||
int port; /* Latest known port of this node */
|
int port; /* Latest known port of this node */
|
||||||
clusterLink *link; /* TCP/IP link with this node */
|
clusterLink *link; /* TCP/IP link with this node */
|
||||||
list *fail_reports; /* List of nodes signaling this as failing */
|
list *fail_reports; /* List of nodes signaling this as failing */
|
||||||
@ -165,7 +165,7 @@ typedef struct {
|
|||||||
char nodename[REDIS_CLUSTER_NAMELEN];
|
char nodename[REDIS_CLUSTER_NAMELEN];
|
||||||
uint32_t ping_sent;
|
uint32_t ping_sent;
|
||||||
uint32_t pong_received;
|
uint32_t pong_received;
|
||||||
char ip[REDIS_IP_STR_LEN]; /* IP address last time it was seen */
|
char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */
|
||||||
uint16_t port; /* port last time it was seen */
|
uint16_t port; /* port last time it was seen */
|
||||||
uint16_t flags; /* node->flags copy */
|
uint16_t flags; /* node->flags copy */
|
||||||
uint16_t notused1; /* Some room for future improvements. */
|
uint16_t notused1; /* Some room for future improvements. */
|
||||||
|
110
src/config.c
110
src/config.c
@ -44,12 +44,12 @@ typedef struct configEnum {
|
|||||||
} configEnum;
|
} configEnum;
|
||||||
|
|
||||||
configEnum maxmemory_policy_enum[] = {
|
configEnum maxmemory_policy_enum[] = {
|
||||||
{"volatile-lru", REDIS_MAXMEMORY_VOLATILE_LRU},
|
{"volatile-lru", MAXMEMORY_VOLATILE_LRU},
|
||||||
{"volatile-random",REDIS_MAXMEMORY_VOLATILE_RANDOM},
|
{"volatile-random",MAXMEMORY_VOLATILE_RANDOM},
|
||||||
{"volatile-ttl",REDIS_MAXMEMORY_VOLATILE_TTL},
|
{"volatile-ttl",MAXMEMORY_VOLATILE_TTL},
|
||||||
{"allkeys-lru",REDIS_MAXMEMORY_ALLKEYS_LRU},
|
{"allkeys-lru",MAXMEMORY_ALLKEYS_LRU},
|
||||||
{"allkeys-random",REDIS_MAXMEMORY_ALLKEYS_RANDOM},
|
{"allkeys-random",MAXMEMORY_ALLKEYS_RANDOM},
|
||||||
{"noeviction",REDIS_MAXMEMORY_NO_EVICTION},
|
{"noeviction",MAXMEMORY_NO_EVICTION},
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,18 +67,18 @@ configEnum syslog_facility_enum[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
configEnum loglevel_enum[] = {
|
configEnum loglevel_enum[] = {
|
||||||
{"debug", REDIS_DEBUG},
|
{"debug", LL_DEBUG},
|
||||||
{"verbose", REDIS_VERBOSE},
|
{"verbose", LL_VERBOSE},
|
||||||
{"notice", REDIS_NOTICE},
|
{"notice", LL_NOTICE},
|
||||||
{"warning", REDIS_WARNING},
|
{"warning", LL_WARNING},
|
||||||
{NULL,0}
|
{NULL,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
configEnum supervised_mode_enum[] = {
|
configEnum supervised_mode_enum[] = {
|
||||||
{"upstart", REDIS_SUPERVISED_UPSTART},
|
{"upstart", SUPERVISED_UPSTART},
|
||||||
{"systemd", REDIS_SUPERVISED_SYSTEMD},
|
{"systemd", SUPERVISED_SYSTEMD},
|
||||||
{"auto", REDIS_SUPERVISED_AUTODETECT},
|
{"auto", SUPERVISED_AUTODETECT},
|
||||||
{"no", REDIS_SUPERVISED_NONE},
|
{"no", SUPERVISED_NONE},
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ configEnum aof_fsync_enum[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Output buffer limits presets. */
|
/* Output buffer limits presets. */
|
||||||
clientBufferLimitsConfig clientBufferLimitsDefaults[REDIS_CLIENT_TYPE_COUNT] = {
|
clientBufferLimitsConfig clientBufferLimitsDefaults[CLIENT_TYPE_COUNT] = {
|
||||||
{0, 0, 0}, /* normal */
|
{0, 0, 0}, /* normal */
|
||||||
{1024*1024*256, 1024*1024*64, 60}, /* slave */
|
{1024*1024*256, 1024*1024*64, 60}, /* slave */
|
||||||
{1024*1024*32, 1024*1024*8, 60} /* pubsub */
|
{1024*1024*32, 1024*1024*8, 60} /* pubsub */
|
||||||
@ -209,7 +209,7 @@ void loadServerConfigFromString(char *config) {
|
|||||||
} else if (!strcasecmp(argv[0],"bind") && argc >= 2) {
|
} else if (!strcasecmp(argv[0],"bind") && argc >= 2) {
|
||||||
int j, addresses = argc-1;
|
int j, addresses = argc-1;
|
||||||
|
|
||||||
if (addresses > REDIS_BINDADDR_MAX) {
|
if (addresses > CONFIG_BINDADDR_MAX) {
|
||||||
err = "Too many bind addresses specified"; goto loaderr;
|
err = "Too many bind addresses specified"; goto loaderr;
|
||||||
}
|
}
|
||||||
for (j = 0; j < addresses; j++)
|
for (j = 0; j < addresses; j++)
|
||||||
@ -236,7 +236,7 @@ void loadServerConfigFromString(char *config) {
|
|||||||
}
|
}
|
||||||
} else if (!strcasecmp(argv[0],"dir") && argc == 2) {
|
} else if (!strcasecmp(argv[0],"dir") && argc == 2) {
|
||||||
if (chdir(argv[1]) == -1) {
|
if (chdir(argv[1]) == -1) {
|
||||||
serverLog(REDIS_WARNING,"Can't chdir to '%s': %s",
|
serverLog(LL_WARNING,"Can't chdir to '%s': %s",
|
||||||
argv[1], strerror(errno));
|
argv[1], strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ void loadServerConfigFromString(char *config) {
|
|||||||
slaveof_linenum = linenum;
|
slaveof_linenum = linenum;
|
||||||
server.masterhost = sdsnew(argv[1]);
|
server.masterhost = sdsnew(argv[1]);
|
||||||
server.masterport = atoi(argv[2]);
|
server.masterport = atoi(argv[2]);
|
||||||
server.repl_state = REDIS_REPL_CONNECT;
|
server.repl_state = REPL_STATE_CONNECT;
|
||||||
} else if (!strcasecmp(argv[0],"repl-ping-slave-period") && argc == 2) {
|
} else if (!strcasecmp(argv[0],"repl-ping-slave-period") && argc == 2) {
|
||||||
server.repl_ping_slave_period = atoi(argv[1]);
|
server.repl_ping_slave_period = atoi(argv[1]);
|
||||||
if (server.repl_ping_slave_period <= 0) {
|
if (server.repl_ping_slave_period <= 0) {
|
||||||
@ -376,15 +376,15 @@ void loadServerConfigFromString(char *config) {
|
|||||||
}
|
}
|
||||||
} else if (!strcasecmp(argv[0],"hz") && argc == 2) {
|
} else if (!strcasecmp(argv[0],"hz") && argc == 2) {
|
||||||
server.hz = atoi(argv[1]);
|
server.hz = atoi(argv[1]);
|
||||||
if (server.hz < REDIS_MIN_HZ) server.hz = REDIS_MIN_HZ;
|
if (server.hz < CONFIG_MIN_HZ) server.hz = CONFIG_MIN_HZ;
|
||||||
if (server.hz > REDIS_MAX_HZ) server.hz = REDIS_MAX_HZ;
|
if (server.hz > CONFIG_MAX_HZ) server.hz = CONFIG_MAX_HZ;
|
||||||
} else if (!strcasecmp(argv[0],"appendonly") && argc == 2) {
|
} else if (!strcasecmp(argv[0],"appendonly") && argc == 2) {
|
||||||
int yes;
|
int yes;
|
||||||
|
|
||||||
if ((yes = yesnotoi(argv[1])) == -1) {
|
if ((yes = yesnotoi(argv[1])) == -1) {
|
||||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||||
}
|
}
|
||||||
server.aof_state = yes ? REDIS_AOF_ON : REDIS_AOF_OFF;
|
server.aof_state = yes ? AOF_ON : AOF_OFF;
|
||||||
} else if (!strcasecmp(argv[0],"appendfilename") && argc == 2) {
|
} else if (!strcasecmp(argv[0],"appendfilename") && argc == 2) {
|
||||||
if (!pathIsBaseName(argv[1])) {
|
if (!pathIsBaseName(argv[1])) {
|
||||||
err = "appendfilename can't be a path, just a filename";
|
err = "appendfilename can't be a path, just a filename";
|
||||||
@ -427,8 +427,8 @@ void loadServerConfigFromString(char *config) {
|
|||||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
|
} else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
|
||||||
if (strlen(argv[1]) > REDIS_AUTHPASS_MAX_LEN) {
|
if (strlen(argv[1]) > CONFIG_AUTHPASS_MAX_LEN) {
|
||||||
err = "Password is longer than REDIS_AUTHPASS_MAX_LEN";
|
err = "Password is longer than CONFIG_AUTHPASS_MAX_LEN";
|
||||||
goto loaderr;
|
goto loaderr;
|
||||||
}
|
}
|
||||||
server.requirepass = zstrdup(argv[1]);
|
server.requirepass = zstrdup(argv[1]);
|
||||||
@ -637,7 +637,7 @@ loaderr:
|
|||||||
* just load a string. */
|
* just load a string. */
|
||||||
void loadServerConfig(char *filename, char *options) {
|
void loadServerConfig(char *filename, char *options) {
|
||||||
sds config = sdsempty();
|
sds config = sdsempty();
|
||||||
char buf[REDIS_CONFIGLINE_MAX+1];
|
char buf[CONFIG_MAX_LINE+1];
|
||||||
|
|
||||||
/* Load the file content */
|
/* Load the file content */
|
||||||
if (filename) {
|
if (filename) {
|
||||||
@ -647,12 +647,12 @@ void loadServerConfig(char *filename, char *options) {
|
|||||||
fp = stdin;
|
fp = stdin;
|
||||||
} else {
|
} else {
|
||||||
if ((fp = fopen(filename,"r")) == NULL) {
|
if ((fp = fopen(filename,"r")) == NULL) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Fatal error, can't open config file '%s'", filename);
|
"Fatal error, can't open config file '%s'", filename);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL)
|
while(fgets(buf,CONFIG_MAX_LINE+1,fp) != NULL)
|
||||||
config = sdscat(config,buf);
|
config = sdscat(config,buf);
|
||||||
if (fp != stdin) fclose(fp);
|
if (fp != stdin) fclose(fp);
|
||||||
}
|
}
|
||||||
@ -718,7 +718,7 @@ void configSetCommand(client *c) {
|
|||||||
zfree(server.rdb_filename);
|
zfree(server.rdb_filename);
|
||||||
server.rdb_filename = zstrdup(o->ptr);
|
server.rdb_filename = zstrdup(o->ptr);
|
||||||
} config_set_special_field("requirepass") {
|
} config_set_special_field("requirepass") {
|
||||||
if (sdslen(o->ptr) > REDIS_AUTHPASS_MAX_LEN) goto badfmt;
|
if (sdslen(o->ptr) > CONFIG_AUTHPASS_MAX_LEN) goto badfmt;
|
||||||
zfree(server.requirepass);
|
zfree(server.requirepass);
|
||||||
server.requirepass = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL;
|
server.requirepass = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL;
|
||||||
} config_set_special_field("masterauth") {
|
} config_set_special_field("masterauth") {
|
||||||
@ -739,10 +739,10 @@ void configSetCommand(client *c) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((unsigned int) aeGetSetSize(server.el) <
|
if ((unsigned int) aeGetSetSize(server.el) <
|
||||||
server.maxclients + REDIS_EVENTLOOP_FDSET_INCR)
|
server.maxclients + CONFIG_FDSET_INCR)
|
||||||
{
|
{
|
||||||
if (aeResizeSetSize(server.el,
|
if (aeResizeSetSize(server.el,
|
||||||
server.maxclients + REDIS_EVENTLOOP_FDSET_INCR) == AE_ERR)
|
server.maxclients + CONFIG_FDSET_INCR) == AE_ERR)
|
||||||
{
|
{
|
||||||
addReplyError(c,"The event loop API used by Redis is not able to handle the specified number of clients");
|
addReplyError(c,"The event loop API used by Redis is not able to handle the specified number of clients");
|
||||||
server.maxclients = orig_value;
|
server.maxclients = orig_value;
|
||||||
@ -754,9 +754,9 @@ void configSetCommand(client *c) {
|
|||||||
int enable = yesnotoi(o->ptr);
|
int enable = yesnotoi(o->ptr);
|
||||||
|
|
||||||
if (enable == -1) goto badfmt;
|
if (enable == -1) goto badfmt;
|
||||||
if (enable == 0 && server.aof_state != REDIS_AOF_OFF) {
|
if (enable == 0 && server.aof_state != AOF_OFF) {
|
||||||
stopAppendOnly();
|
stopAppendOnly();
|
||||||
} else if (enable && server.aof_state == REDIS_AOF_OFF) {
|
} else if (enable && server.aof_state == AOF_OFF) {
|
||||||
if (startAppendOnly() == C_ERR) {
|
if (startAppendOnly() == C_ERR) {
|
||||||
addReplyError(c,
|
addReplyError(c,
|
||||||
"Unable to turn on AOF. Check server logs.");
|
"Unable to turn on AOF. Check server logs.");
|
||||||
@ -940,8 +940,8 @@ void configSetCommand(client *c) {
|
|||||||
"hz",server.hz,0,LLONG_MAX) {
|
"hz",server.hz,0,LLONG_MAX) {
|
||||||
/* Hz is more an hint from the user, so we accept values out of range
|
/* Hz is more an hint from the user, so we accept values out of range
|
||||||
* but cap them to reasonable values. */
|
* but cap them to reasonable values. */
|
||||||
if (server.hz < REDIS_MIN_HZ) server.hz = REDIS_MIN_HZ;
|
if (server.hz < CONFIG_MIN_HZ) server.hz = CONFIG_MIN_HZ;
|
||||||
if (server.hz > REDIS_MAX_HZ) server.hz = REDIS_MAX_HZ;
|
if (server.hz > CONFIG_MAX_HZ) server.hz = CONFIG_MAX_HZ;
|
||||||
} config_set_numerical_field(
|
} config_set_numerical_field(
|
||||||
"watchdog-period",ll,0,LLONG_MAX) {
|
"watchdog-period",ll,0,LLONG_MAX) {
|
||||||
if (ll)
|
if (ll)
|
||||||
@ -954,7 +954,7 @@ void configSetCommand(client *c) {
|
|||||||
} config_set_memory_field("maxmemory",server.maxmemory) {
|
} config_set_memory_field("maxmemory",server.maxmemory) {
|
||||||
if (server.maxmemory) {
|
if (server.maxmemory) {
|
||||||
if (server.maxmemory < zmalloc_used_memory()) {
|
if (server.maxmemory < zmalloc_used_memory()) {
|
||||||
serverLog(REDIS_WARNING,"WARNING: the new maxmemory value set via CONFIG SET is smaller than the current memory usage. This will result in keys eviction and/or inability to accept new write commands depending on the maxmemory-policy.");
|
serverLog(LL_WARNING,"WARNING: the new maxmemory value set via CONFIG SET is smaller than the current memory usage. This will result in keys eviction and/or inability to accept new write commands depending on the maxmemory-policy.");
|
||||||
}
|
}
|
||||||
freeMemoryIfNeeded();
|
freeMemoryIfNeeded();
|
||||||
}
|
}
|
||||||
@ -1130,7 +1130,7 @@ void configGetCommand(client *c) {
|
|||||||
|
|
||||||
if (stringmatch(pattern,"appendonly",0)) {
|
if (stringmatch(pattern,"appendonly",0)) {
|
||||||
addReplyBulkCString(c,"appendonly");
|
addReplyBulkCString(c,"appendonly");
|
||||||
addReplyBulkCString(c,server.aof_state == REDIS_AOF_OFF ? "no" : "yes");
|
addReplyBulkCString(c,server.aof_state == AOF_OFF ? "no" : "yes");
|
||||||
matches++;
|
matches++;
|
||||||
}
|
}
|
||||||
if (stringmatch(pattern,"dir",0)) {
|
if (stringmatch(pattern,"dir",0)) {
|
||||||
@ -1163,13 +1163,13 @@ void configGetCommand(client *c) {
|
|||||||
sds buf = sdsempty();
|
sds buf = sdsempty();
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < REDIS_CLIENT_TYPE_COUNT; j++) {
|
for (j = 0; j < CLIENT_TYPE_COUNT; j++) {
|
||||||
buf = sdscatprintf(buf,"%s %llu %llu %ld",
|
buf = sdscatprintf(buf,"%s %llu %llu %ld",
|
||||||
getClientTypeName(j),
|
getClientTypeName(j),
|
||||||
server.client_obuf_limits[j].hard_limit_bytes,
|
server.client_obuf_limits[j].hard_limit_bytes,
|
||||||
server.client_obuf_limits[j].soft_limit_bytes,
|
server.client_obuf_limits[j].soft_limit_bytes,
|
||||||
(long) server.client_obuf_limits[j].soft_limit_seconds);
|
(long) server.client_obuf_limits[j].soft_limit_seconds);
|
||||||
if (j != REDIS_CLIENT_TYPE_COUNT-1)
|
if (j != CLIENT_TYPE_COUNT-1)
|
||||||
buf = sdscatlen(buf," ",1);
|
buf = sdscatlen(buf," ",1);
|
||||||
}
|
}
|
||||||
addReplyBulkCString(c,"client-output-buffer-limit");
|
addReplyBulkCString(c,"client-output-buffer-limit");
|
||||||
@ -1297,7 +1297,7 @@ void rewriteConfigMarkAsProcessed(struct rewriteConfigState *state, const char *
|
|||||||
struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
|
struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
|
||||||
FILE *fp = fopen(path,"r");
|
FILE *fp = fopen(path,"r");
|
||||||
struct rewriteConfigState *state = zmalloc(sizeof(*state));
|
struct rewriteConfigState *state = zmalloc(sizeof(*state));
|
||||||
char buf[REDIS_CONFIGLINE_MAX+1];
|
char buf[CONFIG_MAX_LINE+1];
|
||||||
int linenum = -1;
|
int linenum = -1;
|
||||||
|
|
||||||
if (fp == NULL && errno != ENOENT) return NULL;
|
if (fp == NULL && errno != ENOENT) return NULL;
|
||||||
@ -1310,7 +1310,7 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
|
|||||||
if (fp == NULL) return state;
|
if (fp == NULL) return state;
|
||||||
|
|
||||||
/* Read the old file line by line, populate the state. */
|
/* Read the old file line by line, populate the state. */
|
||||||
while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL) {
|
while(fgets(buf,CONFIG_MAX_LINE+1,fp) != NULL) {
|
||||||
int argc;
|
int argc;
|
||||||
sds *argv;
|
sds *argv;
|
||||||
sds line = sdstrim(sdsnew(buf),"\r\n\t ");
|
sds line = sdstrim(sdsnew(buf),"\r\n\t ");
|
||||||
@ -1566,7 +1566,7 @@ void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state
|
|||||||
int j;
|
int j;
|
||||||
char *option = "client-output-buffer-limit";
|
char *option = "client-output-buffer-limit";
|
||||||
|
|
||||||
for (j = 0; j < REDIS_CLIENT_TYPE_COUNT; j++) {
|
for (j = 0; j < CLIENT_TYPE_COUNT; j++) {
|
||||||
int force = (server.client_obuf_limits[j].hard_limit_bytes !=
|
int force = (server.client_obuf_limits[j].hard_limit_bytes !=
|
||||||
clientBufferLimitsDefaults[j].hard_limit_bytes) ||
|
clientBufferLimitsDefaults[j].hard_limit_bytes) ||
|
||||||
(server.client_obuf_limits[j].soft_limit_bytes !=
|
(server.client_obuf_limits[j].soft_limit_bytes !=
|
||||||
@ -1657,7 +1657,7 @@ void rewriteConfigRemoveOrphaned(struct rewriteConfigState *state) {
|
|||||||
/* Don't blank lines about options the rewrite process
|
/* Don't blank lines about options the rewrite process
|
||||||
* don't understand. */
|
* don't understand. */
|
||||||
if (dictFind(state->rewritten,option) == NULL) {
|
if (dictFind(state->rewritten,option) == NULL) {
|
||||||
serverLog(REDIS_DEBUG,"Not rewritten option: %s", option);
|
serverLog(LL_DEBUG,"Not rewritten option: %s", option);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1751,12 +1751,12 @@ int rewriteConfig(char *path) {
|
|||||||
|
|
||||||
rewriteConfigYesNoOption(state,"daemonize",server.daemonize,0);
|
rewriteConfigYesNoOption(state,"daemonize",server.daemonize,0);
|
||||||
rewriteConfigStringOption(state,"pidfile",server.pidfile,CONFIG_DEFAULT_PID_FILE);
|
rewriteConfigStringOption(state,"pidfile",server.pidfile,CONFIG_DEFAULT_PID_FILE);
|
||||||
rewriteConfigNumericalOption(state,"port",server.port,REDIS_SERVERPORT);
|
rewriteConfigNumericalOption(state,"port",server.port,CONFIG_DEFAULT_SERVER_PORT);
|
||||||
rewriteConfigNumericalOption(state,"tcp-backlog",server.tcp_backlog,REDIS_TCP_BACKLOG);
|
rewriteConfigNumericalOption(state,"tcp-backlog",server.tcp_backlog,CONFIG_DEFAULT_TCP_BACKLOG);
|
||||||
rewriteConfigBindOption(state);
|
rewriteConfigBindOption(state);
|
||||||
rewriteConfigStringOption(state,"unixsocket",server.unixsocket,NULL);
|
rewriteConfigStringOption(state,"unixsocket",server.unixsocket,NULL);
|
||||||
rewriteConfigOctalOption(state,"unixsocketperm",server.unixsocketperm,CONFIG_DEFAULT_UNIX_SOCKET_PERM);
|
rewriteConfigOctalOption(state,"unixsocketperm",server.unixsocketperm,CONFIG_DEFAULT_UNIX_SOCKET_PERM);
|
||||||
rewriteConfigNumericalOption(state,"timeout",server.maxidletime,REDIS_MAXIDLETIME);
|
rewriteConfigNumericalOption(state,"timeout",server.maxidletime,CONFIG_DEFAULT_CLIENT_TIMEOUT);
|
||||||
rewriteConfigNumericalOption(state,"tcp-keepalive",server.tcpkeepalive,CONFIG_DEFAULT_TCP_KEEPALIVE);
|
rewriteConfigNumericalOption(state,"tcp-keepalive",server.tcpkeepalive,CONFIG_DEFAULT_TCP_KEEPALIVE);
|
||||||
rewriteConfigEnumOption(state,"loglevel",server.verbosity,loglevel_enum,CONFIG_DEFAULT_VERBOSITY);
|
rewriteConfigEnumOption(state,"loglevel",server.verbosity,loglevel_enum,CONFIG_DEFAULT_VERBOSITY);
|
||||||
rewriteConfigStringOption(state,"logfile",server.logfile,CONFIG_DEFAULT_LOGFILE);
|
rewriteConfigStringOption(state,"logfile",server.logfile,CONFIG_DEFAULT_LOGFILE);
|
||||||
@ -1774,8 +1774,8 @@ int rewriteConfig(char *path) {
|
|||||||
rewriteConfigStringOption(state,"masterauth",server.masterauth,NULL);
|
rewriteConfigStringOption(state,"masterauth",server.masterauth,NULL);
|
||||||
rewriteConfigYesNoOption(state,"slave-serve-stale-data",server.repl_serve_stale_data,CONFIG_DEFAULT_SLAVE_SERVE_STALE_DATA);
|
rewriteConfigYesNoOption(state,"slave-serve-stale-data",server.repl_serve_stale_data,CONFIG_DEFAULT_SLAVE_SERVE_STALE_DATA);
|
||||||
rewriteConfigYesNoOption(state,"slave-read-only",server.repl_slave_ro,CONFIG_DEFAULT_SLAVE_READ_ONLY);
|
rewriteConfigYesNoOption(state,"slave-read-only",server.repl_slave_ro,CONFIG_DEFAULT_SLAVE_READ_ONLY);
|
||||||
rewriteConfigNumericalOption(state,"repl-ping-slave-period",server.repl_ping_slave_period,REDIS_REPL_PING_SLAVE_PERIOD);
|
rewriteConfigNumericalOption(state,"repl-ping-slave-period",server.repl_ping_slave_period,CONFIG_DEFAULT_REPL_PING_SLAVE_PERIOD);
|
||||||
rewriteConfigNumericalOption(state,"repl-timeout",server.repl_timeout,REDIS_REPL_TIMEOUT);
|
rewriteConfigNumericalOption(state,"repl-timeout",server.repl_timeout,CONFIG_DEFAULT_REPL_TIMEOUT);
|
||||||
rewriteConfigBytesOption(state,"repl-backlog-size",server.repl_backlog_size,CONFIG_DEFAULT_REPL_BACKLOG_SIZE);
|
rewriteConfigBytesOption(state,"repl-backlog-size",server.repl_backlog_size,CONFIG_DEFAULT_REPL_BACKLOG_SIZE);
|
||||||
rewriteConfigBytesOption(state,"repl-backlog-ttl",server.repl_backlog_time_limit,CONFIG_DEFAULT_REPL_BACKLOG_TIME_LIMIT);
|
rewriteConfigBytesOption(state,"repl-backlog-ttl",server.repl_backlog_time_limit,CONFIG_DEFAULT_REPL_BACKLOG_TIME_LIMIT);
|
||||||
rewriteConfigYesNoOption(state,"repl-disable-tcp-nodelay",server.repl_disable_tcp_nodelay,CONFIG_DEFAULT_REPL_DISABLE_TCP_NODELAY);
|
rewriteConfigYesNoOption(state,"repl-disable-tcp-nodelay",server.repl_disable_tcp_nodelay,CONFIG_DEFAULT_REPL_DISABLE_TCP_NODELAY);
|
||||||
@ -1789,22 +1789,22 @@ int rewriteConfig(char *path) {
|
|||||||
rewriteConfigBytesOption(state,"maxmemory",server.maxmemory,CONFIG_DEFAULT_MAXMEMORY);
|
rewriteConfigBytesOption(state,"maxmemory",server.maxmemory,CONFIG_DEFAULT_MAXMEMORY);
|
||||||
rewriteConfigEnumOption(state,"maxmemory-policy",server.maxmemory_policy,maxmemory_policy_enum,CONFIG_DEFAULT_MAXMEMORY_POLICY);
|
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,"maxmemory-samples",server.maxmemory_samples,CONFIG_DEFAULT_MAXMEMORY_SAMPLES);
|
||||||
rewriteConfigYesNoOption(state,"appendonly",server.aof_state != REDIS_AOF_OFF,0);
|
rewriteConfigYesNoOption(state,"appendonly",server.aof_state != AOF_OFF,0);
|
||||||
rewriteConfigStringOption(state,"appendfilename",server.aof_filename,CONFIG_DEFAULT_AOF_FILENAME);
|
rewriteConfigStringOption(state,"appendfilename",server.aof_filename,CONFIG_DEFAULT_AOF_FILENAME);
|
||||||
rewriteConfigEnumOption(state,"appendfsync",server.aof_fsync,aof_fsync_enum,CONFIG_DEFAULT_AOF_FSYNC);
|
rewriteConfigEnumOption(state,"appendfsync",server.aof_fsync,aof_fsync_enum,CONFIG_DEFAULT_AOF_FSYNC);
|
||||||
rewriteConfigYesNoOption(state,"no-appendfsync-on-rewrite",server.aof_no_fsync_on_rewrite,CONFIG_DEFAULT_AOF_NO_FSYNC_ON_REWRITE);
|
rewriteConfigYesNoOption(state,"no-appendfsync-on-rewrite",server.aof_no_fsync_on_rewrite,CONFIG_DEFAULT_AOF_NO_FSYNC_ON_REWRITE);
|
||||||
rewriteConfigNumericalOption(state,"auto-aof-rewrite-percentage",server.aof_rewrite_perc,REDIS_AOF_REWRITE_PERC);
|
rewriteConfigNumericalOption(state,"auto-aof-rewrite-percentage",server.aof_rewrite_perc,AOF_REWRITE_PERC);
|
||||||
rewriteConfigBytesOption(state,"auto-aof-rewrite-min-size",server.aof_rewrite_min_size,REDIS_AOF_REWRITE_MIN_SIZE);
|
rewriteConfigBytesOption(state,"auto-aof-rewrite-min-size",server.aof_rewrite_min_size,AOF_REWRITE_MIN_SIZE);
|
||||||
rewriteConfigNumericalOption(state,"lua-time-limit",server.lua_time_limit,REDIS_LUA_TIME_LIMIT);
|
rewriteConfigNumericalOption(state,"lua-time-limit",server.lua_time_limit,LUA_SCRIPT_TIME_LIMIT);
|
||||||
rewriteConfigYesNoOption(state,"cluster-enabled",server.cluster_enabled,0);
|
rewriteConfigYesNoOption(state,"cluster-enabled",server.cluster_enabled,0);
|
||||||
rewriteConfigStringOption(state,"cluster-config-file",server.cluster_configfile,CONFIG_DEFAULT_CLUSTER_CONFIG_FILE);
|
rewriteConfigStringOption(state,"cluster-config-file",server.cluster_configfile,CONFIG_DEFAULT_CLUSTER_CONFIG_FILE);
|
||||||
rewriteConfigYesNoOption(state,"cluster-require-full-coverage",server.cluster_require_full_coverage,REDIS_CLUSTER_DEFAULT_REQUIRE_FULL_COVERAGE);
|
rewriteConfigYesNoOption(state,"cluster-require-full-coverage",server.cluster_require_full_coverage,REDIS_CLUSTER_DEFAULT_REQUIRE_FULL_COVERAGE);
|
||||||
rewriteConfigNumericalOption(state,"cluster-node-timeout",server.cluster_node_timeout,REDIS_CLUSTER_DEFAULT_NODE_TIMEOUT);
|
rewriteConfigNumericalOption(state,"cluster-node-timeout",server.cluster_node_timeout,REDIS_CLUSTER_DEFAULT_NODE_TIMEOUT);
|
||||||
rewriteConfigNumericalOption(state,"cluster-migration-barrier",server.cluster_migration_barrier,REDIS_CLUSTER_DEFAULT_MIGRATION_BARRIER);
|
rewriteConfigNumericalOption(state,"cluster-migration-barrier",server.cluster_migration_barrier,REDIS_CLUSTER_DEFAULT_MIGRATION_BARRIER);
|
||||||
rewriteConfigNumericalOption(state,"cluster-slave-validity-factor",server.cluster_slave_validity_factor,REDIS_CLUSTER_DEFAULT_SLAVE_VALIDITY);
|
rewriteConfigNumericalOption(state,"cluster-slave-validity-factor",server.cluster_slave_validity_factor,REDIS_CLUSTER_DEFAULT_SLAVE_VALIDITY);
|
||||||
rewriteConfigNumericalOption(state,"slowlog-log-slower-than",server.slowlog_log_slower_than,REDIS_SLOWLOG_LOG_SLOWER_THAN);
|
rewriteConfigNumericalOption(state,"slowlog-log-slower-than",server.slowlog_log_slower_than,CONFIG_DEFAULT_SLOWLOG_LOG_SLOWER_THAN);
|
||||||
rewriteConfigNumericalOption(state,"latency-monitor-threshold",server.latency_monitor_threshold,CONFIG_DEFAULT_LATENCY_MONITOR_THRESHOLD);
|
rewriteConfigNumericalOption(state,"latency-monitor-threshold",server.latency_monitor_threshold,CONFIG_DEFAULT_LATENCY_MONITOR_THRESHOLD);
|
||||||
rewriteConfigNumericalOption(state,"slowlog-max-len",server.slowlog_max_len,REDIS_SLOWLOG_MAX_LEN);
|
rewriteConfigNumericalOption(state,"slowlog-max-len",server.slowlog_max_len,CONFIG_DEFAULT_SLOWLOG_MAX_LEN);
|
||||||
rewriteConfigNotifykeyspaceeventsOption(state);
|
rewriteConfigNotifykeyspaceeventsOption(state);
|
||||||
rewriteConfigNumericalOption(state,"hash-max-ziplist-entries",server.hash_max_ziplist_entries,OBJ_HASH_MAX_ZIPLIST_ENTRIES);
|
rewriteConfigNumericalOption(state,"hash-max-ziplist-entries",server.hash_max_ziplist_entries,OBJ_HASH_MAX_ZIPLIST_ENTRIES);
|
||||||
rewriteConfigNumericalOption(state,"hash-max-ziplist-value",server.hash_max_ziplist_value,OBJ_HASH_MAX_ZIPLIST_VALUE);
|
rewriteConfigNumericalOption(state,"hash-max-ziplist-value",server.hash_max_ziplist_value,OBJ_HASH_MAX_ZIPLIST_VALUE);
|
||||||
@ -1819,7 +1819,7 @@ int rewriteConfig(char *path) {
|
|||||||
rewriteConfigNumericalOption(state,"hz",server.hz,CONFIG_DEFAULT_HZ);
|
rewriteConfigNumericalOption(state,"hz",server.hz,CONFIG_DEFAULT_HZ);
|
||||||
rewriteConfigYesNoOption(state,"aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync,CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC);
|
rewriteConfigYesNoOption(state,"aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync,CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC);
|
||||||
rewriteConfigYesNoOption(state,"aof-load-truncated",server.aof_load_truncated,CONFIG_DEFAULT_AOF_LOAD_TRUNCATED);
|
rewriteConfigYesNoOption(state,"aof-load-truncated",server.aof_load_truncated,CONFIG_DEFAULT_AOF_LOAD_TRUNCATED);
|
||||||
rewriteConfigEnumOption(state,"supervised",server.supervised_mode,supervised_mode_enum,REDIS_SUPERVISED_NONE);
|
rewriteConfigEnumOption(state,"supervised",server.supervised_mode,supervised_mode_enum,SUPERVISED_NONE);
|
||||||
|
|
||||||
/* Rewrite Sentinel config if in Sentinel mode. */
|
/* Rewrite Sentinel config if in Sentinel mode. */
|
||||||
if (server.sentinel_mode) rewriteConfigSentinelOption(state);
|
if (server.sentinel_mode) rewriteConfigSentinelOption(state);
|
||||||
@ -1862,10 +1862,10 @@ void configCommand(client *c) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rewriteConfig(server.configfile) == -1) {
|
if (rewriteConfig(server.configfile) == -1) {
|
||||||
serverLog(REDIS_WARNING,"CONFIG REWRITE failed: %s", strerror(errno));
|
serverLog(LL_WARNING,"CONFIG REWRITE failed: %s", strerror(errno));
|
||||||
addReplyErrorFormat(c,"Rewriting config file: %s", strerror(errno));
|
addReplyErrorFormat(c,"Rewriting config file: %s", strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,"CONFIG REWRITE executed with success.");
|
serverLog(LL_WARNING,"CONFIG REWRITE executed with success.");
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
36
src/db.c
36
src/db.c
@ -81,7 +81,7 @@ robj *lookupKeyRead(redisDb *db, robj *key) {
|
|||||||
if (server.current_client &&
|
if (server.current_client &&
|
||||||
server.current_client != server.master &&
|
server.current_client != server.master &&
|
||||||
server.current_client->cmd &&
|
server.current_client->cmd &&
|
||||||
server.current_client->cmd->flags & REDIS_CMD_READONLY)
|
server.current_client->cmd->flags & CMD_READONLY)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -309,7 +309,7 @@ void delCommand(client *c) {
|
|||||||
expireIfNeeded(c->db,c->argv[j]);
|
expireIfNeeded(c->db,c->argv[j]);
|
||||||
if (dbDelete(c->db,c->argv[j])) {
|
if (dbDelete(c->db,c->argv[j])) {
|
||||||
signalModifiedKey(c->db,c->argv[j]);
|
signalModifiedKey(c->db,c->argv[j]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,
|
notifyKeyspaceEvent(NOTIFY_GENERIC,
|
||||||
"del",c->argv[j],c->db->id);
|
"del",c->argv[j],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
deleted++;
|
deleted++;
|
||||||
@ -412,7 +412,7 @@ void scanCallback(void *privdata, const dictEntry *de) {
|
|||||||
incrRefCount(key);
|
incrRefCount(key);
|
||||||
val = createStringObjectFromLongDouble(*(double*)dictGetVal(de),0);
|
val = createStringObjectFromLongDouble(*(double*)dictGetVal(de),0);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Type not handled in SCAN callback.");
|
serverPanic("Type not handled in SCAN callback.");
|
||||||
}
|
}
|
||||||
|
|
||||||
listAddNodeTail(keys, key);
|
listAddNodeTail(keys, key);
|
||||||
@ -560,7 +560,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long cursor) {
|
|||||||
}
|
}
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Not handled encoding in SCAN.");
|
serverPanic("Not handled encoding in SCAN.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 3: Filter elements. */
|
/* Step 3: Filter elements. */
|
||||||
@ -576,7 +576,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long cursor) {
|
|||||||
if (!stringmatchlen(pat, patlen, kobj->ptr, sdslen(kobj->ptr), 0))
|
if (!stringmatchlen(pat, patlen, kobj->ptr, sdslen(kobj->ptr), 0))
|
||||||
filter = 1;
|
filter = 1;
|
||||||
} else {
|
} else {
|
||||||
char buf[REDIS_LONGSTR_SIZE];
|
char buf[LONG_STR_SIZE];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
serverAssert(kobj->encoding == OBJ_ENCODING_INT);
|
serverAssert(kobj->encoding == OBJ_ENCODING_INT);
|
||||||
@ -669,9 +669,9 @@ void shutdownCommand(client *c) {
|
|||||||
return;
|
return;
|
||||||
} else if (c->argc == 2) {
|
} else if (c->argc == 2) {
|
||||||
if (!strcasecmp(c->argv[1]->ptr,"nosave")) {
|
if (!strcasecmp(c->argv[1]->ptr,"nosave")) {
|
||||||
flags |= REDIS_SHUTDOWN_NOSAVE;
|
flags |= SHUTDOWN_NOSAVE;
|
||||||
} else if (!strcasecmp(c->argv[1]->ptr,"save")) {
|
} else if (!strcasecmp(c->argv[1]->ptr,"save")) {
|
||||||
flags |= REDIS_SHUTDOWN_SAVE;
|
flags |= SHUTDOWN_SAVE;
|
||||||
} else {
|
} else {
|
||||||
addReply(c,shared.syntaxerr);
|
addReply(c,shared.syntaxerr);
|
||||||
return;
|
return;
|
||||||
@ -684,7 +684,7 @@ void shutdownCommand(client *c) {
|
|||||||
*
|
*
|
||||||
* Also when in Sentinel mode clear the SAVE flag and force NOSAVE. */
|
* Also when in Sentinel mode clear the SAVE flag and force NOSAVE. */
|
||||||
if (server.loading || server.sentinel_mode)
|
if (server.loading || server.sentinel_mode)
|
||||||
flags = (flags & ~REDIS_SHUTDOWN_SAVE) | REDIS_SHUTDOWN_NOSAVE;
|
flags = (flags & ~SHUTDOWN_SAVE) | SHUTDOWN_NOSAVE;
|
||||||
if (prepareForShutdown(flags) == C_OK) exit(0);
|
if (prepareForShutdown(flags) == C_OK) exit(0);
|
||||||
addReplyError(c,"Errors trying to SHUTDOWN. Check logs.");
|
addReplyError(c,"Errors trying to SHUTDOWN. Check logs.");
|
||||||
}
|
}
|
||||||
@ -723,9 +723,9 @@ void renameGenericCommand(client *c, int nx) {
|
|||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
signalModifiedKey(c->db,c->argv[2]);
|
signalModifiedKey(c->db,c->argv[2]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"rename_from",
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"rename_from",
|
||||||
c->argv[1],c->db->id);
|
c->argv[1],c->db->id);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"rename_to",
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"rename_to",
|
||||||
c->argv[2],c->db->id);
|
c->argv[2],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,nx ? shared.cone : shared.ok);
|
addReply(c,nx ? shared.cone : shared.ok);
|
||||||
@ -844,7 +844,7 @@ void propagateExpire(redisDb *db, robj *key) {
|
|||||||
incrRefCount(argv[0]);
|
incrRefCount(argv[0]);
|
||||||
incrRefCount(argv[1]);
|
incrRefCount(argv[1]);
|
||||||
|
|
||||||
if (server.aof_state != REDIS_AOF_OFF)
|
if (server.aof_state != AOF_OFF)
|
||||||
feedAppendOnlyFile(server.delCommand,db->id,argv,2);
|
feedAppendOnlyFile(server.delCommand,db->id,argv,2);
|
||||||
replicationFeedSlaves(server.slaves,db->id,argv,2);
|
replicationFeedSlaves(server.slaves,db->id,argv,2);
|
||||||
|
|
||||||
@ -883,7 +883,7 @@ int expireIfNeeded(redisDb *db, robj *key) {
|
|||||||
/* Delete the key */
|
/* Delete the key */
|
||||||
server.stat_expiredkeys++;
|
server.stat_expiredkeys++;
|
||||||
propagateExpire(db,key);
|
propagateExpire(db,key);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_EXPIRED,
|
notifyKeyspaceEvent(NOTIFY_EXPIRED,
|
||||||
"expired",key,db->id);
|
"expired",key,db->id);
|
||||||
return dbDelete(db,key);
|
return dbDelete(db,key);
|
||||||
}
|
}
|
||||||
@ -932,14 +932,14 @@ void expireGenericCommand(client *c, long long basetime, int unit) {
|
|||||||
rewriteClientCommandVector(c,2,aux,key);
|
rewriteClientCommandVector(c,2,aux,key);
|
||||||
decrRefCount(aux);
|
decrRefCount(aux);
|
||||||
signalModifiedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",key,c->db->id);
|
||||||
addReply(c, shared.cone);
|
addReply(c, shared.cone);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
setExpire(c->db,key,when);
|
setExpire(c->db,key,when);
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
signalModifiedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"expire",key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"expire",key,c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1015,7 +1015,7 @@ void persistCommand(client *c) {
|
|||||||
* (firstkey, lastkey, step). */
|
* (firstkey, lastkey, step). */
|
||||||
int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, int *numkeys) {
|
int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, int *numkeys) {
|
||||||
int j, i = 0, last, *keys;
|
int j, i = 0, last, *keys;
|
||||||
REDIS_NOTUSED(argv);
|
UNUSED(argv);
|
||||||
|
|
||||||
if (cmd->firstkey == 0) {
|
if (cmd->firstkey == 0) {
|
||||||
*numkeys = 0;
|
*numkeys = 0;
|
||||||
@ -1061,7 +1061,7 @@ void getKeysFreeResult(int *result) {
|
|||||||
* ZINTERSTORE <destkey> <num-keys> <key> <key> ... <key> <options> */
|
* ZINTERSTORE <destkey> <num-keys> <key> <key> ... <key> <options> */
|
||||||
int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
|
int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
|
||||||
int i, num, *keys;
|
int i, num, *keys;
|
||||||
REDIS_NOTUSED(cmd);
|
UNUSED(cmd);
|
||||||
|
|
||||||
num = atoi(argv[2]->ptr);
|
num = atoi(argv[2]->ptr);
|
||||||
/* Sanity check. Don't return any key if the command is going to
|
/* Sanity check. Don't return any key if the command is going to
|
||||||
@ -1090,7 +1090,7 @@ int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *nu
|
|||||||
* EVALSHA <script> <num-keys> <key> <key> ... <key> [more stuff] */
|
* EVALSHA <script> <num-keys> <key> <key> ... <key> [more stuff] */
|
||||||
int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
|
int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
|
||||||
int i, num, *keys;
|
int i, num, *keys;
|
||||||
REDIS_NOTUSED(cmd);
|
UNUSED(cmd);
|
||||||
|
|
||||||
num = atoi(argv[2]->ptr);
|
num = atoi(argv[2]->ptr);
|
||||||
/* Sanity check. Don't return any key if the command is going to
|
/* Sanity check. Don't return any key if the command is going to
|
||||||
@ -1118,7 +1118,7 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
|
|||||||
* correctly identify keys in the "STORE" option. */
|
* correctly identify keys in the "STORE" option. */
|
||||||
int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
|
int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
|
||||||
int i, j, num, *keys, found_store = 0;
|
int i, j, num, *keys, found_store = 0;
|
||||||
REDIS_NOTUSED(cmd);
|
UNUSED(cmd);
|
||||||
|
|
||||||
num = 0;
|
num = 0;
|
||||||
keys = zmalloc(sizeof(int)*2); /* Alloc 2 places for the worst case. */
|
keys = zmalloc(sizeof(int)*2); /* Alloc 2 places for the worst case. */
|
||||||
|
124
src/debug.c
124
src/debug.c
@ -153,7 +153,7 @@ void computeDatasetDigest(unsigned char *final) {
|
|||||||
if (o->type == OBJ_STRING) {
|
if (o->type == OBJ_STRING) {
|
||||||
mixObjectDigest(digest,o);
|
mixObjectDigest(digest,o);
|
||||||
} else if (o->type == OBJ_LIST) {
|
} else if (o->type == OBJ_LIST) {
|
||||||
listTypeIterator *li = listTypeInitIterator(o,0,REDIS_TAIL);
|
listTypeIterator *li = listTypeInitIterator(o,0,LIST_TAIL);
|
||||||
listTypeEntry entry;
|
listTypeEntry entry;
|
||||||
while(listTypeNext(li,&entry)) {
|
while(listTypeNext(li,&entry)) {
|
||||||
robj *eleobj = listTypeGet(&entry);
|
robj *eleobj = listTypeGet(&entry);
|
||||||
@ -219,7 +219,7 @@ void computeDatasetDigest(unsigned char *final) {
|
|||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
} else if (o->type == OBJ_HASH) {
|
} else if (o->type == OBJ_HASH) {
|
||||||
hashTypeIterator *hi;
|
hashTypeIterator *hi;
|
||||||
@ -240,7 +240,7 @@ void computeDatasetDigest(unsigned char *final) {
|
|||||||
}
|
}
|
||||||
hashTypeReleaseIterator(hi);
|
hashTypeReleaseIterator(hi);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown object type");
|
serverPanic("Unknown object type");
|
||||||
}
|
}
|
||||||
/* If the key has an expire, add it to the mix */
|
/* If the key has an expire, add it to the mix */
|
||||||
if (expiretime != -1) xorDigest(digest,"!!expire!!",10);
|
if (expiretime != -1) xorDigest(digest,"!!expire!!",10);
|
||||||
@ -278,7 +278,7 @@ void debugCommand(client *c) {
|
|||||||
addReplyError(c,"Error trying to load the RDB dump");
|
addReplyError(c,"Error trying to load the RDB dump");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_WARNING,"DB reloaded by DEBUG RELOAD");
|
serverLog(LL_WARNING,"DB reloaded by DEBUG RELOAD");
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
} else if (!strcasecmp(c->argv[1]->ptr,"loadaof")) {
|
} else if (!strcasecmp(c->argv[1]->ptr,"loadaof")) {
|
||||||
emptyDb(NULL);
|
emptyDb(NULL);
|
||||||
@ -287,7 +287,7 @@ void debugCommand(client *c) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
server.dirty = 0; /* Prevent AOF / replication */
|
server.dirty = 0; /* Prevent AOF / replication */
|
||||||
serverLog(REDIS_WARNING,"Append Only File loaded by DEBUG LOADAOF");
|
serverLog(LL_WARNING,"Append Only File loaded by DEBUG LOADAOF");
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
} else if (!strcasecmp(c->argv[1]->ptr,"object") && c->argc == 3) {
|
} else if (!strcasecmp(c->argv[1]->ptr,"object") && c->argc == 3) {
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
@ -472,13 +472,13 @@ void debugCommand(client *c) {
|
|||||||
|
|
||||||
void _serverAssert(char *estr, char *file, int line) {
|
void _serverAssert(char *estr, char *file, int line) {
|
||||||
bugReportStart();
|
bugReportStart();
|
||||||
serverLog(REDIS_WARNING,"=== ASSERTION FAILED ===");
|
serverLog(LL_WARNING,"=== ASSERTION FAILED ===");
|
||||||
serverLog(REDIS_WARNING,"==> %s:%d '%s' is not true",file,line,estr);
|
serverLog(LL_WARNING,"==> %s:%d '%s' is not true",file,line,estr);
|
||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_BACKTRACE
|
||||||
server.assert_failed = estr;
|
server.assert_failed = estr;
|
||||||
server.assert_file = file;
|
server.assert_file = file;
|
||||||
server.assert_line = line;
|
server.assert_line = line;
|
||||||
serverLog(REDIS_WARNING,"(forcing SIGSEGV to print the bug report.)");
|
serverLog(LL_WARNING,"(forcing SIGSEGV to print the bug report.)");
|
||||||
#endif
|
#endif
|
||||||
*((char*)-1) = 'x';
|
*((char*)-1) = 'x';
|
||||||
}
|
}
|
||||||
@ -487,10 +487,10 @@ void _serverAssertPrintClientInfo(client *c) {
|
|||||||
int j;
|
int j;
|
||||||
|
|
||||||
bugReportStart();
|
bugReportStart();
|
||||||
serverLog(REDIS_WARNING,"=== ASSERTION FAILED CLIENT CONTEXT ===");
|
serverLog(LL_WARNING,"=== ASSERTION FAILED CLIENT CONTEXT ===");
|
||||||
serverLog(REDIS_WARNING,"client->flags = %d", c->flags);
|
serverLog(LL_WARNING,"client->flags = %d", c->flags);
|
||||||
serverLog(REDIS_WARNING,"client->fd = %d", c->fd);
|
serverLog(LL_WARNING,"client->fd = %d", c->fd);
|
||||||
serverLog(REDIS_WARNING,"client->argc = %d", c->argc);
|
serverLog(LL_WARNING,"client->argc = %d", c->argc);
|
||||||
for (j=0; j < c->argc; j++) {
|
for (j=0; j < c->argc; j++) {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
char *arg;
|
char *arg;
|
||||||
@ -502,38 +502,38 @@ void _serverAssertPrintClientInfo(client *c) {
|
|||||||
c->argv[j]->type, c->argv[j]->encoding);
|
c->argv[j]->type, c->argv[j]->encoding);
|
||||||
arg = buf;
|
arg = buf;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_WARNING,"client->argv[%d] = \"%s\" (refcount: %d)",
|
serverLog(LL_WARNING,"client->argv[%d] = \"%s\" (refcount: %d)",
|
||||||
j, arg, c->argv[j]->refcount);
|
j, arg, c->argv[j]->refcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void serverLogObjectDebugInfo(robj *o) {
|
void serverLogObjectDebugInfo(robj *o) {
|
||||||
serverLog(REDIS_WARNING,"Object type: %d", o->type);
|
serverLog(LL_WARNING,"Object type: %d", o->type);
|
||||||
serverLog(REDIS_WARNING,"Object encoding: %d", o->encoding);
|
serverLog(LL_WARNING,"Object encoding: %d", o->encoding);
|
||||||
serverLog(REDIS_WARNING,"Object refcount: %d", o->refcount);
|
serverLog(LL_WARNING,"Object refcount: %d", o->refcount);
|
||||||
if (o->type == OBJ_STRING && sdsEncodedObject(o)) {
|
if (o->type == OBJ_STRING && sdsEncodedObject(o)) {
|
||||||
serverLog(REDIS_WARNING,"Object raw string len: %zu", sdslen(o->ptr));
|
serverLog(LL_WARNING,"Object raw string len: %zu", sdslen(o->ptr));
|
||||||
if (sdslen(o->ptr) < 4096) {
|
if (sdslen(o->ptr) < 4096) {
|
||||||
sds repr = sdscatrepr(sdsempty(),o->ptr,sdslen(o->ptr));
|
sds repr = sdscatrepr(sdsempty(),o->ptr,sdslen(o->ptr));
|
||||||
serverLog(REDIS_WARNING,"Object raw string content: %s", repr);
|
serverLog(LL_WARNING,"Object raw string content: %s", repr);
|
||||||
sdsfree(repr);
|
sdsfree(repr);
|
||||||
}
|
}
|
||||||
} else if (o->type == OBJ_LIST) {
|
} else if (o->type == OBJ_LIST) {
|
||||||
serverLog(REDIS_WARNING,"List length: %d", (int) listTypeLength(o));
|
serverLog(LL_WARNING,"List length: %d", (int) listTypeLength(o));
|
||||||
} else if (o->type == OBJ_SET) {
|
} else if (o->type == OBJ_SET) {
|
||||||
serverLog(REDIS_WARNING,"Set size: %d", (int) setTypeSize(o));
|
serverLog(LL_WARNING,"Set size: %d", (int) setTypeSize(o));
|
||||||
} else if (o->type == OBJ_HASH) {
|
} else if (o->type == OBJ_HASH) {
|
||||||
serverLog(REDIS_WARNING,"Hash size: %d", (int) hashTypeLength(o));
|
serverLog(LL_WARNING,"Hash size: %d", (int) hashTypeLength(o));
|
||||||
} else if (o->type == OBJ_ZSET) {
|
} else if (o->type == OBJ_ZSET) {
|
||||||
serverLog(REDIS_WARNING,"Sorted set size: %d", (int) zsetLength(o));
|
serverLog(LL_WARNING,"Sorted set size: %d", (int) zsetLength(o));
|
||||||
if (o->encoding == OBJ_ENCODING_SKIPLIST)
|
if (o->encoding == OBJ_ENCODING_SKIPLIST)
|
||||||
serverLog(REDIS_WARNING,"Skiplist level: %d", (int) ((zset*)o->ptr)->zsl->level);
|
serverLog(LL_WARNING,"Skiplist level: %d", (int) ((zset*)o->ptr)->zsl->level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serverAssertPrintObject(robj *o) {
|
void _serverAssertPrintObject(robj *o) {
|
||||||
bugReportStart();
|
bugReportStart();
|
||||||
serverLog(REDIS_WARNING,"=== ASSERTION FAILED OBJECT CONTEXT ===");
|
serverLog(LL_WARNING,"=== ASSERTION FAILED OBJECT CONTEXT ===");
|
||||||
serverLogObjectDebugInfo(o);
|
serverLogObjectDebugInfo(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,21 +543,21 @@ void _serverAssertWithInfo(client *c, robj *o, char *estr, char *file, int line)
|
|||||||
_serverAssert(estr,file,line);
|
_serverAssert(estr,file,line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _redisPanic(char *msg, char *file, int line) {
|
void _serverPanic(char *msg, char *file, int line) {
|
||||||
bugReportStart();
|
bugReportStart();
|
||||||
serverLog(REDIS_WARNING,"------------------------------------------------");
|
serverLog(LL_WARNING,"------------------------------------------------");
|
||||||
serverLog(REDIS_WARNING,"!!! Software Failure. Press left mouse button to continue");
|
serverLog(LL_WARNING,"!!! Software Failure. Press left mouse button to continue");
|
||||||
serverLog(REDIS_WARNING,"Guru Meditation: %s #%s:%d",msg,file,line);
|
serverLog(LL_WARNING,"Guru Meditation: %s #%s:%d",msg,file,line);
|
||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_BACKTRACE
|
||||||
serverLog(REDIS_WARNING,"(forcing SIGSEGV in order to print the stack trace)");
|
serverLog(LL_WARNING,"(forcing SIGSEGV in order to print the stack trace)");
|
||||||
#endif
|
#endif
|
||||||
serverLog(REDIS_WARNING,"------------------------------------------------");
|
serverLog(LL_WARNING,"------------------------------------------------");
|
||||||
*((char*)-1) = 'x';
|
*((char*)-1) = 'x';
|
||||||
}
|
}
|
||||||
|
|
||||||
void bugReportStart(void) {
|
void bugReportStart(void) {
|
||||||
if (server.bug_report_start == 0) {
|
if (server.bug_report_start == 0) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"\n\n=== REDIS BUG REPORT START: Cut & paste starting from here ===");
|
"\n\n=== REDIS BUG REPORT START: Cut & paste starting from here ===");
|
||||||
server.bug_report_start = 1;
|
server.bug_report_start = 1;
|
||||||
}
|
}
|
||||||
@ -602,20 +602,20 @@ void logStackContent(void **sp) {
|
|||||||
unsigned long val = (unsigned long) sp[i];
|
unsigned long val = (unsigned long) sp[i];
|
||||||
|
|
||||||
if (sizeof(long) == 4)
|
if (sizeof(long) == 4)
|
||||||
serverLog(REDIS_WARNING, "(%08lx) -> %08lx", addr, val);
|
serverLog(LL_WARNING, "(%08lx) -> %08lx", addr, val);
|
||||||
else
|
else
|
||||||
serverLog(REDIS_WARNING, "(%016lx) -> %016lx", addr, val);
|
serverLog(LL_WARNING, "(%016lx) -> %016lx", addr, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void logRegisters(ucontext_t *uc) {
|
void logRegisters(ucontext_t *uc) {
|
||||||
serverLog(REDIS_WARNING, "--- REGISTERS");
|
serverLog(LL_WARNING, "--- REGISTERS");
|
||||||
|
|
||||||
/* OSX */
|
/* OSX */
|
||||||
#if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)
|
#if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)
|
||||||
/* OSX AMD64 */
|
/* OSX AMD64 */
|
||||||
#if defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__)
|
#if defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__)
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"\n"
|
"\n"
|
||||||
"RAX:%016lx RBX:%016lx\nRCX:%016lx RDX:%016lx\n"
|
"RAX:%016lx RBX:%016lx\nRCX:%016lx RDX:%016lx\n"
|
||||||
"RDI:%016lx RSI:%016lx\nRBP:%016lx RSP:%016lx\n"
|
"RDI:%016lx RSI:%016lx\nRBP:%016lx RSP:%016lx\n"
|
||||||
@ -647,7 +647,7 @@ void logRegisters(ucontext_t *uc) {
|
|||||||
logStackContent((void**)uc->uc_mcontext->__ss.__rsp);
|
logStackContent((void**)uc->uc_mcontext->__ss.__rsp);
|
||||||
#else
|
#else
|
||||||
/* OSX x86 */
|
/* OSX x86 */
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"\n"
|
"\n"
|
||||||
"EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n"
|
"EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n"
|
||||||
"EDI:%08lx ESI:%08lx EBP:%08lx ESP:%08lx\n"
|
"EDI:%08lx ESI:%08lx EBP:%08lx ESP:%08lx\n"
|
||||||
@ -676,7 +676,7 @@ void logRegisters(ucontext_t *uc) {
|
|||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
/* Linux x86 */
|
/* Linux x86 */
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"\n"
|
"\n"
|
||||||
"EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n"
|
"EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n"
|
||||||
"EDI:%08lx ESI:%08lx EBP:%08lx ESP:%08lx\n"
|
"EDI:%08lx ESI:%08lx EBP:%08lx ESP:%08lx\n"
|
||||||
@ -702,7 +702,7 @@ void logRegisters(ucontext_t *uc) {
|
|||||||
logStackContent((void**)uc->uc_mcontext.gregs[7]);
|
logStackContent((void**)uc->uc_mcontext.gregs[7]);
|
||||||
#elif defined(__X86_64__) || defined(__x86_64__)
|
#elif defined(__X86_64__) || defined(__x86_64__)
|
||||||
/* Linux AMD64 */
|
/* Linux AMD64 */
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"\n"
|
"\n"
|
||||||
"RAX:%016lx RBX:%016lx\nRCX:%016lx RDX:%016lx\n"
|
"RAX:%016lx RBX:%016lx\nRCX:%016lx RDX:%016lx\n"
|
||||||
"RDI:%016lx RSI:%016lx\nRBP:%016lx RSP:%016lx\n"
|
"RDI:%016lx RSI:%016lx\nRBP:%016lx RSP:%016lx\n"
|
||||||
@ -732,7 +732,7 @@ void logRegisters(ucontext_t *uc) {
|
|||||||
logStackContent((void**)uc->uc_mcontext.gregs[15]);
|
logStackContent((void**)uc->uc_mcontext.gregs[15]);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
" Dumping of registers not supported for this OS/arch");
|
" Dumping of registers not supported for this OS/arch");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -774,15 +774,15 @@ void logCurrentClient(void) {
|
|||||||
sds client;
|
sds client;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
serverLog(REDIS_WARNING, "--- CURRENT CLIENT INFO");
|
serverLog(LL_WARNING, "--- CURRENT CLIENT INFO");
|
||||||
client = catClientInfoString(sdsempty(),cc);
|
client = catClientInfoString(sdsempty(),cc);
|
||||||
serverLog(REDIS_WARNING,"client: %s", client);
|
serverLog(LL_WARNING,"client: %s", client);
|
||||||
sdsfree(client);
|
sdsfree(client);
|
||||||
for (j = 0; j < cc->argc; j++) {
|
for (j = 0; j < cc->argc; j++) {
|
||||||
robj *decoded;
|
robj *decoded;
|
||||||
|
|
||||||
decoded = getDecodedObject(cc->argv[j]);
|
decoded = getDecodedObject(cc->argv[j]);
|
||||||
serverLog(REDIS_WARNING,"argv[%d]: '%s'", j, (char*)decoded->ptr);
|
serverLog(LL_WARNING,"argv[%d]: '%s'", j, (char*)decoded->ptr);
|
||||||
decrRefCount(decoded);
|
decrRefCount(decoded);
|
||||||
}
|
}
|
||||||
/* Check if the first argument, usually a key, is found inside the
|
/* Check if the first argument, usually a key, is found inside the
|
||||||
@ -795,7 +795,7 @@ void logCurrentClient(void) {
|
|||||||
de = dictFind(cc->db->dict, key->ptr);
|
de = dictFind(cc->db->dict, key->ptr);
|
||||||
if (de) {
|
if (de) {
|
||||||
val = dictGetVal(de);
|
val = dictGetVal(de);
|
||||||
serverLog(REDIS_WARNING,"key '%s' found in DB containing the following object:", (char*)key->ptr);
|
serverLog(LL_WARNING,"key '%s' found in DB containing the following object:", (char*)key->ptr);
|
||||||
serverLogObjectDebugInfo(val);
|
serverLogObjectDebugInfo(val);
|
||||||
}
|
}
|
||||||
decrRefCount(key);
|
decrRefCount(key);
|
||||||
@ -889,28 +889,28 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
|
|||||||
ucontext_t *uc = (ucontext_t*) secret;
|
ucontext_t *uc = (ucontext_t*) secret;
|
||||||
sds infostring, clients;
|
sds infostring, clients;
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
REDIS_NOTUSED(info);
|
UNUSED(info);
|
||||||
|
|
||||||
bugReportStart();
|
bugReportStart();
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
" Redis %s crashed by signal: %d", REDIS_VERSION, sig);
|
" Redis %s crashed by signal: %d", REDIS_VERSION, sig);
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
" Failed assertion: %s (%s:%d)", server.assert_failed,
|
" Failed assertion: %s (%s:%d)", server.assert_failed,
|
||||||
server.assert_file, server.assert_line);
|
server.assert_file, server.assert_line);
|
||||||
|
|
||||||
/* Log the stack trace */
|
/* Log the stack trace */
|
||||||
serverLog(REDIS_WARNING, "--- STACK TRACE");
|
serverLog(LL_WARNING, "--- STACK TRACE");
|
||||||
logStackTrace(uc);
|
logStackTrace(uc);
|
||||||
|
|
||||||
/* Log INFO and CLIENT LIST */
|
/* Log INFO and CLIENT LIST */
|
||||||
serverLog(REDIS_WARNING, "--- INFO OUTPUT");
|
serverLog(LL_WARNING, "--- INFO OUTPUT");
|
||||||
infostring = genRedisInfoString("all");
|
infostring = genRedisInfoString("all");
|
||||||
infostring = sdscatprintf(infostring, "hash_init_value: %u\n",
|
infostring = sdscatprintf(infostring, "hash_init_value: %u\n",
|
||||||
dictGetHashFunctionSeed());
|
dictGetHashFunctionSeed());
|
||||||
serverLogRaw(REDIS_WARNING, infostring);
|
serverLogRaw(LL_WARNING, infostring);
|
||||||
serverLog(REDIS_WARNING, "--- CLIENT LIST OUTPUT");
|
serverLog(LL_WARNING, "--- CLIENT LIST OUTPUT");
|
||||||
clients = getAllClientsInfoString();
|
clients = getAllClientsInfoString();
|
||||||
serverLogRaw(REDIS_WARNING, clients);
|
serverLogRaw(LL_WARNING, clients);
|
||||||
sdsfree(infostring);
|
sdsfree(infostring);
|
||||||
sdsfree(clients);
|
sdsfree(clients);
|
||||||
|
|
||||||
@ -922,18 +922,18 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
|
|||||||
|
|
||||||
#if defined(HAVE_PROC_MAPS)
|
#if defined(HAVE_PROC_MAPS)
|
||||||
/* Test memory */
|
/* Test memory */
|
||||||
serverLog(REDIS_WARNING, "--- FAST MEMORY TEST");
|
serverLog(LL_WARNING, "--- FAST MEMORY TEST");
|
||||||
bioKillThreads();
|
bioKillThreads();
|
||||||
if (memtest_test_linux_anonymous_maps()) {
|
if (memtest_test_linux_anonymous_maps()) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"!!! MEMORY ERROR DETECTED! Check your memory ASAP !!!");
|
"!!! MEMORY ERROR DETECTED! Check your memory ASAP !!!");
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Fast memory test PASSED, however your memory can still be broken. Please run a memory test for several hours if possible.");
|
"Fast memory test PASSED, however your memory can still be broken. Please run a memory test for several hours if possible.");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"\n=== REDIS BUG REPORT END. Make sure to include from START to END. ===\n\n"
|
"\n=== REDIS BUG REPORT END. Make sure to include from START to END. ===\n\n"
|
||||||
" Please report the crash by opening an issue on github:\n\n"
|
" Please report the crash by opening an issue on github:\n\n"
|
||||||
" http://github.com/antirez/redis/issues\n\n"
|
" http://github.com/antirez/redis/issues\n\n"
|
||||||
@ -969,11 +969,11 @@ void serverLogHexDump(int level, char *descr, void *value, size_t len) {
|
|||||||
len--;
|
len--;
|
||||||
v++;
|
v++;
|
||||||
if (b-buf == 64 || len == 0) {
|
if (b-buf == 64 || len == 0) {
|
||||||
serverLogRaw(level|REDIS_LOG_RAW,buf);
|
serverLogRaw(level|LL_RAW,buf);
|
||||||
b = buf;
|
b = buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serverLogRaw(level|REDIS_LOG_RAW,"\n");
|
serverLogRaw(level|LL_RAW,"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================== Software Watchdog ============================ */
|
/* =========================== Software Watchdog ============================ */
|
||||||
@ -983,16 +983,16 @@ void watchdogSignalHandler(int sig, siginfo_t *info, void *secret) {
|
|||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_BACKTRACE
|
||||||
ucontext_t *uc = (ucontext_t*) secret;
|
ucontext_t *uc = (ucontext_t*) secret;
|
||||||
#endif
|
#endif
|
||||||
REDIS_NOTUSED(info);
|
UNUSED(info);
|
||||||
REDIS_NOTUSED(sig);
|
UNUSED(sig);
|
||||||
|
|
||||||
serverLogFromHandler(REDIS_WARNING,"\n--- WATCHDOG TIMER EXPIRED ---");
|
serverLogFromHandler(LL_WARNING,"\n--- WATCHDOG TIMER EXPIRED ---");
|
||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_BACKTRACE
|
||||||
logStackTrace(uc);
|
logStackTrace(uc);
|
||||||
#else
|
#else
|
||||||
serverLogFromHandler(REDIS_WARNING,"Sorry: no support for backtrace().");
|
serverLogFromHandler(LL_WARNING,"Sorry: no support for backtrace().");
|
||||||
#endif
|
#endif
|
||||||
serverLogFromHandler(REDIS_WARNING,"--------\n");
|
serverLogFromHandler(LL_WARNING,"--------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Schedule a SIGALRM delivery after the specified period in milliseconds.
|
/* Schedule a SIGALRM delivery after the specified period in milliseconds.
|
||||||
|
@ -991,7 +991,7 @@ uint64_t hllCount(struct hllhdr *hdr, int *invalid) {
|
|||||||
} else if (hdr->encoding == HLL_RAW) {
|
} else if (hdr->encoding == HLL_RAW) {
|
||||||
E = hllRawSum(hdr->registers,PE,&ez);
|
E = hllRawSum(hdr->registers,PE,&ez);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown HyperLogLog encoding in hllCount()");
|
serverPanic("Unknown HyperLogLog encoding in hllCount()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Muliply the inverse of E for alpha_m * m^2 to have the raw estimate. */
|
/* Muliply the inverse of E for alpha_m * m^2 to have the raw estimate. */
|
||||||
@ -1184,7 +1184,7 @@ void pfaddCommand(client *c) {
|
|||||||
hdr = o->ptr;
|
hdr = o->ptr;
|
||||||
if (updated) {
|
if (updated) {
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"pfadd",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"pfadd",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
HLL_INVALIDATE_CACHE(hdr);
|
HLL_INVALIDATE_CACHE(hdr);
|
||||||
}
|
}
|
||||||
@ -1337,7 +1337,7 @@ void pfmergeCommand(client *c) {
|
|||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
/* We generate an PFADD event for PFMERGE for semantical simplicity
|
/* We generate an PFADD event for PFMERGE for semantical simplicity
|
||||||
* since in theory this is a mass-add of elements. */
|
* since in theory this is a mass-add of elements. */
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"pfadd",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"pfadd",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
/* Dictionary type for latency events. */
|
/* Dictionary type for latency events. */
|
||||||
int dictStringKeyCompare(void *privdata, const void *key1, const void *key2) {
|
int dictStringKeyCompare(void *privdata, const void *key1, const void *key2) {
|
||||||
REDIS_NOTUSED(privdata);
|
UNUSED(privdata);
|
||||||
return strcmp(key1,key2) == 0;
|
return strcmp(key1,key2) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
src/multi.c
36
src/multi.c
@ -72,28 +72,28 @@ void queueMultiCommand(client *c) {
|
|||||||
void discardTransaction(client *c) {
|
void discardTransaction(client *c) {
|
||||||
freeClientMultiState(c);
|
freeClientMultiState(c);
|
||||||
initClientMultiState(c);
|
initClientMultiState(c);
|
||||||
c->flags &= ~(REDIS_MULTI|REDIS_DIRTY_CAS|REDIS_DIRTY_EXEC);
|
c->flags &= ~(CLIENT_MULTI|CLIENT_DIRTY_CAS|CLIENT_DIRTY_EXEC);
|
||||||
unwatchAllKeys(c);
|
unwatchAllKeys(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flag the transacation as DIRTY_EXEC so that EXEC will fail.
|
/* Flag the transacation as DIRTY_EXEC so that EXEC will fail.
|
||||||
* Should be called every time there is an error while queueing a command. */
|
* Should be called every time there is an error while queueing a command. */
|
||||||
void flagTransaction(client *c) {
|
void flagTransaction(client *c) {
|
||||||
if (c->flags & REDIS_MULTI)
|
if (c->flags & CLIENT_MULTI)
|
||||||
c->flags |= REDIS_DIRTY_EXEC;
|
c->flags |= CLIENT_DIRTY_EXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
void multiCommand(client *c) {
|
void multiCommand(client *c) {
|
||||||
if (c->flags & REDIS_MULTI) {
|
if (c->flags & CLIENT_MULTI) {
|
||||||
addReplyError(c,"MULTI calls can not be nested");
|
addReplyError(c,"MULTI calls can not be nested");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c->flags |= REDIS_MULTI;
|
c->flags |= CLIENT_MULTI;
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
void discardCommand(client *c) {
|
void discardCommand(client *c) {
|
||||||
if (!(c->flags & REDIS_MULTI)) {
|
if (!(c->flags & CLIENT_MULTI)) {
|
||||||
addReplyError(c,"DISCARD without MULTI");
|
addReplyError(c,"DISCARD without MULTI");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ void execCommandPropagateMulti(client *c) {
|
|||||||
robj *multistring = createStringObject("MULTI",5);
|
robj *multistring = createStringObject("MULTI",5);
|
||||||
|
|
||||||
propagate(server.multiCommand,c->db->id,&multistring,1,
|
propagate(server.multiCommand,c->db->id,&multistring,1,
|
||||||
REDIS_PROPAGATE_AOF|REDIS_PROPAGATE_REPL);
|
PROPAGATE_AOF|PROPAGATE_REPL);
|
||||||
decrRefCount(multistring);
|
decrRefCount(multistring);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ void execCommand(client *c) {
|
|||||||
struct redisCommand *orig_cmd;
|
struct redisCommand *orig_cmd;
|
||||||
int must_propagate = 0; /* Need to propagate MULTI/EXEC to AOF / slaves? */
|
int must_propagate = 0; /* Need to propagate MULTI/EXEC to AOF / slaves? */
|
||||||
|
|
||||||
if (!(c->flags & REDIS_MULTI)) {
|
if (!(c->flags & CLIENT_MULTI)) {
|
||||||
addReplyError(c,"EXEC without MULTI");
|
addReplyError(c,"EXEC without MULTI");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -129,8 +129,8 @@ void execCommand(client *c) {
|
|||||||
* A failed EXEC in the first case returns a multi bulk nil object
|
* A failed EXEC in the first case returns a multi bulk nil object
|
||||||
* (technically it is not an error but a special behavior), while
|
* (technically it is not an error but a special behavior), while
|
||||||
* in the second an EXECABORT error is returned. */
|
* in the second an EXECABORT error is returned. */
|
||||||
if (c->flags & (REDIS_DIRTY_CAS|REDIS_DIRTY_EXEC)) {
|
if (c->flags & (CLIENT_DIRTY_CAS|CLIENT_DIRTY_EXEC)) {
|
||||||
addReply(c, c->flags & REDIS_DIRTY_EXEC ? shared.execaborterr :
|
addReply(c, c->flags & CLIENT_DIRTY_EXEC ? shared.execaborterr :
|
||||||
shared.nullmultibulk);
|
shared.nullmultibulk);
|
||||||
discardTransaction(c);
|
discardTransaction(c);
|
||||||
goto handle_monitor;
|
goto handle_monitor;
|
||||||
@ -151,12 +151,12 @@ void execCommand(client *c) {
|
|||||||
* This way we'll deliver the MULTI/..../EXEC block as a whole and
|
* This way we'll deliver the MULTI/..../EXEC block as a whole and
|
||||||
* both the AOF and the replication link will have the same consistency
|
* both the AOF and the replication link will have the same consistency
|
||||||
* and atomicity guarantees. */
|
* and atomicity guarantees. */
|
||||||
if (!must_propagate && !(c->cmd->flags & REDIS_CMD_READONLY)) {
|
if (!must_propagate && !(c->cmd->flags & CMD_READONLY)) {
|
||||||
execCommandPropagateMulti(c);
|
execCommandPropagateMulti(c);
|
||||||
must_propagate = 1;
|
must_propagate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
call(c,REDIS_CALL_FULL);
|
call(c,CMD_CALL_FULL);
|
||||||
|
|
||||||
/* Commands may alter argc/argv, restore mstate. */
|
/* Commands may alter argc/argv, restore mstate. */
|
||||||
c->mstate.commands[j].argc = c->argc;
|
c->mstate.commands[j].argc = c->argc;
|
||||||
@ -175,7 +175,7 @@ handle_monitor:
|
|||||||
/* Send EXEC to clients waiting data from MONITOR. We do it here
|
/* Send EXEC to clients waiting data from MONITOR. We do it here
|
||||||
* since the natural order of commands execution is actually:
|
* since the natural order of commands execution is actually:
|
||||||
* MUTLI, EXEC, ... commands inside transaction ...
|
* MUTLI, EXEC, ... commands inside transaction ...
|
||||||
* Instead EXEC is flagged as REDIS_CMD_SKIP_MONITOR in the command
|
* Instead EXEC is flagged as CMD_SKIP_MONITOR in the command
|
||||||
* table, and we do it here with correct ordering. */
|
* table, and we do it here with correct ordering. */
|
||||||
if (listLength(server.monitors) && !server.loading)
|
if (listLength(server.monitors) && !server.loading)
|
||||||
replicationFeedMonitors(c,server.monitors,c->db->id,c->argv,c->argc);
|
replicationFeedMonitors(c,server.monitors,c->db->id,c->argv,c->argc);
|
||||||
@ -267,13 +267,13 @@ void touchWatchedKey(redisDb *db, robj *key) {
|
|||||||
clients = dictFetchValue(db->watched_keys, key);
|
clients = dictFetchValue(db->watched_keys, key);
|
||||||
if (!clients) return;
|
if (!clients) return;
|
||||||
|
|
||||||
/* Mark all the clients watching this key as REDIS_DIRTY_CAS */
|
/* Mark all the clients watching this key as CLIENT_DIRTY_CAS */
|
||||||
/* Check if we are already watching for this key */
|
/* Check if we are already watching for this key */
|
||||||
listRewind(clients,&li);
|
listRewind(clients,&li);
|
||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
client *c = listNodeValue(ln);
|
client *c = listNodeValue(ln);
|
||||||
|
|
||||||
c->flags |= REDIS_DIRTY_CAS;
|
c->flags |= CLIENT_DIRTY_CAS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ void touchWatchedKeysOnFlush(int dbid) {
|
|||||||
* removed. */
|
* removed. */
|
||||||
if (dbid == -1 || wk->db->id == dbid) {
|
if (dbid == -1 || wk->db->id == dbid) {
|
||||||
if (dictFind(wk->db->dict, wk->key->ptr) != NULL)
|
if (dictFind(wk->db->dict, wk->key->ptr) != NULL)
|
||||||
c->flags |= REDIS_DIRTY_CAS;
|
c->flags |= CLIENT_DIRTY_CAS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ void touchWatchedKeysOnFlush(int dbid) {
|
|||||||
void watchCommand(client *c) {
|
void watchCommand(client *c) {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
if (c->flags & REDIS_MULTI) {
|
if (c->flags & CLIENT_MULTI) {
|
||||||
addReplyError(c,"WATCH inside MULTI is not allowed");
|
addReplyError(c,"WATCH inside MULTI is not allowed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -318,6 +318,6 @@ void watchCommand(client *c) {
|
|||||||
|
|
||||||
void unwatchCommand(client *c) {
|
void unwatchCommand(client *c) {
|
||||||
unwatchAllKeys(c);
|
unwatchAllKeys(c);
|
||||||
c->flags &= (~REDIS_DIRTY_CAS);
|
c->flags &= (~CLIENT_DIRTY_CAS);
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
|
254
src/networking.c
254
src/networking.c
@ -65,7 +65,7 @@ client *createClient(int fd) {
|
|||||||
client *c = zmalloc(sizeof(client));
|
client *c = zmalloc(sizeof(client));
|
||||||
|
|
||||||
/* passing -1 as fd it is possible to create a non connected client.
|
/* passing -1 as fd it is possible to create a non connected client.
|
||||||
* This is useful since all the Redis commands needs to be executed
|
* This is useful since all the commands needs to be executed
|
||||||
* in the context of a client. When commands are executed in other
|
* in the context of a client. When commands are executed in other
|
||||||
* contexts (for instance a Lua script) we need a non connected client. */
|
* contexts (for instance a Lua script) we need a non connected client. */
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
@ -99,7 +99,7 @@ client *createClient(int fd) {
|
|||||||
c->flags = 0;
|
c->flags = 0;
|
||||||
c->ctime = c->lastinteraction = server.unixtime;
|
c->ctime = c->lastinteraction = server.unixtime;
|
||||||
c->authenticated = 0;
|
c->authenticated = 0;
|
||||||
c->replstate = REDIS_REPL_NONE;
|
c->replstate = REPL_STATE_NONE;
|
||||||
c->repl_put_online_on_ack = 0;
|
c->repl_put_online_on_ack = 0;
|
||||||
c->reploff = 0;
|
c->reploff = 0;
|
||||||
c->repl_ack_off = 0;
|
c->repl_ack_off = 0;
|
||||||
@ -110,7 +110,7 @@ client *createClient(int fd) {
|
|||||||
c->obuf_soft_limit_reached_time = 0;
|
c->obuf_soft_limit_reached_time = 0;
|
||||||
listSetFreeMethod(c->reply,decrRefCountVoid);
|
listSetFreeMethod(c->reply,decrRefCountVoid);
|
||||||
listSetDupMethod(c->reply,dupClientReplyValue);
|
listSetDupMethod(c->reply,dupClientReplyValue);
|
||||||
c->btype = REDIS_BLOCKED_NONE;
|
c->btype = BLOCKED_NONE;
|
||||||
c->bpop.timeout = 0;
|
c->bpop.timeout = 0;
|
||||||
c->bpop.keys = dictCreate(&setDictType,NULL);
|
c->bpop.keys = dictCreate(&setDictType,NULL);
|
||||||
c->bpop.target = NULL;
|
c->bpop.target = NULL;
|
||||||
@ -153,20 +153,20 @@ client *createClient(int fd) {
|
|||||||
int prepareClientToWrite(client *c) {
|
int prepareClientToWrite(client *c) {
|
||||||
/* If it's the Lua client we always return ok without installing any
|
/* If it's the Lua client we always return ok without installing any
|
||||||
* handler since there is no socket at all. */
|
* handler since there is no socket at all. */
|
||||||
if (c->flags & REDIS_LUA_CLIENT) return C_OK;
|
if (c->flags & CLIENT_LUA) return C_OK;
|
||||||
|
|
||||||
/* Masters don't receive replies, unless REDIS_MASTER_FORCE_REPLY flag
|
/* Masters don't receive replies, unless CLIENT_MASTER_FORCE_REPLY flag
|
||||||
* is set. */
|
* is set. */
|
||||||
if ((c->flags & REDIS_MASTER) &&
|
if ((c->flags & CLIENT_MASTER) &&
|
||||||
!(c->flags & REDIS_MASTER_FORCE_REPLY)) return C_ERR;
|
!(c->flags & CLIENT_MASTER_FORCE_REPLY)) return C_ERR;
|
||||||
|
|
||||||
if (c->fd <= 0) return C_ERR; /* Fake client for AOF loading. */
|
if (c->fd <= 0) return C_ERR; /* Fake client for AOF loading. */
|
||||||
|
|
||||||
/* Only install the handler if not already installed and, in case of
|
/* Only install the handler if not already installed and, in case of
|
||||||
* slaves, if the client can actually receive writes. */
|
* slaves, if the client can actually receive writes. */
|
||||||
if (c->bufpos == 0 && listLength(c->reply) == 0 &&
|
if (c->bufpos == 0 && listLength(c->reply) == 0 &&
|
||||||
(c->replstate == REDIS_REPL_NONE ||
|
(c->replstate == REPL_STATE_NONE ||
|
||||||
(c->replstate == REDIS_REPL_ONLINE && !c->repl_put_online_on_ack)))
|
(c->replstate == SLAVE_STATE_ONLINE && !c->repl_put_online_on_ack)))
|
||||||
{
|
{
|
||||||
/* Try to install the write handler. */
|
/* Try to install the write handler. */
|
||||||
if (aeCreateFileEvent(server.el, c->fd, AE_WRITABLE,
|
if (aeCreateFileEvent(server.el, c->fd, AE_WRITABLE,
|
||||||
@ -204,7 +204,7 @@ robj *dupLastObjectIfNeeded(list *reply) {
|
|||||||
int _addReplyToBuffer(client *c, const char *s, size_t len) {
|
int _addReplyToBuffer(client *c, const char *s, size_t len) {
|
||||||
size_t available = sizeof(c->buf)-c->bufpos;
|
size_t available = sizeof(c->buf)-c->bufpos;
|
||||||
|
|
||||||
if (c->flags & REDIS_CLOSE_AFTER_REPLY) return C_OK;
|
if (c->flags & CLIENT_CLOSE_AFTER_REPLY) return C_OK;
|
||||||
|
|
||||||
/* If there already are entries in the reply list, we cannot
|
/* If there already are entries in the reply list, we cannot
|
||||||
* add anything more to the static buffer. */
|
* add anything more to the static buffer. */
|
||||||
@ -221,7 +221,7 @@ int _addReplyToBuffer(client *c, const char *s, size_t len) {
|
|||||||
void _addReplyObjectToList(client *c, robj *o) {
|
void _addReplyObjectToList(client *c, robj *o) {
|
||||||
robj *tail;
|
robj *tail;
|
||||||
|
|
||||||
if (c->flags & REDIS_CLOSE_AFTER_REPLY) return;
|
if (c->flags & CLIENT_CLOSE_AFTER_REPLY) return;
|
||||||
|
|
||||||
if (listLength(c->reply) == 0) {
|
if (listLength(c->reply) == 0) {
|
||||||
incrRefCount(o);
|
incrRefCount(o);
|
||||||
@ -233,7 +233,7 @@ void _addReplyObjectToList(client *c, robj *o) {
|
|||||||
/* Append to this object when possible. */
|
/* Append to this object when possible. */
|
||||||
if (tail->ptr != NULL &&
|
if (tail->ptr != NULL &&
|
||||||
tail->encoding == OBJ_ENCODING_RAW &&
|
tail->encoding == OBJ_ENCODING_RAW &&
|
||||||
sdslen(tail->ptr)+sdslen(o->ptr) <= REDIS_REPLY_CHUNK_BYTES)
|
sdslen(tail->ptr)+sdslen(o->ptr) <= PROTO_REPLY_CHUNK_BYTES)
|
||||||
{
|
{
|
||||||
c->reply_bytes -= sdsZmallocSize(tail->ptr);
|
c->reply_bytes -= sdsZmallocSize(tail->ptr);
|
||||||
tail = dupLastObjectIfNeeded(c->reply);
|
tail = dupLastObjectIfNeeded(c->reply);
|
||||||
@ -253,7 +253,7 @@ void _addReplyObjectToList(client *c, robj *o) {
|
|||||||
void _addReplySdsToList(client *c, sds s) {
|
void _addReplySdsToList(client *c, sds s) {
|
||||||
robj *tail;
|
robj *tail;
|
||||||
|
|
||||||
if (c->flags & REDIS_CLOSE_AFTER_REPLY) {
|
if (c->flags & CLIENT_CLOSE_AFTER_REPLY) {
|
||||||
sdsfree(s);
|
sdsfree(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -266,7 +266,7 @@ void _addReplySdsToList(client *c, sds s) {
|
|||||||
|
|
||||||
/* Append to this object when possible. */
|
/* Append to this object when possible. */
|
||||||
if (tail->ptr != NULL && tail->encoding == OBJ_ENCODING_RAW &&
|
if (tail->ptr != NULL && tail->encoding == OBJ_ENCODING_RAW &&
|
||||||
sdslen(tail->ptr)+sdslen(s) <= REDIS_REPLY_CHUNK_BYTES)
|
sdslen(tail->ptr)+sdslen(s) <= PROTO_REPLY_CHUNK_BYTES)
|
||||||
{
|
{
|
||||||
c->reply_bytes -= sdsZmallocSize(tail->ptr);
|
c->reply_bytes -= sdsZmallocSize(tail->ptr);
|
||||||
tail = dupLastObjectIfNeeded(c->reply);
|
tail = dupLastObjectIfNeeded(c->reply);
|
||||||
@ -284,7 +284,7 @@ void _addReplySdsToList(client *c, sds s) {
|
|||||||
void _addReplyStringToList(client *c, const char *s, size_t len) {
|
void _addReplyStringToList(client *c, const char *s, size_t len) {
|
||||||
robj *tail;
|
robj *tail;
|
||||||
|
|
||||||
if (c->flags & REDIS_CLOSE_AFTER_REPLY) return;
|
if (c->flags & CLIENT_CLOSE_AFTER_REPLY) return;
|
||||||
|
|
||||||
if (listLength(c->reply) == 0) {
|
if (listLength(c->reply) == 0) {
|
||||||
robj *o = createStringObject(s,len);
|
robj *o = createStringObject(s,len);
|
||||||
@ -296,7 +296,7 @@ void _addReplyStringToList(client *c, const char *s, size_t len) {
|
|||||||
|
|
||||||
/* Append to this object when possible. */
|
/* Append to this object when possible. */
|
||||||
if (tail->ptr != NULL && tail->encoding == OBJ_ENCODING_RAW &&
|
if (tail->ptr != NULL && tail->encoding == OBJ_ENCODING_RAW &&
|
||||||
sdslen(tail->ptr)+len <= REDIS_REPLY_CHUNK_BYTES)
|
sdslen(tail->ptr)+len <= PROTO_REPLY_CHUNK_BYTES)
|
||||||
{
|
{
|
||||||
c->reply_bytes -= sdsZmallocSize(tail->ptr);
|
c->reply_bytes -= sdsZmallocSize(tail->ptr);
|
||||||
tail = dupLastObjectIfNeeded(c->reply);
|
tail = dupLastObjectIfNeeded(c->reply);
|
||||||
@ -349,7 +349,7 @@ void addReply(client *c, robj *obj) {
|
|||||||
_addReplyObjectToList(c,obj);
|
_addReplyObjectToList(c,obj);
|
||||||
decrRefCount(obj);
|
decrRefCount(obj);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Wrong obj->encoding in addReply()");
|
serverPanic("Wrong obj->encoding in addReply()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,10 +480,10 @@ void addReplyLongLongWithPrefix(client *c, long long ll, char prefix) {
|
|||||||
/* Things like $3\r\n or *2\r\n are emitted very often by the protocol
|
/* Things like $3\r\n or *2\r\n are emitted very often by the protocol
|
||||||
* so we have a few shared objects to use if the integer is small
|
* so we have a few shared objects to use if the integer is small
|
||||||
* like it is most of the times. */
|
* like it is most of the times. */
|
||||||
if (prefix == '*' && ll < REDIS_SHARED_BULKHDR_LEN && ll >= 0) {
|
if (prefix == '*' && ll < OBJ_SHARED_BULKHDR_LEN && ll >= 0) {
|
||||||
addReply(c,shared.mbulkhdr[ll]);
|
addReply(c,shared.mbulkhdr[ll]);
|
||||||
return;
|
return;
|
||||||
} else if (prefix == '$' && ll < REDIS_SHARED_BULKHDR_LEN && ll >= 0) {
|
} else if (prefix == '$' && ll < OBJ_SHARED_BULKHDR_LEN && ll >= 0) {
|
||||||
addReply(c,shared.bulkhdr[ll]);
|
addReply(c,shared.bulkhdr[ll]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -505,7 +505,7 @@ void addReplyLongLong(client *c, long long ll) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addReplyMultiBulkLen(client *c, long length) {
|
void addReplyMultiBulkLen(client *c, long length) {
|
||||||
if (length < REDIS_SHARED_BULKHDR_LEN)
|
if (length < OBJ_SHARED_BULKHDR_LEN)
|
||||||
addReply(c,shared.mbulkhdr[length]);
|
addReply(c,shared.mbulkhdr[length]);
|
||||||
else
|
else
|
||||||
addReplyLongLongWithPrefix(c,length,'*');
|
addReplyLongLongWithPrefix(c,length,'*');
|
||||||
@ -531,7 +531,7 @@ void addReplyBulkLen(client *c, robj *obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < REDIS_SHARED_BULKHDR_LEN)
|
if (len < OBJ_SHARED_BULKHDR_LEN)
|
||||||
addReply(c,shared.bulkhdr[len]);
|
addReply(c,shared.bulkhdr[len]);
|
||||||
else
|
else
|
||||||
addReplyLongLongWithPrefix(c,len,'$');
|
addReplyLongLongWithPrefix(c,len,'$');
|
||||||
@ -592,7 +592,7 @@ void copyClientOutputBuffer(client *dst, client *src) {
|
|||||||
static void acceptCommonHandler(int fd, int flags) {
|
static void acceptCommonHandler(int fd, int flags) {
|
||||||
client *c;
|
client *c;
|
||||||
if ((c = createClient(fd)) == NULL) {
|
if ((c = createClient(fd)) == NULL) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Error registering fd event for the new client: %s (fd=%d)",
|
"Error registering fd event for the new client: %s (fd=%d)",
|
||||||
strerror(errno),fd);
|
strerror(errno),fd);
|
||||||
close(fd); /* May be already closed, just ignore errors */
|
close(fd); /* May be already closed, just ignore errors */
|
||||||
@ -619,40 +619,40 @@ static void acceptCommonHandler(int fd, int flags) {
|
|||||||
|
|
||||||
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
|
int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
|
||||||
char cip[REDIS_IP_STR_LEN];
|
char cip[NET_IP_STR_LEN];
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
REDIS_NOTUSED(privdata);
|
UNUSED(privdata);
|
||||||
|
|
||||||
while(max--) {
|
while(max--) {
|
||||||
cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
|
cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
|
||||||
if (cfd == ANET_ERR) {
|
if (cfd == ANET_ERR) {
|
||||||
if (errno != EWOULDBLOCK)
|
if (errno != EWOULDBLOCK)
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Accepting client connection: %s", server.neterr);
|
"Accepting client connection: %s", server.neterr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_VERBOSE,"Accepted %s:%d", cip, cport);
|
serverLog(LL_VERBOSE,"Accepted %s:%d", cip, cport);
|
||||||
acceptCommonHandler(cfd,0);
|
acceptCommonHandler(cfd,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
int cfd, max = MAX_ACCEPTS_PER_CALL;
|
int cfd, max = MAX_ACCEPTS_PER_CALL;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
REDIS_NOTUSED(privdata);
|
UNUSED(privdata);
|
||||||
|
|
||||||
while(max--) {
|
while(max--) {
|
||||||
cfd = anetUnixAccept(server.neterr, fd);
|
cfd = anetUnixAccept(server.neterr, fd);
|
||||||
if (cfd == ANET_ERR) {
|
if (cfd == ANET_ERR) {
|
||||||
if (errno != EWOULDBLOCK)
|
if (errno != EWOULDBLOCK)
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Accepting client connection: %s", server.neterr);
|
"Accepting client connection: %s", server.neterr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_VERBOSE,"Accepted connection to %s", server.unixsocket);
|
serverLog(LL_VERBOSE,"Accepted connection to %s", server.unixsocket);
|
||||||
acceptCommonHandler(cfd,REDIS_UNIX_SOCKET);
|
acceptCommonHandler(cfd,CLIENT_UNIX_SOCKET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,7 +678,7 @@ void disconnectSlaves(void) {
|
|||||||
* master into an unexpected way. */
|
* master into an unexpected way. */
|
||||||
void replicationHandleMasterDisconnection(void) {
|
void replicationHandleMasterDisconnection(void) {
|
||||||
server.master = NULL;
|
server.master = NULL;
|
||||||
server.repl_state = REDIS_REPL_CONNECT;
|
server.repl_state = REPL_STATE_CONNECT;
|
||||||
server.repl_down_since = server.unixtime;
|
server.repl_down_since = server.unixtime;
|
||||||
/* We lost connection with our master, force our slaves to resync
|
/* We lost connection with our master, force our slaves to resync
|
||||||
* with us as well to load the new data set.
|
* with us as well to load the new data set.
|
||||||
@ -699,12 +699,12 @@ void freeClient(client *c) {
|
|||||||
*
|
*
|
||||||
* Note that before doing this we make sure that the client is not in
|
* Note that before doing this we make sure that the client is not in
|
||||||
* some unexpected state, by checking its flags. */
|
* some unexpected state, by checking its flags. */
|
||||||
if (server.master && c->flags & REDIS_MASTER) {
|
if (server.master && c->flags & CLIENT_MASTER) {
|
||||||
serverLog(REDIS_WARNING,"Connection with master lost.");
|
serverLog(LL_WARNING,"Connection with master lost.");
|
||||||
if (!(c->flags & (REDIS_CLOSE_AFTER_REPLY|
|
if (!(c->flags & (CLIENT_CLOSE_AFTER_REPLY|
|
||||||
REDIS_CLOSE_ASAP|
|
CLIENT_CLOSE_ASAP|
|
||||||
REDIS_BLOCKED|
|
CLIENT_BLOCKED|
|
||||||
REDIS_UNBLOCKED)))
|
CLIENT_UNBLOCKED)))
|
||||||
{
|
{
|
||||||
replicationCacheMaster(c);
|
replicationCacheMaster(c);
|
||||||
return;
|
return;
|
||||||
@ -712,8 +712,8 @@ void freeClient(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Log link disconnection with slave */
|
/* Log link disconnection with slave */
|
||||||
if ((c->flags & REDIS_SLAVE) && !(c->flags & REDIS_MONITOR)) {
|
if ((c->flags & CLIENT_SLAVE) && !(c->flags & CLIENT_MONITOR)) {
|
||||||
serverLog(REDIS_WARNING,"Connection with slave %s lost.",
|
serverLog(LL_WARNING,"Connection with slave %s lost.",
|
||||||
replicationGetSlaveName(c));
|
replicationGetSlaveName(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,7 +722,7 @@ void freeClient(client *c) {
|
|||||||
c->querybuf = NULL;
|
c->querybuf = NULL;
|
||||||
|
|
||||||
/* Deallocate structures used to block on blocking ops. */
|
/* Deallocate structures used to block on blocking ops. */
|
||||||
if (c->flags & REDIS_BLOCKED) unblockClient(c);
|
if (c->flags & CLIENT_BLOCKED) unblockClient(c);
|
||||||
dictRelease(c->bpop.keys);
|
dictRelease(c->bpop.keys);
|
||||||
|
|
||||||
/* UNWATCH all the keys */
|
/* UNWATCH all the keys */
|
||||||
@ -754,7 +754,7 @@ void freeClient(client *c) {
|
|||||||
|
|
||||||
/* When client was just unblocked because of a blocking operation,
|
/* When client was just unblocked because of a blocking operation,
|
||||||
* remove it from the list of unblocked clients. */
|
* remove it from the list of unblocked clients. */
|
||||||
if (c->flags & REDIS_UNBLOCKED) {
|
if (c->flags & CLIENT_UNBLOCKED) {
|
||||||
ln = listSearchKey(server.unblocked_clients,c);
|
ln = listSearchKey(server.unblocked_clients,c);
|
||||||
serverAssert(ln != NULL);
|
serverAssert(ln != NULL);
|
||||||
listDelNode(server.unblocked_clients,ln);
|
listDelNode(server.unblocked_clients,ln);
|
||||||
@ -762,30 +762,30 @@ void freeClient(client *c) {
|
|||||||
|
|
||||||
/* Master/slave cleanup Case 1:
|
/* Master/slave cleanup Case 1:
|
||||||
* we lost the connection with a slave. */
|
* we lost the connection with a slave. */
|
||||||
if (c->flags & REDIS_SLAVE) {
|
if (c->flags & CLIENT_SLAVE) {
|
||||||
if (c->replstate == REDIS_REPL_SEND_BULK) {
|
if (c->replstate == SLAVE_STATE_SEND_BULK) {
|
||||||
if (c->repldbfd != -1) close(c->repldbfd);
|
if (c->repldbfd != -1) close(c->repldbfd);
|
||||||
if (c->replpreamble) sdsfree(c->replpreamble);
|
if (c->replpreamble) sdsfree(c->replpreamble);
|
||||||
}
|
}
|
||||||
list *l = (c->flags & REDIS_MONITOR) ? server.monitors : server.slaves;
|
list *l = (c->flags & CLIENT_MONITOR) ? server.monitors : server.slaves;
|
||||||
ln = listSearchKey(l,c);
|
ln = listSearchKey(l,c);
|
||||||
serverAssert(ln != NULL);
|
serverAssert(ln != NULL);
|
||||||
listDelNode(l,ln);
|
listDelNode(l,ln);
|
||||||
/* We need to remember the time when we started to have zero
|
/* We need to remember the time when we started to have zero
|
||||||
* attached slaves, as after some time we'll free the replication
|
* attached slaves, as after some time we'll free the replication
|
||||||
* backlog. */
|
* backlog. */
|
||||||
if (c->flags & REDIS_SLAVE && listLength(server.slaves) == 0)
|
if (c->flags & CLIENT_SLAVE && listLength(server.slaves) == 0)
|
||||||
server.repl_no_slaves_since = server.unixtime;
|
server.repl_no_slaves_since = server.unixtime;
|
||||||
refreshGoodSlavesCount();
|
refreshGoodSlavesCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Master/slave cleanup Case 2:
|
/* Master/slave cleanup Case 2:
|
||||||
* we lost the connection with the master. */
|
* we lost the connection with the master. */
|
||||||
if (c->flags & REDIS_MASTER) replicationHandleMasterDisconnection();
|
if (c->flags & CLIENT_MASTER) replicationHandleMasterDisconnection();
|
||||||
|
|
||||||
/* If this client was scheduled for async freeing we need to remove it
|
/* If this client was scheduled for async freeing we need to remove it
|
||||||
* from the queue. */
|
* from the queue. */
|
||||||
if (c->flags & REDIS_CLOSE_ASAP) {
|
if (c->flags & CLIENT_CLOSE_ASAP) {
|
||||||
ln = listSearchKey(server.clients_to_close,c);
|
ln = listSearchKey(server.clients_to_close,c);
|
||||||
serverAssert(ln != NULL);
|
serverAssert(ln != NULL);
|
||||||
listDelNode(server.clients_to_close,ln);
|
listDelNode(server.clients_to_close,ln);
|
||||||
@ -805,8 +805,8 @@ void freeClient(client *c) {
|
|||||||
* a context where calling freeClient() is not possible, because the client
|
* a context where calling freeClient() is not possible, because the client
|
||||||
* should be valid for the continuation of the flow of the program. */
|
* should be valid for the continuation of the flow of the program. */
|
||||||
void freeClientAsync(client *c) {
|
void freeClientAsync(client *c) {
|
||||||
if (c->flags & REDIS_CLOSE_ASAP || c->flags & REDIS_LUA_CLIENT) return;
|
if (c->flags & CLIENT_CLOSE_ASAP || c->flags & CLIENT_LUA) return;
|
||||||
c->flags |= REDIS_CLOSE_ASAP;
|
c->flags |= CLIENT_CLOSE_ASAP;
|
||||||
listAddNodeTail(server.clients_to_close,c);
|
listAddNodeTail(server.clients_to_close,c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,7 +815,7 @@ void freeClientsInAsyncFreeQueue(void) {
|
|||||||
listNode *ln = listFirst(server.clients_to_close);
|
listNode *ln = listFirst(server.clients_to_close);
|
||||||
client *c = listNodeValue(ln);
|
client *c = listNodeValue(ln);
|
||||||
|
|
||||||
c->flags &= ~REDIS_CLOSE_ASAP;
|
c->flags &= ~CLIENT_CLOSE_ASAP;
|
||||||
freeClient(c);
|
freeClient(c);
|
||||||
listDelNode(server.clients_to_close,ln);
|
listDelNode(server.clients_to_close,ln);
|
||||||
}
|
}
|
||||||
@ -827,8 +827,8 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
size_t objlen;
|
size_t objlen;
|
||||||
size_t objmem;
|
size_t objmem;
|
||||||
robj *o;
|
robj *o;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
|
|
||||||
while(c->bufpos > 0 || listLength(c->reply)) {
|
while(c->bufpos > 0 || listLength(c->reply)) {
|
||||||
if (c->bufpos > 0) {
|
if (c->bufpos > 0) {
|
||||||
@ -866,7 +866,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
c->reply_bytes -= objmem;
|
c->reply_bytes -= objmem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Note that we avoid to send more than REDIS_MAX_WRITE_PER_EVENT
|
/* Note that we avoid to send more than NET_MAX_WRITES_PER_EVENT
|
||||||
* bytes, in a single threaded server it's a good idea to serve
|
* bytes, in a single threaded server it's a good idea to serve
|
||||||
* other clients as well, even if a very large request comes from
|
* other clients as well, even if a very large request comes from
|
||||||
* super fast link that is always able to accept data (in real world
|
* super fast link that is always able to accept data (in real world
|
||||||
@ -875,7 +875,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
* However if we are over the maxmemory limit we ignore that and
|
* However if we are over the maxmemory limit we ignore that and
|
||||||
* just deliver as much data as it is possible to deliver. */
|
* just deliver as much data as it is possible to deliver. */
|
||||||
server.stat_net_output_bytes += totwritten;
|
server.stat_net_output_bytes += totwritten;
|
||||||
if (totwritten > REDIS_MAX_WRITE_PER_EVENT &&
|
if (totwritten > NET_MAX_WRITES_PER_EVENT &&
|
||||||
(server.maxmemory == 0 ||
|
(server.maxmemory == 0 ||
|
||||||
zmalloc_used_memory() < server.maxmemory)) break;
|
zmalloc_used_memory() < server.maxmemory)) break;
|
||||||
}
|
}
|
||||||
@ -883,7 +883,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
nwritten = 0;
|
nwritten = 0;
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"Error writing to client: %s", strerror(errno));
|
"Error writing to client: %s", strerror(errno));
|
||||||
freeClient(c);
|
freeClient(c);
|
||||||
return;
|
return;
|
||||||
@ -894,14 +894,14 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
* as an interaction, since we always send REPLCONF ACK commands
|
* as an interaction, since we always send REPLCONF ACK commands
|
||||||
* that take some time to just fill the socket output buffer.
|
* that take some time to just fill the socket output buffer.
|
||||||
* We just rely on data / pings received for timeout detection. */
|
* We just rely on data / pings received for timeout detection. */
|
||||||
if (!(c->flags & REDIS_MASTER)) c->lastinteraction = server.unixtime;
|
if (!(c->flags & CLIENT_MASTER)) c->lastinteraction = server.unixtime;
|
||||||
}
|
}
|
||||||
if (c->bufpos == 0 && listLength(c->reply) == 0) {
|
if (c->bufpos == 0 && listLength(c->reply) == 0) {
|
||||||
c->sentlen = 0;
|
c->sentlen = 0;
|
||||||
aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE);
|
aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE);
|
||||||
|
|
||||||
/* Close connection after entire reply has been sent. */
|
/* Close connection after entire reply has been sent. */
|
||||||
if (c->flags & REDIS_CLOSE_AFTER_REPLY) freeClient(c);
|
if (c->flags & CLIENT_CLOSE_AFTER_REPLY) freeClient(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -915,8 +915,8 @@ void resetClient(client *c) {
|
|||||||
c->bulklen = -1;
|
c->bulklen = -1;
|
||||||
/* We clear the ASKING flag as well if we are not inside a MULTI, and
|
/* We clear the ASKING flag as well if we are not inside a MULTI, and
|
||||||
* if what we just executed is not the ASKING command itself. */
|
* if what we just executed is not the ASKING command itself. */
|
||||||
if (!(c->flags & REDIS_MULTI) && prevcmd != askingCommand)
|
if (!(c->flags & CLIENT_MULTI) && prevcmd != askingCommand)
|
||||||
c->flags &= (~REDIS_ASKING);
|
c->flags &= (~CLIENT_ASKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
int processInlineBuffer(client *c) {
|
int processInlineBuffer(client *c) {
|
||||||
@ -930,7 +930,7 @@ int processInlineBuffer(client *c) {
|
|||||||
|
|
||||||
/* Nothing to do without a \r\n */
|
/* Nothing to do without a \r\n */
|
||||||
if (newline == NULL) {
|
if (newline == NULL) {
|
||||||
if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) {
|
if (sdslen(c->querybuf) > PROTO_INLINE_MAX_SIZE) {
|
||||||
addReplyError(c,"Protocol error: too big inline request");
|
addReplyError(c,"Protocol error: too big inline request");
|
||||||
setProtocolError(c,0);
|
setProtocolError(c,0);
|
||||||
}
|
}
|
||||||
@ -955,7 +955,7 @@ int processInlineBuffer(client *c) {
|
|||||||
/* Newline from slaves can be used to refresh the last ACK time.
|
/* Newline from slaves can be used to refresh the last ACK time.
|
||||||
* This is useful for a slave to ping back while loading a big
|
* This is useful for a slave to ping back while loading a big
|
||||||
* RDB file. */
|
* RDB file. */
|
||||||
if (querylen == 0 && c->flags & REDIS_SLAVE)
|
if (querylen == 0 && c->flags & CLIENT_SLAVE)
|
||||||
c->repl_ack_time = server.unixtime;
|
c->repl_ack_time = server.unixtime;
|
||||||
|
|
||||||
/* Leave data after the first line of the query in the buffer */
|
/* Leave data after the first line of the query in the buffer */
|
||||||
@ -983,13 +983,13 @@ int processInlineBuffer(client *c) {
|
|||||||
/* Helper function. Trims query buffer to make the function that processes
|
/* Helper function. Trims query buffer to make the function that processes
|
||||||
* multi bulk requests idempotent. */
|
* multi bulk requests idempotent. */
|
||||||
static void setProtocolError(client *c, int pos) {
|
static void setProtocolError(client *c, int pos) {
|
||||||
if (server.verbosity <= REDIS_VERBOSE) {
|
if (server.verbosity <= LL_VERBOSE) {
|
||||||
sds client = catClientInfoString(sdsempty(),c);
|
sds client = catClientInfoString(sdsempty(),c);
|
||||||
serverLog(REDIS_VERBOSE,
|
serverLog(LL_VERBOSE,
|
||||||
"Protocol error from client: %s", client);
|
"Protocol error from client: %s", client);
|
||||||
sdsfree(client);
|
sdsfree(client);
|
||||||
}
|
}
|
||||||
c->flags |= REDIS_CLOSE_AFTER_REPLY;
|
c->flags |= CLIENT_CLOSE_AFTER_REPLY;
|
||||||
sdsrange(c->querybuf,pos,-1);
|
sdsrange(c->querybuf,pos,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1005,7 +1005,7 @@ int processMultibulkBuffer(client *c) {
|
|||||||
/* Multi bulk length cannot be read without a \r\n */
|
/* Multi bulk length cannot be read without a \r\n */
|
||||||
newline = strchr(c->querybuf,'\r');
|
newline = strchr(c->querybuf,'\r');
|
||||||
if (newline == NULL) {
|
if (newline == NULL) {
|
||||||
if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) {
|
if (sdslen(c->querybuf) > PROTO_INLINE_MAX_SIZE) {
|
||||||
addReplyError(c,"Protocol error: too big mbulk count string");
|
addReplyError(c,"Protocol error: too big mbulk count string");
|
||||||
setProtocolError(c,0);
|
setProtocolError(c,0);
|
||||||
}
|
}
|
||||||
@ -1045,7 +1045,7 @@ int processMultibulkBuffer(client *c) {
|
|||||||
if (c->bulklen == -1) {
|
if (c->bulklen == -1) {
|
||||||
newline = strchr(c->querybuf+pos,'\r');
|
newline = strchr(c->querybuf+pos,'\r');
|
||||||
if (newline == NULL) {
|
if (newline == NULL) {
|
||||||
if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) {
|
if (sdslen(c->querybuf) > PROTO_INLINE_MAX_SIZE) {
|
||||||
addReplyError(c,
|
addReplyError(c,
|
||||||
"Protocol error: too big bulk count string");
|
"Protocol error: too big bulk count string");
|
||||||
setProtocolError(c,0);
|
setProtocolError(c,0);
|
||||||
@ -1074,7 +1074,7 @@ int processMultibulkBuffer(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pos += newline-(c->querybuf+pos)+2;
|
pos += newline-(c->querybuf+pos)+2;
|
||||||
if (ll >= REDIS_MBULK_BIG_ARG) {
|
if (ll >= PROTO_MBULK_BIG_ARG) {
|
||||||
size_t qblen;
|
size_t qblen;
|
||||||
|
|
||||||
/* If we are going to read a large object from network
|
/* If we are going to read a large object from network
|
||||||
@ -1101,7 +1101,7 @@ int processMultibulkBuffer(client *c) {
|
|||||||
* instead of creating a new object by *copying* the sds we
|
* instead of creating a new object by *copying* the sds we
|
||||||
* just use the current sds string. */
|
* just use the current sds string. */
|
||||||
if (pos == 0 &&
|
if (pos == 0 &&
|
||||||
c->bulklen >= REDIS_MBULK_BIG_ARG &&
|
c->bulklen >= PROTO_MBULK_BIG_ARG &&
|
||||||
(signed) sdslen(c->querybuf) == c->bulklen+2)
|
(signed) sdslen(c->querybuf) == c->bulklen+2)
|
||||||
{
|
{
|
||||||
c->argv[c->argc++] = createObject(OBJ_STRING,c->querybuf);
|
c->argv[c->argc++] = createObject(OBJ_STRING,c->querybuf);
|
||||||
@ -1136,31 +1136,31 @@ void processInputBuffer(client *c) {
|
|||||||
/* Keep processing while there is something in the input buffer */
|
/* Keep processing while there is something in the input buffer */
|
||||||
while(sdslen(c->querybuf)) {
|
while(sdslen(c->querybuf)) {
|
||||||
/* Return if clients are paused. */
|
/* Return if clients are paused. */
|
||||||
if (!(c->flags & REDIS_SLAVE) && clientsArePaused()) break;
|
if (!(c->flags & CLIENT_SLAVE) && clientsArePaused()) break;
|
||||||
|
|
||||||
/* Immediately abort if the client is in the middle of something. */
|
/* Immediately abort if the client is in the middle of something. */
|
||||||
if (c->flags & REDIS_BLOCKED) break;
|
if (c->flags & CLIENT_BLOCKED) break;
|
||||||
|
|
||||||
/* REDIS_CLOSE_AFTER_REPLY closes the connection once the reply is
|
/* CLIENT_CLOSE_AFTER_REPLY closes the connection once the reply is
|
||||||
* written to the client. Make sure to not let the reply grow after
|
* written to the client. Make sure to not let the reply grow after
|
||||||
* this flag has been set (i.e. don't process more commands). */
|
* this flag has been set (i.e. don't process more commands). */
|
||||||
if (c->flags & REDIS_CLOSE_AFTER_REPLY) break;
|
if (c->flags & CLIENT_CLOSE_AFTER_REPLY) break;
|
||||||
|
|
||||||
/* Determine request type when unknown. */
|
/* Determine request type when unknown. */
|
||||||
if (!c->reqtype) {
|
if (!c->reqtype) {
|
||||||
if (c->querybuf[0] == '*') {
|
if (c->querybuf[0] == '*') {
|
||||||
c->reqtype = REDIS_REQ_MULTIBULK;
|
c->reqtype = PROTO_REQ_MULTIBULK;
|
||||||
} else {
|
} else {
|
||||||
c->reqtype = REDIS_REQ_INLINE;
|
c->reqtype = PROTO_REQ_INLINE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->reqtype == REDIS_REQ_INLINE) {
|
if (c->reqtype == PROTO_REQ_INLINE) {
|
||||||
if (processInlineBuffer(c) != C_OK) break;
|
if (processInlineBuffer(c) != C_OK) break;
|
||||||
} else if (c->reqtype == REDIS_REQ_MULTIBULK) {
|
} else if (c->reqtype == PROTO_REQ_MULTIBULK) {
|
||||||
if (processMultibulkBuffer(c) != C_OK) break;
|
if (processMultibulkBuffer(c) != C_OK) break;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown request type");
|
serverPanic("Unknown request type");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Multibulk processing could see a <= 0 length. */
|
/* Multibulk processing could see a <= 0 length. */
|
||||||
@ -1179,18 +1179,18 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
client *c = (client*) privdata;
|
client *c = (client*) privdata;
|
||||||
int nread, readlen;
|
int nread, readlen;
|
||||||
size_t qblen;
|
size_t qblen;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
|
|
||||||
readlen = REDIS_IOBUF_LEN;
|
readlen = PROTO_IOBUF_LEN;
|
||||||
/* If this is a multi bulk request, and we are processing a bulk reply
|
/* If this is a multi bulk request, and we are processing a bulk reply
|
||||||
* that is large enough, try to maximize the probability that the query
|
* that is large enough, try to maximize the probability that the query
|
||||||
* buffer contains exactly the SDS string representing the object, even
|
* buffer contains exactly the SDS string representing the object, even
|
||||||
* at the risk of requiring more read(2) calls. This way the function
|
* at the risk of requiring more read(2) calls. This way the function
|
||||||
* processMultiBulkBuffer() can avoid copying buffers to create the
|
* processMultiBulkBuffer() can avoid copying buffers to create the
|
||||||
* Redis Object representing the argument. */
|
* Redis Object representing the argument. */
|
||||||
if (c->reqtype == REDIS_REQ_MULTIBULK && c->multibulklen && c->bulklen != -1
|
if (c->reqtype == PROTO_REQ_MULTIBULK && c->multibulklen && c->bulklen != -1
|
||||||
&& c->bulklen >= REDIS_MBULK_BIG_ARG)
|
&& c->bulklen >= PROTO_MBULK_BIG_ARG)
|
||||||
{
|
{
|
||||||
int remaining = (unsigned)(c->bulklen+2)-sdslen(c->querybuf);
|
int remaining = (unsigned)(c->bulklen+2)-sdslen(c->querybuf);
|
||||||
|
|
||||||
@ -1205,25 +1205,25 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_VERBOSE, "Reading from client: %s",strerror(errno));
|
serverLog(LL_VERBOSE, "Reading from client: %s",strerror(errno));
|
||||||
freeClient(c);
|
freeClient(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (nread == 0) {
|
} else if (nread == 0) {
|
||||||
serverLog(REDIS_VERBOSE, "Client closed connection");
|
serverLog(LL_VERBOSE, "Client closed connection");
|
||||||
freeClient(c);
|
freeClient(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdsIncrLen(c->querybuf,nread);
|
sdsIncrLen(c->querybuf,nread);
|
||||||
c->lastinteraction = server.unixtime;
|
c->lastinteraction = server.unixtime;
|
||||||
if (c->flags & REDIS_MASTER) c->reploff += nread;
|
if (c->flags & CLIENT_MASTER) c->reploff += nread;
|
||||||
server.stat_net_input_bytes += nread;
|
server.stat_net_input_bytes += nread;
|
||||||
if (sdslen(c->querybuf) > server.client_max_querybuf_len) {
|
if (sdslen(c->querybuf) > server.client_max_querybuf_len) {
|
||||||
sds ci = catClientInfoString(sdsempty(),c), bytes = sdsempty();
|
sds ci = catClientInfoString(sdsempty(),c), bytes = sdsempty();
|
||||||
|
|
||||||
bytes = sdscatrepr(bytes,c->querybuf,64);
|
bytes = sdscatrepr(bytes,c->querybuf,64);
|
||||||
serverLog(REDIS_WARNING,"Closing client that reached max query buffer length: %s (qbuf initial bytes: %s)", ci, bytes);
|
serverLog(LL_WARNING,"Closing client that reached max query buffer length: %s (qbuf initial bytes: %s)", ci, bytes);
|
||||||
sdsfree(ci);
|
sdsfree(ci);
|
||||||
sdsfree(bytes);
|
sdsfree(bytes);
|
||||||
freeClient(c);
|
freeClient(c);
|
||||||
@ -1255,7 +1255,7 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
|
|||||||
* For IPv6 addresses we use [] around the IP part, like in "[::1]:1234".
|
* For IPv6 addresses we use [] around the IP part, like in "[::1]:1234".
|
||||||
* For Unix sockets we use path:0, like in "/tmp/redis:0".
|
* For Unix sockets we use path:0, like in "/tmp/redis:0".
|
||||||
*
|
*
|
||||||
* A Peer ID always fits inside a buffer of REDIS_PEER_ID_LEN bytes, including
|
* A Peer ID always fits inside a buffer of NET_PEER_ID_LEN bytes, including
|
||||||
* the null term.
|
* the null term.
|
||||||
*
|
*
|
||||||
* On failure the function still populates 'peerid' with the "?:0" string
|
* On failure the function still populates 'peerid' with the "?:0" string
|
||||||
@ -1263,7 +1263,7 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
|
|||||||
* anyway (see anetPeerToString implementation for more info). */
|
* anyway (see anetPeerToString implementation for more info). */
|
||||||
void genClientPeerId(client *client, char *peerid,
|
void genClientPeerId(client *client, char *peerid,
|
||||||
size_t peerid_len) {
|
size_t peerid_len) {
|
||||||
if (client->flags & REDIS_UNIX_SOCKET) {
|
if (client->flags & CLIENT_UNIX_SOCKET) {
|
||||||
/* Unix socket client. */
|
/* Unix socket client. */
|
||||||
snprintf(peerid,peerid_len,"%s:0",server.unixsocket);
|
snprintf(peerid,peerid_len,"%s:0",server.unixsocket);
|
||||||
} else {
|
} else {
|
||||||
@ -1277,7 +1277,7 @@ void genClientPeerId(client *client, char *peerid,
|
|||||||
* The Peer ID never changes during the life of the client, however it
|
* The Peer ID never changes during the life of the client, however it
|
||||||
* is expensive to compute. */
|
* is expensive to compute. */
|
||||||
char *getClientPeerId(client *c) {
|
char *getClientPeerId(client *c) {
|
||||||
char peerid[REDIS_PEER_ID_LEN];
|
char peerid[NET_PEER_ID_LEN];
|
||||||
|
|
||||||
if (c->peerid == NULL) {
|
if (c->peerid == NULL) {
|
||||||
genClientPeerId(c,peerid,sizeof(peerid));
|
genClientPeerId(c,peerid,sizeof(peerid));
|
||||||
@ -1293,21 +1293,21 @@ sds catClientInfoString(sds s, client *client) {
|
|||||||
int emask;
|
int emask;
|
||||||
|
|
||||||
p = flags;
|
p = flags;
|
||||||
if (client->flags & REDIS_SLAVE) {
|
if (client->flags & CLIENT_SLAVE) {
|
||||||
if (client->flags & REDIS_MONITOR)
|
if (client->flags & CLIENT_MONITOR)
|
||||||
*p++ = 'O';
|
*p++ = 'O';
|
||||||
else
|
else
|
||||||
*p++ = 'S';
|
*p++ = 'S';
|
||||||
}
|
}
|
||||||
if (client->flags & REDIS_MASTER) *p++ = 'M';
|
if (client->flags & CLIENT_MASTER) *p++ = 'M';
|
||||||
if (client->flags & REDIS_MULTI) *p++ = 'x';
|
if (client->flags & CLIENT_MULTI) *p++ = 'x';
|
||||||
if (client->flags & REDIS_BLOCKED) *p++ = 'b';
|
if (client->flags & CLIENT_BLOCKED) *p++ = 'b';
|
||||||
if (client->flags & REDIS_DIRTY_CAS) *p++ = 'd';
|
if (client->flags & CLIENT_DIRTY_CAS) *p++ = 'd';
|
||||||
if (client->flags & REDIS_CLOSE_AFTER_REPLY) *p++ = 'c';
|
if (client->flags & CLIENT_CLOSE_AFTER_REPLY) *p++ = 'c';
|
||||||
if (client->flags & REDIS_UNBLOCKED) *p++ = 'u';
|
if (client->flags & CLIENT_UNBLOCKED) *p++ = 'u';
|
||||||
if (client->flags & REDIS_CLOSE_ASAP) *p++ = 'A';
|
if (client->flags & CLIENT_CLOSE_ASAP) *p++ = 'A';
|
||||||
if (client->flags & REDIS_UNIX_SOCKET) *p++ = 'U';
|
if (client->flags & CLIENT_UNIX_SOCKET) *p++ = 'U';
|
||||||
if (client->flags & REDIS_READONLY) *p++ = 'r';
|
if (client->flags & CLIENT_READONLY) *p++ = 'r';
|
||||||
if (p == flags) *p++ = 'N';
|
if (p == flags) *p++ = 'N';
|
||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
|
|
||||||
@ -1328,7 +1328,7 @@ sds catClientInfoString(sds s, client *client) {
|
|||||||
client->db->id,
|
client->db->id,
|
||||||
(int) dictSize(client->pubsub_channels),
|
(int) dictSize(client->pubsub_channels),
|
||||||
(int) listLength(client->pubsub_patterns),
|
(int) listLength(client->pubsub_patterns),
|
||||||
(client->flags & REDIS_MULTI) ? client->mstate.count : -1,
|
(client->flags & CLIENT_MULTI) ? client->mstate.count : -1,
|
||||||
(unsigned long long) sdslen(client->querybuf),
|
(unsigned long long) sdslen(client->querybuf),
|
||||||
(unsigned long long) sdsavail(client->querybuf),
|
(unsigned long long) sdsavail(client->querybuf),
|
||||||
(unsigned long long) client->bufpos,
|
(unsigned long long) client->bufpos,
|
||||||
@ -1425,7 +1425,7 @@ void clientCommand(client *c) {
|
|||||||
client = listNodeValue(ln);
|
client = listNodeValue(ln);
|
||||||
if (addr && strcmp(getClientPeerId(client),addr) != 0) continue;
|
if (addr && strcmp(getClientPeerId(client),addr) != 0) continue;
|
||||||
if (type != -1 &&
|
if (type != -1 &&
|
||||||
(client->flags & REDIS_MASTER ||
|
(client->flags & CLIENT_MASTER ||
|
||||||
getClientType(client) != type)) continue;
|
getClientType(client) != type)) continue;
|
||||||
if (id != 0 && client->id != id) continue;
|
if (id != 0 && client->id != id) continue;
|
||||||
if (c == client && skipme) continue;
|
if (c == client && skipme) continue;
|
||||||
@ -1451,7 +1451,7 @@ void clientCommand(client *c) {
|
|||||||
|
|
||||||
/* If this client has to be closed, flag it as CLOSE_AFTER_REPLY
|
/* If this client has to be closed, flag it as CLOSE_AFTER_REPLY
|
||||||
* only after we queued the reply to its output buffers. */
|
* only after we queued the reply to its output buffers. */
|
||||||
if (close_this_client) c->flags |= REDIS_CLOSE_AFTER_REPLY;
|
if (close_this_client) c->flags |= CLIENT_CLOSE_AFTER_REPLY;
|
||||||
} else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) {
|
} else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) {
|
||||||
int j, len = sdslen(c->argv[2]->ptr);
|
int j, len = sdslen(c->argv[2]->ptr);
|
||||||
char *p = c->argv[2]->ptr;
|
char *p = c->argv[2]->ptr;
|
||||||
@ -1578,30 +1578,30 @@ unsigned long getClientOutputBufferMemoryUsage(client *c) {
|
|||||||
* classes of clients.
|
* classes of clients.
|
||||||
*
|
*
|
||||||
* The function will return one of the following:
|
* The function will return one of the following:
|
||||||
* REDIS_CLIENT_TYPE_NORMAL -> Normal client
|
* CLIENT_TYPE_NORMAL -> Normal client
|
||||||
* REDIS_CLIENT_TYPE_SLAVE -> Slave or client executing MONITOR command
|
* CLIENT_TYPE_SLAVE -> Slave or client executing MONITOR command
|
||||||
* REDIS_CLIENT_TYPE_PUBSUB -> Client subscribed to Pub/Sub channels
|
* CLIENT_TYPE_PUBSUB -> Client subscribed to Pub/Sub channels
|
||||||
*/
|
*/
|
||||||
int getClientType(client *c) {
|
int getClientType(client *c) {
|
||||||
if ((c->flags & REDIS_SLAVE) && !(c->flags & REDIS_MONITOR))
|
if ((c->flags & CLIENT_SLAVE) && !(c->flags & CLIENT_MONITOR))
|
||||||
return REDIS_CLIENT_TYPE_SLAVE;
|
return CLIENT_TYPE_SLAVE;
|
||||||
if (c->flags & REDIS_PUBSUB)
|
if (c->flags & CLIENT_PUBSUB)
|
||||||
return REDIS_CLIENT_TYPE_PUBSUB;
|
return CLIENT_TYPE_PUBSUB;
|
||||||
return REDIS_CLIENT_TYPE_NORMAL;
|
return CLIENT_TYPE_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getClientTypeByName(char *name) {
|
int getClientTypeByName(char *name) {
|
||||||
if (!strcasecmp(name,"normal")) return REDIS_CLIENT_TYPE_NORMAL;
|
if (!strcasecmp(name,"normal")) return CLIENT_TYPE_NORMAL;
|
||||||
else if (!strcasecmp(name,"slave")) return REDIS_CLIENT_TYPE_SLAVE;
|
else if (!strcasecmp(name,"slave")) return CLIENT_TYPE_SLAVE;
|
||||||
else if (!strcasecmp(name,"pubsub")) return REDIS_CLIENT_TYPE_PUBSUB;
|
else if (!strcasecmp(name,"pubsub")) return CLIENT_TYPE_PUBSUB;
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *getClientTypeName(int class) {
|
char *getClientTypeName(int class) {
|
||||||
switch(class) {
|
switch(class) {
|
||||||
case REDIS_CLIENT_TYPE_NORMAL: return "normal";
|
case CLIENT_TYPE_NORMAL: return "normal";
|
||||||
case REDIS_CLIENT_TYPE_SLAVE: return "slave";
|
case CLIENT_TYPE_SLAVE: return "slave";
|
||||||
case REDIS_CLIENT_TYPE_PUBSUB: return "pubsub";
|
case CLIENT_TYPE_PUBSUB: return "pubsub";
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1648,19 +1648,19 @@ int checkClientOutputBufferLimits(client *c) {
|
|||||||
|
|
||||||
/* Asynchronously close a client if soft or hard limit is reached on the
|
/* Asynchronously close a client if soft or hard limit is reached on the
|
||||||
* output buffer size. The caller can check if the client will be closed
|
* output buffer size. The caller can check if the client will be closed
|
||||||
* checking if the client REDIS_CLOSE_ASAP flag is set.
|
* checking if the client CLIENT_CLOSE_ASAP flag is set.
|
||||||
*
|
*
|
||||||
* Note: we need to close the client asynchronously because this function is
|
* Note: we need to close the client asynchronously because this function is
|
||||||
* called from contexts where the client can't be freed safely, i.e. from the
|
* called from contexts where the client can't be freed safely, i.e. from the
|
||||||
* lower level functions pushing data inside the client output buffers. */
|
* lower level functions pushing data inside the client output buffers. */
|
||||||
void asyncCloseClientOnOutputBufferLimitReached(client *c) {
|
void asyncCloseClientOnOutputBufferLimitReached(client *c) {
|
||||||
serverAssert(c->reply_bytes < SIZE_MAX-(1024*64));
|
serverAssert(c->reply_bytes < SIZE_MAX-(1024*64));
|
||||||
if (c->reply_bytes == 0 || c->flags & REDIS_CLOSE_ASAP) return;
|
if (c->reply_bytes == 0 || c->flags & CLIENT_CLOSE_ASAP) return;
|
||||||
if (checkClientOutputBufferLimits(c)) {
|
if (checkClientOutputBufferLimits(c)) {
|
||||||
sds client = catClientInfoString(sdsempty(),c);
|
sds client = catClientInfoString(sdsempty(),c);
|
||||||
|
|
||||||
freeClientAsync(c);
|
freeClientAsync(c);
|
||||||
serverLog(REDIS_WARNING,"Client %s scheduled to be closed ASAP for overcoming of output buffer limits.", client);
|
serverLog(LL_WARNING,"Client %s scheduled to be closed ASAP for overcoming of output buffer limits.", client);
|
||||||
sdsfree(client);
|
sdsfree(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1678,7 +1678,7 @@ void flushSlavesOutputBuffers(void) {
|
|||||||
|
|
||||||
events = aeGetFileEvents(server.el,slave->fd);
|
events = aeGetFileEvents(server.el,slave->fd);
|
||||||
if (events & AE_WRITABLE &&
|
if (events & AE_WRITABLE &&
|
||||||
slave->replstate == REDIS_REPL_ONLINE &&
|
slave->replstate == SLAVE_STATE_ONLINE &&
|
||||||
listLength(slave->reply))
|
listLength(slave->reply))
|
||||||
{
|
{
|
||||||
sendReplyToClient(server.el,slave->fd,slave,0);
|
sendReplyToClient(server.el,slave->fd,slave,0);
|
||||||
@ -1729,8 +1729,8 @@ int clientsArePaused(void) {
|
|||||||
|
|
||||||
/* Don't touch slaves and blocked clients. The latter pending
|
/* Don't touch slaves and blocked clients. The latter pending
|
||||||
* requests be processed when unblocked. */
|
* requests be processed when unblocked. */
|
||||||
if (c->flags & (REDIS_SLAVE|REDIS_BLOCKED)) continue;
|
if (c->flags & (CLIENT_SLAVE|CLIENT_BLOCKED)) continue;
|
||||||
c->flags |= REDIS_UNBLOCKED;
|
c->flags |= CLIENT_UNBLOCKED;
|
||||||
listAddNodeTail(server.unblocked_clients,c);
|
listAddNodeTail(server.unblocked_clients,c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
src/notify.c
48
src/notify.c
@ -43,17 +43,17 @@ int keyspaceEventsStringToFlags(char *classes) {
|
|||||||
|
|
||||||
while((c = *p++) != '\0') {
|
while((c = *p++) != '\0') {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'A': flags |= REDIS_NOTIFY_ALL; break;
|
case 'A': flags |= NOTIFY_ALL; break;
|
||||||
case 'g': flags |= REDIS_NOTIFY_GENERIC; break;
|
case 'g': flags |= NOTIFY_GENERIC; break;
|
||||||
case '$': flags |= REDIS_NOTIFY_STRING; break;
|
case '$': flags |= NOTIFY_STRING; break;
|
||||||
case 'l': flags |= REDIS_NOTIFY_LIST; break;
|
case 'l': flags |= NOTIFY_LIST; break;
|
||||||
case 's': flags |= REDIS_NOTIFY_SET; break;
|
case 's': flags |= NOTIFY_SET; break;
|
||||||
case 'h': flags |= REDIS_NOTIFY_HASH; break;
|
case 'h': flags |= NOTIFY_HASH; break;
|
||||||
case 'z': flags |= REDIS_NOTIFY_ZSET; break;
|
case 'z': flags |= NOTIFY_ZSET; break;
|
||||||
case 'x': flags |= REDIS_NOTIFY_EXPIRED; break;
|
case 'x': flags |= NOTIFY_EXPIRED; break;
|
||||||
case 'e': flags |= REDIS_NOTIFY_EVICTED; break;
|
case 'e': flags |= NOTIFY_EVICTED; break;
|
||||||
case 'K': flags |= REDIS_NOTIFY_KEYSPACE; break;
|
case 'K': flags |= NOTIFY_KEYSPACE; break;
|
||||||
case 'E': flags |= REDIS_NOTIFY_KEYEVENT; break;
|
case 'E': flags |= NOTIFY_KEYEVENT; break;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,20 +68,20 @@ sds keyspaceEventsFlagsToString(int flags) {
|
|||||||
sds res;
|
sds res;
|
||||||
|
|
||||||
res = sdsempty();
|
res = sdsempty();
|
||||||
if ((flags & REDIS_NOTIFY_ALL) == REDIS_NOTIFY_ALL) {
|
if ((flags & NOTIFY_ALL) == NOTIFY_ALL) {
|
||||||
res = sdscatlen(res,"A",1);
|
res = sdscatlen(res,"A",1);
|
||||||
} else {
|
} else {
|
||||||
if (flags & REDIS_NOTIFY_GENERIC) res = sdscatlen(res,"g",1);
|
if (flags & NOTIFY_GENERIC) res = sdscatlen(res,"g",1);
|
||||||
if (flags & REDIS_NOTIFY_STRING) res = sdscatlen(res,"$",1);
|
if (flags & NOTIFY_STRING) res = sdscatlen(res,"$",1);
|
||||||
if (flags & REDIS_NOTIFY_LIST) res = sdscatlen(res,"l",1);
|
if (flags & NOTIFY_LIST) res = sdscatlen(res,"l",1);
|
||||||
if (flags & REDIS_NOTIFY_SET) res = sdscatlen(res,"s",1);
|
if (flags & NOTIFY_SET) res = sdscatlen(res,"s",1);
|
||||||
if (flags & REDIS_NOTIFY_HASH) res = sdscatlen(res,"h",1);
|
if (flags & NOTIFY_HASH) res = sdscatlen(res,"h",1);
|
||||||
if (flags & REDIS_NOTIFY_ZSET) res = sdscatlen(res,"z",1);
|
if (flags & NOTIFY_ZSET) res = sdscatlen(res,"z",1);
|
||||||
if (flags & REDIS_NOTIFY_EXPIRED) res = sdscatlen(res,"x",1);
|
if (flags & NOTIFY_EXPIRED) res = sdscatlen(res,"x",1);
|
||||||
if (flags & REDIS_NOTIFY_EVICTED) res = sdscatlen(res,"e",1);
|
if (flags & NOTIFY_EVICTED) res = sdscatlen(res,"e",1);
|
||||||
}
|
}
|
||||||
if (flags & REDIS_NOTIFY_KEYSPACE) res = sdscatlen(res,"K",1);
|
if (flags & NOTIFY_KEYSPACE) res = sdscatlen(res,"K",1);
|
||||||
if (flags & REDIS_NOTIFY_KEYEVENT) res = sdscatlen(res,"E",1);
|
if (flags & NOTIFY_KEYEVENT) res = sdscatlen(res,"E",1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) {
|
|||||||
eventobj = createStringObject(event,strlen(event));
|
eventobj = createStringObject(event,strlen(event));
|
||||||
|
|
||||||
/* __keyspace@<db>__:<key> <event> notifications. */
|
/* __keyspace@<db>__:<key> <event> notifications. */
|
||||||
if (server.notify_keyspace_events & REDIS_NOTIFY_KEYSPACE) {
|
if (server.notify_keyspace_events & NOTIFY_KEYSPACE) {
|
||||||
chan = sdsnewlen("__keyspace@",11);
|
chan = sdsnewlen("__keyspace@",11);
|
||||||
len = ll2string(buf,sizeof(buf),dbid);
|
len = ll2string(buf,sizeof(buf),dbid);
|
||||||
chan = sdscatlen(chan, buf, len);
|
chan = sdscatlen(chan, buf, len);
|
||||||
@ -116,7 +116,7 @@ void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* __keyevente@<db>__:<event> <key> notifications. */
|
/* __keyevente@<db>__:<event> <key> notifications. */
|
||||||
if (server.notify_keyspace_events & REDIS_NOTIFY_KEYEVENT) {
|
if (server.notify_keyspace_events & NOTIFY_KEYEVENT) {
|
||||||
chan = sdsnewlen("__keyevent@",11);
|
chan = sdsnewlen("__keyevent@",11);
|
||||||
if (len == -1) len = ll2string(buf,sizeof(buf),dbid);
|
if (len == -1) len = ll2string(buf,sizeof(buf),dbid);
|
||||||
chan = sdscatlen(chan, buf, len);
|
chan = sdscatlen(chan, buf, len);
|
||||||
|
36
src/object.c
36
src/object.c
@ -95,7 +95,7 @@ robj *createStringObject(const char *ptr, size_t len) {
|
|||||||
|
|
||||||
robj *createStringObjectFromLongLong(long long value) {
|
robj *createStringObjectFromLongLong(long long value) {
|
||||||
robj *o;
|
robj *o;
|
||||||
if (value >= 0 && value < REDIS_SHARED_INTEGERS) {
|
if (value >= 0 && value < OBJ_SHARED_INTEGERS) {
|
||||||
incrRefCount(shared.integers[value]);
|
incrRefCount(shared.integers[value]);
|
||||||
o = shared.integers[value];
|
o = shared.integers[value];
|
||||||
} else {
|
} else {
|
||||||
@ -176,7 +176,7 @@ robj *dupStringObject(robj *o) {
|
|||||||
d->ptr = o->ptr;
|
d->ptr = o->ptr;
|
||||||
return d;
|
return d;
|
||||||
default:
|
default:
|
||||||
redisPanic("Wrong encoding.");
|
serverPanic("Wrong encoding.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,7 +246,7 @@ void freeListObject(robj *o) {
|
|||||||
quicklistRelease(o->ptr);
|
quicklistRelease(o->ptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
redisPanic("Unknown list encoding type");
|
serverPanic("Unknown list encoding type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ void freeSetObject(robj *o) {
|
|||||||
zfree(o->ptr);
|
zfree(o->ptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
redisPanic("Unknown set encoding type");
|
serverPanic("Unknown set encoding type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ void freeZsetObject(robj *o) {
|
|||||||
zfree(o->ptr);
|
zfree(o->ptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,7 +289,7 @@ void freeHashObject(robj *o) {
|
|||||||
zfree(o->ptr);
|
zfree(o->ptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
redisPanic("Unknown hash encoding type");
|
serverPanic("Unknown hash encoding type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,7 +299,7 @@ void incrRefCount(robj *o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void decrRefCount(robj *o) {
|
void decrRefCount(robj *o) {
|
||||||
if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0");
|
if (o->refcount <= 0) serverPanic("decrRefCount against refcount <= 0");
|
||||||
if (o->refcount == 1) {
|
if (o->refcount == 1) {
|
||||||
switch(o->type) {
|
switch(o->type) {
|
||||||
case OBJ_STRING: freeStringObject(o); break;
|
case OBJ_STRING: freeStringObject(o); break;
|
||||||
@ -307,7 +307,7 @@ void decrRefCount(robj *o) {
|
|||||||
case OBJ_SET: freeSetObject(o); break;
|
case OBJ_SET: freeSetObject(o); break;
|
||||||
case OBJ_ZSET: freeZsetObject(o); break;
|
case OBJ_ZSET: freeZsetObject(o); break;
|
||||||
case OBJ_HASH: freeHashObject(o); break;
|
case OBJ_HASH: freeHashObject(o); break;
|
||||||
default: redisPanic("Unknown object type"); break;
|
default: serverPanic("Unknown object type"); break;
|
||||||
}
|
}
|
||||||
zfree(o);
|
zfree(o);
|
||||||
} else {
|
} else {
|
||||||
@ -389,10 +389,10 @@ robj *tryObjectEncoding(robj *o) {
|
|||||||
* because every object needs to have a private LRU field for the LRU
|
* because every object needs to have a private LRU field for the LRU
|
||||||
* algorithm to work well. */
|
* algorithm to work well. */
|
||||||
if ((server.maxmemory == 0 ||
|
if ((server.maxmemory == 0 ||
|
||||||
(server.maxmemory_policy != REDIS_MAXMEMORY_VOLATILE_LRU &&
|
(server.maxmemory_policy != MAXMEMORY_VOLATILE_LRU &&
|
||||||
server.maxmemory_policy != REDIS_MAXMEMORY_ALLKEYS_LRU)) &&
|
server.maxmemory_policy != MAXMEMORY_ALLKEYS_LRU)) &&
|
||||||
value >= 0 &&
|
value >= 0 &&
|
||||||
value < REDIS_SHARED_INTEGERS)
|
value < OBJ_SHARED_INTEGERS)
|
||||||
{
|
{
|
||||||
decrRefCount(o);
|
decrRefCount(o);
|
||||||
incrRefCount(shared.integers[value]);
|
incrRefCount(shared.integers[value]);
|
||||||
@ -453,7 +453,7 @@ robj *getDecodedObject(robj *o) {
|
|||||||
dec = createStringObject(buf,strlen(buf));
|
dec = createStringObject(buf,strlen(buf));
|
||||||
return dec;
|
return dec;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown encoding type");
|
serverPanic("Unknown encoding type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,7 +555,7 @@ int getDoubleFromObject(robj *o, double *target) {
|
|||||||
} else if (o->encoding == OBJ_ENCODING_INT) {
|
} else if (o->encoding == OBJ_ENCODING_INT) {
|
||||||
value = (long)o->ptr;
|
value = (long)o->ptr;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown string encoding");
|
serverPanic("Unknown string encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*target = value;
|
*target = value;
|
||||||
@ -593,7 +593,7 @@ int getLongDoubleFromObject(robj *o, long double *target) {
|
|||||||
} else if (o->encoding == OBJ_ENCODING_INT) {
|
} else if (o->encoding == OBJ_ENCODING_INT) {
|
||||||
value = (long)o->ptr;
|
value = (long)o->ptr;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown string encoding");
|
serverPanic("Unknown string encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*target = value;
|
*target = value;
|
||||||
@ -631,7 +631,7 @@ int getLongLongFromObject(robj *o, long long *target) {
|
|||||||
} else if (o->encoding == OBJ_ENCODING_INT) {
|
} else if (o->encoding == OBJ_ENCODING_INT) {
|
||||||
value = (long)o->ptr;
|
value = (long)o->ptr;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown string encoding");
|
serverPanic("Unknown string encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target) *target = value;
|
if (target) *target = value;
|
||||||
@ -687,10 +687,10 @@ char *strEncoding(int encoding) {
|
|||||||
unsigned long long estimateObjectIdleTime(robj *o) {
|
unsigned long long estimateObjectIdleTime(robj *o) {
|
||||||
unsigned long long lruclock = LRU_CLOCK();
|
unsigned long long lruclock = LRU_CLOCK();
|
||||||
if (lruclock >= o->lru) {
|
if (lruclock >= o->lru) {
|
||||||
return (lruclock - o->lru) * REDIS_LRU_CLOCK_RESOLUTION;
|
return (lruclock - o->lru) * LRU_CLOCK_RESOLUTION;
|
||||||
} else {
|
} else {
|
||||||
return (lruclock + (REDIS_LRU_CLOCK_MAX - o->lru)) *
|
return (lruclock + (LRU_CLOCK_MAX - o->lru)) *
|
||||||
REDIS_LRU_CLOCK_RESOLUTION;
|
LRU_CLOCK_RESOLUTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/pubsub.c
10
src/pubsub.c
@ -279,7 +279,7 @@ void subscribeCommand(client *c) {
|
|||||||
|
|
||||||
for (j = 1; j < c->argc; j++)
|
for (j = 1; j < c->argc; j++)
|
||||||
pubsubSubscribeChannel(c,c->argv[j]);
|
pubsubSubscribeChannel(c,c->argv[j]);
|
||||||
c->flags |= REDIS_PUBSUB;
|
c->flags |= CLIENT_PUBSUB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsubscribeCommand(client *c) {
|
void unsubscribeCommand(client *c) {
|
||||||
@ -291,7 +291,7 @@ void unsubscribeCommand(client *c) {
|
|||||||
for (j = 1; j < c->argc; j++)
|
for (j = 1; j < c->argc; j++)
|
||||||
pubsubUnsubscribeChannel(c,c->argv[j],1);
|
pubsubUnsubscribeChannel(c,c->argv[j],1);
|
||||||
}
|
}
|
||||||
if (clientSubscriptionsCount(c) == 0) c->flags &= ~REDIS_PUBSUB;
|
if (clientSubscriptionsCount(c) == 0) c->flags &= ~CLIENT_PUBSUB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void psubscribeCommand(client *c) {
|
void psubscribeCommand(client *c) {
|
||||||
@ -299,7 +299,7 @@ void psubscribeCommand(client *c) {
|
|||||||
|
|
||||||
for (j = 1; j < c->argc; j++)
|
for (j = 1; j < c->argc; j++)
|
||||||
pubsubSubscribePattern(c,c->argv[j]);
|
pubsubSubscribePattern(c,c->argv[j]);
|
||||||
c->flags |= REDIS_PUBSUB;
|
c->flags |= CLIENT_PUBSUB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void punsubscribeCommand(client *c) {
|
void punsubscribeCommand(client *c) {
|
||||||
@ -311,7 +311,7 @@ void punsubscribeCommand(client *c) {
|
|||||||
for (j = 1; j < c->argc; j++)
|
for (j = 1; j < c->argc; j++)
|
||||||
pubsubUnsubscribePattern(c,c->argv[j],1);
|
pubsubUnsubscribePattern(c,c->argv[j],1);
|
||||||
}
|
}
|
||||||
if (clientSubscriptionsCount(c) == 0) c->flags &= ~REDIS_PUBSUB;
|
if (clientSubscriptionsCount(c) == 0) c->flags &= ~CLIENT_PUBSUB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void publishCommand(client *c) {
|
void publishCommand(client *c) {
|
||||||
@ -319,7 +319,7 @@ void publishCommand(client *c) {
|
|||||||
if (server.cluster_enabled)
|
if (server.cluster_enabled)
|
||||||
clusterPropagatePublish(c->argv[1],c->argv[2]);
|
clusterPropagatePublish(c->argv[1],c->argv[2]);
|
||||||
else
|
else
|
||||||
forceCommandPropagation(c,REDIS_PROPAGATE_REPL);
|
forceCommandPropagation(c,PROPAGATE_REPL);
|
||||||
addReplyLongLong(c,receivers);
|
addReplyLongLong(c,receivers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
254
src/rdb.c
254
src/rdb.c
@ -47,7 +47,7 @@
|
|||||||
#define rdbExitReportCorruptRDB(reason) rdbCheckThenExit(reason, __LINE__);
|
#define rdbExitReportCorruptRDB(reason) rdbCheckThenExit(reason, __LINE__);
|
||||||
|
|
||||||
void rdbCheckThenExit(char *reason, int where) {
|
void rdbCheckThenExit(char *reason, int where) {
|
||||||
serverLog(REDIS_WARNING, "Corrupt RDB detected at rdb.c:%d (%s). "
|
serverLog(LL_WARNING, "Corrupt RDB detected at rdb.c:%d (%s). "
|
||||||
"Running 'redis-check-rdb %s'",
|
"Running 'redis-check-rdb %s'",
|
||||||
where, reason, server.rdb_filename);
|
where, reason, server.rdb_filename);
|
||||||
redis_check_rdb(server.rdb_filename);
|
redis_check_rdb(server.rdb_filename);
|
||||||
@ -91,7 +91,7 @@ long long rdbLoadMillisecondTime(rio *rdb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Saves an encoded length. The first two bits in the first byte are used to
|
/* Saves an encoded length. The first two bits in the first byte are used to
|
||||||
* hold the encoding type. See the REDIS_RDB_* definitions for more information
|
* hold the encoding type. See the RDB_* definitions for more information
|
||||||
* on the types of encoding. */
|
* on the types of encoding. */
|
||||||
int rdbSaveLen(rio *rdb, uint32_t len) {
|
int rdbSaveLen(rio *rdb, uint32_t len) {
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
@ -99,18 +99,18 @@ int rdbSaveLen(rio *rdb, uint32_t len) {
|
|||||||
|
|
||||||
if (len < (1<<6)) {
|
if (len < (1<<6)) {
|
||||||
/* Save a 6 bit len */
|
/* Save a 6 bit len */
|
||||||
buf[0] = (len&0xFF)|(REDIS_RDB_6BITLEN<<6);
|
buf[0] = (len&0xFF)|(RDB_6BITLEN<<6);
|
||||||
if (rdbWriteRaw(rdb,buf,1) == -1) return -1;
|
if (rdbWriteRaw(rdb,buf,1) == -1) return -1;
|
||||||
nwritten = 1;
|
nwritten = 1;
|
||||||
} else if (len < (1<<14)) {
|
} else if (len < (1<<14)) {
|
||||||
/* Save a 14 bit len */
|
/* Save a 14 bit len */
|
||||||
buf[0] = ((len>>8)&0xFF)|(REDIS_RDB_14BITLEN<<6);
|
buf[0] = ((len>>8)&0xFF)|(RDB_14BITLEN<<6);
|
||||||
buf[1] = len&0xFF;
|
buf[1] = len&0xFF;
|
||||||
if (rdbWriteRaw(rdb,buf,2) == -1) return -1;
|
if (rdbWriteRaw(rdb,buf,2) == -1) return -1;
|
||||||
nwritten = 2;
|
nwritten = 2;
|
||||||
} else {
|
} else {
|
||||||
/* Save a 32 bit len */
|
/* Save a 32 bit len */
|
||||||
buf[0] = (REDIS_RDB_32BITLEN<<6);
|
buf[0] = (RDB_32BITLEN<<6);
|
||||||
if (rdbWriteRaw(rdb,buf,1) == -1) return -1;
|
if (rdbWriteRaw(rdb,buf,1) == -1) return -1;
|
||||||
len = htonl(len);
|
len = htonl(len);
|
||||||
if (rdbWriteRaw(rdb,&len,4) == -1) return -1;
|
if (rdbWriteRaw(rdb,&len,4) == -1) return -1;
|
||||||
@ -120,7 +120,7 @@ int rdbSaveLen(rio *rdb, uint32_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load an encoded length. The "isencoded" argument is set to 1 if the length
|
/* Load an encoded length. The "isencoded" argument is set to 1 if the length
|
||||||
* is not actually a length but an "encoding type". See the REDIS_RDB_ENC_*
|
* is not actually a length but an "encoding type". See the RDB_ENC_*
|
||||||
* definitions in rdb.h for more information. */
|
* definitions in rdb.h for more information. */
|
||||||
uint32_t rdbLoadLen(rio *rdb, int *isencoded) {
|
uint32_t rdbLoadLen(rio *rdb, int *isencoded) {
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
@ -128,22 +128,22 @@ uint32_t rdbLoadLen(rio *rdb, int *isencoded) {
|
|||||||
int type;
|
int type;
|
||||||
|
|
||||||
if (isencoded) *isencoded = 0;
|
if (isencoded) *isencoded = 0;
|
||||||
if (rioRead(rdb,buf,1) == 0) return REDIS_RDB_LENERR;
|
if (rioRead(rdb,buf,1) == 0) return RDB_LENERR;
|
||||||
type = (buf[0]&0xC0)>>6;
|
type = (buf[0]&0xC0)>>6;
|
||||||
if (type == REDIS_RDB_ENCVAL) {
|
if (type == RDB_ENCVAL) {
|
||||||
/* Read a 6 bit encoding type. */
|
/* Read a 6 bit encoding type. */
|
||||||
if (isencoded) *isencoded = 1;
|
if (isencoded) *isencoded = 1;
|
||||||
return buf[0]&0x3F;
|
return buf[0]&0x3F;
|
||||||
} else if (type == REDIS_RDB_6BITLEN) {
|
} else if (type == RDB_6BITLEN) {
|
||||||
/* Read a 6 bit len. */
|
/* Read a 6 bit len. */
|
||||||
return buf[0]&0x3F;
|
return buf[0]&0x3F;
|
||||||
} else if (type == REDIS_RDB_14BITLEN) {
|
} else if (type == RDB_14BITLEN) {
|
||||||
/* Read a 14 bit len. */
|
/* Read a 14 bit len. */
|
||||||
if (rioRead(rdb,buf+1,1) == 0) return REDIS_RDB_LENERR;
|
if (rioRead(rdb,buf+1,1) == 0) return RDB_LENERR;
|
||||||
return ((buf[0]&0x3F)<<8)|buf[1];
|
return ((buf[0]&0x3F)<<8)|buf[1];
|
||||||
} else {
|
} else {
|
||||||
/* Read a 32 bit len. */
|
/* Read a 32 bit len. */
|
||||||
if (rioRead(rdb,&len,4) == 0) return REDIS_RDB_LENERR;
|
if (rioRead(rdb,&len,4) == 0) return RDB_LENERR;
|
||||||
return ntohl(len);
|
return ntohl(len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,16 +154,16 @@ uint32_t rdbLoadLen(rio *rdb, int *isencoded) {
|
|||||||
* length is returned. Otherwise 0 is returned. */
|
* length is returned. Otherwise 0 is returned. */
|
||||||
int rdbEncodeInteger(long long value, unsigned char *enc) {
|
int rdbEncodeInteger(long long value, unsigned char *enc) {
|
||||||
if (value >= -(1<<7) && value <= (1<<7)-1) {
|
if (value >= -(1<<7) && value <= (1<<7)-1) {
|
||||||
enc[0] = (REDIS_RDB_ENCVAL<<6)|REDIS_RDB_ENC_INT8;
|
enc[0] = (RDB_ENCVAL<<6)|RDB_ENC_INT8;
|
||||||
enc[1] = value&0xFF;
|
enc[1] = value&0xFF;
|
||||||
return 2;
|
return 2;
|
||||||
} else if (value >= -(1<<15) && value <= (1<<15)-1) {
|
} else if (value >= -(1<<15) && value <= (1<<15)-1) {
|
||||||
enc[0] = (REDIS_RDB_ENCVAL<<6)|REDIS_RDB_ENC_INT16;
|
enc[0] = (RDB_ENCVAL<<6)|RDB_ENC_INT16;
|
||||||
enc[1] = value&0xFF;
|
enc[1] = value&0xFF;
|
||||||
enc[2] = (value>>8)&0xFF;
|
enc[2] = (value>>8)&0xFF;
|
||||||
return 3;
|
return 3;
|
||||||
} else if (value >= -((long long)1<<31) && value <= ((long long)1<<31)-1) {
|
} else if (value >= -((long long)1<<31) && value <= ((long long)1<<31)-1) {
|
||||||
enc[0] = (REDIS_RDB_ENCVAL<<6)|REDIS_RDB_ENC_INT32;
|
enc[0] = (RDB_ENCVAL<<6)|RDB_ENC_INT32;
|
||||||
enc[1] = value&0xFF;
|
enc[1] = value&0xFF;
|
||||||
enc[2] = (value>>8)&0xFF;
|
enc[2] = (value>>8)&0xFF;
|
||||||
enc[3] = (value>>16)&0xFF;
|
enc[3] = (value>>16)&0xFF;
|
||||||
@ -183,15 +183,15 @@ void *rdbLoadIntegerObject(rio *rdb, int enctype, int flags) {
|
|||||||
unsigned char enc[4];
|
unsigned char enc[4];
|
||||||
long long val;
|
long long val;
|
||||||
|
|
||||||
if (enctype == REDIS_RDB_ENC_INT8) {
|
if (enctype == RDB_ENC_INT8) {
|
||||||
if (rioRead(rdb,enc,1) == 0) return NULL;
|
if (rioRead(rdb,enc,1) == 0) return NULL;
|
||||||
val = (signed char)enc[0];
|
val = (signed char)enc[0];
|
||||||
} else if (enctype == REDIS_RDB_ENC_INT16) {
|
} else if (enctype == RDB_ENC_INT16) {
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
if (rioRead(rdb,enc,2) == 0) return NULL;
|
if (rioRead(rdb,enc,2) == 0) return NULL;
|
||||||
v = enc[0]|(enc[1]<<8);
|
v = enc[0]|(enc[1]<<8);
|
||||||
val = (int16_t)v;
|
val = (int16_t)v;
|
||||||
} else if (enctype == REDIS_RDB_ENC_INT32) {
|
} else if (enctype == RDB_ENC_INT32) {
|
||||||
uint32_t v;
|
uint32_t v;
|
||||||
if (rioRead(rdb,enc,4) == 0) return NULL;
|
if (rioRead(rdb,enc,4) == 0) return NULL;
|
||||||
v = enc[0]|(enc[1]<<8)|(enc[2]<<16)|(enc[3]<<24);
|
v = enc[0]|(enc[1]<<8)|(enc[2]<<16)|(enc[3]<<24);
|
||||||
@ -201,7 +201,7 @@ void *rdbLoadIntegerObject(rio *rdb, int enctype, int flags) {
|
|||||||
rdbExitReportCorruptRDB("Unknown RDB integer encoding type");
|
rdbExitReportCorruptRDB("Unknown RDB integer encoding type");
|
||||||
}
|
}
|
||||||
if (plain) {
|
if (plain) {
|
||||||
char buf[REDIS_LONGSTR_SIZE], *p;
|
char buf[LONG_STR_SIZE], *p;
|
||||||
int len = ll2string(buf,sizeof(buf),val);
|
int len = ll2string(buf,sizeof(buf),val);
|
||||||
p = zmalloc(len);
|
p = zmalloc(len);
|
||||||
memcpy(p,buf,len);
|
memcpy(p,buf,len);
|
||||||
@ -238,7 +238,7 @@ ssize_t rdbSaveLzfBlob(rio *rdb, void *data, size_t compress_len,
|
|||||||
ssize_t n, nwritten = 0;
|
ssize_t n, nwritten = 0;
|
||||||
|
|
||||||
/* Data compressed! Let's save it on disk */
|
/* Data compressed! Let's save it on disk */
|
||||||
byte = (REDIS_RDB_ENCVAL<<6)|REDIS_RDB_ENC_LZF;
|
byte = (RDB_ENCVAL<<6)|RDB_ENC_LZF;
|
||||||
if ((n = rdbWriteRaw(rdb,&byte,1)) == -1) goto writeerr;
|
if ((n = rdbWriteRaw(rdb,&byte,1)) == -1) goto writeerr;
|
||||||
nwritten += n;
|
nwritten += n;
|
||||||
|
|
||||||
@ -284,8 +284,8 @@ void *rdbLoadLzfStringObject(rio *rdb, int flags) {
|
|||||||
unsigned char *c = NULL;
|
unsigned char *c = NULL;
|
||||||
sds val = NULL;
|
sds val = NULL;
|
||||||
|
|
||||||
if ((clen = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((clen = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
|
||||||
if ((len = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
|
||||||
if ((c = zmalloc(clen)) == NULL) goto err;
|
if ((c = zmalloc(clen)) == NULL) goto err;
|
||||||
|
|
||||||
/* Allocate our target according to the uncompressed size. */
|
/* Allocate our target according to the uncompressed size. */
|
||||||
@ -397,18 +397,18 @@ void *rdbGenericLoadStringObject(rio *rdb, int flags) {
|
|||||||
len = rdbLoadLen(rdb,&isencoded);
|
len = rdbLoadLen(rdb,&isencoded);
|
||||||
if (isencoded) {
|
if (isencoded) {
|
||||||
switch(len) {
|
switch(len) {
|
||||||
case REDIS_RDB_ENC_INT8:
|
case RDB_ENC_INT8:
|
||||||
case REDIS_RDB_ENC_INT16:
|
case RDB_ENC_INT16:
|
||||||
case REDIS_RDB_ENC_INT32:
|
case RDB_ENC_INT32:
|
||||||
return rdbLoadIntegerObject(rdb,len,flags);
|
return rdbLoadIntegerObject(rdb,len,flags);
|
||||||
case REDIS_RDB_ENC_LZF:
|
case RDB_ENC_LZF:
|
||||||
return rdbLoadLzfStringObject(rdb,flags);
|
return rdbLoadLzfStringObject(rdb,flags);
|
||||||
default:
|
default:
|
||||||
rdbExitReportCorruptRDB("Unknown RDB encoding type");
|
rdbExitReportCorruptRDB("Unknown RDB encoding type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == REDIS_RDB_LENERR) return NULL;
|
if (len == RDB_LENERR) return NULL;
|
||||||
if (!plain) {
|
if (!plain) {
|
||||||
robj *o = encode ? createStringObject(NULL,len) :
|
robj *o = encode ? createStringObject(NULL,len) :
|
||||||
createRawStringObject(NULL,len);
|
createRawStringObject(NULL,len);
|
||||||
@ -499,35 +499,35 @@ int rdbLoadDoubleValue(rio *rdb, double *val) {
|
|||||||
int rdbSaveObjectType(rio *rdb, robj *o) {
|
int rdbSaveObjectType(rio *rdb, robj *o) {
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case OBJ_STRING:
|
case OBJ_STRING:
|
||||||
return rdbSaveType(rdb,REDIS_RDB_TYPE_STRING);
|
return rdbSaveType(rdb,RDB_TYPE_STRING);
|
||||||
case OBJ_LIST:
|
case OBJ_LIST:
|
||||||
if (o->encoding == OBJ_ENCODING_QUICKLIST)
|
if (o->encoding == OBJ_ENCODING_QUICKLIST)
|
||||||
return rdbSaveType(rdb,REDIS_RDB_TYPE_LIST_QUICKLIST);
|
return rdbSaveType(rdb,RDB_TYPE_LIST_QUICKLIST);
|
||||||
else
|
else
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
case OBJ_SET:
|
case OBJ_SET:
|
||||||
if (o->encoding == OBJ_ENCODING_INTSET)
|
if (o->encoding == OBJ_ENCODING_INTSET)
|
||||||
return rdbSaveType(rdb,REDIS_RDB_TYPE_SET_INTSET);
|
return rdbSaveType(rdb,RDB_TYPE_SET_INTSET);
|
||||||
else if (o->encoding == OBJ_ENCODING_HT)
|
else if (o->encoding == OBJ_ENCODING_HT)
|
||||||
return rdbSaveType(rdb,REDIS_RDB_TYPE_SET);
|
return rdbSaveType(rdb,RDB_TYPE_SET);
|
||||||
else
|
else
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
case OBJ_ZSET:
|
case OBJ_ZSET:
|
||||||
if (o->encoding == OBJ_ENCODING_ZIPLIST)
|
if (o->encoding == OBJ_ENCODING_ZIPLIST)
|
||||||
return rdbSaveType(rdb,REDIS_RDB_TYPE_ZSET_ZIPLIST);
|
return rdbSaveType(rdb,RDB_TYPE_ZSET_ZIPLIST);
|
||||||
else if (o->encoding == OBJ_ENCODING_SKIPLIST)
|
else if (o->encoding == OBJ_ENCODING_SKIPLIST)
|
||||||
return rdbSaveType(rdb,REDIS_RDB_TYPE_ZSET);
|
return rdbSaveType(rdb,RDB_TYPE_ZSET);
|
||||||
else
|
else
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
case OBJ_HASH:
|
case OBJ_HASH:
|
||||||
if (o->encoding == OBJ_ENCODING_ZIPLIST)
|
if (o->encoding == OBJ_ENCODING_ZIPLIST)
|
||||||
return rdbSaveType(rdb,REDIS_RDB_TYPE_HASH_ZIPLIST);
|
return rdbSaveType(rdb,RDB_TYPE_HASH_ZIPLIST);
|
||||||
else if (o->encoding == OBJ_ENCODING_HT)
|
else if (o->encoding == OBJ_ENCODING_HT)
|
||||||
return rdbSaveType(rdb,REDIS_RDB_TYPE_HASH);
|
return rdbSaveType(rdb,RDB_TYPE_HASH);
|
||||||
else
|
else
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
default:
|
default:
|
||||||
redisPanic("Unknown object type");
|
serverPanic("Unknown object type");
|
||||||
}
|
}
|
||||||
return -1; /* avoid warning */
|
return -1; /* avoid warning */
|
||||||
}
|
}
|
||||||
@ -570,7 +570,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
}
|
}
|
||||||
} while ((node = node->next));
|
} while ((node = node->next));
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
} else if (o->type == OBJ_SET) {
|
} else if (o->type == OBJ_SET) {
|
||||||
/* Save a set value */
|
/* Save a set value */
|
||||||
@ -594,7 +594,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
if ((n = rdbSaveRawString(rdb,o->ptr,l)) == -1) return -1;
|
if ((n = rdbSaveRawString(rdb,o->ptr,l)) == -1) return -1;
|
||||||
nwritten += n;
|
nwritten += n;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
} else if (o->type == OBJ_ZSET) {
|
} else if (o->type == OBJ_ZSET) {
|
||||||
/* Save a sorted set value */
|
/* Save a sorted set value */
|
||||||
@ -622,7 +622,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
} else if (o->type == OBJ_HASH) {
|
} else if (o->type == OBJ_HASH) {
|
||||||
/* Save a hash value */
|
/* Save a hash value */
|
||||||
@ -651,11 +651,11 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown object type");
|
serverPanic("Unknown object type");
|
||||||
}
|
}
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
@ -681,7 +681,7 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val,
|
|||||||
if (expiretime != -1) {
|
if (expiretime != -1) {
|
||||||
/* If this key is already expired skip it */
|
/* If this key is already expired skip it */
|
||||||
if (expiretime < now) return 0;
|
if (expiretime < now) return 0;
|
||||||
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_EXPIRETIME_MS) == -1) return -1;
|
if (rdbSaveType(rdb,RDB_OPCODE_EXPIRETIME_MS) == -1) return -1;
|
||||||
if (rdbSaveMillisecondTime(rdb,expiretime) == -1) return -1;
|
if (rdbSaveMillisecondTime(rdb,expiretime) == -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -694,7 +694,7 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val,
|
|||||||
|
|
||||||
/* Save an AUX field. */
|
/* Save an AUX field. */
|
||||||
int rdbSaveAuxField(rio *rdb, void *key, size_t keylen, void *val, size_t vallen) {
|
int rdbSaveAuxField(rio *rdb, void *key, size_t keylen, void *val, size_t vallen) {
|
||||||
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_AUX) == -1) return -1;
|
if (rdbSaveType(rdb,RDB_OPCODE_AUX) == -1) return -1;
|
||||||
if (rdbSaveRawString(rdb,key,keylen) == -1) return -1;
|
if (rdbSaveRawString(rdb,key,keylen) == -1) return -1;
|
||||||
if (rdbSaveRawString(rdb,val,vallen) == -1) return -1;
|
if (rdbSaveRawString(rdb,val,vallen) == -1) return -1;
|
||||||
return 1;
|
return 1;
|
||||||
@ -708,7 +708,7 @@ int rdbSaveAuxFieldStrStr(rio *rdb, char *key, char *val) {
|
|||||||
|
|
||||||
/* Wrapper for strlen(key) + integer type (up to long long range). */
|
/* Wrapper for strlen(key) + integer type (up to long long range). */
|
||||||
int rdbSaveAuxFieldStrInt(rio *rdb, char *key, long long val) {
|
int rdbSaveAuxFieldStrInt(rio *rdb, char *key, long long val) {
|
||||||
char buf[REDIS_LONGSTR_SIZE];
|
char buf[LONG_STR_SIZE];
|
||||||
int vlen = ll2string(buf,sizeof(buf),val);
|
int vlen = ll2string(buf,sizeof(buf),val);
|
||||||
return rdbSaveAuxField(rdb,key,strlen(key),buf,vlen);
|
return rdbSaveAuxField(rdb,key,strlen(key),buf,vlen);
|
||||||
}
|
}
|
||||||
@ -743,7 +743,7 @@ int rdbSaveRio(rio *rdb, int *error) {
|
|||||||
|
|
||||||
if (server.rdb_checksum)
|
if (server.rdb_checksum)
|
||||||
rdb->update_cksum = rioGenericUpdateChecksum;
|
rdb->update_cksum = rioGenericUpdateChecksum;
|
||||||
snprintf(magic,sizeof(magic),"REDIS%04d",REDIS_RDB_VERSION);
|
snprintf(magic,sizeof(magic),"REDIS%04d",RDB_VERSION);
|
||||||
if (rdbWriteRaw(rdb,magic,9) == -1) goto werr;
|
if (rdbWriteRaw(rdb,magic,9) == -1) goto werr;
|
||||||
if (rdbSaveInfoAuxFields(rdb) == -1) goto werr;
|
if (rdbSaveInfoAuxFields(rdb) == -1) goto werr;
|
||||||
|
|
||||||
@ -755,7 +755,7 @@ int rdbSaveRio(rio *rdb, int *error) {
|
|||||||
if (!di) return C_ERR;
|
if (!di) return C_ERR;
|
||||||
|
|
||||||
/* Write the SELECT DB opcode */
|
/* Write the SELECT DB opcode */
|
||||||
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_SELECTDB) == -1) goto werr;
|
if (rdbSaveType(rdb,RDB_OPCODE_SELECTDB) == -1) goto werr;
|
||||||
if (rdbSaveLen(rdb,j) == -1) goto werr;
|
if (rdbSaveLen(rdb,j) == -1) goto werr;
|
||||||
|
|
||||||
/* Write the RESIZE DB opcode. We trim the size to UINT32_MAX, which
|
/* Write the RESIZE DB opcode. We trim the size to UINT32_MAX, which
|
||||||
@ -769,7 +769,7 @@ int rdbSaveRio(rio *rdb, int *error) {
|
|||||||
expires_size = (dictSize(db->dict) <= UINT32_MAX) ?
|
expires_size = (dictSize(db->dict) <= UINT32_MAX) ?
|
||||||
dictSize(db->expires) :
|
dictSize(db->expires) :
|
||||||
UINT32_MAX;
|
UINT32_MAX;
|
||||||
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_RESIZEDB) == -1) goto werr;
|
if (rdbSaveType(rdb,RDB_OPCODE_RESIZEDB) == -1) goto werr;
|
||||||
if (rdbSaveLen(rdb,db_size) == -1) goto werr;
|
if (rdbSaveLen(rdb,db_size) == -1) goto werr;
|
||||||
if (rdbSaveLen(rdb,expires_size) == -1) goto werr;
|
if (rdbSaveLen(rdb,expires_size) == -1) goto werr;
|
||||||
|
|
||||||
@ -788,7 +788,7 @@ int rdbSaveRio(rio *rdb, int *error) {
|
|||||||
di = NULL; /* So that we don't release it again on error. */
|
di = NULL; /* So that we don't release it again on error. */
|
||||||
|
|
||||||
/* EOF opcode */
|
/* EOF opcode */
|
||||||
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_EOF) == -1) goto werr;
|
if (rdbSaveType(rdb,RDB_OPCODE_EOF) == -1) goto werr;
|
||||||
|
|
||||||
/* CRC64 checksum. It will be zero if checksum computation is disabled, the
|
/* CRC64 checksum. It will be zero if checksum computation is disabled, the
|
||||||
* loading code skips the check in this case. */
|
* loading code skips the check in this case. */
|
||||||
@ -812,15 +812,15 @@ werr:
|
|||||||
* This way processes receiving the payload can understand when it ends
|
* This way processes receiving the payload can understand when it ends
|
||||||
* without doing any processing of the content. */
|
* without doing any processing of the content. */
|
||||||
int rdbSaveRioWithEOFMark(rio *rdb, int *error) {
|
int rdbSaveRioWithEOFMark(rio *rdb, int *error) {
|
||||||
char eofmark[REDIS_EOF_MARK_SIZE];
|
char eofmark[RDB_EOF_MARK_SIZE];
|
||||||
|
|
||||||
getRandomHexChars(eofmark,REDIS_EOF_MARK_SIZE);
|
getRandomHexChars(eofmark,RDB_EOF_MARK_SIZE);
|
||||||
if (error) *error = 0;
|
if (error) *error = 0;
|
||||||
if (rioWrite(rdb,"$EOF:",5) == 0) goto werr;
|
if (rioWrite(rdb,"$EOF:",5) == 0) goto werr;
|
||||||
if (rioWrite(rdb,eofmark,REDIS_EOF_MARK_SIZE) == 0) goto werr;
|
if (rioWrite(rdb,eofmark,RDB_EOF_MARK_SIZE) == 0) goto werr;
|
||||||
if (rioWrite(rdb,"\r\n",2) == 0) goto werr;
|
if (rioWrite(rdb,"\r\n",2) == 0) goto werr;
|
||||||
if (rdbSaveRio(rdb,error) == C_ERR) goto werr;
|
if (rdbSaveRio(rdb,error) == C_ERR) goto werr;
|
||||||
if (rioWrite(rdb,eofmark,REDIS_EOF_MARK_SIZE) == 0) goto werr;
|
if (rioWrite(rdb,eofmark,RDB_EOF_MARK_SIZE) == 0) goto werr;
|
||||||
return C_OK;
|
return C_OK;
|
||||||
|
|
||||||
werr: /* Write error. */
|
werr: /* Write error. */
|
||||||
@ -839,7 +839,7 @@ int rdbSave(char *filename) {
|
|||||||
snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid());
|
snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid());
|
||||||
fp = fopen(tmpfile,"w");
|
fp = fopen(tmpfile,"w");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
serverLog(REDIS_WARNING, "Failed opening .rdb for saving: %s",
|
serverLog(LL_WARNING, "Failed opening .rdb for saving: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
@ -858,18 +858,18 @@ int rdbSave(char *filename) {
|
|||||||
/* Use RENAME to make sure the DB file is changed atomically only
|
/* Use RENAME to make sure the DB file is changed atomically only
|
||||||
* if the generate DB file is ok. */
|
* if the generate DB file is ok. */
|
||||||
if (rename(tmpfile,filename) == -1) {
|
if (rename(tmpfile,filename) == -1) {
|
||||||
serverLog(REDIS_WARNING,"Error moving temp DB file on the final destination: %s", strerror(errno));
|
serverLog(LL_WARNING,"Error moving temp DB file on the final destination: %s", strerror(errno));
|
||||||
unlink(tmpfile);
|
unlink(tmpfile);
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_NOTICE,"DB saved on disk");
|
serverLog(LL_NOTICE,"DB saved on disk");
|
||||||
server.dirty = 0;
|
server.dirty = 0;
|
||||||
server.lastsave = time(NULL);
|
server.lastsave = time(NULL);
|
||||||
server.lastbgsave_status = C_OK;
|
server.lastbgsave_status = C_OK;
|
||||||
return C_OK;
|
return C_OK;
|
||||||
|
|
||||||
werr:
|
werr:
|
||||||
serverLog(REDIS_WARNING,"Write error saving DB on disk: %s", strerror(errno));
|
serverLog(LL_WARNING,"Write error saving DB on disk: %s", strerror(errno));
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
unlink(tmpfile);
|
unlink(tmpfile);
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
@ -896,7 +896,7 @@ int rdbSaveBackground(char *filename) {
|
|||||||
size_t private_dirty = zmalloc_get_private_dirty();
|
size_t private_dirty = zmalloc_get_private_dirty();
|
||||||
|
|
||||||
if (private_dirty) {
|
if (private_dirty) {
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"RDB: %zu MB of memory used by copy-on-write",
|
"RDB: %zu MB of memory used by copy-on-write",
|
||||||
private_dirty/(1024*1024));
|
private_dirty/(1024*1024));
|
||||||
}
|
}
|
||||||
@ -909,14 +909,14 @@ int rdbSaveBackground(char *filename) {
|
|||||||
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
|
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
|
||||||
if (childpid == -1) {
|
if (childpid == -1) {
|
||||||
server.lastbgsave_status = C_ERR;
|
server.lastbgsave_status = C_ERR;
|
||||||
serverLog(REDIS_WARNING,"Can't save in background: fork: %s",
|
serverLog(LL_WARNING,"Can't save in background: fork: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_NOTICE,"Background saving started by pid %d",childpid);
|
serverLog(LL_NOTICE,"Background saving started by pid %d",childpid);
|
||||||
server.rdb_save_time_start = time(NULL);
|
server.rdb_save_time_start = time(NULL);
|
||||||
server.rdb_child_pid = childpid;
|
server.rdb_child_pid = childpid;
|
||||||
server.rdb_child_type = REDIS_RDB_CHILD_TYPE_DISK;
|
server.rdb_child_type = RDB_CHILD_TYPE_DISK;
|
||||||
updateDictResizePolicy();
|
updateDictResizePolicy();
|
||||||
return C_OK;
|
return C_OK;
|
||||||
}
|
}
|
||||||
@ -937,13 +937,13 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
size_t len;
|
size_t len;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (rdbtype == REDIS_RDB_TYPE_STRING) {
|
if (rdbtype == RDB_TYPE_STRING) {
|
||||||
/* Read string value */
|
/* Read string value */
|
||||||
if ((o = rdbLoadEncodedStringObject(rdb)) == NULL) return NULL;
|
if ((o = rdbLoadEncodedStringObject(rdb)) == NULL) return NULL;
|
||||||
o = tryObjectEncoding(o);
|
o = tryObjectEncoding(o);
|
||||||
} else if (rdbtype == REDIS_RDB_TYPE_LIST) {
|
} else if (rdbtype == RDB_TYPE_LIST) {
|
||||||
/* Read list value */
|
/* Read list value */
|
||||||
if ((len = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
|
||||||
|
|
||||||
o = createQuicklistObject();
|
o = createQuicklistObject();
|
||||||
quicklistSetOptions(o->ptr, server.list_max_ziplist_size,
|
quicklistSetOptions(o->ptr, server.list_max_ziplist_size,
|
||||||
@ -958,9 +958,9 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
decrRefCount(dec);
|
decrRefCount(dec);
|
||||||
decrRefCount(ele);
|
decrRefCount(ele);
|
||||||
}
|
}
|
||||||
} else if (rdbtype == REDIS_RDB_TYPE_SET) {
|
} else if (rdbtype == RDB_TYPE_SET) {
|
||||||
/* Read list/set value */
|
/* Read list/set value */
|
||||||
if ((len = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
|
||||||
|
|
||||||
/* Use a regular set when there are too many entries. */
|
/* Use a regular set when there are too many entries. */
|
||||||
if (len > server.set_max_intset_entries) {
|
if (len > server.set_max_intset_entries) {
|
||||||
@ -997,13 +997,13 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
decrRefCount(ele);
|
decrRefCount(ele);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (rdbtype == REDIS_RDB_TYPE_ZSET) {
|
} else if (rdbtype == RDB_TYPE_ZSET) {
|
||||||
/* Read list/set value */
|
/* Read list/set value */
|
||||||
size_t zsetlen;
|
size_t zsetlen;
|
||||||
size_t maxelelen = 0;
|
size_t maxelelen = 0;
|
||||||
zset *zs;
|
zset *zs;
|
||||||
|
|
||||||
if ((zsetlen = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((zsetlen = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
|
||||||
o = createZsetObject();
|
o = createZsetObject();
|
||||||
zs = o->ptr;
|
zs = o->ptr;
|
||||||
|
|
||||||
@ -1030,12 +1030,12 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
if (zsetLength(o) <= server.zset_max_ziplist_entries &&
|
if (zsetLength(o) <= server.zset_max_ziplist_entries &&
|
||||||
maxelelen <= server.zset_max_ziplist_value)
|
maxelelen <= server.zset_max_ziplist_value)
|
||||||
zsetConvert(o,OBJ_ENCODING_ZIPLIST);
|
zsetConvert(o,OBJ_ENCODING_ZIPLIST);
|
||||||
} else if (rdbtype == REDIS_RDB_TYPE_HASH) {
|
} else if (rdbtype == RDB_TYPE_HASH) {
|
||||||
size_t len;
|
size_t len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
len = rdbLoadLen(rdb, NULL);
|
len = rdbLoadLen(rdb, NULL);
|
||||||
if (len == REDIS_RDB_LENERR) return NULL;
|
if (len == RDB_LENERR) return NULL;
|
||||||
|
|
||||||
o = createHashObject();
|
o = createHashObject();
|
||||||
|
|
||||||
@ -1095,8 +1095,8 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
|
|
||||||
/* All pairs should be read by now */
|
/* All pairs should be read by now */
|
||||||
serverAssert(len == 0);
|
serverAssert(len == 0);
|
||||||
} else if (rdbtype == REDIS_RDB_TYPE_LIST_QUICKLIST) {
|
} else if (rdbtype == RDB_TYPE_LIST_QUICKLIST) {
|
||||||
if ((len = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
|
||||||
o = createQuicklistObject();
|
o = createQuicklistObject();
|
||||||
quicklistSetOptions(o->ptr, server.list_max_ziplist_size,
|
quicklistSetOptions(o->ptr, server.list_max_ziplist_size,
|
||||||
server.list_compress_depth);
|
server.list_compress_depth);
|
||||||
@ -1106,11 +1106,11 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
if (zl == NULL) return NULL;
|
if (zl == NULL) return NULL;
|
||||||
quicklistAppendZiplist(o->ptr, zl);
|
quicklistAppendZiplist(o->ptr, zl);
|
||||||
}
|
}
|
||||||
} else if (rdbtype == REDIS_RDB_TYPE_HASH_ZIPMAP ||
|
} else if (rdbtype == RDB_TYPE_HASH_ZIPMAP ||
|
||||||
rdbtype == REDIS_RDB_TYPE_LIST_ZIPLIST ||
|
rdbtype == RDB_TYPE_LIST_ZIPLIST ||
|
||||||
rdbtype == REDIS_RDB_TYPE_SET_INTSET ||
|
rdbtype == RDB_TYPE_SET_INTSET ||
|
||||||
rdbtype == REDIS_RDB_TYPE_ZSET_ZIPLIST ||
|
rdbtype == RDB_TYPE_ZSET_ZIPLIST ||
|
||||||
rdbtype == REDIS_RDB_TYPE_HASH_ZIPLIST)
|
rdbtype == RDB_TYPE_HASH_ZIPLIST)
|
||||||
{
|
{
|
||||||
unsigned char *encoded = rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN);
|
unsigned char *encoded = rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN);
|
||||||
if (encoded == NULL) return NULL;
|
if (encoded == NULL) return NULL;
|
||||||
@ -1123,7 +1123,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
* size as this is an O(N) scan. Eventually everything will get
|
* size as this is an O(N) scan. Eventually everything will get
|
||||||
* converted. */
|
* converted. */
|
||||||
switch(rdbtype) {
|
switch(rdbtype) {
|
||||||
case REDIS_RDB_TYPE_HASH_ZIPMAP:
|
case RDB_TYPE_HASH_ZIPMAP:
|
||||||
/* Convert to ziplist encoded hash. This must be deprecated
|
/* Convert to ziplist encoded hash. This must be deprecated
|
||||||
* when loading dumps created by Redis 2.4 gets deprecated. */
|
* when loading dumps created by Redis 2.4 gets deprecated. */
|
||||||
{
|
{
|
||||||
@ -1152,24 +1152,24 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REDIS_RDB_TYPE_LIST_ZIPLIST:
|
case RDB_TYPE_LIST_ZIPLIST:
|
||||||
o->type = OBJ_LIST;
|
o->type = OBJ_LIST;
|
||||||
o->encoding = OBJ_ENCODING_ZIPLIST;
|
o->encoding = OBJ_ENCODING_ZIPLIST;
|
||||||
listTypeConvert(o,OBJ_ENCODING_QUICKLIST);
|
listTypeConvert(o,OBJ_ENCODING_QUICKLIST);
|
||||||
break;
|
break;
|
||||||
case REDIS_RDB_TYPE_SET_INTSET:
|
case RDB_TYPE_SET_INTSET:
|
||||||
o->type = OBJ_SET;
|
o->type = OBJ_SET;
|
||||||
o->encoding = OBJ_ENCODING_INTSET;
|
o->encoding = OBJ_ENCODING_INTSET;
|
||||||
if (intsetLen(o->ptr) > server.set_max_intset_entries)
|
if (intsetLen(o->ptr) > server.set_max_intset_entries)
|
||||||
setTypeConvert(o,OBJ_ENCODING_HT);
|
setTypeConvert(o,OBJ_ENCODING_HT);
|
||||||
break;
|
break;
|
||||||
case REDIS_RDB_TYPE_ZSET_ZIPLIST:
|
case RDB_TYPE_ZSET_ZIPLIST:
|
||||||
o->type = OBJ_ZSET;
|
o->type = OBJ_ZSET;
|
||||||
o->encoding = OBJ_ENCODING_ZIPLIST;
|
o->encoding = OBJ_ENCODING_ZIPLIST;
|
||||||
if (zsetLength(o) > server.zset_max_ziplist_entries)
|
if (zsetLength(o) > server.zset_max_ziplist_entries)
|
||||||
zsetConvert(o,OBJ_ENCODING_SKIPLIST);
|
zsetConvert(o,OBJ_ENCODING_SKIPLIST);
|
||||||
break;
|
break;
|
||||||
case REDIS_RDB_TYPE_HASH_ZIPLIST:
|
case RDB_TYPE_HASH_ZIPLIST:
|
||||||
o->type = OBJ_HASH;
|
o->type = OBJ_HASH;
|
||||||
o->encoding = OBJ_ENCODING_ZIPLIST;
|
o->encoding = OBJ_ENCODING_ZIPLIST;
|
||||||
if (hashTypeLength(o) > server.hash_max_ziplist_entries)
|
if (hashTypeLength(o) > server.hash_max_ziplist_entries)
|
||||||
@ -1225,7 +1225,7 @@ void rdbLoadProgressCallback(rio *r, const void *buf, size_t len) {
|
|||||||
* our cached time since it is used to create and update the last
|
* our cached time since it is used to create and update the last
|
||||||
* interaction time with clients and for other important things. */
|
* interaction time with clients and for other important things. */
|
||||||
updateCachedTime();
|
updateCachedTime();
|
||||||
if (server.masterhost && server.repl_state == REDIS_REPL_TRANSFER)
|
if (server.masterhost && server.repl_state == REPL_STATE_TRANSFER)
|
||||||
replicationSendNewlineToMaster();
|
replicationSendNewlineToMaster();
|
||||||
loadingProgress(r->processed_bytes);
|
loadingProgress(r->processed_bytes);
|
||||||
processEventsWhileBlocked();
|
processEventsWhileBlocked();
|
||||||
@ -1250,14 +1250,14 @@ int rdbLoad(char *filename) {
|
|||||||
buf[9] = '\0';
|
buf[9] = '\0';
|
||||||
if (memcmp(buf,"REDIS",5) != 0) {
|
if (memcmp(buf,"REDIS",5) != 0) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
serverLog(REDIS_WARNING,"Wrong signature trying to load DB from file");
|
serverLog(LL_WARNING,"Wrong signature trying to load DB from file");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
rdbver = atoi(buf+5);
|
rdbver = atoi(buf+5);
|
||||||
if (rdbver < 1 || rdbver > REDIS_RDB_VERSION) {
|
if (rdbver < 1 || rdbver > RDB_VERSION) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
serverLog(REDIS_WARNING,"Can't handle RDB format version %d",rdbver);
|
serverLog(LL_WARNING,"Can't handle RDB format version %d",rdbver);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
@ -1271,7 +1271,7 @@ int rdbLoad(char *filename) {
|
|||||||
if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;
|
if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;
|
||||||
|
|
||||||
/* Handle special types. */
|
/* Handle special types. */
|
||||||
if (type == REDIS_RDB_OPCODE_EXPIRETIME) {
|
if (type == RDB_OPCODE_EXPIRETIME) {
|
||||||
/* EXPIRETIME: load an expire associated with the next key
|
/* EXPIRETIME: load an expire associated with the next key
|
||||||
* to load. Note that after loading an expire we need to
|
* to load. Note that after loading an expire we need to
|
||||||
* load the actual type, and continue. */
|
* load the actual type, and continue. */
|
||||||
@ -1281,21 +1281,21 @@ int rdbLoad(char *filename) {
|
|||||||
/* the EXPIRETIME opcode specifies time in seconds, so convert
|
/* the EXPIRETIME opcode specifies time in seconds, so convert
|
||||||
* into milliseconds. */
|
* into milliseconds. */
|
||||||
expiretime *= 1000;
|
expiretime *= 1000;
|
||||||
} else if (type == REDIS_RDB_OPCODE_EXPIRETIME_MS) {
|
} else if (type == RDB_OPCODE_EXPIRETIME_MS) {
|
||||||
/* EXPIRETIME_MS: milliseconds precision expire times introduced
|
/* EXPIRETIME_MS: milliseconds precision expire times introduced
|
||||||
* with RDB v3. Like EXPIRETIME but no with more precision. */
|
* with RDB v3. Like EXPIRETIME but no with more precision. */
|
||||||
if ((expiretime = rdbLoadMillisecondTime(&rdb)) == -1) goto eoferr;
|
if ((expiretime = rdbLoadMillisecondTime(&rdb)) == -1) goto eoferr;
|
||||||
/* We read the time so we need to read the object type again. */
|
/* We read the time so we need to read the object type again. */
|
||||||
if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;
|
if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;
|
||||||
} else if (type == REDIS_RDB_OPCODE_EOF) {
|
} else if (type == RDB_OPCODE_EOF) {
|
||||||
/* EOF: End of file, exit the main loop. */
|
/* EOF: End of file, exit the main loop. */
|
||||||
break;
|
break;
|
||||||
} else if (type == REDIS_RDB_OPCODE_SELECTDB) {
|
} else if (type == RDB_OPCODE_SELECTDB) {
|
||||||
/* SELECTDB: Select the specified database. */
|
/* SELECTDB: Select the specified database. */
|
||||||
if ((dbid = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
|
if ((dbid = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
|
||||||
goto eoferr;
|
goto eoferr;
|
||||||
if (dbid >= (unsigned)server.dbnum) {
|
if (dbid >= (unsigned)server.dbnum) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"FATAL: Data file was created with a Redis "
|
"FATAL: Data file was created with a Redis "
|
||||||
"server configured to handle more than %d "
|
"server configured to handle more than %d "
|
||||||
"databases. Exiting\n", server.dbnum);
|
"databases. Exiting\n", server.dbnum);
|
||||||
@ -1303,18 +1303,18 @@ int rdbLoad(char *filename) {
|
|||||||
}
|
}
|
||||||
db = server.db+dbid;
|
db = server.db+dbid;
|
||||||
continue; /* Read type again. */
|
continue; /* Read type again. */
|
||||||
} else if (type == REDIS_RDB_OPCODE_RESIZEDB) {
|
} else if (type == RDB_OPCODE_RESIZEDB) {
|
||||||
/* RESIZEDB: Hint about the size of the keys in the currently
|
/* RESIZEDB: Hint about the size of the keys in the currently
|
||||||
* selected data base, in order to avoid useless rehashing. */
|
* selected data base, in order to avoid useless rehashing. */
|
||||||
uint32_t db_size, expires_size;
|
uint32_t db_size, expires_size;
|
||||||
if ((db_size = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
|
if ((db_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
|
||||||
goto eoferr;
|
goto eoferr;
|
||||||
if ((expires_size = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
|
if ((expires_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
|
||||||
goto eoferr;
|
goto eoferr;
|
||||||
dictExpand(db->dict,db_size);
|
dictExpand(db->dict,db_size);
|
||||||
dictExpand(db->expires,expires_size);
|
dictExpand(db->expires,expires_size);
|
||||||
continue; /* Read type again. */
|
continue; /* Read type again. */
|
||||||
} else if (type == REDIS_RDB_OPCODE_AUX) {
|
} else if (type == RDB_OPCODE_AUX) {
|
||||||
/* AUX: generic string-string fields. Use to add state to RDB
|
/* AUX: generic string-string fields. Use to add state to RDB
|
||||||
* which is backward compatible. Implementations of RDB loading
|
* which is backward compatible. Implementations of RDB loading
|
||||||
* are requierd to skip AUX fields they don't understand.
|
* are requierd to skip AUX fields they don't understand.
|
||||||
@ -1328,13 +1328,13 @@ int rdbLoad(char *filename) {
|
|||||||
/* All the fields with a name staring with '%' are considered
|
/* All the fields with a name staring with '%' are considered
|
||||||
* information fields and are logged at startup with a log
|
* information fields and are logged at startup with a log
|
||||||
* level of NOTICE. */
|
* level of NOTICE. */
|
||||||
serverLog(REDIS_NOTICE,"RDB '%s': %s",
|
serverLog(LL_NOTICE,"RDB '%s': %s",
|
||||||
(char*)auxkey->ptr,
|
(char*)auxkey->ptr,
|
||||||
(char*)auxval->ptr);
|
(char*)auxval->ptr);
|
||||||
} else {
|
} else {
|
||||||
/* We ignore fields we don't understand, as by AUX field
|
/* We ignore fields we don't understand, as by AUX field
|
||||||
* contract. */
|
* contract. */
|
||||||
serverLog(REDIS_DEBUG,"Unrecognized RDB AUX field: '%s'",
|
serverLog(LL_DEBUG,"Unrecognized RDB AUX field: '%s'",
|
||||||
(char*)auxkey->ptr);
|
(char*)auxkey->ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1372,9 +1372,9 @@ int rdbLoad(char *filename) {
|
|||||||
if (rioRead(&rdb,&cksum,8) == 0) goto eoferr;
|
if (rioRead(&rdb,&cksum,8) == 0) goto eoferr;
|
||||||
memrev64ifbe(&cksum);
|
memrev64ifbe(&cksum);
|
||||||
if (cksum == 0) {
|
if (cksum == 0) {
|
||||||
serverLog(REDIS_WARNING,"RDB file was saved with checksum disabled: no check performed.");
|
serverLog(LL_WARNING,"RDB file was saved with checksum disabled: no check performed.");
|
||||||
} else if (cksum != expected) {
|
} else if (cksum != expected) {
|
||||||
serverLog(REDIS_WARNING,"Wrong RDB checksum. Aborting now.");
|
serverLog(LL_WARNING,"Wrong RDB checksum. Aborting now.");
|
||||||
rdbExitReportCorruptRDB("RDB CRC error");
|
rdbExitReportCorruptRDB("RDB CRC error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1384,7 +1384,7 @@ int rdbLoad(char *filename) {
|
|||||||
return C_OK;
|
return C_OK;
|
||||||
|
|
||||||
eoferr: /* unexpected end of file is handled here with a fatal exit */
|
eoferr: /* unexpected end of file is handled here with a fatal exit */
|
||||||
serverLog(REDIS_WARNING,"Short read or OOM loading DB. Unrecoverable error, aborting now.");
|
serverLog(LL_WARNING,"Short read or OOM loading DB. Unrecoverable error, aborting now.");
|
||||||
rdbExitReportCorruptRDB("Unexpected EOF reading RDB file");
|
rdbExitReportCorruptRDB("Unexpected EOF reading RDB file");
|
||||||
return C_ERR; /* Just to avoid warning */
|
return C_ERR; /* Just to avoid warning */
|
||||||
}
|
}
|
||||||
@ -1393,18 +1393,18 @@ eoferr: /* unexpected end of file is handled here with a fatal exit */
|
|||||||
* This function covers the case of actual BGSAVEs. */
|
* This function covers the case of actual BGSAVEs. */
|
||||||
void backgroundSaveDoneHandlerDisk(int exitcode, int bysignal) {
|
void backgroundSaveDoneHandlerDisk(int exitcode, int bysignal) {
|
||||||
if (!bysignal && exitcode == 0) {
|
if (!bysignal && exitcode == 0) {
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Background saving terminated with success");
|
"Background saving terminated with success");
|
||||||
server.dirty = server.dirty - server.dirty_before_bgsave;
|
server.dirty = server.dirty - server.dirty_before_bgsave;
|
||||||
server.lastsave = time(NULL);
|
server.lastsave = time(NULL);
|
||||||
server.lastbgsave_status = C_OK;
|
server.lastbgsave_status = C_OK;
|
||||||
} else if (!bysignal && exitcode != 0) {
|
} else if (!bysignal && exitcode != 0) {
|
||||||
serverLog(REDIS_WARNING, "Background saving error");
|
serverLog(LL_WARNING, "Background saving error");
|
||||||
server.lastbgsave_status = C_ERR;
|
server.lastbgsave_status = C_ERR;
|
||||||
} else {
|
} else {
|
||||||
mstime_t latency;
|
mstime_t latency;
|
||||||
|
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Background saving terminated by signal %d", bysignal);
|
"Background saving terminated by signal %d", bysignal);
|
||||||
latencyStartMonitor(latency);
|
latencyStartMonitor(latency);
|
||||||
rdbRemoveTempFile(server.rdb_child_pid);
|
rdbRemoveTempFile(server.rdb_child_pid);
|
||||||
@ -1416,12 +1416,12 @@ void backgroundSaveDoneHandlerDisk(int exitcode, int bysignal) {
|
|||||||
server.lastbgsave_status = C_ERR;
|
server.lastbgsave_status = C_ERR;
|
||||||
}
|
}
|
||||||
server.rdb_child_pid = -1;
|
server.rdb_child_pid = -1;
|
||||||
server.rdb_child_type = REDIS_RDB_CHILD_TYPE_NONE;
|
server.rdb_child_type = RDB_CHILD_TYPE_NONE;
|
||||||
server.rdb_save_time_last = time(NULL)-server.rdb_save_time_start;
|
server.rdb_save_time_last = time(NULL)-server.rdb_save_time_start;
|
||||||
server.rdb_save_time_start = -1;
|
server.rdb_save_time_start = -1;
|
||||||
/* Possibly there are slaves waiting for a BGSAVE in order to be served
|
/* Possibly there are slaves waiting for a BGSAVE in order to be served
|
||||||
* (the first stage of SYNC is a bulk transfer of dump.rdb) */
|
* (the first stage of SYNC is a bulk transfer of dump.rdb) */
|
||||||
updateSlavesWaitingBgsave((!bysignal && exitcode == 0) ? C_OK : C_ERR, REDIS_RDB_CHILD_TYPE_DISK);
|
updateSlavesWaitingBgsave((!bysignal && exitcode == 0) ? C_OK : C_ERR, RDB_CHILD_TYPE_DISK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A background saving child (BGSAVE) terminated its work. Handle this.
|
/* A background saving child (BGSAVE) terminated its work. Handle this.
|
||||||
@ -1431,16 +1431,16 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
|
|||||||
uint64_t *ok_slaves;
|
uint64_t *ok_slaves;
|
||||||
|
|
||||||
if (!bysignal && exitcode == 0) {
|
if (!bysignal && exitcode == 0) {
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"Background RDB transfer terminated with success");
|
"Background RDB transfer terminated with success");
|
||||||
} else if (!bysignal && exitcode != 0) {
|
} else if (!bysignal && exitcode != 0) {
|
||||||
serverLog(REDIS_WARNING, "Background transfer error");
|
serverLog(LL_WARNING, "Background transfer error");
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Background transfer terminated by signal %d", bysignal);
|
"Background transfer terminated by signal %d", bysignal);
|
||||||
}
|
}
|
||||||
server.rdb_child_pid = -1;
|
server.rdb_child_pid = -1;
|
||||||
server.rdb_child_type = REDIS_RDB_CHILD_TYPE_NONE;
|
server.rdb_child_type = RDB_CHILD_TYPE_NONE;
|
||||||
server.rdb_save_time_start = -1;
|
server.rdb_save_time_start = -1;
|
||||||
|
|
||||||
/* If the child returns an OK exit code, read the set of slave client
|
/* If the child returns an OK exit code, read the set of slave client
|
||||||
@ -1484,7 +1484,7 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
|
|||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
client *slave = ln->value;
|
client *slave = ln->value;
|
||||||
|
|
||||||
if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_END) {
|
if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_END) {
|
||||||
uint64_t j;
|
uint64_t j;
|
||||||
int errorcode = 0;
|
int errorcode = 0;
|
||||||
|
|
||||||
@ -1498,14 +1498,14 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j == ok_slaves[0] || errorcode != 0) {
|
if (j == ok_slaves[0] || errorcode != 0) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Closing slave %s: child->slave RDB transfer failed: %s",
|
"Closing slave %s: child->slave RDB transfer failed: %s",
|
||||||
replicationGetSlaveName(slave),
|
replicationGetSlaveName(slave),
|
||||||
(errorcode == 0) ? "RDB transfer child aborted"
|
(errorcode == 0) ? "RDB transfer child aborted"
|
||||||
: strerror(errorcode));
|
: strerror(errorcode));
|
||||||
freeClient(slave);
|
freeClient(slave);
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Slave %s correctly received the streamed RDB file.",
|
"Slave %s correctly received the streamed RDB file.",
|
||||||
replicationGetSlaveName(slave));
|
replicationGetSlaveName(slave));
|
||||||
/* Restore the socket as non-blocking. */
|
/* Restore the socket as non-blocking. */
|
||||||
@ -1516,26 +1516,26 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
|
|||||||
}
|
}
|
||||||
zfree(ok_slaves);
|
zfree(ok_slaves);
|
||||||
|
|
||||||
updateSlavesWaitingBgsave((!bysignal && exitcode == 0) ? C_OK : C_ERR, REDIS_RDB_CHILD_TYPE_SOCKET);
|
updateSlavesWaitingBgsave((!bysignal && exitcode == 0) ? C_OK : C_ERR, RDB_CHILD_TYPE_SOCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When a background RDB saving/transfer terminates, call the right handler. */
|
/* When a background RDB saving/transfer terminates, call the right handler. */
|
||||||
void backgroundSaveDoneHandler(int exitcode, int bysignal) {
|
void backgroundSaveDoneHandler(int exitcode, int bysignal) {
|
||||||
switch(server.rdb_child_type) {
|
switch(server.rdb_child_type) {
|
||||||
case REDIS_RDB_CHILD_TYPE_DISK:
|
case RDB_CHILD_TYPE_DISK:
|
||||||
backgroundSaveDoneHandlerDisk(exitcode,bysignal);
|
backgroundSaveDoneHandlerDisk(exitcode,bysignal);
|
||||||
break;
|
break;
|
||||||
case REDIS_RDB_CHILD_TYPE_SOCKET:
|
case RDB_CHILD_TYPE_SOCKET:
|
||||||
backgroundSaveDoneHandlerSocket(exitcode,bysignal);
|
backgroundSaveDoneHandlerSocket(exitcode,bysignal);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
redisPanic("Unknown RDB child type.");
|
serverPanic("Unknown RDB child type.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Spawn an RDB child that writes the RDB to the sockets of the slaves
|
/* Spawn an RDB child that writes the RDB to the sockets of the slaves
|
||||||
* that are currently in REDIS_REPL_WAIT_BGSAVE_START state. */
|
* that are currently in SLAVE_STATE_WAIT_BGSAVE_START state. */
|
||||||
int rdbSaveToSlavesSockets(void) {
|
int rdbSaveToSlavesSockets(void) {
|
||||||
int *fds;
|
int *fds;
|
||||||
uint64_t *clientids;
|
uint64_t *clientids;
|
||||||
@ -1568,10 +1568,10 @@ int rdbSaveToSlavesSockets(void) {
|
|||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
client *slave = ln->value;
|
client *slave = ln->value;
|
||||||
|
|
||||||
if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_START) {
|
if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_START) {
|
||||||
clientids[numfds] = slave->id;
|
clientids[numfds] = slave->id;
|
||||||
fds[numfds++] = slave->fd;
|
fds[numfds++] = slave->fd;
|
||||||
slave->replstate = REDIS_REPL_WAIT_BGSAVE_END;
|
slave->replstate = SLAVE_STATE_WAIT_BGSAVE_END;
|
||||||
/* Put the socket in non-blocking mode to simplify RDB transfer.
|
/* Put the socket in non-blocking mode to simplify RDB transfer.
|
||||||
* We'll restore it when the children returns (since duped socket
|
* We'll restore it when the children returns (since duped socket
|
||||||
* will share the O_NONBLOCK attribute with the parent). */
|
* will share the O_NONBLOCK attribute with the parent). */
|
||||||
@ -1601,7 +1601,7 @@ int rdbSaveToSlavesSockets(void) {
|
|||||||
size_t private_dirty = zmalloc_get_private_dirty();
|
size_t private_dirty = zmalloc_get_private_dirty();
|
||||||
|
|
||||||
if (private_dirty) {
|
if (private_dirty) {
|
||||||
serverLog(REDIS_NOTICE,
|
serverLog(LL_NOTICE,
|
||||||
"RDB: %zu MB of memory used by copy-on-write",
|
"RDB: %zu MB of memory used by copy-on-write",
|
||||||
private_dirty/(1024*1024));
|
private_dirty/(1024*1024));
|
||||||
}
|
}
|
||||||
@ -1654,17 +1654,17 @@ int rdbSaveToSlavesSockets(void) {
|
|||||||
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
|
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
|
||||||
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
|
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
|
||||||
if (childpid == -1) {
|
if (childpid == -1) {
|
||||||
serverLog(REDIS_WARNING,"Can't save in background: fork: %s",
|
serverLog(LL_WARNING,"Can't save in background: fork: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
zfree(fds);
|
zfree(fds);
|
||||||
close(pipefds[0]);
|
close(pipefds[0]);
|
||||||
close(pipefds[1]);
|
close(pipefds[1]);
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_NOTICE,"Background RDB transfer started by pid %d",childpid);
|
serverLog(LL_NOTICE,"Background RDB transfer started by pid %d",childpid);
|
||||||
server.rdb_save_time_start = time(NULL);
|
server.rdb_save_time_start = time(NULL);
|
||||||
server.rdb_child_pid = childpid;
|
server.rdb_child_pid = childpid;
|
||||||
server.rdb_child_type = REDIS_RDB_CHILD_TYPE_SOCKET;
|
server.rdb_child_type = RDB_CHILD_TYPE_SOCKET;
|
||||||
updateDictResizePolicy();
|
updateDictResizePolicy();
|
||||||
zfree(fds);
|
zfree(fds);
|
||||||
return C_OK;
|
return C_OK;
|
||||||
|
60
src/rdb.h
60
src/rdb.h
@ -27,8 +27,8 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REDIS_RDB_H
|
#ifndef __RDB_H
|
||||||
#define __REDIS_RDB_H
|
#define __RDB_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "rio.h"
|
#include "rio.h"
|
||||||
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
/* The current RDB version. When the format changes in a way that is no longer
|
/* The current RDB version. When the format changes in a way that is no longer
|
||||||
* backward compatible this number gets incremented. */
|
* backward compatible this number gets incremented. */
|
||||||
#define REDIS_RDB_VERSION 7
|
#define RDB_VERSION 7
|
||||||
|
|
||||||
/* Defines related to the dump file format. To store 32 bits lengths for short
|
/* Defines related to the dump file format. To store 32 bits lengths for short
|
||||||
* keys requires a lot of space, so we check the most significant 2 bits of
|
* keys requires a lot of space, so we check the most significant 2 bits of
|
||||||
@ -49,52 +49,52 @@
|
|||||||
* 10|000000 [32 bit integer] => if it's 01, a full 32 bit len will follow
|
* 10|000000 [32 bit integer] => if it's 01, a full 32 bit len will follow
|
||||||
* 11|000000 this means: specially encoded object will follow. The six bits
|
* 11|000000 this means: specially encoded object will follow. The six bits
|
||||||
* number specify the kind of object that follows.
|
* number specify the kind of object that follows.
|
||||||
* See the REDIS_RDB_ENC_* defines.
|
* See the RDB_ENC_* defines.
|
||||||
*
|
*
|
||||||
* Lengths up to 63 are stored using a single byte, most DB keys, and may
|
* Lengths up to 63 are stored using a single byte, most DB keys, and may
|
||||||
* values, will fit inside. */
|
* values, will fit inside. */
|
||||||
#define REDIS_RDB_6BITLEN 0
|
#define RDB_6BITLEN 0
|
||||||
#define REDIS_RDB_14BITLEN 1
|
#define RDB_14BITLEN 1
|
||||||
#define REDIS_RDB_32BITLEN 2
|
#define RDB_32BITLEN 2
|
||||||
#define REDIS_RDB_ENCVAL 3
|
#define RDB_ENCVAL 3
|
||||||
#define REDIS_RDB_LENERR UINT_MAX
|
#define RDB_LENERR UINT_MAX
|
||||||
|
|
||||||
/* When a length of a string object stored on disk has the first two bits
|
/* When a length of a string object stored on disk has the first two bits
|
||||||
* set, the remaining two bits specify a special encoding for the object
|
* set, the remaining two bits specify a special encoding for the object
|
||||||
* accordingly to the following defines: */
|
* accordingly to the following defines: */
|
||||||
#define REDIS_RDB_ENC_INT8 0 /* 8 bit signed integer */
|
#define RDB_ENC_INT8 0 /* 8 bit signed integer */
|
||||||
#define REDIS_RDB_ENC_INT16 1 /* 16 bit signed integer */
|
#define RDB_ENC_INT16 1 /* 16 bit signed integer */
|
||||||
#define REDIS_RDB_ENC_INT32 2 /* 32 bit signed integer */
|
#define RDB_ENC_INT32 2 /* 32 bit signed integer */
|
||||||
#define REDIS_RDB_ENC_LZF 3 /* string compressed with FASTLZ */
|
#define RDB_ENC_LZF 3 /* string compressed with FASTLZ */
|
||||||
|
|
||||||
/* Dup object types to RDB object types. Only reason is readability (are we
|
/* Dup object types to RDB object types. Only reason is readability (are we
|
||||||
* dealing with RDB types or with in-memory object types?). */
|
* dealing with RDB types or with in-memory object types?). */
|
||||||
#define REDIS_RDB_TYPE_STRING 0
|
#define RDB_TYPE_STRING 0
|
||||||
#define REDIS_RDB_TYPE_LIST 1
|
#define RDB_TYPE_LIST 1
|
||||||
#define REDIS_RDB_TYPE_SET 2
|
#define RDB_TYPE_SET 2
|
||||||
#define REDIS_RDB_TYPE_ZSET 3
|
#define RDB_TYPE_ZSET 3
|
||||||
#define REDIS_RDB_TYPE_HASH 4
|
#define RDB_TYPE_HASH 4
|
||||||
/* NOTE: WHEN ADDING NEW RDB TYPE, UPDATE rdbIsObjectType() BELOW */
|
/* NOTE: WHEN ADDING NEW RDB TYPE, UPDATE rdbIsObjectType() BELOW */
|
||||||
|
|
||||||
/* Object types for encoded objects. */
|
/* Object types for encoded objects. */
|
||||||
#define REDIS_RDB_TYPE_HASH_ZIPMAP 9
|
#define RDB_TYPE_HASH_ZIPMAP 9
|
||||||
#define REDIS_RDB_TYPE_LIST_ZIPLIST 10
|
#define RDB_TYPE_LIST_ZIPLIST 10
|
||||||
#define REDIS_RDB_TYPE_SET_INTSET 11
|
#define RDB_TYPE_SET_INTSET 11
|
||||||
#define REDIS_RDB_TYPE_ZSET_ZIPLIST 12
|
#define RDB_TYPE_ZSET_ZIPLIST 12
|
||||||
#define REDIS_RDB_TYPE_HASH_ZIPLIST 13
|
#define RDB_TYPE_HASH_ZIPLIST 13
|
||||||
#define REDIS_RDB_TYPE_LIST_QUICKLIST 14
|
#define RDB_TYPE_LIST_QUICKLIST 14
|
||||||
/* NOTE: WHEN ADDING NEW RDB TYPE, UPDATE rdbIsObjectType() BELOW */
|
/* NOTE: WHEN ADDING NEW RDB TYPE, UPDATE rdbIsObjectType() BELOW */
|
||||||
|
|
||||||
/* Test if a type is an object type. */
|
/* Test if a type is an object type. */
|
||||||
#define rdbIsObjectType(t) ((t >= 0 && t <= 4) || (t >= 9 && t <= 14))
|
#define rdbIsObjectType(t) ((t >= 0 && t <= 4) || (t >= 9 && t <= 14))
|
||||||
|
|
||||||
/* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */
|
/* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */
|
||||||
#define REDIS_RDB_OPCODE_AUX 250
|
#define RDB_OPCODE_AUX 250
|
||||||
#define REDIS_RDB_OPCODE_RESIZEDB 251
|
#define RDB_OPCODE_RESIZEDB 251
|
||||||
#define REDIS_RDB_OPCODE_EXPIRETIME_MS 252
|
#define RDB_OPCODE_EXPIRETIME_MS 252
|
||||||
#define REDIS_RDB_OPCODE_EXPIRETIME 253
|
#define RDB_OPCODE_EXPIRETIME 253
|
||||||
#define REDIS_RDB_OPCODE_SELECTDB 254
|
#define RDB_OPCODE_SELECTDB 254
|
||||||
#define REDIS_RDB_OPCODE_EOF 255
|
#define RDB_OPCODE_EOF 255
|
||||||
|
|
||||||
int rdbSaveType(rio *rdb, unsigned char type);
|
int rdbSaveType(rio *rdb, unsigned char type);
|
||||||
int rdbLoadType(rio *rdb);
|
int rdbLoadType(rio *rdb);
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#include "adlist.h"
|
#include "adlist.h"
|
||||||
#include "zmalloc.h"
|
#include "zmalloc.h"
|
||||||
|
|
||||||
#define REDIS_NOTUSED(V) ((void) V)
|
#define UNUSED(V) ((void) V)
|
||||||
#define RANDPTR_INITIAL_SIZE 8
|
#define RANDPTR_INITIAL_SIZE 8
|
||||||
|
|
||||||
static struct config {
|
static struct config {
|
||||||
@ -188,9 +188,9 @@ static void clientDone(client c) {
|
|||||||
static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
client c = privdata;
|
client c = privdata;
|
||||||
void *reply = NULL;
|
void *reply = NULL;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(fd);
|
UNUSED(fd);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
|
|
||||||
/* Calculate latency only for the first read event. This means that the
|
/* Calculate latency only for the first read event. This means that the
|
||||||
* server already sent the reply and we need to parse it. Parsing overhead
|
* server already sent the reply and we need to parse it. Parsing overhead
|
||||||
@ -246,9 +246,9 @@ static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
|
|
||||||
static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
client c = privdata;
|
client c = privdata;
|
||||||
REDIS_NOTUSED(el);
|
UNUSED(el);
|
||||||
REDIS_NOTUSED(fd);
|
UNUSED(fd);
|
||||||
REDIS_NOTUSED(mask);
|
UNUSED(mask);
|
||||||
|
|
||||||
/* Initialize request when nothing was written. */
|
/* Initialize request when nothing was written. */
|
||||||
if (c->written == 0) {
|
if (c->written == 0) {
|
||||||
@ -595,9 +595,9 @@ usage:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData) {
|
int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData) {
|
||||||
REDIS_NOTUSED(eventLoop);
|
UNUSED(eventLoop);
|
||||||
REDIS_NOTUSED(id);
|
UNUSED(id);
|
||||||
REDIS_NOTUSED(clientData);
|
UNUSED(clientData);
|
||||||
|
|
||||||
if (config.liveclients == 0) {
|
if (config.liveclients == 0) {
|
||||||
fprintf(stderr,"All clients disconnected... aborting.\n");
|
fprintf(stderr,"All clients disconnected... aborting.\n");
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#include "crc64.h"
|
#include "crc64.h"
|
||||||
|
|
||||||
#define ERROR(...) { \
|
#define ERROR(...) { \
|
||||||
serverLog(REDIS_WARNING, __VA_ARGS__); \
|
serverLog(LL_WARNING, __VA_ARGS__); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,9 +88,9 @@ static int rdbCheckType(unsigned char t) {
|
|||||||
/* In case a new object type is added, update the following
|
/* In case a new object type is added, update the following
|
||||||
* condition as necessary. */
|
* condition as necessary. */
|
||||||
return
|
return
|
||||||
(t >= REDIS_RDB_TYPE_HASH_ZIPMAP && t <= REDIS_RDB_TYPE_HASH_ZIPLIST) ||
|
(t >= RDB_TYPE_HASH_ZIPMAP && t <= RDB_TYPE_HASH_ZIPLIST) ||
|
||||||
t <= REDIS_RDB_TYPE_HASH ||
|
t <= RDB_TYPE_HASH ||
|
||||||
t >= REDIS_RDB_OPCODE_EXPIRETIME_MS;
|
t >= RDB_OPCODE_EXPIRETIME_MS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* when number of bytes to read is negative, do a peek */
|
/* when number of bytes to read is negative, do a peek */
|
||||||
@ -159,7 +159,7 @@ static int peekType() {
|
|||||||
static int processTime(int type) {
|
static int processTime(int type) {
|
||||||
uint32_t offset = CURR_OFFSET;
|
uint32_t offset = CURR_OFFSET;
|
||||||
unsigned char t[8];
|
unsigned char t[8];
|
||||||
int timelen = (type == REDIS_RDB_OPCODE_EXPIRETIME_MS) ? 8 : 4;
|
int timelen = (type == RDB_OPCODE_EXPIRETIME_MS) ? 8 : 4;
|
||||||
|
|
||||||
if (readBytes(t,timelen)) {
|
if (readBytes(t,timelen)) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -177,22 +177,22 @@ static uint32_t loadLength(int *isencoded) {
|
|||||||
int type;
|
int type;
|
||||||
|
|
||||||
if (isencoded) *isencoded = 0;
|
if (isencoded) *isencoded = 0;
|
||||||
if (!readBytes(buf, 1)) return REDIS_RDB_LENERR;
|
if (!readBytes(buf, 1)) return RDB_LENERR;
|
||||||
type = (buf[0] & 0xC0) >> 6;
|
type = (buf[0] & 0xC0) >> 6;
|
||||||
if (type == REDIS_RDB_6BITLEN) {
|
if (type == RDB_6BITLEN) {
|
||||||
/* Read a 6 bit len */
|
/* Read a 6 bit len */
|
||||||
return buf[0] & 0x3F;
|
return buf[0] & 0x3F;
|
||||||
} else if (type == REDIS_RDB_ENCVAL) {
|
} else if (type == RDB_ENCVAL) {
|
||||||
/* Read a 6 bit len encoding type */
|
/* Read a 6 bit len encoding type */
|
||||||
if (isencoded) *isencoded = 1;
|
if (isencoded) *isencoded = 1;
|
||||||
return buf[0] & 0x3F;
|
return buf[0] & 0x3F;
|
||||||
} else if (type == REDIS_RDB_14BITLEN) {
|
} else if (type == RDB_14BITLEN) {
|
||||||
/* Read a 14 bit len */
|
/* Read a 14 bit len */
|
||||||
if (!readBytes(buf+1,1)) return REDIS_RDB_LENERR;
|
if (!readBytes(buf+1,1)) return RDB_LENERR;
|
||||||
return ((buf[0] & 0x3F) << 8) | buf[1];
|
return ((buf[0] & 0x3F) << 8) | buf[1];
|
||||||
} else {
|
} else {
|
||||||
/* Read a 32 bit len */
|
/* Read a 32 bit len */
|
||||||
if (!readBytes(&len, 4)) return REDIS_RDB_LENERR;
|
if (!readBytes(&len, 4)) return RDB_LENERR;
|
||||||
return (unsigned int)ntohl(len);
|
return (unsigned int)ntohl(len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,17 +202,17 @@ static char *loadIntegerObject(int enctype) {
|
|||||||
unsigned char enc[4];
|
unsigned char enc[4];
|
||||||
long long val;
|
long long val;
|
||||||
|
|
||||||
if (enctype == REDIS_RDB_ENC_INT8) {
|
if (enctype == RDB_ENC_INT8) {
|
||||||
uint8_t v;
|
uint8_t v;
|
||||||
if (!readBytes(enc, 1)) return NULL;
|
if (!readBytes(enc, 1)) return NULL;
|
||||||
v = enc[0];
|
v = enc[0];
|
||||||
val = (int8_t)v;
|
val = (int8_t)v;
|
||||||
} else if (enctype == REDIS_RDB_ENC_INT16) {
|
} else if (enctype == RDB_ENC_INT16) {
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
if (!readBytes(enc, 2)) return NULL;
|
if (!readBytes(enc, 2)) return NULL;
|
||||||
v = enc[0]|(enc[1]<<8);
|
v = enc[0]|(enc[1]<<8);
|
||||||
val = (int16_t)v;
|
val = (int16_t)v;
|
||||||
} else if (enctype == REDIS_RDB_ENC_INT32) {
|
} else if (enctype == RDB_ENC_INT32) {
|
||||||
uint32_t v;
|
uint32_t v;
|
||||||
if (!readBytes(enc, 4)) return NULL;
|
if (!readBytes(enc, 4)) return NULL;
|
||||||
v = enc[0]|(enc[1]<<8)|(enc[2]<<16)|(enc[3]<<24);
|
v = enc[0]|(enc[1]<<8)|(enc[2]<<16)|(enc[3]<<24);
|
||||||
@ -233,8 +233,8 @@ static char* loadLzfStringObject() {
|
|||||||
unsigned int slen, clen;
|
unsigned int slen, clen;
|
||||||
char *c, *s;
|
char *c, *s;
|
||||||
|
|
||||||
if ((clen = loadLength(NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((clen = loadLength(NULL)) == RDB_LENERR) return NULL;
|
||||||
if ((slen = loadLength(NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((slen = loadLength(NULL)) == RDB_LENERR) return NULL;
|
||||||
|
|
||||||
c = zmalloc(clen);
|
c = zmalloc(clen);
|
||||||
if (!readBytes(c, clen)) {
|
if (!readBytes(c, clen)) {
|
||||||
@ -261,11 +261,11 @@ static char* loadStringObject() {
|
|||||||
len = loadLength(&isencoded);
|
len = loadLength(&isencoded);
|
||||||
if (isencoded) {
|
if (isencoded) {
|
||||||
switch(len) {
|
switch(len) {
|
||||||
case REDIS_RDB_ENC_INT8:
|
case RDB_ENC_INT8:
|
||||||
case REDIS_RDB_ENC_INT16:
|
case RDB_ENC_INT16:
|
||||||
case REDIS_RDB_ENC_INT32:
|
case RDB_ENC_INT32:
|
||||||
return loadIntegerObject(len);
|
return loadIntegerObject(len);
|
||||||
case REDIS_RDB_ENC_LZF:
|
case RDB_ENC_LZF:
|
||||||
return loadLzfStringObject();
|
return loadLzfStringObject();
|
||||||
default:
|
default:
|
||||||
/* unknown encoding */
|
/* unknown encoding */
|
||||||
@ -274,7 +274,7 @@ static char* loadStringObject() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == REDIS_RDB_LENERR) return NULL;
|
if (len == RDB_LENERR) return NULL;
|
||||||
|
|
||||||
char *buf = zmalloc(sizeof(char) * (len+1));
|
char *buf = zmalloc(sizeof(char) * (len+1));
|
||||||
if (buf == NULL) return NULL;
|
if (buf == NULL) return NULL;
|
||||||
@ -357,30 +357,30 @@ static int loadPair(entry *e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
if (e->type == REDIS_RDB_TYPE_LIST ||
|
if (e->type == RDB_TYPE_LIST ||
|
||||||
e->type == REDIS_RDB_TYPE_SET ||
|
e->type == RDB_TYPE_SET ||
|
||||||
e->type == REDIS_RDB_TYPE_ZSET ||
|
e->type == RDB_TYPE_ZSET ||
|
||||||
e->type == REDIS_RDB_TYPE_HASH) {
|
e->type == RDB_TYPE_HASH) {
|
||||||
if ((length = loadLength(NULL)) == REDIS_RDB_LENERR) {
|
if ((length = loadLength(NULL)) == RDB_LENERR) {
|
||||||
SHIFT_ERROR(offset, "Error reading %s length", types[e->type]);
|
SHIFT_ERROR(offset, "Error reading %s length", types[e->type]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(e->type) {
|
switch(e->type) {
|
||||||
case REDIS_RDB_TYPE_STRING:
|
case RDB_TYPE_STRING:
|
||||||
case REDIS_RDB_TYPE_HASH_ZIPMAP:
|
case RDB_TYPE_HASH_ZIPMAP:
|
||||||
case REDIS_RDB_TYPE_LIST_ZIPLIST:
|
case RDB_TYPE_LIST_ZIPLIST:
|
||||||
case REDIS_RDB_TYPE_SET_INTSET:
|
case RDB_TYPE_SET_INTSET:
|
||||||
case REDIS_RDB_TYPE_ZSET_ZIPLIST:
|
case RDB_TYPE_ZSET_ZIPLIST:
|
||||||
case REDIS_RDB_TYPE_HASH_ZIPLIST:
|
case RDB_TYPE_HASH_ZIPLIST:
|
||||||
if (!processStringObject(NULL)) {
|
if (!processStringObject(NULL)) {
|
||||||
SHIFT_ERROR(offset, "Error reading entry value");
|
SHIFT_ERROR(offset, "Error reading entry value");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REDIS_RDB_TYPE_LIST:
|
case RDB_TYPE_LIST:
|
||||||
case REDIS_RDB_TYPE_SET:
|
case RDB_TYPE_SET:
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
offset = CURR_OFFSET;
|
offset = CURR_OFFSET;
|
||||||
if (!processStringObject(NULL)) {
|
if (!processStringObject(NULL)) {
|
||||||
@ -389,7 +389,7 @@ static int loadPair(entry *e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REDIS_RDB_TYPE_ZSET:
|
case RDB_TYPE_ZSET:
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
offset = CURR_OFFSET;
|
offset = CURR_OFFSET;
|
||||||
if (!processStringObject(NULL)) {
|
if (!processStringObject(NULL)) {
|
||||||
@ -403,7 +403,7 @@ static int loadPair(entry *e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REDIS_RDB_TYPE_HASH:
|
case RDB_TYPE_HASH:
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
offset = CURR_OFFSET;
|
offset = CURR_OFFSET;
|
||||||
if (!processStringObject(NULL)) {
|
if (!processStringObject(NULL)) {
|
||||||
@ -439,8 +439,8 @@ static entry loadEntry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
offset[1] = CURR_OFFSET;
|
offset[1] = CURR_OFFSET;
|
||||||
if (e.type == REDIS_RDB_OPCODE_SELECTDB) {
|
if (e.type == RDB_OPCODE_SELECTDB) {
|
||||||
if ((length = loadLength(NULL)) == REDIS_RDB_LENERR) {
|
if ((length = loadLength(NULL)) == RDB_LENERR) {
|
||||||
SHIFT_ERROR(offset[1], "Error reading database number");
|
SHIFT_ERROR(offset[1], "Error reading database number");
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -448,7 +448,7 @@ static entry loadEntry() {
|
|||||||
SHIFT_ERROR(offset[1], "Database number out of range (%d)", length);
|
SHIFT_ERROR(offset[1], "Database number out of range (%d)", length);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
} else if (e.type == REDIS_RDB_OPCODE_EOF) {
|
} else if (e.type == RDB_OPCODE_EOF) {
|
||||||
if (positions[level].offset < positions[level].size) {
|
if (positions[level].offset < positions[level].size) {
|
||||||
SHIFT_ERROR(offset[0], "Unexpected EOF");
|
SHIFT_ERROR(offset[0], "Unexpected EOF");
|
||||||
} else {
|
} else {
|
||||||
@ -457,8 +457,8 @@ static entry loadEntry() {
|
|||||||
return e;
|
return e;
|
||||||
} else {
|
} else {
|
||||||
/* optionally consume expire */
|
/* optionally consume expire */
|
||||||
if (e.type == REDIS_RDB_OPCODE_EXPIRETIME ||
|
if (e.type == RDB_OPCODE_EXPIRETIME ||
|
||||||
e.type == REDIS_RDB_OPCODE_EXPIRETIME_MS) {
|
e.type == RDB_OPCODE_EXPIRETIME_MS) {
|
||||||
if (!processTime(e.type)) return e;
|
if (!processTime(e.type)) return e;
|
||||||
if (!loadType(&e)) return e;
|
if (!loadType(&e)) return e;
|
||||||
}
|
}
|
||||||
@ -491,7 +491,7 @@ static void printCentered(int indent, int width, char* body) {
|
|||||||
|
|
||||||
memset(head, '=', indent);
|
memset(head, '=', indent);
|
||||||
memset(tail, '=', width - 2 - indent - strlen(body));
|
memset(tail, '=', width - 2 - indent - strlen(body));
|
||||||
serverLog(REDIS_WARNING, "%s %s %s", head, body, tail);
|
serverLog(LL_WARNING, "%s %s %s", head, body, tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printValid(uint64_t ops, uint64_t bytes) {
|
static void printValid(uint64_t ops, uint64_t bytes) {
|
||||||
@ -538,7 +538,7 @@ static void printErrorStack(entry *e) {
|
|||||||
|
|
||||||
/* display error stack */
|
/* display error stack */
|
||||||
for (i = 0; i < errors.level; i++) {
|
for (i = 0; i < errors.level; i++) {
|
||||||
serverLog(REDIS_WARNING, "0x%08lx - %s",
|
serverLog(LL_WARNING, "0x%08lx - %s",
|
||||||
(unsigned long) errors.offset[i], errors.error[i]);
|
(unsigned long) errors.offset[i], errors.error[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,7 +551,7 @@ void process(void) {
|
|||||||
/* Exclude the final checksum for RDB >= 5. Will be checked at the end. */
|
/* Exclude the final checksum for RDB >= 5. Will be checked at the end. */
|
||||||
if (dump_version >= 5) {
|
if (dump_version >= 5) {
|
||||||
if (positions[0].size < 8) {
|
if (positions[0].size < 8) {
|
||||||
serverLog(REDIS_WARNING, "RDB version >= 5 but no room for checksum.");
|
serverLog(LL_WARNING, "RDB version >= 5 but no room for checksum.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
positions[0].size -= 8;
|
positions[0].size -= 8;
|
||||||
@ -608,7 +608,7 @@ void process(void) {
|
|||||||
printValid(num_valid_ops, num_valid_bytes);
|
printValid(num_valid_ops, num_valid_bytes);
|
||||||
|
|
||||||
/* expect an eof */
|
/* expect an eof */
|
||||||
if (entry.type != REDIS_RDB_OPCODE_EOF) {
|
if (entry.type != RDB_OPCODE_EOF) {
|
||||||
/* last byte should be EOF, add error */
|
/* last byte should be EOF, add error */
|
||||||
errors.level = 0;
|
errors.level = 0;
|
||||||
SHIFT_ERROR(positions[0].offset, "Expected EOF, got %s", types[entry.type]);
|
SHIFT_ERROR(positions[0].offset, "Expected EOF, got %s", types[entry.type]);
|
||||||
@ -636,13 +636,13 @@ void process(void) {
|
|||||||
if (crc != crc2) {
|
if (crc != crc2) {
|
||||||
SHIFT_ERROR(positions[0].offset, "RDB CRC64 does not match.");
|
SHIFT_ERROR(positions[0].offset, "RDB CRC64 does not match.");
|
||||||
} else {
|
} else {
|
||||||
serverLog(REDIS_WARNING, "CRC64 checksum is OK");
|
serverLog(LL_WARNING, "CRC64 checksum is OK");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print summary on errors */
|
/* print summary on errors */
|
||||||
if (num_errors) {
|
if (num_errors) {
|
||||||
serverLog(REDIS_WARNING, "Total unprocessable opcodes: %llu",
|
serverLog(LL_WARNING, "Total unprocessable opcodes: %llu",
|
||||||
(unsigned long long) num_errors);
|
(unsigned long long) num_errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -679,16 +679,16 @@ int redis_check_rdb(char *rdbfilename) {
|
|||||||
errors.level = 0;
|
errors.level = 0;
|
||||||
|
|
||||||
/* Object types */
|
/* Object types */
|
||||||
sprintf(types[REDIS_RDB_TYPE_STRING], "STRING");
|
sprintf(types[RDB_TYPE_STRING], "STRING");
|
||||||
sprintf(types[REDIS_RDB_TYPE_LIST], "LIST");
|
sprintf(types[RDB_TYPE_LIST], "LIST");
|
||||||
sprintf(types[REDIS_RDB_TYPE_SET], "SET");
|
sprintf(types[RDB_TYPE_SET], "SET");
|
||||||
sprintf(types[REDIS_RDB_TYPE_ZSET], "ZSET");
|
sprintf(types[RDB_TYPE_ZSET], "ZSET");
|
||||||
sprintf(types[REDIS_RDB_TYPE_HASH], "HASH");
|
sprintf(types[RDB_TYPE_HASH], "HASH");
|
||||||
|
|
||||||
/* Object types only used for dumping to disk */
|
/* Object types only used for dumping to disk */
|
||||||
sprintf(types[REDIS_RDB_OPCODE_EXPIRETIME], "EXPIRETIME");
|
sprintf(types[RDB_OPCODE_EXPIRETIME], "EXPIRETIME");
|
||||||
sprintf(types[REDIS_RDB_OPCODE_SELECTDB], "SELECTDB");
|
sprintf(types[RDB_OPCODE_SELECTDB], "SELECTDB");
|
||||||
sprintf(types[REDIS_RDB_OPCODE_EOF], "EOF");
|
sprintf(types[RDB_OPCODE_EOF], "EOF");
|
||||||
|
|
||||||
process();
|
process();
|
||||||
|
|
||||||
@ -704,7 +704,7 @@ int redis_check_rdb_main(char **argv, int argc) {
|
|||||||
fprintf(stderr, "Usage: %s <rdb-file-name>\n", argv[0]);
|
fprintf(stderr, "Usage: %s <rdb-file-name>\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
serverLog(REDIS_WARNING, "Checking RDB file %s", argv[1]);
|
serverLog(LL_WARNING, "Checking RDB file %s", argv[1]);
|
||||||
exit(redis_check_rdb(argv[1]));
|
exit(redis_check_rdb(argv[1]));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
#include "anet.h"
|
#include "anet.h"
|
||||||
#include "ae.h"
|
#include "ae.h"
|
||||||
|
|
||||||
#define REDIS_NOTUSED(V) ((void) V)
|
#define UNUSED(V) ((void) V)
|
||||||
|
|
||||||
#define OUTPUT_STANDARD 0
|
#define OUTPUT_STANDARD 0
|
||||||
#define OUTPUT_RAW 1
|
#define OUTPUT_RAW 1
|
||||||
@ -2128,7 +2128,7 @@ unsigned long compute_something_fast(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void intrinsicLatencyModeStop(int s) {
|
static void intrinsicLatencyModeStop(int s) {
|
||||||
REDIS_NOTUSED(s);
|
UNUSED(s);
|
||||||
force_cancel_loop = 1;
|
force_cancel_loop = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
10
src/rio.c
10
src/rio.c
@ -81,7 +81,7 @@ static off_t rioBufferTell(rio *r) {
|
|||||||
/* Flushes any buffer to target device if applicable. Returns 1 on success
|
/* Flushes any buffer to target device if applicable. Returns 1 on success
|
||||||
* and 0 on failures. */
|
* and 0 on failures. */
|
||||||
static int rioBufferFlush(rio *r) {
|
static int rioBufferFlush(rio *r) {
|
||||||
REDIS_NOTUSED(r);
|
UNUSED(r);
|
||||||
return 1; /* Nothing to do, our write just appends to the buffer. */
|
return 1; /* Nothing to do, our write just appends to the buffer. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ static size_t rioFdsetWrite(rio *r, const void *buf, size_t len) {
|
|||||||
if (len) {
|
if (len) {
|
||||||
r->io.fdset.buf = sdscatlen(r->io.fdset.buf,buf,len);
|
r->io.fdset.buf = sdscatlen(r->io.fdset.buf,buf,len);
|
||||||
len = 0; /* Prevent entering the while belove if we don't flush. */
|
len = 0; /* Prevent entering the while belove if we don't flush. */
|
||||||
if (sdslen(r->io.fdset.buf) > REDIS_IOBUF_LEN) doflush = 1;
|
if (sdslen(r->io.fdset.buf) > PROTO_IOBUF_LEN) doflush = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doflush) {
|
if (doflush) {
|
||||||
@ -232,9 +232,9 @@ static size_t rioFdsetWrite(rio *r, const void *buf, size_t len) {
|
|||||||
|
|
||||||
/* Returns 1 or 0 for success/failure. */
|
/* Returns 1 or 0 for success/failure. */
|
||||||
static size_t rioFdsetRead(rio *r, void *buf, size_t len) {
|
static size_t rioFdsetRead(rio *r, void *buf, size_t len) {
|
||||||
REDIS_NOTUSED(r);
|
UNUSED(r);
|
||||||
REDIS_NOTUSED(buf);
|
UNUSED(buf);
|
||||||
REDIS_NOTUSED(len);
|
UNUSED(len);
|
||||||
return 0; /* Error, this target does not support reading. */
|
return 0; /* Error, this target does not support reading. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
char *recursion_warning =
|
char *recursion_warning =
|
||||||
"luaRedisGenericCommand() recursive call detected. "
|
"luaRedisGenericCommand() recursive call detected. "
|
||||||
"Are you doing funny stuff with Lua debug hooks?";
|
"Are you doing funny stuff with Lua debug hooks?";
|
||||||
serverLog(REDIS_WARNING,"%s",recursion_warning);
|
serverLog(LL_WARNING,"%s",recursion_warning);
|
||||||
luaPushError(lua,recursion_warning);
|
luaPushError(lua,recursion_warning);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -309,7 +309,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
c->cmd = cmd;
|
c->cmd = cmd;
|
||||||
|
|
||||||
/* There are commands that are not allowed inside scripts. */
|
/* There are commands that are not allowed inside scripts. */
|
||||||
if (cmd->flags & REDIS_CMD_NOSCRIPT) {
|
if (cmd->flags & CMD_NOSCRIPT) {
|
||||||
luaPushError(lua, "This Redis command is not allowed from scripts");
|
luaPushError(lua, "This Redis command is not allowed from scripts");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -317,14 +317,14 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
/* Write commands are forbidden against read-only slaves, or if a
|
/* Write commands are forbidden against read-only slaves, or if a
|
||||||
* command marked as non-deterministic was already called in the context
|
* command marked as non-deterministic was already called in the context
|
||||||
* of this script. */
|
* of this script. */
|
||||||
if (cmd->flags & REDIS_CMD_WRITE) {
|
if (cmd->flags & CMD_WRITE) {
|
||||||
if (server.lua_random_dirty) {
|
if (server.lua_random_dirty) {
|
||||||
luaPushError(lua,
|
luaPushError(lua,
|
||||||
"Write commands not allowed after non deterministic commands");
|
"Write commands not allowed after non deterministic commands");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else if (server.masterhost && server.repl_slave_ro &&
|
} else if (server.masterhost && server.repl_slave_ro &&
|
||||||
!server.loading &&
|
!server.loading &&
|
||||||
!(server.lua_caller->flags & REDIS_MASTER))
|
!(server.lua_caller->flags & CLIENT_MASTER))
|
||||||
{
|
{
|
||||||
luaPushError(lua, shared.roslaveerr->ptr);
|
luaPushError(lua, shared.roslaveerr->ptr);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -342,7 +342,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
* first write in the context of this script, otherwise we can't stop
|
* first write in the context of this script, otherwise we can't stop
|
||||||
* in the middle. */
|
* in the middle. */
|
||||||
if (server.maxmemory && server.lua_write_dirty == 0 &&
|
if (server.maxmemory && server.lua_write_dirty == 0 &&
|
||||||
(cmd->flags & REDIS_CMD_DENYOOM))
|
(cmd->flags & CMD_DENYOOM))
|
||||||
{
|
{
|
||||||
if (freeMemoryIfNeeded() == C_ERR) {
|
if (freeMemoryIfNeeded() == C_ERR) {
|
||||||
luaPushError(lua, shared.oomerr->ptr);
|
luaPushError(lua, shared.oomerr->ptr);
|
||||||
@ -350,16 +350,16 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->flags & REDIS_CMD_RANDOM) server.lua_random_dirty = 1;
|
if (cmd->flags & CMD_RANDOM) server.lua_random_dirty = 1;
|
||||||
if (cmd->flags & REDIS_CMD_WRITE) server.lua_write_dirty = 1;
|
if (cmd->flags & CMD_WRITE) server.lua_write_dirty = 1;
|
||||||
|
|
||||||
/* If this is a Redis Cluster node, we need to make sure Lua is not
|
/* If this is a Redis Cluster node, we need to make sure Lua is not
|
||||||
* trying to access non-local keys, with the exception of commands
|
* trying to access non-local keys, with the exception of commands
|
||||||
* received from our master. */
|
* received from our master. */
|
||||||
if (server.cluster_enabled && !(server.lua_caller->flags & REDIS_MASTER)) {
|
if (server.cluster_enabled && !(server.lua_caller->flags & CLIENT_MASTER)) {
|
||||||
/* Duplicate relevant flags in the lua client. */
|
/* Duplicate relevant flags in the lua client. */
|
||||||
c->flags &= ~(REDIS_READONLY|REDIS_ASKING);
|
c->flags &= ~(CLIENT_READONLY|CLIENT_ASKING);
|
||||||
c->flags |= server.lua_caller->flags & (REDIS_READONLY|REDIS_ASKING);
|
c->flags |= server.lua_caller->flags & (CLIENT_READONLY|CLIENT_ASKING);
|
||||||
if (getNodeByQuery(c,c->cmd,c->argv,c->argc,NULL,NULL) !=
|
if (getNodeByQuery(c,c->cmd,c->argv,c->argc,NULL,NULL) !=
|
||||||
server.cluster->myself)
|
server.cluster->myself)
|
||||||
{
|
{
|
||||||
@ -371,12 +371,12 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Run the command */
|
/* Run the command */
|
||||||
call(c,REDIS_CALL_SLOWLOG | REDIS_CALL_STATS);
|
call(c,CMD_CALL_SLOWLOG | CMD_CALL_STATS);
|
||||||
|
|
||||||
/* Convert the result of the Redis command into a suitable Lua type.
|
/* Convert the result of the Redis command into a suitable Lua type.
|
||||||
* The first thing we need is to create a single string from the client
|
* The first thing we need is to create a single string from the client
|
||||||
* output buffers. */
|
* output buffers. */
|
||||||
if (listLength(c->reply) == 0 && c->bufpos < REDIS_REPLY_CHUNK_BYTES) {
|
if (listLength(c->reply) == 0 && c->bufpos < PROTO_REPLY_CHUNK_BYTES) {
|
||||||
/* This is a fast path for the common case of a reply inside the
|
/* This is a fast path for the common case of a reply inside the
|
||||||
* client static buffer. Don't create an SDS string but just use
|
* client static buffer. Don't create an SDS string but just use
|
||||||
* the client buffer directly. */
|
* the client buffer directly. */
|
||||||
@ -397,7 +397,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
redisProtocolToLuaType(lua,reply);
|
redisProtocolToLuaType(lua,reply);
|
||||||
/* Sort the output array if needed, assuming it is a non-null multi bulk
|
/* Sort the output array if needed, assuming it is a non-null multi bulk
|
||||||
* reply as expected. */
|
* reply as expected. */
|
||||||
if ((cmd->flags & REDIS_CMD_SORT_FOR_SCRIPT) &&
|
if ((cmd->flags & CMD_SORT_FOR_SCRIPT) &&
|
||||||
(reply[0] == '*' && reply[1] != '-')) {
|
(reply[0] == '*' && reply[1] != '-')) {
|
||||||
luaSortArray(lua);
|
luaSortArray(lua);
|
||||||
}
|
}
|
||||||
@ -515,7 +515,7 @@ int luaLogCommand(lua_State *lua) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
level = lua_tonumber(lua,-argc);
|
level = lua_tonumber(lua,-argc);
|
||||||
if (level < REDIS_DEBUG || level > REDIS_WARNING) {
|
if (level < LL_DEBUG || level > LL_WARNING) {
|
||||||
luaPushError(lua, "Invalid debug level.");
|
luaPushError(lua, "Invalid debug level.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -539,12 +539,12 @@ int luaLogCommand(lua_State *lua) {
|
|||||||
|
|
||||||
void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
|
void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
|
||||||
long long elapsed;
|
long long elapsed;
|
||||||
REDIS_NOTUSED(ar);
|
UNUSED(ar);
|
||||||
REDIS_NOTUSED(lua);
|
UNUSED(lua);
|
||||||
|
|
||||||
elapsed = mstime() - server.lua_time_start;
|
elapsed = mstime() - server.lua_time_start;
|
||||||
if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) {
|
if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) {
|
||||||
serverLog(REDIS_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed);
|
serverLog(LL_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed);
|
||||||
server.lua_timedout = 1;
|
server.lua_timedout = 1;
|
||||||
/* Once the script timeouts we reenter the event loop to permit others
|
/* Once the script timeouts we reenter the event loop to permit others
|
||||||
* to call SCRIPT KILL or SHUTDOWN NOSAVE if needed. For this reason
|
* to call SCRIPT KILL or SHUTDOWN NOSAVE if needed. For this reason
|
||||||
@ -555,7 +555,7 @@ void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
|
|||||||
}
|
}
|
||||||
if (server.lua_timedout) processEventsWhileBlocked();
|
if (server.lua_timedout) processEventsWhileBlocked();
|
||||||
if (server.lua_kill) {
|
if (server.lua_kill) {
|
||||||
serverLog(REDIS_WARNING,"Lua script killed by user with SCRIPT KILL.");
|
serverLog(LL_WARNING,"Lua script killed by user with SCRIPT KILL.");
|
||||||
lua_pushstring(lua,"Script killed by user with SCRIPT KILL...");
|
lua_pushstring(lua,"Script killed by user with SCRIPT KILL...");
|
||||||
lua_error(lua);
|
lua_error(lua);
|
||||||
}
|
}
|
||||||
@ -668,20 +668,20 @@ void scriptingInit(void) {
|
|||||||
lua_pushcfunction(lua,luaLogCommand);
|
lua_pushcfunction(lua,luaLogCommand);
|
||||||
lua_settable(lua,-3);
|
lua_settable(lua,-3);
|
||||||
|
|
||||||
lua_pushstring(lua,"LOG_DEBUG");
|
lua_pushstring(lua,"LL_DEBUG");
|
||||||
lua_pushnumber(lua,REDIS_DEBUG);
|
lua_pushnumber(lua,LL_DEBUG);
|
||||||
lua_settable(lua,-3);
|
lua_settable(lua,-3);
|
||||||
|
|
||||||
lua_pushstring(lua,"LOG_VERBOSE");
|
lua_pushstring(lua,"LL_VERBOSE");
|
||||||
lua_pushnumber(lua,REDIS_VERBOSE);
|
lua_pushnumber(lua,LL_VERBOSE);
|
||||||
lua_settable(lua,-3);
|
lua_settable(lua,-3);
|
||||||
|
|
||||||
lua_pushstring(lua,"LOG_NOTICE");
|
lua_pushstring(lua,"LL_NOTICE");
|
||||||
lua_pushnumber(lua,REDIS_NOTICE);
|
lua_pushnumber(lua,LL_NOTICE);
|
||||||
lua_settable(lua,-3);
|
lua_settable(lua,-3);
|
||||||
|
|
||||||
lua_pushstring(lua,"LOG_WARNING");
|
lua_pushstring(lua,"LL_WARNING");
|
||||||
lua_pushnumber(lua,REDIS_WARNING);
|
lua_pushnumber(lua,LL_WARNING);
|
||||||
lua_settable(lua,-3);
|
lua_settable(lua,-3);
|
||||||
|
|
||||||
/* redis.sha1hex */
|
/* redis.sha1hex */
|
||||||
@ -752,7 +752,7 @@ void scriptingInit(void) {
|
|||||||
* by scriptingReset(). */
|
* by scriptingReset(). */
|
||||||
if (server.lua_client == NULL) {
|
if (server.lua_client == NULL) {
|
||||||
server.lua_client = createClient(-1);
|
server.lua_client = createClient(-1);
|
||||||
server.lua_client->flags |= REDIS_LUA_CLIENT;
|
server.lua_client->flags |= CLIENT_LUA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lua beginners often don't use "local", this is likely to introduce
|
/* Lua beginners often don't use "local", this is likely to introduce
|
||||||
@ -1085,7 +1085,7 @@ void evalGenericCommand(client *c, int evalsha) {
|
|||||||
rewriteClientCommandArgument(c,0,
|
rewriteClientCommandArgument(c,0,
|
||||||
resetRefCount(createStringObject("EVAL",4)));
|
resetRefCount(createStringObject("EVAL",4)));
|
||||||
rewriteClientCommandArgument(c,1,script);
|
rewriteClientCommandArgument(c,1,script);
|
||||||
forceCommandPropagation(c,REDIS_PROPAGATE_REPL|REDIS_PROPAGATE_AOF);
|
forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1182,7 +1182,7 @@ void scriptCommand(client *c) {
|
|||||||
}
|
}
|
||||||
addReplyBulkCBuffer(c,funcname+2,40);
|
addReplyBulkCBuffer(c,funcname+2,40);
|
||||||
sdsfree(sha);
|
sdsfree(sha);
|
||||||
forceCommandPropagation(c,REDIS_PROPAGATE_REPL|REDIS_PROPAGATE_AOF);
|
forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF);
|
||||||
} else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
|
} else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
|
||||||
if (server.lua_caller == NULL) {
|
if (server.lua_caller == NULL) {
|
||||||
addReplySds(c,sdsnew("-NOTBUSY No scripts in execution right now.\r\n"));
|
addReplySds(c,sdsnew("-NOTBUSY No scripts in execution right now.\r\n"));
|
||||||
|
174
src/sentinel.c
174
src/sentinel.c
@ -226,7 +226,7 @@ typedef struct sentinelRedisInstance {
|
|||||||
|
|
||||||
/* Main state. */
|
/* Main state. */
|
||||||
struct sentinelState {
|
struct sentinelState {
|
||||||
char myid[REDIS_RUN_ID_SIZE+1]; /* This sentinel ID. */
|
char myid[CONFIG_RUN_ID_SIZE+1]; /* This sentinel ID. */
|
||||||
uint64_t current_epoch; /* Current epoch. */
|
uint64_t current_epoch; /* Current epoch. */
|
||||||
dict *masters; /* Dictionary of master sentinelRedisInstances.
|
dict *masters; /* Dictionary of master sentinelRedisInstances.
|
||||||
Key is the instance name, value is the
|
Key is the instance name, value is the
|
||||||
@ -384,7 +384,7 @@ int dictSdsKeyCompare(void *privdata, const void *key1, const void *key2);
|
|||||||
void releaseSentinelRedisInstance(sentinelRedisInstance *ri);
|
void releaseSentinelRedisInstance(sentinelRedisInstance *ri);
|
||||||
|
|
||||||
void dictInstancesValDestructor (void *privdata, void *obj) {
|
void dictInstancesValDestructor (void *privdata, void *obj) {
|
||||||
REDIS_NOTUSED(privdata);
|
UNUSED(privdata);
|
||||||
releaseSentinelRedisInstance(obj);
|
releaseSentinelRedisInstance(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,11 +477,11 @@ void sentinelIsRunning(void) {
|
|||||||
int j;
|
int j;
|
||||||
|
|
||||||
if (server.configfile == NULL) {
|
if (server.configfile == NULL) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Sentinel started without a config file. Exiting...");
|
"Sentinel started without a config file. Exiting...");
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (access(server.configfile,W_OK) == -1) {
|
} else if (access(server.configfile,W_OK) == -1) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Sentinel config file %s is not writable: %s. Exiting...",
|
"Sentinel config file %s is not writable: %s. Exiting...",
|
||||||
server.configfile,strerror(errno));
|
server.configfile,strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -490,17 +490,17 @@ void sentinelIsRunning(void) {
|
|||||||
/* If this Sentinel has yet no ID set in the configuration file, we
|
/* If this Sentinel has yet no ID set in the configuration file, we
|
||||||
* pick a random one and persist the config on disk. From now on this
|
* pick a random one and persist the config on disk. From now on this
|
||||||
* will be this Sentinel ID across restarts. */
|
* will be this Sentinel ID across restarts. */
|
||||||
for (j = 0; j < REDIS_RUN_ID_SIZE; j++)
|
for (j = 0; j < CONFIG_RUN_ID_SIZE; j++)
|
||||||
if (sentinel.myid[j] != 0) break;
|
if (sentinel.myid[j] != 0) break;
|
||||||
|
|
||||||
if (j == REDIS_RUN_ID_SIZE) {
|
if (j == CONFIG_RUN_ID_SIZE) {
|
||||||
/* Pick ID and presist the config. */
|
/* Pick ID and presist the config. */
|
||||||
getRandomHexChars(sentinel.myid,REDIS_RUN_ID_SIZE);
|
getRandomHexChars(sentinel.myid,CONFIG_RUN_ID_SIZE);
|
||||||
sentinelFlushConfig();
|
sentinelFlushConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Log its ID to make debugging of issues simpler. */
|
/* Log its ID to make debugging of issues simpler. */
|
||||||
serverLog(REDIS_WARNING,"Sentinel ID is %s", sentinel.myid);
|
serverLog(LL_WARNING,"Sentinel ID is %s", sentinel.myid);
|
||||||
|
|
||||||
/* We want to generate a +monitor event for every configured master
|
/* We want to generate a +monitor event for every configured master
|
||||||
* at startup. */
|
* at startup. */
|
||||||
@ -515,7 +515,7 @@ void sentinelIsRunning(void) {
|
|||||||
* EINVAL: Invalid port number.
|
* EINVAL: Invalid port number.
|
||||||
*/
|
*/
|
||||||
sentinelAddr *createSentinelAddr(char *hostname, int port) {
|
sentinelAddr *createSentinelAddr(char *hostname, int port) {
|
||||||
char ip[REDIS_IP_STR_LEN];
|
char ip[NET_IP_STR_LEN];
|
||||||
sentinelAddr *sa;
|
sentinelAddr *sa;
|
||||||
|
|
||||||
if (port <= 0 || port > 65535) {
|
if (port <= 0 || port > 65535) {
|
||||||
@ -557,7 +557,7 @@ int sentinelAddrIsEqual(sentinelAddr *a, sentinelAddr *b) {
|
|||||||
|
|
||||||
/* Send an event to log, pub/sub, user notification script.
|
/* Send an event to log, pub/sub, user notification script.
|
||||||
*
|
*
|
||||||
* 'level' is the log level for logging. Only REDIS_WARNING events will trigger
|
* 'level' is the log level for logging. Only LL_WARNING events will trigger
|
||||||
* the execution of the user notification script.
|
* the execution of the user notification script.
|
||||||
*
|
*
|
||||||
* 'type' is the message type, also used as a pub/sub channel name.
|
* 'type' is the message type, also used as a pub/sub channel name.
|
||||||
@ -582,7 +582,7 @@ int sentinelAddrIsEqual(sentinelAddr *a, sentinelAddr *b) {
|
|||||||
void sentinelEvent(int level, char *type, sentinelRedisInstance *ri,
|
void sentinelEvent(int level, char *type, sentinelRedisInstance *ri,
|
||||||
const char *fmt, ...) {
|
const char *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char msg[REDIS_MAX_LOGMSG_LEN];
|
char msg[LOG_MAX_LEN];
|
||||||
robj *channel, *payload;
|
robj *channel, *payload;
|
||||||
|
|
||||||
/* Handle %@ */
|
/* Handle %@ */
|
||||||
@ -617,7 +617,7 @@ void sentinelEvent(int level, char *type, sentinelRedisInstance *ri,
|
|||||||
serverLog(level,"%s %s",type,msg);
|
serverLog(level,"%s %s",type,msg);
|
||||||
|
|
||||||
/* Publish the message via Pub/Sub if it's not a debugging one. */
|
/* Publish the message via Pub/Sub if it's not a debugging one. */
|
||||||
if (level != REDIS_DEBUG) {
|
if (level != LL_DEBUG) {
|
||||||
channel = createStringObject(type,strlen(type));
|
channel = createStringObject(type,strlen(type));
|
||||||
payload = createStringObject(msg,strlen(msg));
|
payload = createStringObject(msg,strlen(msg));
|
||||||
pubsubPublishMessage(channel,payload);
|
pubsubPublishMessage(channel,payload);
|
||||||
@ -626,7 +626,7 @@ void sentinelEvent(int level, char *type, sentinelRedisInstance *ri,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Call the notification script if applicable. */
|
/* Call the notification script if applicable. */
|
||||||
if (level == REDIS_WARNING && ri != NULL) {
|
if (level == LL_WARNING && ri != NULL) {
|
||||||
sentinelRedisInstance *master = (ri->flags & SRI_MASTER) ?
|
sentinelRedisInstance *master = (ri->flags & SRI_MASTER) ?
|
||||||
ri : ri->master;
|
ri : ri->master;
|
||||||
if (master && master->notification_script) {
|
if (master && master->notification_script) {
|
||||||
@ -647,7 +647,7 @@ void sentinelGenerateInitialMonitorEvents(void) {
|
|||||||
di = dictGetIterator(sentinel.masters);
|
di = dictGetIterator(sentinel.masters);
|
||||||
while((de = dictNext(di)) != NULL) {
|
while((de = dictNext(di)) != NULL) {
|
||||||
sentinelRedisInstance *ri = dictGetVal(de);
|
sentinelRedisInstance *ri = dictGetVal(de);
|
||||||
sentinelEvent(REDIS_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
|
sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
}
|
}
|
||||||
@ -757,7 +757,7 @@ void sentinelRunPendingScripts(void) {
|
|||||||
/* Parent (fork error).
|
/* Parent (fork error).
|
||||||
* We report fork errors as signal 99, in order to unify the
|
* We report fork errors as signal 99, in order to unify the
|
||||||
* reporting with other kind of errors. */
|
* reporting with other kind of errors. */
|
||||||
sentinelEvent(REDIS_WARNING,"-script-error",NULL,
|
sentinelEvent(LL_WARNING,"-script-error",NULL,
|
||||||
"%s %d %d", sj->argv[0], 99, 0);
|
"%s %d %d", sj->argv[0], 99, 0);
|
||||||
sj->flags &= ~SENTINEL_SCRIPT_RUNNING;
|
sj->flags &= ~SENTINEL_SCRIPT_RUNNING;
|
||||||
sj->pid = 0;
|
sj->pid = 0;
|
||||||
@ -769,7 +769,7 @@ void sentinelRunPendingScripts(void) {
|
|||||||
} else {
|
} else {
|
||||||
sentinel.running_scripts++;
|
sentinel.running_scripts++;
|
||||||
sj->pid = pid;
|
sj->pid = pid;
|
||||||
sentinelEvent(REDIS_DEBUG,"+script-child",NULL,"%ld",(long)pid);
|
sentinelEvent(LL_DEBUG,"+script-child",NULL,"%ld",(long)pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -803,12 +803,12 @@ void sentinelCollectTerminatedScripts(void) {
|
|||||||
sentinelScriptJob *sj;
|
sentinelScriptJob *sj;
|
||||||
|
|
||||||
if (WIFSIGNALED(statloc)) bysignal = WTERMSIG(statloc);
|
if (WIFSIGNALED(statloc)) bysignal = WTERMSIG(statloc);
|
||||||
sentinelEvent(REDIS_DEBUG,"-script-child",NULL,"%ld %d %d",
|
sentinelEvent(LL_DEBUG,"-script-child",NULL,"%ld %d %d",
|
||||||
(long)pid, exitcode, bysignal);
|
(long)pid, exitcode, bysignal);
|
||||||
|
|
||||||
ln = sentinelGetScriptListNodeByPid(pid);
|
ln = sentinelGetScriptListNodeByPid(pid);
|
||||||
if (ln == NULL) {
|
if (ln == NULL) {
|
||||||
serverLog(REDIS_WARNING,"wait3() returned a pid (%ld) we can't find in our scripts execution queue!", (long)pid);
|
serverLog(LL_WARNING,"wait3() returned a pid (%ld) we can't find in our scripts execution queue!", (long)pid);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sj = ln->value;
|
sj = ln->value;
|
||||||
@ -827,7 +827,7 @@ void sentinelCollectTerminatedScripts(void) {
|
|||||||
/* Otherwise let's remove the script, but log the event if the
|
/* Otherwise let's remove the script, but log the event if the
|
||||||
* execution did not terminated in the best of the ways. */
|
* execution did not terminated in the best of the ways. */
|
||||||
if (bysignal || exitcode != 0) {
|
if (bysignal || exitcode != 0) {
|
||||||
sentinelEvent(REDIS_WARNING,"-script-error",NULL,
|
sentinelEvent(LL_WARNING,"-script-error",NULL,
|
||||||
"%s %d %d", sj->argv[0], bysignal, exitcode);
|
"%s %d %d", sj->argv[0], bysignal, exitcode);
|
||||||
}
|
}
|
||||||
listDelNode(sentinel.scripts_queue,ln);
|
listDelNode(sentinel.scripts_queue,ln);
|
||||||
@ -851,7 +851,7 @@ void sentinelKillTimedoutScripts(void) {
|
|||||||
if (sj->flags & SENTINEL_SCRIPT_RUNNING &&
|
if (sj->flags & SENTINEL_SCRIPT_RUNNING &&
|
||||||
(now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME)
|
(now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME)
|
||||||
{
|
{
|
||||||
sentinelEvent(REDIS_WARNING,"-script-timeout",NULL,"%s %ld",
|
sentinelEvent(LL_WARNING,"-script-timeout",NULL,"%s %ld",
|
||||||
sj->argv[0], (long)sj->pid);
|
sj->argv[0], (long)sj->pid);
|
||||||
kill(sj->pid,SIGKILL);
|
kill(sj->pid,SIGKILL);
|
||||||
}
|
}
|
||||||
@ -1075,7 +1075,7 @@ int sentinelUpdateSentinelAddressInAllMasters(sentinelRedisInstance *ri) {
|
|||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
if (reconfigured)
|
if (reconfigured)
|
||||||
sentinelEvent(REDIS_NOTICE,"+sentinel-address-update", ri,
|
sentinelEvent(LL_NOTICE,"+sentinel-address-update", ri,
|
||||||
"%@ %d additional matching instances", reconfigured);
|
"%@ %d additional matching instances", reconfigured);
|
||||||
return reconfigured;
|
return reconfigured;
|
||||||
}
|
}
|
||||||
@ -1107,7 +1107,7 @@ void sentinelLinkEstablishedCallback(const redisAsyncContext *c, int status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sentinelDisconnectCallback(const redisAsyncContext *c, int status) {
|
void sentinelDisconnectCallback(const redisAsyncContext *c, int status) {
|
||||||
REDIS_NOTUSED(status);
|
UNUSED(status);
|
||||||
instanceLinkConnectionError(c);
|
instanceLinkConnectionError(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1138,7 +1138,7 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *
|
|||||||
sentinelRedisInstance *ri;
|
sentinelRedisInstance *ri;
|
||||||
sentinelAddr *addr;
|
sentinelAddr *addr;
|
||||||
dict *table = NULL;
|
dict *table = NULL;
|
||||||
char slavename[REDIS_PEER_ID_LEN], *sdsname;
|
char slavename[NET_PEER_ID_LEN], *sdsname;
|
||||||
|
|
||||||
serverAssert(flags & (SRI_MASTER|SRI_SLAVE|SRI_SENTINEL));
|
serverAssert(flags & (SRI_MASTER|SRI_SLAVE|SRI_SENTINEL));
|
||||||
serverAssert((flags & SRI_MASTER) || master != NULL);
|
serverAssert((flags & SRI_MASTER) || master != NULL);
|
||||||
@ -1260,7 +1260,7 @@ sentinelRedisInstance *sentinelRedisInstanceLookupSlave(
|
|||||||
{
|
{
|
||||||
sds key;
|
sds key;
|
||||||
sentinelRedisInstance *slave;
|
sentinelRedisInstance *slave;
|
||||||
char buf[REDIS_PEER_ID_LEN];
|
char buf[NET_PEER_ID_LEN];
|
||||||
|
|
||||||
serverAssert(ri->flags & SRI_MASTER);
|
serverAssert(ri->flags & SRI_MASTER);
|
||||||
anetFormatAddr(buf,sizeof(buf),ip,port);
|
anetFormatAddr(buf,sizeof(buf),ip,port);
|
||||||
@ -1417,7 +1417,7 @@ void sentinelResetMaster(sentinelRedisInstance *ri, int flags) {
|
|||||||
ri->role_reported_time = mstime();
|
ri->role_reported_time = mstime();
|
||||||
ri->role_reported = SRI_MASTER;
|
ri->role_reported = SRI_MASTER;
|
||||||
if (flags & SENTINEL_GENERATE_EVENT)
|
if (flags & SENTINEL_GENERATE_EVENT)
|
||||||
sentinelEvent(REDIS_WARNING,"+reset-master",ri,"%@");
|
sentinelEvent(LL_WARNING,"+reset-master",ri,"%@");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call sentinelResetMaster() on every master with a name matching the specified
|
/* Call sentinelResetMaster() on every master with a name matching the specified
|
||||||
@ -1495,7 +1495,7 @@ int sentinelResetMasterAndChangeAddress(sentinelRedisInstance *master, char *ip,
|
|||||||
slave = createSentinelRedisInstance(NULL,SRI_SLAVE,slaves[j]->ip,
|
slave = createSentinelRedisInstance(NULL,SRI_SLAVE,slaves[j]->ip,
|
||||||
slaves[j]->port, master->quorum, master);
|
slaves[j]->port, master->quorum, master);
|
||||||
releaseSentinelAddr(slaves[j]);
|
releaseSentinelAddr(slaves[j]);
|
||||||
if (slave) sentinelEvent(REDIS_NOTICE,"+slave",slave,"%@");
|
if (slave) sentinelEvent(LL_NOTICE,"+slave",slave,"%@");
|
||||||
}
|
}
|
||||||
zfree(slaves);
|
zfree(slaves);
|
||||||
|
|
||||||
@ -1624,9 +1624,9 @@ char *sentinelHandleConfiguration(char **argv, int argc) {
|
|||||||
if (current_epoch > sentinel.current_epoch)
|
if (current_epoch > sentinel.current_epoch)
|
||||||
sentinel.current_epoch = current_epoch;
|
sentinel.current_epoch = current_epoch;
|
||||||
} else if (!strcasecmp(argv[0],"myid") && argc == 2) {
|
} else if (!strcasecmp(argv[0],"myid") && argc == 2) {
|
||||||
if (strlen(argv[1]) != REDIS_RUN_ID_SIZE)
|
if (strlen(argv[1]) != CONFIG_RUN_ID_SIZE)
|
||||||
return "Malformed Sentinel id in myid option.";
|
return "Malformed Sentinel id in myid option.";
|
||||||
memcpy(sentinel.myid,argv[1],REDIS_RUN_ID_SIZE);
|
memcpy(sentinel.myid,argv[1],CONFIG_RUN_ID_SIZE);
|
||||||
} else if (!strcasecmp(argv[0],"config-epoch") && argc == 3) {
|
} else if (!strcasecmp(argv[0],"config-epoch") && argc == 3) {
|
||||||
/* config-epoch <name> <epoch> */
|
/* config-epoch <name> <epoch> */
|
||||||
ri = sentinelGetMasterByName(argv[1]);
|
ri = sentinelGetMasterByName(argv[1]);
|
||||||
@ -1852,7 +1852,7 @@ void sentinelFlushConfig(void) {
|
|||||||
|
|
||||||
werr:
|
werr:
|
||||||
if (fd != -1) close(fd);
|
if (fd != -1) close(fd);
|
||||||
serverLog(REDIS_WARNING,"WARNING: Sentinel was not able to save the new configuration on disk!!!: %s", strerror(errno));
|
serverLog(LL_WARNING,"WARNING: Sentinel was not able to save the new configuration on disk!!!: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ====================== hiredis connection handling ======================= */
|
/* ====================== hiredis connection handling ======================= */
|
||||||
@ -1903,9 +1903,9 @@ void sentinelReconnectInstance(sentinelRedisInstance *ri) {
|
|||||||
|
|
||||||
/* Commands connection. */
|
/* Commands connection. */
|
||||||
if (link->cc == NULL) {
|
if (link->cc == NULL) {
|
||||||
link->cc = redisAsyncConnectBind(ri->addr->ip,ri->addr->port,REDIS_BIND_ADDR);
|
link->cc = redisAsyncConnectBind(ri->addr->ip,ri->addr->port,NET_FIRST_BIND_ADDR);
|
||||||
if (link->cc->err) {
|
if (link->cc->err) {
|
||||||
sentinelEvent(REDIS_DEBUG,"-cmd-link-reconnection",ri,"%@ #%s",
|
sentinelEvent(LL_DEBUG,"-cmd-link-reconnection",ri,"%@ #%s",
|
||||||
link->cc->errstr);
|
link->cc->errstr);
|
||||||
instanceLinkCloseConnection(link,link->cc);
|
instanceLinkCloseConnection(link,link->cc);
|
||||||
} else {
|
} else {
|
||||||
@ -1925,9 +1925,9 @@ void sentinelReconnectInstance(sentinelRedisInstance *ri) {
|
|||||||
}
|
}
|
||||||
/* Pub / Sub */
|
/* Pub / Sub */
|
||||||
if ((ri->flags & (SRI_MASTER|SRI_SLAVE)) && link->pc == NULL) {
|
if ((ri->flags & (SRI_MASTER|SRI_SLAVE)) && link->pc == NULL) {
|
||||||
link->pc = redisAsyncConnectBind(ri->addr->ip,ri->addr->port,REDIS_BIND_ADDR);
|
link->pc = redisAsyncConnectBind(ri->addr->ip,ri->addr->port,NET_FIRST_BIND_ADDR);
|
||||||
if (link->pc->err) {
|
if (link->pc->err) {
|
||||||
sentinelEvent(REDIS_DEBUG,"-pubsub-link-reconnection",ri,"%@ #%s",
|
sentinelEvent(LL_DEBUG,"-pubsub-link-reconnection",ri,"%@ #%s",
|
||||||
link->pc->errstr);
|
link->pc->errstr);
|
||||||
instanceLinkCloseConnection(link,link->pc);
|
instanceLinkCloseConnection(link,link->pc);
|
||||||
} else {
|
} else {
|
||||||
@ -2001,7 +2001,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
|
|||||||
ri->runid = sdsnewlen(l+7,40);
|
ri->runid = sdsnewlen(l+7,40);
|
||||||
} else {
|
} else {
|
||||||
if (strncmp(ri->runid,l+7,40) != 0) {
|
if (strncmp(ri->runid,l+7,40) != 0) {
|
||||||
sentinelEvent(REDIS_NOTICE,"+reboot",ri,"%@");
|
sentinelEvent(LL_NOTICE,"+reboot",ri,"%@");
|
||||||
sdsfree(ri->runid);
|
sdsfree(ri->runid);
|
||||||
ri->runid = sdsnewlen(l+7,40);
|
ri->runid = sdsnewlen(l+7,40);
|
||||||
}
|
}
|
||||||
@ -2042,7 +2042,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
|
|||||||
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(LL_NOTICE,"+slave",slave,"%@");
|
||||||
sentinelFlushConfig();
|
sentinelFlushConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2112,7 +2112,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
|
|||||||
if (role == SRI_SLAVE) ri->slave_conf_change_time = mstime();
|
if (role == SRI_SLAVE) ri->slave_conf_change_time = mstime();
|
||||||
/* Log the event with +role-change if the new role is coherent or
|
/* Log the event with +role-change if the new role is coherent or
|
||||||
* with -role-change if there is a mismatch with the current config. */
|
* with -role-change if there is a mismatch with the current config. */
|
||||||
sentinelEvent(REDIS_VERBOSE,
|
sentinelEvent(LL_VERBOSE,
|
||||||
((ri->flags & (SRI_MASTER|SRI_SLAVE)) == role) ?
|
((ri->flags & (SRI_MASTER|SRI_SLAVE)) == role) ?
|
||||||
"+role-change" : "-role-change",
|
"+role-change" : "-role-change",
|
||||||
ri, "%@ new reported role is %s",
|
ri, "%@ new reported role is %s",
|
||||||
@ -2149,11 +2149,11 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
|
|||||||
ri->master->failover_state = SENTINEL_FAILOVER_STATE_RECONF_SLAVES;
|
ri->master->failover_state = SENTINEL_FAILOVER_STATE_RECONF_SLAVES;
|
||||||
ri->master->failover_state_change_time = mstime();
|
ri->master->failover_state_change_time = mstime();
|
||||||
sentinelFlushConfig();
|
sentinelFlushConfig();
|
||||||
sentinelEvent(REDIS_WARNING,"+promoted-slave",ri,"%@");
|
sentinelEvent(LL_WARNING,"+promoted-slave",ri,"%@");
|
||||||
if (sentinel.simfailure_flags &
|
if (sentinel.simfailure_flags &
|
||||||
SENTINEL_SIMFAILURE_CRASH_AFTER_PROMOTION)
|
SENTINEL_SIMFAILURE_CRASH_AFTER_PROMOTION)
|
||||||
sentinelSimFailureCrash();
|
sentinelSimFailureCrash();
|
||||||
sentinelEvent(REDIS_WARNING,"+failover-state-reconf-slaves",
|
sentinelEvent(LL_WARNING,"+failover-state-reconf-slaves",
|
||||||
ri->master,"%@");
|
ri->master,"%@");
|
||||||
sentinelCallClientReconfScript(ri->master,SENTINEL_LEADER,
|
sentinelCallClientReconfScript(ri->master,SENTINEL_LEADER,
|
||||||
"start",ri->master->addr,ri->addr);
|
"start",ri->master->addr,ri->addr);
|
||||||
@ -2173,7 +2173,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
|
|||||||
ri->master->addr->ip,
|
ri->master->addr->ip,
|
||||||
ri->master->addr->port);
|
ri->master->addr->port);
|
||||||
if (retval == C_OK)
|
if (retval == C_OK)
|
||||||
sentinelEvent(REDIS_NOTICE,"+convert-to-slave",ri,"%@");
|
sentinelEvent(LL_NOTICE,"+convert-to-slave",ri,"%@");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2196,7 +2196,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
|
|||||||
ri->master->addr->ip,
|
ri->master->addr->ip,
|
||||||
ri->master->addr->port);
|
ri->master->addr->port);
|
||||||
if (retval == C_OK)
|
if (retval == C_OK)
|
||||||
sentinelEvent(REDIS_NOTICE,"+fix-slave-config",ri,"%@");
|
sentinelEvent(LL_NOTICE,"+fix-slave-config",ri,"%@");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2214,7 +2214,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
|
|||||||
{
|
{
|
||||||
ri->flags &= ~SRI_RECONF_SENT;
|
ri->flags &= ~SRI_RECONF_SENT;
|
||||||
ri->flags |= SRI_RECONF_INPROG;
|
ri->flags |= SRI_RECONF_INPROG;
|
||||||
sentinelEvent(REDIS_NOTICE,"+slave-reconf-inprog",ri,"%@");
|
sentinelEvent(LL_NOTICE,"+slave-reconf-inprog",ri,"%@");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SRI_RECONF_INPROG -> SRI_RECONF_DONE */
|
/* SRI_RECONF_INPROG -> SRI_RECONF_DONE */
|
||||||
@ -2223,7 +2223,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
|
|||||||
{
|
{
|
||||||
ri->flags &= ~SRI_RECONF_INPROG;
|
ri->flags &= ~SRI_RECONF_INPROG;
|
||||||
ri->flags |= SRI_RECONF_DONE;
|
ri->flags |= SRI_RECONF_DONE;
|
||||||
sentinelEvent(REDIS_NOTICE,"+slave-reconf-done",ri,"%@");
|
sentinelEvent(LL_NOTICE,"+slave-reconf-done",ri,"%@");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2245,8 +2245,8 @@ void sentinelInfoReplyCallback(redisAsyncContext *c, void *reply, void *privdata
|
|||||||
* value of the command but its effects directly. */
|
* value of the command but its effects directly. */
|
||||||
void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
|
void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
|
||||||
instanceLink *link = c->data;
|
instanceLink *link = c->data;
|
||||||
REDIS_NOTUSED(reply);
|
UNUSED(reply);
|
||||||
REDIS_NOTUSED(privdata);
|
UNUSED(privdata);
|
||||||
|
|
||||||
if (link) link->pending_commands--;
|
if (link) link->pending_commands--;
|
||||||
}
|
}
|
||||||
@ -2338,7 +2338,7 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) {
|
|||||||
* with the new address back. */
|
* with the new address back. */
|
||||||
removed = removeMatchingSentinelFromMaster(master,token[2]);
|
removed = removeMatchingSentinelFromMaster(master,token[2]);
|
||||||
if (removed) {
|
if (removed) {
|
||||||
sentinelEvent(REDIS_NOTICE,"+sentinel-address-switch",master,
|
sentinelEvent(LL_NOTICE,"+sentinel-address-switch",master,
|
||||||
"%@ ip %s port %d for %s", token[0],port,token[2]);
|
"%@ ip %s port %d for %s", token[0],port,token[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2346,7 +2346,7 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) {
|
|||||||
si = createSentinelRedisInstance(NULL,SRI_SENTINEL,
|
si = createSentinelRedisInstance(NULL,SRI_SENTINEL,
|
||||||
token[0],port,master->quorum,master);
|
token[0],port,master->quorum,master);
|
||||||
if (si) {
|
if (si) {
|
||||||
if (!removed) sentinelEvent(REDIS_NOTICE,"+sentinel",si,"%@");
|
if (!removed) sentinelEvent(LL_NOTICE,"+sentinel",si,"%@");
|
||||||
/* The runid is NULL after a new instance creation and
|
/* The runid is NULL after a new instance creation and
|
||||||
* for Sentinels we don't have a later chance to fill it,
|
* for Sentinels we don't have a later chance to fill it,
|
||||||
* so do it now. */
|
* so do it now. */
|
||||||
@ -2361,7 +2361,7 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) {
|
|||||||
if (current_epoch > sentinel.current_epoch) {
|
if (current_epoch > sentinel.current_epoch) {
|
||||||
sentinel.current_epoch = current_epoch;
|
sentinel.current_epoch = current_epoch;
|
||||||
sentinelFlushConfig();
|
sentinelFlushConfig();
|
||||||
sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
|
sentinelEvent(LL_WARNING,"+new-epoch",master,"%llu",
|
||||||
(unsigned long long) sentinel.current_epoch);
|
(unsigned long long) sentinel.current_epoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2373,8 +2373,8 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) {
|
|||||||
{
|
{
|
||||||
sentinelAddr *old_addr;
|
sentinelAddr *old_addr;
|
||||||
|
|
||||||
sentinelEvent(REDIS_WARNING,"+config-update-from",si,"%@");
|
sentinelEvent(LL_WARNING,"+config-update-from",si,"%@");
|
||||||
sentinelEvent(REDIS_WARNING,"+switch-master",
|
sentinelEvent(LL_WARNING,"+switch-master",
|
||||||
master,"%s %s %d %s %d",
|
master,"%s %s %d %s %d",
|
||||||
master->name,
|
master->name,
|
||||||
master->addr->ip, master->addr->port,
|
master->addr->ip, master->addr->port,
|
||||||
@ -2403,7 +2403,7 @@ cleanup:
|
|||||||
void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privdata) {
|
void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privdata) {
|
||||||
sentinelRedisInstance *ri = privdata;
|
sentinelRedisInstance *ri = privdata;
|
||||||
redisReply *r;
|
redisReply *r;
|
||||||
REDIS_NOTUSED(c);
|
UNUSED(c);
|
||||||
|
|
||||||
if (!reply || !ri) return;
|
if (!reply || !ri) return;
|
||||||
r = reply;
|
r = reply;
|
||||||
@ -2440,8 +2440,8 @@ void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privd
|
|||||||
* Returns C_OK if the PUBLISH was queued correctly, otherwise
|
* Returns C_OK if the PUBLISH was queued correctly, otherwise
|
||||||
* C_ERR is returned. */
|
* C_ERR is returned. */
|
||||||
int sentinelSendHello(sentinelRedisInstance *ri) {
|
int sentinelSendHello(sentinelRedisInstance *ri) {
|
||||||
char ip[REDIS_IP_STR_LEN];
|
char ip[NET_IP_STR_LEN];
|
||||||
char payload[REDIS_IP_STR_LEN+1024];
|
char payload[NET_IP_STR_LEN+1024];
|
||||||
int retval;
|
int retval;
|
||||||
char *announce_ip;
|
char *announce_ip;
|
||||||
int announce_port;
|
int announce_port;
|
||||||
@ -2967,7 +2967,7 @@ void sentinelCommand(client *c) {
|
|||||||
addReplySds(c,sdsnew("-NOGOODSLAVE No suitable slave to promote\r\n"));
|
addReplySds(c,sdsnew("-NOGOODSLAVE No suitable slave to promote\r\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
serverLog(REDIS_WARNING,"Executing user requested FAILOVER of '%s'",
|
serverLog(LL_WARNING,"Executing user requested FAILOVER of '%s'",
|
||||||
ri->name);
|
ri->name);
|
||||||
sentinelStartFailover(ri);
|
sentinelStartFailover(ri);
|
||||||
ri->flags |= SRI_FORCE_FAILOVER;
|
ri->flags |= SRI_FORCE_FAILOVER;
|
||||||
@ -2981,7 +2981,7 @@ void sentinelCommand(client *c) {
|
|||||||
/* SENTINEL MONITOR <name> <ip> <port> <quorum> */
|
/* SENTINEL MONITOR <name> <ip> <port> <quorum> */
|
||||||
sentinelRedisInstance *ri;
|
sentinelRedisInstance *ri;
|
||||||
long quorum, port;
|
long quorum, port;
|
||||||
char ip[REDIS_IP_STR_LEN];
|
char ip[NET_IP_STR_LEN];
|
||||||
|
|
||||||
if (c->argc != 6) goto numargserr;
|
if (c->argc != 6) goto numargserr;
|
||||||
if (getLongFromObjectOrReply(c,c->argv[5],&quorum,"Invalid quorum")
|
if (getLongFromObjectOrReply(c,c->argv[5],&quorum,"Invalid quorum")
|
||||||
@ -3019,7 +3019,7 @@ void sentinelCommand(client *c) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sentinelFlushConfig();
|
sentinelFlushConfig();
|
||||||
sentinelEvent(REDIS_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
|
sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(c->argv[1]->ptr,"flushconfig")) {
|
} else if (!strcasecmp(c->argv[1]->ptr,"flushconfig")) {
|
||||||
@ -3032,7 +3032,7 @@ void sentinelCommand(client *c) {
|
|||||||
|
|
||||||
if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2]))
|
if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2]))
|
||||||
== NULL) return;
|
== NULL) return;
|
||||||
sentinelEvent(REDIS_WARNING,"-monitor",ri,"%@");
|
sentinelEvent(LL_WARNING,"-monitor",ri,"%@");
|
||||||
dictDelete(sentinel.masters,c->argv[2]->ptr);
|
dictDelete(sentinel.masters,c->argv[2]->ptr);
|
||||||
sentinelFlushConfig();
|
sentinelFlushConfig();
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
@ -3136,13 +3136,13 @@ void sentinelCommand(client *c) {
|
|||||||
if (!strcasecmp(c->argv[j]->ptr,"crash-after-election")) {
|
if (!strcasecmp(c->argv[j]->ptr,"crash-after-election")) {
|
||||||
sentinel.simfailure_flags |=
|
sentinel.simfailure_flags |=
|
||||||
SENTINEL_SIMFAILURE_CRASH_AFTER_ELECTION;
|
SENTINEL_SIMFAILURE_CRASH_AFTER_ELECTION;
|
||||||
serverLog(REDIS_WARNING,"Failure simulation: this Sentinel "
|
serverLog(LL_WARNING,"Failure simulation: this Sentinel "
|
||||||
"will crash after being successfully elected as failover "
|
"will crash after being successfully elected as failover "
|
||||||
"leader");
|
"leader");
|
||||||
} else if (!strcasecmp(c->argv[j]->ptr,"crash-after-promotion")) {
|
} else if (!strcasecmp(c->argv[j]->ptr,"crash-after-promotion")) {
|
||||||
sentinel.simfailure_flags |=
|
sentinel.simfailure_flags |=
|
||||||
SENTINEL_SIMFAILURE_CRASH_AFTER_PROMOTION;
|
SENTINEL_SIMFAILURE_CRASH_AFTER_PROMOTION;
|
||||||
serverLog(REDIS_WARNING,"Failure simulation: this Sentinel "
|
serverLog(LL_WARNING,"Failure simulation: this Sentinel "
|
||||||
"will crash after promoting the selected slave to master");
|
"will crash after promoting the selected slave to master");
|
||||||
} else if (!strcasecmp(c->argv[j]->ptr,"help")) {
|
} else if (!strcasecmp(c->argv[j]->ptr,"help")) {
|
||||||
addReplyMultiBulkLen(c,2);
|
addReplyMultiBulkLen(c,2);
|
||||||
@ -3324,7 +3324,7 @@ void sentinelSetCommand(client *c) {
|
|||||||
if (changes) sentinelFlushConfig();
|
if (changes) sentinelFlushConfig();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sentinelEvent(REDIS_WARNING,"+set",ri,"%@ %s %s",option,value);
|
sentinelEvent(LL_WARNING,"+set",ri,"%@ %s %s",option,value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changes) sentinelFlushConfig();
|
if (changes) sentinelFlushConfig();
|
||||||
@ -3406,14 +3406,14 @@ void sentinelCheckSubjectivelyDown(sentinelRedisInstance *ri) {
|
|||||||
{
|
{
|
||||||
/* Is subjectively down */
|
/* Is subjectively down */
|
||||||
if ((ri->flags & SRI_S_DOWN) == 0) {
|
if ((ri->flags & SRI_S_DOWN) == 0) {
|
||||||
sentinelEvent(REDIS_WARNING,"+sdown",ri,"%@");
|
sentinelEvent(LL_WARNING,"+sdown",ri,"%@");
|
||||||
ri->s_down_since_time = mstime();
|
ri->s_down_since_time = mstime();
|
||||||
ri->flags |= SRI_S_DOWN;
|
ri->flags |= SRI_S_DOWN;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Is subjectively up */
|
/* Is subjectively up */
|
||||||
if (ri->flags & SRI_S_DOWN) {
|
if (ri->flags & SRI_S_DOWN) {
|
||||||
sentinelEvent(REDIS_WARNING,"-sdown",ri,"%@");
|
sentinelEvent(LL_WARNING,"-sdown",ri,"%@");
|
||||||
ri->flags &= ~(SRI_S_DOWN|SRI_SCRIPT_KILL_SENT);
|
ri->flags &= ~(SRI_S_DOWN|SRI_SCRIPT_KILL_SENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3447,14 +3447,14 @@ void sentinelCheckObjectivelyDown(sentinelRedisInstance *master) {
|
|||||||
/* Set the flag accordingly to the outcome. */
|
/* Set the flag accordingly to the outcome. */
|
||||||
if (odown) {
|
if (odown) {
|
||||||
if ((master->flags & SRI_O_DOWN) == 0) {
|
if ((master->flags & SRI_O_DOWN) == 0) {
|
||||||
sentinelEvent(REDIS_WARNING,"+odown",master,"%@ #quorum %d/%d",
|
sentinelEvent(LL_WARNING,"+odown",master,"%@ #quorum %d/%d",
|
||||||
quorum, master->quorum);
|
quorum, master->quorum);
|
||||||
master->flags |= SRI_O_DOWN;
|
master->flags |= SRI_O_DOWN;
|
||||||
master->o_down_since_time = mstime();
|
master->o_down_since_time = mstime();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (master->flags & SRI_O_DOWN) {
|
if (master->flags & SRI_O_DOWN) {
|
||||||
sentinelEvent(REDIS_WARNING,"-odown",master,"%@");
|
sentinelEvent(LL_WARNING,"-odown",master,"%@");
|
||||||
master->flags &= ~SRI_O_DOWN;
|
master->flags &= ~SRI_O_DOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3490,7 +3490,7 @@ void sentinelReceiveIsMasterDownReply(redisAsyncContext *c, void *reply, void *p
|
|||||||
* replied with a vote. */
|
* replied with a vote. */
|
||||||
sdsfree(ri->leader);
|
sdsfree(ri->leader);
|
||||||
if ((long long)ri->leader_epoch != r->element[2]->integer)
|
if ((long long)ri->leader_epoch != r->element[2]->integer)
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"%s voted for %s %llu", ri->name,
|
"%s voted for %s %llu", ri->name,
|
||||||
r->element[1]->str,
|
r->element[1]->str,
|
||||||
(unsigned long long) r->element[2]->integer);
|
(unsigned long long) r->element[2]->integer);
|
||||||
@ -3552,7 +3552,7 @@ void sentinelAskMasterStateToOtherSentinels(sentinelRedisInstance *master, int f
|
|||||||
|
|
||||||
/* Crash because of user request via SENTINEL simulate-failure command. */
|
/* Crash because of user request via SENTINEL simulate-failure command. */
|
||||||
void sentinelSimFailureCrash(void) {
|
void sentinelSimFailureCrash(void) {
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Sentinel CRASH because of SENTINEL simulate-failure");
|
"Sentinel CRASH because of SENTINEL simulate-failure");
|
||||||
exit(99);
|
exit(99);
|
||||||
}
|
}
|
||||||
@ -3566,7 +3566,7 @@ char *sentinelVoteLeader(sentinelRedisInstance *master, uint64_t req_epoch, char
|
|||||||
if (req_epoch > sentinel.current_epoch) {
|
if (req_epoch > sentinel.current_epoch) {
|
||||||
sentinel.current_epoch = req_epoch;
|
sentinel.current_epoch = req_epoch;
|
||||||
sentinelFlushConfig();
|
sentinelFlushConfig();
|
||||||
sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
|
sentinelEvent(LL_WARNING,"+new-epoch",master,"%llu",
|
||||||
(unsigned long long) sentinel.current_epoch);
|
(unsigned long long) sentinel.current_epoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3576,7 +3576,7 @@ char *sentinelVoteLeader(sentinelRedisInstance *master, uint64_t req_epoch, char
|
|||||||
master->leader = sdsnew(req_runid);
|
master->leader = sdsnew(req_runid);
|
||||||
master->leader_epoch = sentinel.current_epoch;
|
master->leader_epoch = sentinel.current_epoch;
|
||||||
sentinelFlushConfig();
|
sentinelFlushConfig();
|
||||||
sentinelEvent(REDIS_WARNING,"+vote-for-leader",master,"%s %llu",
|
sentinelEvent(LL_WARNING,"+vote-for-leader",master,"%s %llu",
|
||||||
master->leader, (unsigned long long) master->leader_epoch);
|
master->leader, (unsigned long long) master->leader_epoch);
|
||||||
/* If we did not voted for ourselves, set the master failover start
|
/* If we did not voted for ourselves, set the master failover start
|
||||||
* time to now, in order to force a delay before we can start a
|
* time to now, in order to force a delay before we can start a
|
||||||
@ -3756,9 +3756,9 @@ void sentinelStartFailover(sentinelRedisInstance *master) {
|
|||||||
master->failover_state = SENTINEL_FAILOVER_STATE_WAIT_START;
|
master->failover_state = SENTINEL_FAILOVER_STATE_WAIT_START;
|
||||||
master->flags |= SRI_FAILOVER_IN_PROGRESS;
|
master->flags |= SRI_FAILOVER_IN_PROGRESS;
|
||||||
master->failover_epoch = ++sentinel.current_epoch;
|
master->failover_epoch = ++sentinel.current_epoch;
|
||||||
sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
|
sentinelEvent(LL_WARNING,"+new-epoch",master,"%llu",
|
||||||
(unsigned long long) sentinel.current_epoch);
|
(unsigned long long) sentinel.current_epoch);
|
||||||
sentinelEvent(REDIS_WARNING,"+try-failover",master,"%@");
|
sentinelEvent(LL_WARNING,"+try-failover",master,"%@");
|
||||||
master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
|
master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
|
||||||
master->failover_state_change_time = mstime();
|
master->failover_state_change_time = mstime();
|
||||||
}
|
}
|
||||||
@ -3793,7 +3793,7 @@ int sentinelStartFailoverIfNeeded(sentinelRedisInstance *master) {
|
|||||||
ctime_r(&clock,ctimebuf);
|
ctime_r(&clock,ctimebuf);
|
||||||
ctimebuf[24] = '\0'; /* Remove newline. */
|
ctimebuf[24] = '\0'; /* Remove newline. */
|
||||||
master->failover_delay_logged = master->failover_start_time;
|
master->failover_delay_logged = master->failover_start_time;
|
||||||
serverLog(REDIS_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Next failover delay: I will not start a failover before %s",
|
"Next failover delay: I will not start a failover before %s",
|
||||||
ctimebuf);
|
ctimebuf);
|
||||||
}
|
}
|
||||||
@ -3929,17 +3929,17 @@ void sentinelFailoverWaitStart(sentinelRedisInstance *ri) {
|
|||||||
election_timeout = ri->failover_timeout;
|
election_timeout = ri->failover_timeout;
|
||||||
/* Abort the failover if I'm not the leader after some time. */
|
/* Abort the failover if I'm not the leader after some time. */
|
||||||
if (mstime() - ri->failover_start_time > election_timeout) {
|
if (mstime() - ri->failover_start_time > election_timeout) {
|
||||||
sentinelEvent(REDIS_WARNING,"-failover-abort-not-elected",ri,"%@");
|
sentinelEvent(LL_WARNING,"-failover-abort-not-elected",ri,"%@");
|
||||||
sentinelAbortFailover(ri);
|
sentinelAbortFailover(ri);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sentinelEvent(REDIS_WARNING,"+elected-leader",ri,"%@");
|
sentinelEvent(LL_WARNING,"+elected-leader",ri,"%@");
|
||||||
if (sentinel.simfailure_flags & SENTINEL_SIMFAILURE_CRASH_AFTER_ELECTION)
|
if (sentinel.simfailure_flags & SENTINEL_SIMFAILURE_CRASH_AFTER_ELECTION)
|
||||||
sentinelSimFailureCrash();
|
sentinelSimFailureCrash();
|
||||||
ri->failover_state = SENTINEL_FAILOVER_STATE_SELECT_SLAVE;
|
ri->failover_state = SENTINEL_FAILOVER_STATE_SELECT_SLAVE;
|
||||||
ri->failover_state_change_time = mstime();
|
ri->failover_state_change_time = mstime();
|
||||||
sentinelEvent(REDIS_WARNING,"+failover-state-select-slave",ri,"%@");
|
sentinelEvent(LL_WARNING,"+failover-state-select-slave",ri,"%@");
|
||||||
}
|
}
|
||||||
|
|
||||||
void sentinelFailoverSelectSlave(sentinelRedisInstance *ri) {
|
void sentinelFailoverSelectSlave(sentinelRedisInstance *ri) {
|
||||||
@ -3948,15 +3948,15 @@ void sentinelFailoverSelectSlave(sentinelRedisInstance *ri) {
|
|||||||
/* We don't handle the timeout in this state as the function aborts
|
/* We don't handle the timeout in this state as the function aborts
|
||||||
* the failover or go forward in the next state. */
|
* the failover or go forward in the next state. */
|
||||||
if (slave == NULL) {
|
if (slave == NULL) {
|
||||||
sentinelEvent(REDIS_WARNING,"-failover-abort-no-good-slave",ri,"%@");
|
sentinelEvent(LL_WARNING,"-failover-abort-no-good-slave",ri,"%@");
|
||||||
sentinelAbortFailover(ri);
|
sentinelAbortFailover(ri);
|
||||||
} else {
|
} else {
|
||||||
sentinelEvent(REDIS_WARNING,"+selected-slave",slave,"%@");
|
sentinelEvent(LL_WARNING,"+selected-slave",slave,"%@");
|
||||||
slave->flags |= SRI_PROMOTED;
|
slave->flags |= SRI_PROMOTED;
|
||||||
ri->promoted_slave = slave;
|
ri->promoted_slave = slave;
|
||||||
ri->failover_state = SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE;
|
ri->failover_state = SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE;
|
||||||
ri->failover_state_change_time = mstime();
|
ri->failover_state_change_time = mstime();
|
||||||
sentinelEvent(REDIS_NOTICE,"+failover-state-send-slaveof-noone",
|
sentinelEvent(LL_NOTICE,"+failover-state-send-slaveof-noone",
|
||||||
slave, "%@");
|
slave, "%@");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3969,7 +3969,7 @@ void sentinelFailoverSendSlaveOfNoOne(sentinelRedisInstance *ri) {
|
|||||||
* is reached, then abort the failover. */
|
* is reached, then abort the failover. */
|
||||||
if (ri->link->disconnected) {
|
if (ri->link->disconnected) {
|
||||||
if (mstime() - ri->failover_state_change_time > ri->failover_timeout) {
|
if (mstime() - ri->failover_state_change_time > ri->failover_timeout) {
|
||||||
sentinelEvent(REDIS_WARNING,"-failover-abort-slave-timeout",ri,"%@");
|
sentinelEvent(LL_WARNING,"-failover-abort-slave-timeout",ri,"%@");
|
||||||
sentinelAbortFailover(ri);
|
sentinelAbortFailover(ri);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -3981,7 +3981,7 @@ void sentinelFailoverSendSlaveOfNoOne(sentinelRedisInstance *ri) {
|
|||||||
* if INFO returns a different role (master instead of slave). */
|
* if INFO returns a different role (master instead of slave). */
|
||||||
retval = sentinelSendSlaveOf(ri->promoted_slave,NULL,0);
|
retval = sentinelSendSlaveOf(ri->promoted_slave,NULL,0);
|
||||||
if (retval != C_OK) return;
|
if (retval != C_OK) return;
|
||||||
sentinelEvent(REDIS_NOTICE, "+failover-state-wait-promotion",
|
sentinelEvent(LL_NOTICE, "+failover-state-wait-promotion",
|
||||||
ri->promoted_slave,"%@");
|
ri->promoted_slave,"%@");
|
||||||
ri->failover_state = SENTINEL_FAILOVER_STATE_WAIT_PROMOTION;
|
ri->failover_state = SENTINEL_FAILOVER_STATE_WAIT_PROMOTION;
|
||||||
ri->failover_state_change_time = mstime();
|
ri->failover_state_change_time = mstime();
|
||||||
@ -3993,7 +3993,7 @@ void sentinelFailoverWaitPromotion(sentinelRedisInstance *ri) {
|
|||||||
/* Just handle the timeout. Switching to the next state is handled
|
/* Just handle the timeout. Switching to the next state is handled
|
||||||
* by the function parsing the INFO command of the promoted slave. */
|
* by the function parsing the INFO command of the promoted slave. */
|
||||||
if (mstime() - ri->failover_state_change_time > ri->failover_timeout) {
|
if (mstime() - ri->failover_state_change_time > ri->failover_timeout) {
|
||||||
sentinelEvent(REDIS_WARNING,"-failover-abort-slave-timeout",ri,"%@");
|
sentinelEvent(LL_WARNING,"-failover-abort-slave-timeout",ri,"%@");
|
||||||
sentinelAbortFailover(ri);
|
sentinelAbortFailover(ri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4025,11 +4025,11 @@ void sentinelFailoverDetectEnd(sentinelRedisInstance *master) {
|
|||||||
if (elapsed > master->failover_timeout) {
|
if (elapsed > master->failover_timeout) {
|
||||||
not_reconfigured = 0;
|
not_reconfigured = 0;
|
||||||
timeout = 1;
|
timeout = 1;
|
||||||
sentinelEvent(REDIS_WARNING,"+failover-end-for-timeout",master,"%@");
|
sentinelEvent(LL_WARNING,"+failover-end-for-timeout",master,"%@");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not_reconfigured == 0) {
|
if (not_reconfigured == 0) {
|
||||||
sentinelEvent(REDIS_WARNING,"+failover-end",master,"%@");
|
sentinelEvent(LL_WARNING,"+failover-end",master,"%@");
|
||||||
master->failover_state = SENTINEL_FAILOVER_STATE_UPDATE_CONFIG;
|
master->failover_state = SENTINEL_FAILOVER_STATE_UPDATE_CONFIG;
|
||||||
master->failover_state_change_time = mstime();
|
master->failover_state_change_time = mstime();
|
||||||
}
|
}
|
||||||
@ -4053,7 +4053,7 @@ void sentinelFailoverDetectEnd(sentinelRedisInstance *master) {
|
|||||||
master->promoted_slave->addr->ip,
|
master->promoted_slave->addr->ip,
|
||||||
master->promoted_slave->addr->port);
|
master->promoted_slave->addr->port);
|
||||||
if (retval == C_OK) {
|
if (retval == C_OK) {
|
||||||
sentinelEvent(REDIS_NOTICE,"+slave-reconf-sent-be",slave,"%@");
|
sentinelEvent(LL_NOTICE,"+slave-reconf-sent-be",slave,"%@");
|
||||||
slave->flags |= SRI_RECONF_SENT;
|
slave->flags |= SRI_RECONF_SENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4095,7 +4095,7 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) {
|
|||||||
(mstime() - slave->slave_reconf_sent_time) >
|
(mstime() - slave->slave_reconf_sent_time) >
|
||||||
SENTINEL_SLAVE_RECONF_TIMEOUT)
|
SENTINEL_SLAVE_RECONF_TIMEOUT)
|
||||||
{
|
{
|
||||||
sentinelEvent(REDIS_NOTICE,"-slave-reconf-sent-timeout",slave,"%@");
|
sentinelEvent(LL_NOTICE,"-slave-reconf-sent-timeout",slave,"%@");
|
||||||
slave->flags &= ~SRI_RECONF_SENT;
|
slave->flags &= ~SRI_RECONF_SENT;
|
||||||
slave->flags |= SRI_RECONF_DONE;
|
slave->flags |= SRI_RECONF_DONE;
|
||||||
}
|
}
|
||||||
@ -4112,7 +4112,7 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) {
|
|||||||
if (retval == C_OK) {
|
if (retval == C_OK) {
|
||||||
slave->flags |= SRI_RECONF_SENT;
|
slave->flags |= SRI_RECONF_SENT;
|
||||||
slave->slave_reconf_sent_time = mstime();
|
slave->slave_reconf_sent_time = mstime();
|
||||||
sentinelEvent(REDIS_NOTICE,"+slave-reconf-sent",slave,"%@");
|
sentinelEvent(LL_NOTICE,"+slave-reconf-sent",slave,"%@");
|
||||||
in_progress++;
|
in_progress++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4129,7 +4129,7 @@ void sentinelFailoverSwitchToPromotedSlave(sentinelRedisInstance *master) {
|
|||||||
sentinelRedisInstance *ref = master->promoted_slave ?
|
sentinelRedisInstance *ref = master->promoted_slave ?
|
||||||
master->promoted_slave : master;
|
master->promoted_slave : master;
|
||||||
|
|
||||||
sentinelEvent(REDIS_WARNING,"+switch-master",master,"%s %s %d %s %d",
|
sentinelEvent(LL_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);
|
||||||
|
|
||||||
@ -4197,7 +4197,7 @@ void sentinelHandleRedisInstance(sentinelRedisInstance *ri) {
|
|||||||
if (sentinel.tilt) {
|
if (sentinel.tilt) {
|
||||||
if (mstime()-sentinel.tilt_start_time < SENTINEL_TILT_PERIOD) return;
|
if (mstime()-sentinel.tilt_start_time < SENTINEL_TILT_PERIOD) return;
|
||||||
sentinel.tilt = 0;
|
sentinel.tilt = 0;
|
||||||
sentinelEvent(REDIS_WARNING,"-tilt",NULL,"#tilt mode exited");
|
sentinelEvent(LL_WARNING,"-tilt",NULL,"#tilt mode exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Every kind of instance */
|
/* Every kind of instance */
|
||||||
@ -4270,7 +4270,7 @@ void sentinelCheckTiltCondition(void) {
|
|||||||
if (delta < 0 || delta > SENTINEL_TILT_TRIGGER) {
|
if (delta < 0 || delta > SENTINEL_TILT_TRIGGER) {
|
||||||
sentinel.tilt = 1;
|
sentinel.tilt = 1;
|
||||||
sentinel.tilt_start_time = mstime();
|
sentinel.tilt_start_time = mstime();
|
||||||
sentinelEvent(REDIS_WARNING,"+tilt",NULL,"#tilt mode entered");
|
sentinelEvent(LL_WARNING,"+tilt",NULL,"#tilt mode entered");
|
||||||
}
|
}
|
||||||
sentinel.previous_time = mstime();
|
sentinel.previous_time = mstime();
|
||||||
}
|
}
|
||||||
|
480
src/server.c
480
src/server.c
File diff suppressed because it is too large
Load Diff
402
src/server.h
402
src/server.h
@ -76,35 +76,35 @@ typedef long long mstime_t; /* millisecond time type. */
|
|||||||
|
|
||||||
/* Static server configuration */
|
/* Static server configuration */
|
||||||
#define CONFIG_DEFAULT_HZ 10 /* Time interrupt calls/sec. */
|
#define CONFIG_DEFAULT_HZ 10 /* Time interrupt calls/sec. */
|
||||||
#define REDIS_MIN_HZ 1
|
#define CONFIG_MIN_HZ 1
|
||||||
#define REDIS_MAX_HZ 500
|
#define CONFIG_MAX_HZ 500
|
||||||
#define REDIS_SERVERPORT 6379 /* TCP port */
|
#define CONFIG_DEFAULT_SERVER_PORT 6379 /* TCP port */
|
||||||
#define REDIS_TCP_BACKLOG 511 /* TCP listen backlog */
|
#define CONFIG_DEFAULT_TCP_BACKLOG 511 /* TCP listen backlog */
|
||||||
#define REDIS_MAXIDLETIME 0 /* default client timeout: infinite */
|
#define CONFIG_DEFAULT_CLIENT_TIMEOUT 0 /* default client timeout: infinite */
|
||||||
#define CONFIG_DEFAULT_DBNUM 16
|
#define CONFIG_DEFAULT_DBNUM 16
|
||||||
#define REDIS_CONFIGLINE_MAX 1024
|
#define CONFIG_MAX_LINE 1024
|
||||||
#define REDIS_DBCRON_DBS_PER_CALL 16
|
#define CRON_DBS_PER_CALL 16
|
||||||
#define REDIS_MAX_WRITE_PER_EVENT (1024*64)
|
#define NET_MAX_WRITES_PER_EVENT (1024*64)
|
||||||
#define REDIS_SHARED_SELECT_CMDS 10
|
#define PROTO_SHARED_SELECT_CMDS 10
|
||||||
#define REDIS_SHARED_INTEGERS 10000
|
#define OBJ_SHARED_INTEGERS 10000
|
||||||
#define REDIS_SHARED_BULKHDR_LEN 32
|
#define OBJ_SHARED_BULKHDR_LEN 32
|
||||||
#define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */
|
#define LOG_MAX_LEN 1024 /* Default maximum length of syslog messages */
|
||||||
#define REDIS_AOF_REWRITE_PERC 100
|
#define AOF_REWRITE_PERC 100
|
||||||
#define REDIS_AOF_REWRITE_MIN_SIZE (64*1024*1024)
|
#define AOF_REWRITE_MIN_SIZE (64*1024*1024)
|
||||||
#define REDIS_AOF_REWRITE_ITEMS_PER_CMD 64
|
#define AOF_REWRITE_ITEMS_PER_CMD 64
|
||||||
#define REDIS_SLOWLOG_LOG_SLOWER_THAN 10000
|
#define CONFIG_DEFAULT_SLOWLOG_LOG_SLOWER_THAN 10000
|
||||||
#define REDIS_SLOWLOG_MAX_LEN 128
|
#define CONFIG_DEFAULT_SLOWLOG_MAX_LEN 128
|
||||||
#define CONFIG_DEFAULT_MAX_CLIENTS 10000
|
#define CONFIG_DEFAULT_MAX_CLIENTS 10000
|
||||||
#define REDIS_AUTHPASS_MAX_LEN 512
|
#define CONFIG_AUTHPASS_MAX_LEN 512
|
||||||
#define CONFIG_DEFAULT_SLAVE_PRIORITY 100
|
#define CONFIG_DEFAULT_SLAVE_PRIORITY 100
|
||||||
#define REDIS_REPL_TIMEOUT 60
|
#define CONFIG_DEFAULT_REPL_TIMEOUT 60
|
||||||
#define REDIS_REPL_PING_SLAVE_PERIOD 10
|
#define CONFIG_DEFAULT_REPL_PING_SLAVE_PERIOD 10
|
||||||
#define REDIS_RUN_ID_SIZE 40
|
#define CONFIG_RUN_ID_SIZE 40
|
||||||
#define REDIS_EOF_MARK_SIZE 40
|
#define RDB_EOF_MARK_SIZE 40
|
||||||
#define CONFIG_DEFAULT_REPL_BACKLOG_SIZE (1024*1024) /* 1mb */
|
#define CONFIG_DEFAULT_REPL_BACKLOG_SIZE (1024*1024) /* 1mb */
|
||||||
#define CONFIG_DEFAULT_REPL_BACKLOG_TIME_LIMIT (60*60) /* 1 hour */
|
#define CONFIG_DEFAULT_REPL_BACKLOG_TIME_LIMIT (60*60) /* 1 hour */
|
||||||
#define REDIS_REPL_BACKLOG_MIN_SIZE (1024*16) /* 16k */
|
#define CONFIG_REPL_BACKLOG_MIN_SIZE (1024*16) /* 16k */
|
||||||
#define REDIS_BGSAVE_RETRY_DELAY 5 /* Wait a few secs before trying again. */
|
#define CONFIG_BGSAVE_RETRY_DELAY 5 /* Wait a few secs before trying again. */
|
||||||
#define CONFIG_DEFAULT_PID_FILE "/var/run/redis.pid"
|
#define CONFIG_DEFAULT_PID_FILE "/var/run/redis.pid"
|
||||||
#define CONFIG_DEFAULT_SYSLOG_IDENT "redis"
|
#define CONFIG_DEFAULT_SYSLOG_IDENT "redis"
|
||||||
#define CONFIG_DEFAULT_CLUSTER_CONFIG_FILE "nodes.conf"
|
#define CONFIG_DEFAULT_CLUSTER_CONFIG_FILE "nodes.conf"
|
||||||
@ -131,10 +131,10 @@ typedef long long mstime_t; /* millisecond time type. */
|
|||||||
#define CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC 1
|
#define CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC 1
|
||||||
#define CONFIG_DEFAULT_MIN_SLAVES_TO_WRITE 0
|
#define CONFIG_DEFAULT_MIN_SLAVES_TO_WRITE 0
|
||||||
#define CONFIG_DEFAULT_MIN_SLAVES_MAX_LAG 10
|
#define CONFIG_DEFAULT_MIN_SLAVES_MAX_LAG 10
|
||||||
#define REDIS_IP_STR_LEN 46 /* INET6_ADDRSTRLEN is 46, but we need to be sure */
|
#define NET_IP_STR_LEN 46 /* INET6_ADDRSTRLEN is 46, but we need to be sure */
|
||||||
#define REDIS_PEER_ID_LEN (REDIS_IP_STR_LEN+32) /* Must be enough for ip:port */
|
#define NET_PEER_ID_LEN (NET_IP_STR_LEN+32) /* Must be enough for ip:port */
|
||||||
#define REDIS_BINDADDR_MAX 16
|
#define CONFIG_BINDADDR_MAX 16
|
||||||
#define REDIS_MIN_RESERVED_FDS 32
|
#define CONFIG_MIN_RESERVED_FDS 32
|
||||||
#define CONFIG_DEFAULT_LATENCY_MONITOR_THRESHOLD 0
|
#define CONFIG_DEFAULT_LATENCY_MONITOR_THRESHOLD 0
|
||||||
|
|
||||||
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 20 /* Loopkups per loop. */
|
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 20 /* Loopkups per loop. */
|
||||||
@ -144,44 +144,46 @@ typedef long long mstime_t; /* millisecond time type. */
|
|||||||
#define ACTIVE_EXPIRE_CYCLE_FAST 1
|
#define ACTIVE_EXPIRE_CYCLE_FAST 1
|
||||||
|
|
||||||
/* Instantaneous metrics tracking. */
|
/* Instantaneous metrics tracking. */
|
||||||
#define REDIS_METRIC_SAMPLES 16 /* Number of samples per metric. */
|
#define STATS_METRIC_SAMPLES 16 /* Number of samples per metric. */
|
||||||
#define REDIS_METRIC_COMMAND 0 /* Number of commands executed. */
|
#define STATS_METRIC_COMMAND 0 /* Number of commands executed. */
|
||||||
#define REDIS_METRIC_NET_INPUT 1 /* Bytes read to network .*/
|
#define STATS_METRIC_NET_INPUT 1 /* Bytes read to network .*/
|
||||||
#define REDIS_METRIC_NET_OUTPUT 2 /* Bytes written to network. */
|
#define STATS_METRIC_NET_OUTPUT 2 /* Bytes written to network. */
|
||||||
#define REDIS_METRIC_COUNT 3
|
#define STATS_METRIC_COUNT 3
|
||||||
|
|
||||||
/* Protocol and I/O related defines */
|
/* Protocol and I/O related defines */
|
||||||
#define REDIS_MAX_QUERYBUF_LEN (1024*1024*1024) /* 1GB max query buffer. */
|
#define PROTO_MAX_QUERYBUF_LEN (1024*1024*1024) /* 1GB max query buffer. */
|
||||||
#define REDIS_IOBUF_LEN (1024*16) /* Generic I/O buffer size */
|
#define PROTO_IOBUF_LEN (1024*16) /* Generic I/O buffer size */
|
||||||
#define REDIS_REPLY_CHUNK_BYTES (16*1024) /* 16k output buffer */
|
#define PROTO_REPLY_CHUNK_BYTES (16*1024) /* 16k output buffer */
|
||||||
#define REDIS_INLINE_MAX_SIZE (1024*64) /* Max size of inline reads */
|
#define PROTO_INLINE_MAX_SIZE (1024*64) /* Max size of inline reads */
|
||||||
#define REDIS_MBULK_BIG_ARG (1024*32)
|
#define PROTO_MBULK_BIG_ARG (1024*32)
|
||||||
#define REDIS_LONGSTR_SIZE 21 /* Bytes needed for long -> str */
|
#define LONG_STR_SIZE 21 /* Bytes needed for long -> str */
|
||||||
#define REDIS_AOF_AUTOSYNC_BYTES (1024*1024*32) /* fdatasync every 32MB */
|
#define AOF_AUTOSYNC_BYTES (1024*1024*32) /* fdatasync every 32MB */
|
||||||
/* When configuring the Redis eventloop, we setup it so that the total number
|
|
||||||
* of file descriptors we can handle are server.maxclients + RESERVED_FDS + FDSET_INCR
|
/* When configuring the server eventloop, we setup it so that the total number
|
||||||
* that is our safety margin. */
|
* of file descriptors we can handle are server.maxclients + RESERVED_FDS +
|
||||||
#define REDIS_EVENTLOOP_FDSET_INCR (REDIS_MIN_RESERVED_FDS+96)
|
* a few more to stay safe. Since RESERVED_FDS defaults to 32, we add 96
|
||||||
|
* in order to make sure of not over provisioning more than 128 fds. */
|
||||||
|
#define CONFIG_FDSET_INCR (CONFIG_MIN_RESERVED_FDS+96)
|
||||||
|
|
||||||
/* Hash table parameters */
|
/* Hash table parameters */
|
||||||
#define REDIS_HT_MINFILL 10 /* Minimal hash table fill 10% */
|
#define HASHTABLE_MIN_FILL 10 /* Minimal hash table fill 10% */
|
||||||
|
|
||||||
/* Command flags. Please check the command table defined in the redis.c file
|
/* Command flags. Please check the command table defined in the redis.c file
|
||||||
* for more information about the meaning of every flag. */
|
* for more information about the meaning of every flag. */
|
||||||
#define REDIS_CMD_WRITE 1 /* "w" flag */
|
#define CMD_WRITE 1 /* "w" flag */
|
||||||
#define REDIS_CMD_READONLY 2 /* "r" flag */
|
#define CMD_READONLY 2 /* "r" flag */
|
||||||
#define REDIS_CMD_DENYOOM 4 /* "m" flag */
|
#define CMD_DENYOOM 4 /* "m" flag */
|
||||||
#define REDIS_CMD_NOT_USED_1 8 /* no longer used flag */
|
#define CMD_NOT_USED_1 8 /* no longer used flag */
|
||||||
#define REDIS_CMD_ADMIN 16 /* "a" flag */
|
#define CMD_ADMIN 16 /* "a" flag */
|
||||||
#define REDIS_CMD_PUBSUB 32 /* "p" flag */
|
#define CMD_PUBSUB 32 /* "p" flag */
|
||||||
#define REDIS_CMD_NOSCRIPT 64 /* "s" flag */
|
#define CMD_NOSCRIPT 64 /* "s" flag */
|
||||||
#define REDIS_CMD_RANDOM 128 /* "R" flag */
|
#define CMD_RANDOM 128 /* "R" flag */
|
||||||
#define REDIS_CMD_SORT_FOR_SCRIPT 256 /* "S" flag */
|
#define CMD_SORT_FOR_SCRIPT 256 /* "S" flag */
|
||||||
#define REDIS_CMD_LOADING 512 /* "l" flag */
|
#define CMD_LOADING 512 /* "l" flag */
|
||||||
#define REDIS_CMD_STALE 1024 /* "t" flag */
|
#define CMD_STALE 1024 /* "t" flag */
|
||||||
#define REDIS_CMD_SKIP_MONITOR 2048 /* "M" flag */
|
#define CMD_SKIP_MONITOR 2048 /* "M" flag */
|
||||||
#define REDIS_CMD_ASKING 4096 /* "k" flag */
|
#define CMD_ASKING 4096 /* "k" flag */
|
||||||
#define REDIS_CMD_FAST 8192 /* "F" flag */
|
#define CMD_FAST 8192 /* "F" flag */
|
||||||
|
|
||||||
/* Object types */
|
/* Object types */
|
||||||
#define OBJ_STRING 0
|
#define OBJ_STRING 0
|
||||||
@ -213,115 +215,113 @@ typedef long long mstime_t; /* millisecond time type. */
|
|||||||
* 10|000000 [32 bit integer] => if it's 10, a full 32 bit len will follow
|
* 10|000000 [32 bit integer] => if it's 10, a full 32 bit len will follow
|
||||||
* 11|000000 this means: specially encoded object will follow. The six bits
|
* 11|000000 this means: specially encoded object will follow. The six bits
|
||||||
* number specify the kind of object that follows.
|
* number specify the kind of object that follows.
|
||||||
* See the REDIS_RDB_ENC_* defines.
|
* See the RDB_ENC_* defines.
|
||||||
*
|
*
|
||||||
* Lengths up to 63 are stored using a single byte, most DB keys, and may
|
* Lengths up to 63 are stored using a single byte, most DB keys, and may
|
||||||
* values, will fit inside. */
|
* values, will fit inside. */
|
||||||
#define REDIS_RDB_6BITLEN 0
|
#define RDB_6BITLEN 0
|
||||||
#define REDIS_RDB_14BITLEN 1
|
#define RDB_14BITLEN 1
|
||||||
#define REDIS_RDB_32BITLEN 2
|
#define RDB_32BITLEN 2
|
||||||
#define REDIS_RDB_ENCVAL 3
|
#define RDB_ENCVAL 3
|
||||||
#define REDIS_RDB_LENERR UINT_MAX
|
#define RDB_LENERR UINT_MAX
|
||||||
|
|
||||||
/* When a length of a string object stored on disk has the first two bits
|
/* When a length of a string object stored on disk has the first two bits
|
||||||
* set, the remaining two bits specify a special encoding for the object
|
* set, the remaining two bits specify a special encoding for the object
|
||||||
* accordingly to the following defines: */
|
* accordingly to the following defines: */
|
||||||
#define REDIS_RDB_ENC_INT8 0 /* 8 bit signed integer */
|
#define RDB_ENC_INT8 0 /* 8 bit signed integer */
|
||||||
#define REDIS_RDB_ENC_INT16 1 /* 16 bit signed integer */
|
#define RDB_ENC_INT16 1 /* 16 bit signed integer */
|
||||||
#define REDIS_RDB_ENC_INT32 2 /* 32 bit signed integer */
|
#define RDB_ENC_INT32 2 /* 32 bit signed integer */
|
||||||
#define REDIS_RDB_ENC_LZF 3 /* string compressed with FASTLZ */
|
#define RDB_ENC_LZF 3 /* string compressed with FASTLZ */
|
||||||
|
|
||||||
/* AOF states */
|
/* AOF states */
|
||||||
#define REDIS_AOF_OFF 0 /* AOF is off */
|
#define AOF_OFF 0 /* AOF is off */
|
||||||
#define REDIS_AOF_ON 1 /* AOF is on */
|
#define AOF_ON 1 /* AOF is on */
|
||||||
#define REDIS_AOF_WAIT_REWRITE 2 /* AOF waits rewrite to start appending */
|
#define AOF_WAIT_REWRITE 2 /* AOF waits rewrite to start appending */
|
||||||
|
|
||||||
/* Client flags */
|
/* Client flags */
|
||||||
#define REDIS_SLAVE (1<<0) /* This client is a slave server */
|
#define CLIENT_SLAVE (1<<0) /* This client is a slave server */
|
||||||
#define REDIS_MASTER (1<<1) /* This client is a master server */
|
#define CLIENT_MASTER (1<<1) /* This client is a master server */
|
||||||
#define REDIS_MONITOR (1<<2) /* This client is a slave monitor, see MONITOR */
|
#define CLIENT_MONITOR (1<<2) /* This client is a slave monitor, see MONITOR */
|
||||||
#define REDIS_MULTI (1<<3) /* This client is in a MULTI context */
|
#define CLIENT_MULTI (1<<3) /* This client is in a MULTI context */
|
||||||
#define REDIS_BLOCKED (1<<4) /* The client is waiting in a blocking operation */
|
#define CLIENT_BLOCKED (1<<4) /* The client is waiting in a blocking operation */
|
||||||
#define REDIS_DIRTY_CAS (1<<5) /* Watched keys modified. EXEC will fail. */
|
#define CLIENT_DIRTY_CAS (1<<5) /* Watched keys modified. EXEC will fail. */
|
||||||
#define REDIS_CLOSE_AFTER_REPLY (1<<6) /* Close after writing entire reply. */
|
#define CLIENT_CLOSE_AFTER_REPLY (1<<6) /* Close after writing entire reply. */
|
||||||
#define REDIS_UNBLOCKED (1<<7) /* This client was unblocked and is stored in
|
#define CLIENT_UNBLOCKED (1<<7) /* This client was unblocked and is stored in
|
||||||
server.unblocked_clients */
|
server.unblocked_clients */
|
||||||
#define REDIS_LUA_CLIENT (1<<8) /* This is a non connected client used by Lua */
|
#define CLIENT_LUA (1<<8) /* This is a non connected client used by Lua */
|
||||||
#define REDIS_ASKING (1<<9) /* Client issued the ASKING command */
|
#define CLIENT_ASKING (1<<9) /* Client issued the ASKING command */
|
||||||
#define REDIS_CLOSE_ASAP (1<<10)/* Close this client ASAP */
|
#define CLIENT_CLOSE_ASAP (1<<10)/* Close this client ASAP */
|
||||||
#define REDIS_UNIX_SOCKET (1<<11) /* Client connected via Unix domain socket */
|
#define CLIENT_UNIX_SOCKET (1<<11) /* Client connected via Unix domain socket */
|
||||||
#define REDIS_DIRTY_EXEC (1<<12) /* EXEC will fail for errors while queueing */
|
#define CLIENT_DIRTY_EXEC (1<<12) /* EXEC will fail for errors while queueing */
|
||||||
#define REDIS_MASTER_FORCE_REPLY (1<<13) /* Queue replies even if is master */
|
#define CLIENT_MASTER_FORCE_REPLY (1<<13) /* Queue replies even if is master */
|
||||||
#define REDIS_FORCE_AOF (1<<14) /* Force AOF propagation of current cmd. */
|
#define CLIENT_FORCE_AOF (1<<14) /* Force AOF propagation of current cmd. */
|
||||||
#define REDIS_FORCE_REPL (1<<15) /* Force replication of current cmd. */
|
#define CLIENT_FORCE_REPL (1<<15) /* Force replication of current cmd. */
|
||||||
#define REDIS_PRE_PSYNC (1<<16) /* Instance don't understand PSYNC. */
|
#define CLIENT_PRE_PSYNC (1<<16) /* Instance don't understand PSYNC. */
|
||||||
#define REDIS_READONLY (1<<17) /* Cluster client is in read-only state. */
|
#define CLIENT_READONLY (1<<17) /* Cluster client is in read-only state. */
|
||||||
#define REDIS_PUBSUB (1<<18) /* Client is in Pub/Sub mode. */
|
#define CLIENT_PUBSUB (1<<18) /* Client is in Pub/Sub mode. */
|
||||||
#define REDIS_PREVENT_PROP (1<<19) /* Don't propagate to AOF / Slaves. */
|
#define CLIENT_PREVENT_PROP (1<<19) /* Don't propagate to AOF / Slaves. */
|
||||||
|
|
||||||
/* Client block type (btype field in client structure)
|
/* Client block type (btype field in client structure)
|
||||||
* if REDIS_BLOCKED flag is set. */
|
* if CLIENT_BLOCKED flag is set. */
|
||||||
#define REDIS_BLOCKED_NONE 0 /* Not blocked, no REDIS_BLOCKED flag set. */
|
#define BLOCKED_NONE 0 /* Not blocked, no CLIENT_BLOCKED flag set. */
|
||||||
#define REDIS_BLOCKED_LIST 1 /* BLPOP & co. */
|
#define BLOCKED_LIST 1 /* BLPOP & co. */
|
||||||
#define REDIS_BLOCKED_WAIT 2 /* WAIT for synchronous replication. */
|
#define BLOCKED_WAIT 2 /* WAIT for synchronous replication. */
|
||||||
|
|
||||||
/* Client request types */
|
/* Client request types */
|
||||||
#define REDIS_REQ_INLINE 1
|
#define PROTO_REQ_INLINE 1
|
||||||
#define REDIS_REQ_MULTIBULK 2
|
#define PROTO_REQ_MULTIBULK 2
|
||||||
|
|
||||||
/* Client classes for client limits, currently used only for
|
/* Client classes for client limits, currently used only for
|
||||||
* the max-client-output-buffer limit implementation. */
|
* the max-client-output-buffer limit implementation. */
|
||||||
#define REDIS_CLIENT_TYPE_NORMAL 0 /* Normal req-reply clients + MONITORs */
|
#define CLIENT_TYPE_NORMAL 0 /* Normal req-reply clients + MONITORs */
|
||||||
#define REDIS_CLIENT_TYPE_SLAVE 1 /* Slaves. */
|
#define CLIENT_TYPE_SLAVE 1 /* Slaves. */
|
||||||
#define REDIS_CLIENT_TYPE_PUBSUB 2 /* Clients subscribed to PubSub channels. */
|
#define CLIENT_TYPE_PUBSUB 2 /* Clients subscribed to PubSub channels. */
|
||||||
#define REDIS_CLIENT_TYPE_COUNT 3
|
#define CLIENT_TYPE_COUNT 3
|
||||||
|
|
||||||
/* Slave replication state - from the point of view of the slave. */
|
/* Slave replication state. Used in server.repl_state for slaves to remember
|
||||||
#define REDIS_REPL_NONE 0 /* No active replication */
|
* what to do next. */
|
||||||
#define REDIS_REPL_CONNECT 1 /* Must connect to master */
|
#define REPL_STATE_NONE 0 /* No active replication */
|
||||||
#define REDIS_REPL_CONNECTING 2 /* Connecting to master */
|
#define REPL_STATE_CONNECT 1 /* Must connect to master */
|
||||||
#define REDIS_REPL_RECEIVE_PONG 3 /* Wait for PING reply */
|
#define REPL_STATE_CONNECTING 2 /* Connecting to master */
|
||||||
#define REDIS_REPL_TRANSFER 4 /* Receiving .rdb from master */
|
#define REPL_STATE_RECEIVE_PONG 3 /* Wait for PING reply */
|
||||||
#define REDIS_REPL_CONNECTED 5 /* Connected to master */
|
#define REPL_STATE_TRANSFER 4 /* Receiving .rdb from master */
|
||||||
|
#define REPL_STATE_CONNECTED 5 /* Connected to master */
|
||||||
|
|
||||||
/* Slave replication state - from the point of view of the master.
|
/* State of slaves from the POV of the master. Used in client->replstate.
|
||||||
* In SEND_BULK and ONLINE state the slave receives new updates
|
* In SEND_BULK and ONLINE state the slave receives new updates
|
||||||
* in its output queue. In the WAIT_BGSAVE state instead the server is waiting
|
* in its output queue. In the WAIT_BGSAVE states instead the server is waiting
|
||||||
* to start the next background saving in order to send updates to it. */
|
* to start the next background saving in order to send updates to it. */
|
||||||
#define REDIS_REPL_WAIT_BGSAVE_START 6 /* We need to produce a new RDB file. */
|
#define SLAVE_STATE_WAIT_BGSAVE_START 6 /* We need to produce a new RDB file. */
|
||||||
#define REDIS_REPL_WAIT_BGSAVE_END 7 /* Waiting RDB file creation to finish. */
|
#define SLAVE_STATE_WAIT_BGSAVE_END 7 /* Waiting RDB file creation to finish. */
|
||||||
#define REDIS_REPL_SEND_BULK 8 /* Sending RDB file to slave. */
|
#define SLAVE_STATE_SEND_BULK 8 /* Sending RDB file to slave. */
|
||||||
#define REDIS_REPL_ONLINE 9 /* RDB file transmitted, sending just updates. */
|
#define SLAVE_STATE_ONLINE 9 /* RDB file transmitted, sending just updates. */
|
||||||
|
|
||||||
/* Synchronous read timeout - slave side */
|
/* Synchronous read timeout - slave side */
|
||||||
#define REDIS_REPL_SYNCIO_TIMEOUT 5
|
#define CONFIG_REPL_SYNCIO_TIMEOUT 5
|
||||||
|
|
||||||
/* List related stuff */
|
/* List related stuff */
|
||||||
#define REDIS_HEAD 0
|
#define LIST_HEAD 0
|
||||||
#define REDIS_TAIL 1
|
#define LIST_TAIL 1
|
||||||
|
|
||||||
/* Sort operations */
|
/* Sort operations */
|
||||||
#define REDIS_SORT_GET 0
|
#define SORT_OP_GET 0
|
||||||
#define REDIS_SORT_ASC 1
|
|
||||||
#define REDIS_SORT_DESC 2
|
|
||||||
#define REDIS_SORTKEY_MAX 1024
|
|
||||||
|
|
||||||
/* Log levels */
|
/* Log levels */
|
||||||
#define REDIS_DEBUG 0
|
#define LL_DEBUG 0
|
||||||
#define REDIS_VERBOSE 1
|
#define LL_VERBOSE 1
|
||||||
#define REDIS_NOTICE 2
|
#define LL_NOTICE 2
|
||||||
#define REDIS_WARNING 3
|
#define LL_WARNING 3
|
||||||
#define REDIS_LOG_RAW (1<<10) /* Modifier to log without timestamp */
|
#define LL_RAW (1<<10) /* Modifier to log without timestamp */
|
||||||
#define CONFIG_DEFAULT_VERBOSITY REDIS_NOTICE
|
#define CONFIG_DEFAULT_VERBOSITY LL_NOTICE
|
||||||
|
|
||||||
/* Supervision options */
|
/* Supervision options */
|
||||||
#define REDIS_SUPERVISED_NONE 0
|
#define SUPERVISED_NONE 0
|
||||||
#define REDIS_SUPERVISED_AUTODETECT 1
|
#define SUPERVISED_AUTODETECT 1
|
||||||
#define REDIS_SUPERVISED_SYSTEMD 2
|
#define SUPERVISED_SYSTEMD 2
|
||||||
#define REDIS_SUPERVISED_UPSTART 3
|
#define SUPERVISED_UPSTART 3
|
||||||
|
|
||||||
/* Anti-warning macro... */
|
/* Anti-warning macro... */
|
||||||
#define REDIS_NOTUSED(V) ((void) V)
|
#define UNUSED(V) ((void) V)
|
||||||
|
|
||||||
#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */
|
#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */
|
||||||
#define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
|
#define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
|
||||||
@ -347,64 +347,64 @@ typedef long long mstime_t; /* millisecond time type. */
|
|||||||
#define CONFIG_DEFAULT_HLL_SPARSE_MAX_BYTES 3000
|
#define CONFIG_DEFAULT_HLL_SPARSE_MAX_BYTES 3000
|
||||||
|
|
||||||
/* Sets operations codes */
|
/* Sets operations codes */
|
||||||
#define REDIS_OP_UNION 0
|
#define SET_OP_UNION 0
|
||||||
#define REDIS_OP_DIFF 1
|
#define SET_OP_DIFF 1
|
||||||
#define REDIS_OP_INTER 2
|
#define SET_OP_INTER 2
|
||||||
|
|
||||||
/* Redis maxmemory strategies */
|
/* Redis maxmemory strategies */
|
||||||
#define REDIS_MAXMEMORY_VOLATILE_LRU 0
|
#define MAXMEMORY_VOLATILE_LRU 0
|
||||||
#define REDIS_MAXMEMORY_VOLATILE_TTL 1
|
#define MAXMEMORY_VOLATILE_TTL 1
|
||||||
#define REDIS_MAXMEMORY_VOLATILE_RANDOM 2
|
#define MAXMEMORY_VOLATILE_RANDOM 2
|
||||||
#define REDIS_MAXMEMORY_ALLKEYS_LRU 3
|
#define MAXMEMORY_ALLKEYS_LRU 3
|
||||||
#define REDIS_MAXMEMORY_ALLKEYS_RANDOM 4
|
#define MAXMEMORY_ALLKEYS_RANDOM 4
|
||||||
#define REDIS_MAXMEMORY_NO_EVICTION 5
|
#define MAXMEMORY_NO_EVICTION 5
|
||||||
#define CONFIG_DEFAULT_MAXMEMORY_POLICY REDIS_MAXMEMORY_NO_EVICTION
|
#define CONFIG_DEFAULT_MAXMEMORY_POLICY MAXMEMORY_NO_EVICTION
|
||||||
|
|
||||||
/* Scripting */
|
/* Scripting */
|
||||||
#define REDIS_LUA_TIME_LIMIT 5000 /* milliseconds */
|
#define LUA_SCRIPT_TIME_LIMIT 5000 /* milliseconds */
|
||||||
|
|
||||||
/* Units */
|
/* Units */
|
||||||
#define UNIT_SECONDS 0
|
#define UNIT_SECONDS 0
|
||||||
#define UNIT_MILLISECONDS 1
|
#define UNIT_MILLISECONDS 1
|
||||||
|
|
||||||
/* SHUTDOWN flags */
|
/* SHUTDOWN flags */
|
||||||
#define REDIS_SHUTDOWN_SAVE 1 /* Force SAVE on SHUTDOWN even if no save
|
#define SHUTDOWN_SAVE 1 /* Force SAVE on SHUTDOWN even if no save
|
||||||
points are configured. */
|
points are configured. */
|
||||||
#define REDIS_SHUTDOWN_NOSAVE 2 /* Don't SAVE on SHUTDOWN. */
|
#define SHUTDOWN_NOSAVE 2 /* Don't SAVE on SHUTDOWN. */
|
||||||
|
|
||||||
/* Command call flags, see call() function */
|
/* Command call flags, see call() function */
|
||||||
#define REDIS_CALL_NONE 0
|
#define CMD_CALL_NONE 0
|
||||||
#define REDIS_CALL_SLOWLOG 1
|
#define CMD_CALL_SLOWLOG 1
|
||||||
#define REDIS_CALL_STATS 2
|
#define CMD_CALL_STATS 2
|
||||||
#define REDIS_CALL_PROPAGATE 4
|
#define CMD_CALL_PROPAGATE 4
|
||||||
#define REDIS_CALL_FULL (REDIS_CALL_SLOWLOG | REDIS_CALL_STATS | REDIS_CALL_PROPAGATE)
|
#define CMD_CALL_FULL (CMD_CALL_SLOWLOG | CMD_CALL_STATS | CMD_CALL_PROPAGATE)
|
||||||
|
|
||||||
/* Command propagation flags, see propagate() function */
|
/* Command propagation flags, see propagate() function */
|
||||||
#define REDIS_PROPAGATE_NONE 0
|
#define PROPAGATE_NONE 0
|
||||||
#define REDIS_PROPAGATE_AOF 1
|
#define PROPAGATE_AOF 1
|
||||||
#define REDIS_PROPAGATE_REPL 2
|
#define PROPAGATE_REPL 2
|
||||||
|
|
||||||
/* RDB active child save type. */
|
/* RDB active child save type. */
|
||||||
#define REDIS_RDB_CHILD_TYPE_NONE 0
|
#define RDB_CHILD_TYPE_NONE 0
|
||||||
#define REDIS_RDB_CHILD_TYPE_DISK 1 /* RDB is written to disk. */
|
#define RDB_CHILD_TYPE_DISK 1 /* RDB is written to disk. */
|
||||||
#define REDIS_RDB_CHILD_TYPE_SOCKET 2 /* RDB is written to slave socket. */
|
#define RDB_CHILD_TYPE_SOCKET 2 /* RDB is written to slave socket. */
|
||||||
|
|
||||||
/* Keyspace changes notification classes. Every class is associated with a
|
/* Keyspace changes notification classes. Every class is associated with a
|
||||||
* character for configuration purposes. */
|
* character for configuration purposes. */
|
||||||
#define REDIS_NOTIFY_KEYSPACE (1<<0) /* K */
|
#define NOTIFY_KEYSPACE (1<<0) /* K */
|
||||||
#define REDIS_NOTIFY_KEYEVENT (1<<1) /* E */
|
#define NOTIFY_KEYEVENT (1<<1) /* E */
|
||||||
#define REDIS_NOTIFY_GENERIC (1<<2) /* g */
|
#define NOTIFY_GENERIC (1<<2) /* g */
|
||||||
#define REDIS_NOTIFY_STRING (1<<3) /* $ */
|
#define NOTIFY_STRING (1<<3) /* $ */
|
||||||
#define REDIS_NOTIFY_LIST (1<<4) /* l */
|
#define NOTIFY_LIST (1<<4) /* l */
|
||||||
#define REDIS_NOTIFY_SET (1<<5) /* s */
|
#define NOTIFY_SET (1<<5) /* s */
|
||||||
#define REDIS_NOTIFY_HASH (1<<6) /* h */
|
#define NOTIFY_HASH (1<<6) /* h */
|
||||||
#define REDIS_NOTIFY_ZSET (1<<7) /* z */
|
#define NOTIFY_ZSET (1<<7) /* z */
|
||||||
#define REDIS_NOTIFY_EXPIRED (1<<8) /* x */
|
#define NOTIFY_EXPIRED (1<<8) /* x */
|
||||||
#define REDIS_NOTIFY_EVICTED (1<<9) /* e */
|
#define NOTIFY_EVICTED (1<<9) /* e */
|
||||||
#define REDIS_NOTIFY_ALL (REDIS_NOTIFY_GENERIC | REDIS_NOTIFY_STRING | REDIS_NOTIFY_LIST | REDIS_NOTIFY_SET | REDIS_NOTIFY_HASH | REDIS_NOTIFY_ZSET | REDIS_NOTIFY_EXPIRED | REDIS_NOTIFY_EVICTED) /* A */
|
#define NOTIFY_ALL (NOTIFY_GENERIC | NOTIFY_STRING | NOTIFY_LIST | NOTIFY_SET | NOTIFY_HASH | NOTIFY_ZSET | NOTIFY_EXPIRED | NOTIFY_EVICTED) /* A */
|
||||||
|
|
||||||
/* Get the first bind addr or NULL */
|
/* Get the first bind addr or NULL */
|
||||||
#define REDIS_BIND_ADDR (server.bindaddr_count ? server.bindaddr[0] : NULL)
|
#define NET_FIRST_BIND_ADDR (server.bindaddr_count ? server.bindaddr[0] : NULL)
|
||||||
|
|
||||||
/* Using the following macro you can run code inside serverCron() with the
|
/* Using the following macro you can run code inside serverCron() with the
|
||||||
* specified period, specified in milliseconds.
|
* specified period, specified in milliseconds.
|
||||||
@ -414,7 +414,7 @@ typedef long long mstime_t; /* millisecond time type. */
|
|||||||
/* We can print the stacktrace, so our assert is defined this way: */
|
/* We can print the stacktrace, so our assert is defined this way: */
|
||||||
#define serverAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_serverAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),_exit(1)))
|
#define serverAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_serverAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),_exit(1)))
|
||||||
#define serverAssert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1)))
|
#define serverAssert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1)))
|
||||||
#define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
|
#define serverPanic(_e) _serverPanic(#_e,__FILE__,__LINE__),_exit(1)
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* Data types
|
* Data types
|
||||||
@ -423,13 +423,13 @@ typedef long long mstime_t; /* millisecond time type. */
|
|||||||
/* A redis object, that is a type able to hold a string / list / set */
|
/* A redis object, that is a type able to hold a string / list / set */
|
||||||
|
|
||||||
/* The actual Redis Object */
|
/* The actual Redis Object */
|
||||||
#define REDIS_LRU_BITS 24
|
#define LRU_BITS 24
|
||||||
#define REDIS_LRU_CLOCK_MAX ((1<<REDIS_LRU_BITS)-1) /* Max value of obj->lru */
|
#define LRU_CLOCK_MAX ((1<<LRU_BITS)-1) /* Max value of obj->lru */
|
||||||
#define REDIS_LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */
|
#define LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */
|
||||||
typedef struct redisObject {
|
typedef struct redisObject {
|
||||||
unsigned type:4;
|
unsigned type:4;
|
||||||
unsigned encoding:4;
|
unsigned encoding:4;
|
||||||
unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
|
unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
|
||||||
int refcount;
|
int refcount;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
} robj;
|
} robj;
|
||||||
@ -438,7 +438,7 @@ typedef struct redisObject {
|
|||||||
* If the current resolution is lower than the frequency we refresh the
|
* If the current resolution is lower than the frequency we refresh the
|
||||||
* LRU clock (as it should be in production servers) we return the
|
* LRU clock (as it should be in production servers) we return the
|
||||||
* precomputed value, otherwise we need to resort to a function call. */
|
* precomputed value, otherwise we need to resort to a function call. */
|
||||||
#define LRU_CLOCK() ((1000/server.hz <= REDIS_LRU_CLOCK_RESOLUTION) ? server.lruclock : getLRUClock())
|
#define LRU_CLOCK() ((1000/server.hz <= LRU_CLOCK_RESOLUTION) ? server.lruclock : getLRUClock())
|
||||||
|
|
||||||
/* Macro used to initialize a Redis object allocated on the stack.
|
/* Macro used to initialize a Redis object allocated on the stack.
|
||||||
* Note that this macro is taken near the structure definition to make sure
|
* Note that this macro is taken near the structure definition to make sure
|
||||||
@ -458,7 +458,7 @@ typedef struct redisObject {
|
|||||||
* greater idle times to the right (ascending order).
|
* greater idle times to the right (ascending order).
|
||||||
*
|
*
|
||||||
* Empty entries have the key pointer set to NULL. */
|
* Empty entries have the key pointer set to NULL. */
|
||||||
#define REDIS_EVICTION_POOL_SIZE 16
|
#define MAXMEMORY_EVICTION_POOL_SIZE 16
|
||||||
struct evictionPoolEntry {
|
struct evictionPoolEntry {
|
||||||
unsigned long long idle; /* Object idle time. */
|
unsigned long long idle; /* Object idle time. */
|
||||||
sds key; /* Key name. */
|
sds key; /* Key name. */
|
||||||
@ -499,13 +499,13 @@ typedef struct blockingState {
|
|||||||
mstime_t timeout; /* Blocking operation timeout. If UNIX current time
|
mstime_t timeout; /* Blocking operation timeout. If UNIX current time
|
||||||
* is > timeout then the operation timed out. */
|
* is > timeout then the operation timed out. */
|
||||||
|
|
||||||
/* REDIS_BLOCK_LIST */
|
/* BLOCKED_LIST */
|
||||||
dict *keys; /* The keys we are waiting to terminate a blocking
|
dict *keys; /* The keys we are waiting to terminate a blocking
|
||||||
* operation such as BLPOP. Otherwise NULL. */
|
* operation such as BLPOP. Otherwise NULL. */
|
||||||
robj *target; /* The key that should receive the element,
|
robj *target; /* The key that should receive the element,
|
||||||
* for BRPOPLPUSH. */
|
* for BRPOPLPUSH. */
|
||||||
|
|
||||||
/* REDIS_BLOCK_WAIT */
|
/* BLOCKED_WAIT */
|
||||||
int numreplicas; /* Number of replicas we are waiting for ACK. */
|
int numreplicas; /* Number of replicas we are waiting for ACK. */
|
||||||
long long reploffset; /* Replication offset to reach. */
|
long long reploffset; /* Replication offset to reach. */
|
||||||
} blockingState;
|
} blockingState;
|
||||||
@ -549,7 +549,7 @@ typedef struct client {
|
|||||||
time_t ctime; /* Client creation time */
|
time_t ctime; /* Client creation time */
|
||||||
time_t lastinteraction; /* time of the last interaction, used for timeout */
|
time_t lastinteraction; /* time of the last interaction, used for timeout */
|
||||||
time_t obuf_soft_limit_reached_time;
|
time_t obuf_soft_limit_reached_time;
|
||||||
int flags; /* REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI ... */
|
int flags; /* CLIENT_SLAVE | CLIENT_MONITOR | CLIENT_MULTI ... */
|
||||||
int authenticated; /* when requirepass is non-NULL */
|
int authenticated; /* when requirepass is non-NULL */
|
||||||
int replstate; /* replication state if this is a slave */
|
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 ACK. */
|
||||||
@ -560,10 +560,10 @@ typedef struct client {
|
|||||||
long long reploff; /* replication offset if this is our master */
|
long long reploff; /* replication offset if this is our master */
|
||||||
long long repl_ack_off; /* replication ack offset, if this is a slave */
|
long long repl_ack_off; /* replication ack offset, if this is a slave */
|
||||||
long long repl_ack_time;/* replication ack time, if this is a slave */
|
long long repl_ack_time;/* replication ack time, if this is a slave */
|
||||||
char replrunid[REDIS_RUN_ID_SIZE+1]; /* master run id if this is a master */
|
char replrunid[CONFIG_RUN_ID_SIZE+1]; /* master run id if this is a master */
|
||||||
int slave_listening_port; /* As configured with: SLAVECONF listening-port */
|
int slave_listening_port; /* As configured with: SLAVECONF listening-port */
|
||||||
multiState mstate; /* MULTI/EXEC state */
|
multiState mstate; /* MULTI/EXEC state */
|
||||||
int btype; /* Type of blocking op if REDIS_BLOCKED. */
|
int btype; /* Type of blocking op if CLIENT_BLOCKED. */
|
||||||
blockingState bpop; /* blocking state */
|
blockingState bpop; /* blocking state */
|
||||||
long long woff; /* Last write global replication offset. */
|
long long woff; /* Last write global replication offset. */
|
||||||
list *watched_keys; /* Keys WATCHED for MULTI/EXEC CAS */
|
list *watched_keys; /* Keys WATCHED for MULTI/EXEC CAS */
|
||||||
@ -573,7 +573,7 @@ typedef struct client {
|
|||||||
|
|
||||||
/* Response buffer */
|
/* Response buffer */
|
||||||
int bufpos;
|
int bufpos;
|
||||||
char buf[REDIS_REPLY_CHUNK_BYTES];
|
char buf[PROTO_REPLY_CHUNK_BYTES];
|
||||||
} client;
|
} client;
|
||||||
|
|
||||||
struct saveparam {
|
struct saveparam {
|
||||||
@ -590,10 +590,10 @@ struct sharedObjectsStruct {
|
|||||||
*busykeyerr, *oomerr, *plus, *messagebulk, *pmessagebulk, *subscribebulk,
|
*busykeyerr, *oomerr, *plus, *messagebulk, *pmessagebulk, *subscribebulk,
|
||||||
*unsubscribebulk, *psubscribebulk, *punsubscribebulk, *del, *rpop, *lpop,
|
*unsubscribebulk, *psubscribebulk, *punsubscribebulk, *del, *rpop, *lpop,
|
||||||
*lpush, *emptyscan, *minstring, *maxstring,
|
*lpush, *emptyscan, *minstring, *maxstring,
|
||||||
*select[REDIS_SHARED_SELECT_CMDS],
|
*select[PROTO_SHARED_SELECT_CMDS],
|
||||||
*integers[REDIS_SHARED_INTEGERS],
|
*integers[OBJ_SHARED_INTEGERS],
|
||||||
*mbulkhdr[REDIS_SHARED_BULKHDR_LEN], /* "*<value>\r\n" */
|
*mbulkhdr[OBJ_SHARED_BULKHDR_LEN], /* "*<value>\r\n" */
|
||||||
*bulkhdr[REDIS_SHARED_BULKHDR_LEN]; /* "$<value>\r\n" */
|
*bulkhdr[OBJ_SHARED_BULKHDR_LEN]; /* "$<value>\r\n" */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ZSETs use a specialized version of Skiplists */
|
/* ZSETs use a specialized version of Skiplists */
|
||||||
@ -624,11 +624,11 @@ typedef struct clientBufferLimitsConfig {
|
|||||||
time_t soft_limit_seconds;
|
time_t soft_limit_seconds;
|
||||||
} clientBufferLimitsConfig;
|
} clientBufferLimitsConfig;
|
||||||
|
|
||||||
extern clientBufferLimitsConfig clientBufferLimitsDefaults[REDIS_CLIENT_TYPE_COUNT];
|
extern clientBufferLimitsConfig clientBufferLimitsDefaults[CLIENT_TYPE_COUNT];
|
||||||
|
|
||||||
/* The redisOp structure defines a Redis Operation, that is an instance of
|
/* The redisOp structure defines a Redis Operation, that is an instance of
|
||||||
* a command with an argument vector, database ID, propagation target
|
* a command with an argument vector, database ID, propagation target
|
||||||
* (REDIS_PROPAGATE_*), and command pointer.
|
* (PROPAGATE_*), and command pointer.
|
||||||
*
|
*
|
||||||
* Currently only used to additionally propagate more commands to AOF/Replication
|
* Currently only used to additionally propagate more commands to AOF/Replication
|
||||||
* after the propagation of the executed command. */
|
* after the propagation of the executed command. */
|
||||||
@ -671,26 +671,26 @@ struct redisServer {
|
|||||||
dict *commands; /* Command table */
|
dict *commands; /* Command table */
|
||||||
dict *orig_commands; /* Command table before command renaming. */
|
dict *orig_commands; /* Command table before command renaming. */
|
||||||
aeEventLoop *el;
|
aeEventLoop *el;
|
||||||
unsigned lruclock:REDIS_LRU_BITS; /* Clock for LRU eviction */
|
unsigned lruclock:LRU_BITS; /* Clock for LRU eviction */
|
||||||
int shutdown_asap; /* SHUTDOWN needed ASAP */
|
int shutdown_asap; /* SHUTDOWN needed ASAP */
|
||||||
int activerehashing; /* Incremental rehash in serverCron() */
|
int activerehashing; /* Incremental rehash in serverCron() */
|
||||||
char *requirepass; /* Pass for AUTH command, or NULL */
|
char *requirepass; /* Pass for AUTH command, or NULL */
|
||||||
char *pidfile; /* PID file path */
|
char *pidfile; /* PID file path */
|
||||||
int arch_bits; /* 32 or 64 depending on sizeof(long) */
|
int arch_bits; /* 32 or 64 depending on sizeof(long) */
|
||||||
int cronloops; /* Number of times the cron function run */
|
int cronloops; /* Number of times the cron function run */
|
||||||
char runid[REDIS_RUN_ID_SIZE+1]; /* ID always different at every exec. */
|
char runid[CONFIG_RUN_ID_SIZE+1]; /* ID always different at every exec. */
|
||||||
int sentinel_mode; /* True if this instance is a Sentinel. */
|
int sentinel_mode; /* True if this instance is a Sentinel. */
|
||||||
/* Networking */
|
/* Networking */
|
||||||
int port; /* TCP listening port */
|
int port; /* TCP listening port */
|
||||||
int tcp_backlog; /* TCP listen() backlog */
|
int tcp_backlog; /* TCP listen() backlog */
|
||||||
char *bindaddr[REDIS_BINDADDR_MAX]; /* Addresses we should bind to */
|
char *bindaddr[CONFIG_BINDADDR_MAX]; /* Addresses we should bind to */
|
||||||
int bindaddr_count; /* Number of addresses in server.bindaddr[] */
|
int bindaddr_count; /* Number of addresses in server.bindaddr[] */
|
||||||
char *unixsocket; /* UNIX socket path */
|
char *unixsocket; /* UNIX socket path */
|
||||||
mode_t unixsocketperm; /* UNIX socket permission */
|
mode_t unixsocketperm; /* UNIX socket permission */
|
||||||
int ipfd[REDIS_BINDADDR_MAX]; /* TCP socket file descriptors */
|
int ipfd[CONFIG_BINDADDR_MAX]; /* TCP socket file descriptors */
|
||||||
int ipfd_count; /* Used slots in ipfd[] */
|
int ipfd_count; /* Used slots in ipfd[] */
|
||||||
int sofd; /* Unix socket file descriptor */
|
int sofd; /* Unix socket file descriptor */
|
||||||
int cfd[REDIS_BINDADDR_MAX];/* Cluster bus listening socket */
|
int cfd[CONFIG_BINDADDR_MAX];/* Cluster bus listening socket */
|
||||||
int cfd_count; /* Used slots in cfd[] */
|
int cfd_count; /* Used slots in cfd[] */
|
||||||
list *clients; /* List of active clients */
|
list *clients; /* List of active clients */
|
||||||
list *clients_to_close; /* Clients to close asynchronously */
|
list *clients_to_close; /* Clients to close asynchronously */
|
||||||
@ -737,9 +737,9 @@ struct redisServer {
|
|||||||
struct {
|
struct {
|
||||||
long long last_sample_time; /* Timestamp of last sample in ms */
|
long long last_sample_time; /* Timestamp of last sample in ms */
|
||||||
long long last_sample_count;/* Count in last sample */
|
long long last_sample_count;/* Count in last sample */
|
||||||
long long samples[REDIS_METRIC_SAMPLES];
|
long long samples[STATS_METRIC_SAMPLES];
|
||||||
int idx;
|
int idx;
|
||||||
} inst_metric[REDIS_METRIC_COUNT];
|
} inst_metric[STATS_METRIC_COUNT];
|
||||||
/* Configuration */
|
/* Configuration */
|
||||||
int verbosity; /* Loglevel in redis.conf */
|
int verbosity; /* Loglevel in redis.conf */
|
||||||
int maxidletime; /* Client timeout in seconds */
|
int maxidletime; /* Client timeout in seconds */
|
||||||
@ -748,11 +748,11 @@ struct redisServer {
|
|||||||
size_t client_max_querybuf_len; /* Limit for client query buffer length */
|
size_t client_max_querybuf_len; /* Limit for client query buffer length */
|
||||||
int dbnum; /* Total number of configured DBs */
|
int dbnum; /* Total number of configured DBs */
|
||||||
int supervised; /* 1 if supervised, 0 otherwise. */
|
int supervised; /* 1 if supervised, 0 otherwise. */
|
||||||
int supervised_mode; /* See REDIS_SUPERVISED_* */
|
int supervised_mode; /* See SUPERVISED_* */
|
||||||
int daemonize; /* True if running as a daemon */
|
int daemonize; /* True if running as a daemon */
|
||||||
clientBufferLimitsConfig client_obuf_limits[REDIS_CLIENT_TYPE_COUNT];
|
clientBufferLimitsConfig client_obuf_limits[CLIENT_TYPE_COUNT];
|
||||||
/* AOF persistence */
|
/* AOF persistence */
|
||||||
int aof_state; /* REDIS_AOF_(ON|OFF|WAIT_REWRITE) */
|
int aof_state; /* AOF_(ON|OFF|WAIT_REWRITE) */
|
||||||
int aof_fsync; /* Kind of fsync() policy */
|
int aof_fsync; /* Kind of fsync() policy */
|
||||||
char *aof_filename; /* Name of the AOF file */
|
char *aof_filename; /* Name of the AOF file */
|
||||||
int aof_no_fsync_on_rewrite; /* Don't fsync if a rewrite is in prog. */
|
int aof_no_fsync_on_rewrite; /* Don't fsync if a rewrite is in prog. */
|
||||||
@ -851,7 +851,7 @@ struct redisServer {
|
|||||||
time_t repl_down_since; /* Unix time at which link with master went down */
|
time_t repl_down_since; /* Unix time at which link with master went down */
|
||||||
int repl_disable_tcp_nodelay; /* Disable TCP_NODELAY after SYNC? */
|
int repl_disable_tcp_nodelay; /* Disable TCP_NODELAY after SYNC? */
|
||||||
int slave_priority; /* Reported in INFO and used by Sentinel. */
|
int slave_priority; /* Reported in INFO and used by Sentinel. */
|
||||||
char repl_master_runid[REDIS_RUN_ID_SIZE+1]; /* Master run id for PSYNC. */
|
char repl_master_runid[CONFIG_RUN_ID_SIZE+1]; /* Master run id for PSYNC. */
|
||||||
long long repl_master_initial_offset; /* Master PSYNC offset. */
|
long long repl_master_initial_offset; /* Master PSYNC offset. */
|
||||||
/* Replication script cache. */
|
/* Replication script cache. */
|
||||||
dict *repl_scriptcache_dict; /* SHA1 all slaves are aware of. */
|
dict *repl_scriptcache_dict; /* SHA1 all slaves are aware of. */
|
||||||
@ -892,7 +892,7 @@ struct redisServer {
|
|||||||
dict *pubsub_channels; /* Map channels to list of subscribed clients */
|
dict *pubsub_channels; /* Map channels to list of subscribed clients */
|
||||||
list *pubsub_patterns; /* A list of pubsub_patterns */
|
list *pubsub_patterns; /* A list of pubsub_patterns */
|
||||||
int notify_keyspace_events; /* Events to propagate via Pub/Sub. This is an
|
int notify_keyspace_events; /* Events to propagate via Pub/Sub. This is an
|
||||||
xor of REDIS_NOTIFY... flags. */
|
xor of NOTIFY_... flags. */
|
||||||
/* Cluster */
|
/* Cluster */
|
||||||
int cluster_enabled; /* Is cluster enabled? */
|
int cluster_enabled; /* Is cluster enabled? */
|
||||||
mstime_t cluster_node_timeout; /* Cluster node timeout. */
|
mstime_t cluster_node_timeout; /* Cluster node timeout. */
|
||||||
@ -1583,7 +1583,7 @@ void *realloc(void *ptr, size_t size) __attribute__ ((deprecated));
|
|||||||
/* Debugging stuff */
|
/* Debugging stuff */
|
||||||
void _serverAssertWithInfo(client *c, robj *o, char *estr, char *file, int line);
|
void _serverAssertWithInfo(client *c, robj *o, char *estr, char *file, int line);
|
||||||
void _serverAssert(char *estr, char *file, int line);
|
void _serverAssert(char *estr, char *file, int line);
|
||||||
void _redisPanic(char *msg, char *file, int line);
|
void _serverPanic(char *msg, char *file, int line);
|
||||||
void bugReportStart(void);
|
void bugReportStart(void);
|
||||||
void serverLogObjectDebugInfo(robj *o);
|
void serverLogObjectDebugInfo(robj *o);
|
||||||
void sigsegvHandler(int sig, siginfo_t *info, void *secret);
|
void sigsegvHandler(int sig, siginfo_t *info, void *secret);
|
||||||
|
28
src/sort.c
28
src/sort.c
@ -267,7 +267,7 @@ void sortCommand(client *c) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
listAddNodeTail(operations,createSortOperation(
|
listAddNodeTail(operations,createSortOperation(
|
||||||
REDIS_SORT_GET,c->argv[j+1]));
|
SORT_OP_GET,c->argv[j+1]));
|
||||||
getop++;
|
getop++;
|
||||||
j++;
|
j++;
|
||||||
} else {
|
} else {
|
||||||
@ -293,7 +293,7 @@ void sortCommand(client *c) {
|
|||||||
* scripting and replication. */
|
* scripting and replication. */
|
||||||
if (dontsort &&
|
if (dontsort &&
|
||||||
sortval->type == OBJ_SET &&
|
sortval->type == OBJ_SET &&
|
||||||
(storekey || c->flags & REDIS_LUA_CLIENT))
|
(storekey || c->flags & CLIENT_LUA))
|
||||||
{
|
{
|
||||||
/* Force ALPHA sorting */
|
/* Force ALPHA sorting */
|
||||||
dontsort = 0;
|
dontsort = 0;
|
||||||
@ -310,7 +310,7 @@ void sortCommand(client *c) {
|
|||||||
case OBJ_LIST: vectorlen = listTypeLength(sortval); break;
|
case OBJ_LIST: vectorlen = listTypeLength(sortval); break;
|
||||||
case OBJ_SET: vectorlen = setTypeSize(sortval); break;
|
case OBJ_SET: vectorlen = setTypeSize(sortval); break;
|
||||||
case OBJ_ZSET: vectorlen = dictSize(((zset*)sortval->ptr)->dict); break;
|
case OBJ_ZSET: vectorlen = dictSize(((zset*)sortval->ptr)->dict); break;
|
||||||
default: vectorlen = 0; redisPanic("Bad SORT type"); /* Avoid GCC warning */
|
default: vectorlen = 0; serverPanic("Bad SORT type"); /* Avoid GCC warning */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform LIMIT start,count sanity checking. */
|
/* Perform LIMIT start,count sanity checking. */
|
||||||
@ -355,7 +355,7 @@ void sortCommand(client *c) {
|
|||||||
listTypeEntry entry;
|
listTypeEntry entry;
|
||||||
li = listTypeInitIterator(sortval,
|
li = listTypeInitIterator(sortval,
|
||||||
desc ? (long)(listTypeLength(sortval) - start - 1) : start,
|
desc ? (long)(listTypeLength(sortval) - start - 1) : start,
|
||||||
desc ? REDIS_HEAD : REDIS_TAIL);
|
desc ? LIST_HEAD : LIST_TAIL);
|
||||||
|
|
||||||
while(j < vectorlen && listTypeNext(li,&entry)) {
|
while(j < vectorlen && listTypeNext(li,&entry)) {
|
||||||
vector[j].obj = listTypeGet(&entry);
|
vector[j].obj = listTypeGet(&entry);
|
||||||
@ -369,7 +369,7 @@ void sortCommand(client *c) {
|
|||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
} else if (sortval->type == OBJ_LIST) {
|
} else if (sortval->type == OBJ_LIST) {
|
||||||
listTypeIterator *li = listTypeInitIterator(sortval,0,REDIS_TAIL);
|
listTypeIterator *li = listTypeInitIterator(sortval,0,LIST_TAIL);
|
||||||
listTypeEntry entry;
|
listTypeEntry entry;
|
||||||
while(listTypeNext(li,&entry)) {
|
while(listTypeNext(li,&entry)) {
|
||||||
vector[j].obj = listTypeGet(&entry);
|
vector[j].obj = listTypeGet(&entry);
|
||||||
@ -440,7 +440,7 @@ void sortCommand(client *c) {
|
|||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown type");
|
serverPanic("Unknown type");
|
||||||
}
|
}
|
||||||
serverAssertWithInfo(c,sortval,j == vectorlen);
|
serverAssertWithInfo(c,sortval,j == vectorlen);
|
||||||
|
|
||||||
@ -517,7 +517,7 @@ void sortCommand(client *c) {
|
|||||||
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
||||||
vector[j].obj);
|
vector[j].obj);
|
||||||
|
|
||||||
if (sop->type == REDIS_SORT_GET) {
|
if (sop->type == SORT_OP_GET) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
addReply(c,shared.nullbulk);
|
addReply(c,shared.nullbulk);
|
||||||
} else {
|
} else {
|
||||||
@ -526,7 +526,7 @@ void sortCommand(client *c) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Always fails */
|
/* Always fails */
|
||||||
serverAssertWithInfo(c,sortval,sop->type == REDIS_SORT_GET);
|
serverAssertWithInfo(c,sortval,sop->type == SORT_OP_GET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -539,7 +539,7 @@ void sortCommand(client *c) {
|
|||||||
listIter li;
|
listIter li;
|
||||||
|
|
||||||
if (!getop) {
|
if (!getop) {
|
||||||
listTypePush(sobj,vector[j].obj,REDIS_TAIL);
|
listTypePush(sobj,vector[j].obj,LIST_TAIL);
|
||||||
} else {
|
} else {
|
||||||
listRewind(operations,&li);
|
listRewind(operations,&li);
|
||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
@ -547,29 +547,29 @@ void sortCommand(client *c) {
|
|||||||
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
||||||
vector[j].obj);
|
vector[j].obj);
|
||||||
|
|
||||||
if (sop->type == REDIS_SORT_GET) {
|
if (sop->type == SORT_OP_GET) {
|
||||||
if (!val) val = createStringObject("",0);
|
if (!val) val = createStringObject("",0);
|
||||||
|
|
||||||
/* listTypePush does an incrRefCount, so we should take care
|
/* listTypePush does an incrRefCount, so we should take care
|
||||||
* care of the incremented refcount caused by either
|
* care of the incremented refcount caused by either
|
||||||
* lookupKeyByPattern or createStringObject("",0) */
|
* lookupKeyByPattern or createStringObject("",0) */
|
||||||
listTypePush(sobj,val,REDIS_TAIL);
|
listTypePush(sobj,val,LIST_TAIL);
|
||||||
decrRefCount(val);
|
decrRefCount(val);
|
||||||
} else {
|
} else {
|
||||||
/* Always fails */
|
/* Always fails */
|
||||||
serverAssertWithInfo(c,sortval,sop->type == REDIS_SORT_GET);
|
serverAssertWithInfo(c,sortval,sop->type == SORT_OP_GET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (outputlen) {
|
if (outputlen) {
|
||||||
setKey(c->db,storekey,sobj);
|
setKey(c->db,storekey,sobj);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"sortstore",storekey,
|
notifyKeyspaceEvent(NOTIFY_LIST,"sortstore",storekey,
|
||||||
c->db->id);
|
c->db->id);
|
||||||
server.dirty += outputlen;
|
server.dirty += outputlen;
|
||||||
} else if (dbDelete(c->db,storekey)) {
|
} else if (dbDelete(c->db,storekey)) {
|
||||||
signalModifiedKey(c->db,storekey);
|
signalModifiedKey(c->db,storekey);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",storekey,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",storekey,c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
decrRefCount(sobj);
|
decrRefCount(sobj);
|
||||||
|
44
src/t_hash.c
44
src/t_hash.c
@ -138,7 +138,7 @@ robj *hashTypeGetObject(robj *o, robj *field) {
|
|||||||
value = aux;
|
value = aux;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -161,7 +161,7 @@ size_t hashTypeGetValueLength(robj *o, robj *field) {
|
|||||||
if (hashTypeGetFromHashTable(o, field, &aux) == 0)
|
if (hashTypeGetFromHashTable(o, field, &aux) == 0)
|
||||||
len = stringObjectLen(aux);
|
len = stringObjectLen(aux);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -180,7 +180,7 @@ int hashTypeExists(robj *o, robj *field) {
|
|||||||
|
|
||||||
if (hashTypeGetFromHashTable(o, field, &aux) == 0) return 1;
|
if (hashTypeGetFromHashTable(o, field, &aux) == 0) return 1;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ int hashTypeSet(robj *o, robj *field, robj *value) {
|
|||||||
}
|
}
|
||||||
incrRefCount(value);
|
incrRefCount(value);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
@ -274,7 +274,7 @@ int hashTypeDelete(robj *o, robj *field) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
return deleted;
|
return deleted;
|
||||||
@ -289,7 +289,7 @@ unsigned long hashTypeLength(robj *o) {
|
|||||||
} else if (o->encoding == OBJ_ENCODING_HT) {
|
} else if (o->encoding == OBJ_ENCODING_HT) {
|
||||||
length = dictSize((dict*)o->ptr);
|
length = dictSize((dict*)o->ptr);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
@ -306,7 +306,7 @@ hashTypeIterator *hashTypeInitIterator(robj *subject) {
|
|||||||
} else if (hi->encoding == OBJ_ENCODING_HT) {
|
} else if (hi->encoding == OBJ_ENCODING_HT) {
|
||||||
hi->di = dictGetIterator(subject->ptr);
|
hi->di = dictGetIterator(subject->ptr);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
return hi;
|
return hi;
|
||||||
@ -352,7 +352,7 @@ int hashTypeNext(hashTypeIterator *hi) {
|
|||||||
} else if (hi->encoding == OBJ_ENCODING_HT) {
|
} else if (hi->encoding == OBJ_ENCODING_HT) {
|
||||||
if ((hi->de = dictNext(hi->di)) == NULL) return C_ERR;
|
if ((hi->de = dictNext(hi->di)) == NULL) return C_ERR;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
return C_OK;
|
return C_OK;
|
||||||
}
|
}
|
||||||
@ -410,7 +410,7 @@ robj *hashTypeCurrentObject(hashTypeIterator *hi, int what) {
|
|||||||
hashTypeCurrentFromHashTable(hi, what, &dst);
|
hashTypeCurrentFromHashTable(hi, what, &dst);
|
||||||
incrRefCount(dst);
|
incrRefCount(dst);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
@ -452,7 +452,7 @@ void hashTypeConvertZiplist(robj *o, int enc) {
|
|||||||
value = tryObjectEncoding(value);
|
value = tryObjectEncoding(value);
|
||||||
ret = dictAdd(dict, field, value);
|
ret = dictAdd(dict, field, value);
|
||||||
if (ret != DICT_OK) {
|
if (ret != DICT_OK) {
|
||||||
serverLogHexDump(REDIS_WARNING,"ziplist with dup elements dump",
|
serverLogHexDump(LL_WARNING,"ziplist with dup elements dump",
|
||||||
o->ptr,ziplistBlobLen(o->ptr));
|
o->ptr,ziplistBlobLen(o->ptr));
|
||||||
serverAssert(ret == DICT_OK);
|
serverAssert(ret == DICT_OK);
|
||||||
}
|
}
|
||||||
@ -465,7 +465,7 @@ void hashTypeConvertZiplist(robj *o, int enc) {
|
|||||||
o->ptr = dict;
|
o->ptr = dict;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,9 +473,9 @@ void hashTypeConvert(robj *o, int enc) {
|
|||||||
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
hashTypeConvertZiplist(o, enc);
|
hashTypeConvertZiplist(o, enc);
|
||||||
} else if (o->encoding == OBJ_ENCODING_HT) {
|
} else if (o->encoding == OBJ_ENCODING_HT) {
|
||||||
redisPanic("Not implemented");
|
serverPanic("Not implemented");
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ void hsetCommand(client *c) {
|
|||||||
update = hashTypeSet(o,c->argv[2],c->argv[3]);
|
update = hashTypeSet(o,c->argv[2],c->argv[3]);
|
||||||
addReply(c, update ? shared.czero : shared.cone);
|
addReply(c, update ? shared.czero : shared.cone);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_HASH,"hset",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hset",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,7 +509,7 @@ void hsetnxCommand(client *c) {
|
|||||||
hashTypeSet(o,c->argv[2],c->argv[3]);
|
hashTypeSet(o,c->argv[2],c->argv[3]);
|
||||||
addReply(c, shared.cone);
|
addReply(c, shared.cone);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_HASH,"hset",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hset",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,7 +531,7 @@ void hmsetCommand(client *c) {
|
|||||||
}
|
}
|
||||||
addReply(c, shared.ok);
|
addReply(c, shared.ok);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_HASH,"hset",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hset",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +565,7 @@ void hincrbyCommand(client *c) {
|
|||||||
decrRefCount(new);
|
decrRefCount(new);
|
||||||
addReplyLongLong(c,value);
|
addReplyLongLong(c,value);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_HASH,"hincrby",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hincrby",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,7 +592,7 @@ void hincrbyfloatCommand(client *c) {
|
|||||||
hashTypeSet(o,c->argv[2],new);
|
hashTypeSet(o,c->argv[2],new);
|
||||||
addReplyBulk(c,new);
|
addReplyBulk(c,new);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_HASH,"hincrbyfloat",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hincrbyfloat",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
|
|
||||||
/* Always replicate HINCRBYFLOAT as an HSET command with the final value
|
/* Always replicate HINCRBYFLOAT as an HSET command with the final value
|
||||||
@ -640,7 +640,7 @@ static void addHashFieldToReply(client *c, robj *o, robj *field) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,9 +690,9 @@ void hdelCommand(client *c) {
|
|||||||
}
|
}
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_HASH,"hdel",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hdel",c->argv[1],c->db->id);
|
||||||
if (keyremoved)
|
if (keyremoved)
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],
|
||||||
c->db->id);
|
c->db->id);
|
||||||
server.dirty += deleted;
|
server.dirty += deleted;
|
||||||
}
|
}
|
||||||
@ -736,7 +736,7 @@ static void addHashIteratorCursorToReply(client *c, hashTypeIterator *hi, int wh
|
|||||||
addReplyBulk(c, value);
|
addReplyBulk(c, value);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
134
src/t_list.c
134
src/t_list.c
@ -40,13 +40,13 @@
|
|||||||
* the function takes care of it if needed. */
|
* the function takes care of it if needed. */
|
||||||
void listTypePush(robj *subject, robj *value, int where) {
|
void listTypePush(robj *subject, robj *value, int where) {
|
||||||
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
int pos = (where == REDIS_HEAD) ? QUICKLIST_HEAD : QUICKLIST_TAIL;
|
int pos = (where == LIST_HEAD) ? QUICKLIST_HEAD : QUICKLIST_TAIL;
|
||||||
value = getDecodedObject(value);
|
value = getDecodedObject(value);
|
||||||
size_t len = sdslen(value->ptr);
|
size_t len = sdslen(value->ptr);
|
||||||
quicklistPush(subject->ptr, value->ptr, len, pos);
|
quicklistPush(subject->ptr, value->ptr, len, pos);
|
||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ robj *listTypePop(robj *subject, int where) {
|
|||||||
long long vlong;
|
long long vlong;
|
||||||
robj *value = NULL;
|
robj *value = NULL;
|
||||||
|
|
||||||
int ql_where = where == REDIS_HEAD ? QUICKLIST_HEAD : QUICKLIST_TAIL;
|
int ql_where = where == LIST_HEAD ? QUICKLIST_HEAD : QUICKLIST_TAIL;
|
||||||
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
if (quicklistPopCustom(subject->ptr, ql_where, (unsigned char **)&value,
|
if (quicklistPopCustom(subject->ptr, ql_where, (unsigned char **)&value,
|
||||||
NULL, &vlong, listPopSaver)) {
|
NULL, &vlong, listPopSaver)) {
|
||||||
@ -66,7 +66,7 @@ robj *listTypePop(robj *subject, int where) {
|
|||||||
value = createStringObjectFromLongLong(vlong);
|
value = createStringObjectFromLongLong(vlong);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ unsigned long listTypeLength(robj *subject) {
|
|||||||
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
return quicklistCount(subject->ptr);
|
return quicklistCount(subject->ptr);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,15 +87,15 @@ listTypeIterator *listTypeInitIterator(robj *subject, long index,
|
|||||||
li->encoding = subject->encoding;
|
li->encoding = subject->encoding;
|
||||||
li->direction = direction;
|
li->direction = direction;
|
||||||
li->iter = NULL;
|
li->iter = NULL;
|
||||||
/* REDIS_HEAD means start at TAIL and move *towards* head.
|
/* LIST_HEAD means start at TAIL and move *towards* head.
|
||||||
* REDIS_TAIL means start at HEAD and move *towards tail. */
|
* LIST_TAIL means start at HEAD and move *towards tail. */
|
||||||
int iter_direction =
|
int iter_direction =
|
||||||
direction == REDIS_HEAD ? AL_START_TAIL : AL_START_HEAD;
|
direction == LIST_HEAD ? AL_START_TAIL : AL_START_HEAD;
|
||||||
if (li->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (li->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
li->iter = quicklistGetIteratorAtIdx(li->subject->ptr,
|
li->iter = quicklistGetIteratorAtIdx(li->subject->ptr,
|
||||||
iter_direction, index);
|
iter_direction, index);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
return li;
|
return li;
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ int listTypeNext(listTypeIterator *li, listTypeEntry *entry) {
|
|||||||
if (li->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (li->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
return quicklistNext(li->iter, &entry->entry);
|
return quicklistNext(li->iter, &entry->entry);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ robj *listTypeGet(listTypeEntry *entry) {
|
|||||||
value = createStringObjectFromLongLong(entry->entry.longval);
|
value = createStringObjectFromLongLong(entry->entry.longval);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -143,16 +143,16 @@ void listTypeInsert(listTypeEntry *entry, robj *value, int where) {
|
|||||||
value = getDecodedObject(value);
|
value = getDecodedObject(value);
|
||||||
sds str = value->ptr;
|
sds str = value->ptr;
|
||||||
size_t len = sdslen(str);
|
size_t len = sdslen(str);
|
||||||
if (where == REDIS_TAIL) {
|
if (where == LIST_TAIL) {
|
||||||
quicklistInsertAfter((quicklist *)entry->entry.quicklist,
|
quicklistInsertAfter((quicklist *)entry->entry.quicklist,
|
||||||
&entry->entry, str, len);
|
&entry->entry, str, len);
|
||||||
} else if (where == REDIS_HEAD) {
|
} else if (where == LIST_HEAD) {
|
||||||
quicklistInsertBefore((quicklist *)entry->entry.quicklist,
|
quicklistInsertBefore((quicklist *)entry->entry.quicklist,
|
||||||
&entry->entry, str, len);
|
&entry->entry, str, len);
|
||||||
}
|
}
|
||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ int listTypeEqual(listTypeEntry *entry, robj *o) {
|
|||||||
serverAssertWithInfo(NULL,o,sdsEncodedObject(o));
|
serverAssertWithInfo(NULL,o,sdsEncodedObject(o));
|
||||||
return quicklistCompare(entry->entry.zi,o->ptr,sdslen(o->ptr));
|
return quicklistCompare(entry->entry.zi,o->ptr,sdslen(o->ptr));
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ void listTypeDelete(listTypeIterator *iter, listTypeEntry *entry) {
|
|||||||
if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
quicklistDelEntry(iter->iter, &entry->entry);
|
quicklistDelEntry(iter->iter, &entry->entry);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ void listTypeConvert(robj *subject, int enc) {
|
|||||||
subject->ptr = quicklistCreateFromZiplist(zlen, depth, subject->ptr);
|
subject->ptr = quicklistCreateFromZiplist(zlen, depth, subject->ptr);
|
||||||
subject->encoding = OBJ_ENCODING_QUICKLIST;
|
subject->encoding = OBJ_ENCODING_QUICKLIST;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported list conversion");
|
serverPanic("Unsupported list conversion");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,20 +216,20 @@ void pushGenericCommand(client *c, int where) {
|
|||||||
}
|
}
|
||||||
addReplyLongLong(c, waiting + (lobj ? listTypeLength(lobj) : 0));
|
addReplyLongLong(c, waiting + (lobj ? listTypeLength(lobj) : 0));
|
||||||
if (pushed) {
|
if (pushed) {
|
||||||
char *event = (where == REDIS_HEAD) ? "lpush" : "rpush";
|
char *event = (where == LIST_HEAD) ? "lpush" : "rpush";
|
||||||
|
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,event,c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);
|
||||||
}
|
}
|
||||||
server.dirty += pushed;
|
server.dirty += pushed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lpushCommand(client *c) {
|
void lpushCommand(client *c) {
|
||||||
pushGenericCommand(c,REDIS_HEAD);
|
pushGenericCommand(c,LIST_HEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpushCommand(client *c) {
|
void rpushCommand(client *c) {
|
||||||
pushGenericCommand(c,REDIS_TAIL);
|
pushGenericCommand(c,LIST_TAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushxGenericCommand(client *c, robj *refval, robj *val, int where) {
|
void pushxGenericCommand(client *c, robj *refval, robj *val, int where) {
|
||||||
@ -243,7 +243,7 @@ void pushxGenericCommand(client *c, robj *refval, robj *val, int where) {
|
|||||||
|
|
||||||
if (refval != NULL) {
|
if (refval != NULL) {
|
||||||
/* Seek refval from head to tail */
|
/* Seek refval from head to tail */
|
||||||
iter = listTypeInitIterator(subject,0,REDIS_TAIL);
|
iter = listTypeInitIterator(subject,0,LIST_TAIL);
|
||||||
while (listTypeNext(iter,&entry)) {
|
while (listTypeNext(iter,&entry)) {
|
||||||
if (listTypeEqual(&entry,refval)) {
|
if (listTypeEqual(&entry,refval)) {
|
||||||
listTypeInsert(&entry,val,where);
|
listTypeInsert(&entry,val,where);
|
||||||
@ -255,7 +255,7 @@ void pushxGenericCommand(client *c, robj *refval, robj *val, int where) {
|
|||||||
|
|
||||||
if (inserted) {
|
if (inserted) {
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"linsert",
|
notifyKeyspaceEvent(NOTIFY_LIST,"linsert",
|
||||||
c->argv[1],c->db->id);
|
c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
} else {
|
} else {
|
||||||
@ -264,11 +264,11 @@ void pushxGenericCommand(client *c, robj *refval, robj *val, int where) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char *event = (where == REDIS_HEAD) ? "lpush" : "rpush";
|
char *event = (where == LIST_HEAD) ? "lpush" : "rpush";
|
||||||
|
|
||||||
listTypePush(subject,val,where);
|
listTypePush(subject,val,where);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,event,c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,20 +277,20 @@ void pushxGenericCommand(client *c, robj *refval, robj *val, int where) {
|
|||||||
|
|
||||||
void lpushxCommand(client *c) {
|
void lpushxCommand(client *c) {
|
||||||
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
||||||
pushxGenericCommand(c,NULL,c->argv[2],REDIS_HEAD);
|
pushxGenericCommand(c,NULL,c->argv[2],LIST_HEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpushxCommand(client *c) {
|
void rpushxCommand(client *c) {
|
||||||
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
||||||
pushxGenericCommand(c,NULL,c->argv[2],REDIS_TAIL);
|
pushxGenericCommand(c,NULL,c->argv[2],LIST_TAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void linsertCommand(client *c) {
|
void linsertCommand(client *c) {
|
||||||
c->argv[4] = tryObjectEncoding(c->argv[4]);
|
c->argv[4] = tryObjectEncoding(c->argv[4]);
|
||||||
if (strcasecmp(c->argv[2]->ptr,"after") == 0) {
|
if (strcasecmp(c->argv[2]->ptr,"after") == 0) {
|
||||||
pushxGenericCommand(c,c->argv[3],c->argv[4],REDIS_TAIL);
|
pushxGenericCommand(c,c->argv[3],c->argv[4],LIST_TAIL);
|
||||||
} else if (strcasecmp(c->argv[2]->ptr,"before") == 0) {
|
} else if (strcasecmp(c->argv[2]->ptr,"before") == 0) {
|
||||||
pushxGenericCommand(c,c->argv[3],c->argv[4],REDIS_HEAD);
|
pushxGenericCommand(c,c->argv[3],c->argv[4],LIST_HEAD);
|
||||||
} else {
|
} else {
|
||||||
addReply(c,shared.syntaxerr);
|
addReply(c,shared.syntaxerr);
|
||||||
}
|
}
|
||||||
@ -325,7 +325,7 @@ void lindexCommand(client *c) {
|
|||||||
addReply(c,shared.nullbulk);
|
addReply(c,shared.nullbulk);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,11 +347,11 @@ void lsetCommand(client *c) {
|
|||||||
} else {
|
} else {
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"lset",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,"lset",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,13 +363,13 @@ void popGenericCommand(client *c, int where) {
|
|||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
addReply(c,shared.nullbulk);
|
addReply(c,shared.nullbulk);
|
||||||
} else {
|
} else {
|
||||||
char *event = (where == REDIS_HEAD) ? "lpop" : "rpop";
|
char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
|
||||||
|
|
||||||
addReplyBulk(c,value);
|
addReplyBulk(c,value);
|
||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,event,c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);
|
||||||
if (listTypeLength(o) == 0) {
|
if (listTypeLength(o) == 0) {
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",
|
||||||
c->argv[1],c->db->id);
|
c->argv[1],c->db->id);
|
||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
}
|
}
|
||||||
@ -379,11 +379,11 @@ void popGenericCommand(client *c, int where) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void lpopCommand(client *c) {
|
void lpopCommand(client *c) {
|
||||||
popGenericCommand(c,REDIS_HEAD);
|
popGenericCommand(c,LIST_HEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpopCommand(client *c) {
|
void rpopCommand(client *c) {
|
||||||
popGenericCommand(c,REDIS_TAIL);
|
popGenericCommand(c,LIST_TAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lrangeCommand(client *c) {
|
void lrangeCommand(client *c) {
|
||||||
@ -414,7 +414,7 @@ void lrangeCommand(client *c) {
|
|||||||
/* Return the result in form of a multi-bulk reply */
|
/* Return the result in form of a multi-bulk reply */
|
||||||
addReplyMultiBulkLen(c,rangelen);
|
addReplyMultiBulkLen(c,rangelen);
|
||||||
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
listTypeIterator *iter = listTypeInitIterator(o, start, REDIS_TAIL);
|
listTypeIterator *iter = listTypeInitIterator(o, start, LIST_TAIL);
|
||||||
|
|
||||||
while(rangelen--) {
|
while(rangelen--) {
|
||||||
listTypeEntry entry;
|
listTypeEntry entry;
|
||||||
@ -428,7 +428,7 @@ void lrangeCommand(client *c) {
|
|||||||
}
|
}
|
||||||
listTypeReleaseIterator(iter);
|
listTypeReleaseIterator(iter);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("List encoding is not QUICKLIST!");
|
serverPanic("List encoding is not QUICKLIST!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,13 +465,13 @@ void ltrimCommand(client *c) {
|
|||||||
quicklistDelRange(o->ptr,0,ltrim);
|
quicklistDelRange(o->ptr,0,ltrim);
|
||||||
quicklistDelRange(o->ptr,-rtrim,rtrim);
|
quicklistDelRange(o->ptr,-rtrim,rtrim);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"ltrim",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,"ltrim",c->argv[1],c->db->id);
|
||||||
if (listTypeLength(o) == 0) {
|
if (listTypeLength(o) == 0) {
|
||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
@ -493,9 +493,9 @@ void lremCommand(client *c) {
|
|||||||
listTypeIterator *li;
|
listTypeIterator *li;
|
||||||
if (toremove < 0) {
|
if (toremove < 0) {
|
||||||
toremove = -toremove;
|
toremove = -toremove;
|
||||||
li = listTypeInitIterator(subject,-1,REDIS_HEAD);
|
li = listTypeInitIterator(subject,-1,LIST_HEAD);
|
||||||
} else {
|
} else {
|
||||||
li = listTypeInitIterator(subject,0,REDIS_TAIL);
|
li = listTypeInitIterator(subject,0,LIST_TAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
listTypeEntry entry;
|
listTypeEntry entry;
|
||||||
@ -542,8 +542,8 @@ void rpoplpushHandlePush(client *c, robj *dstkey, robj *dstobj, robj *value) {
|
|||||||
dbAdd(c->db,dstkey,dstobj);
|
dbAdd(c->db,dstkey,dstobj);
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,dstkey);
|
signalModifiedKey(c->db,dstkey);
|
||||||
listTypePush(dstobj,value,REDIS_HEAD);
|
listTypePush(dstobj,value,LIST_HEAD);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"lpush",dstkey,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,"lpush",dstkey,c->db->id);
|
||||||
/* Always send the pushed value to the client. */
|
/* Always send the pushed value to the client. */
|
||||||
addReplyBulk(c,value);
|
addReplyBulk(c,value);
|
||||||
}
|
}
|
||||||
@ -562,7 +562,7 @@ void rpoplpushCommand(client *c) {
|
|||||||
robj *touchedkey = c->argv[1];
|
robj *touchedkey = c->argv[1];
|
||||||
|
|
||||||
if (dobj && checkType(c,dobj,OBJ_LIST)) return;
|
if (dobj && checkType(c,dobj,OBJ_LIST)) return;
|
||||||
value = listTypePop(sobj,REDIS_TAIL);
|
value = listTypePop(sobj,LIST_TAIL);
|
||||||
/* We saved touched key, and protect it, since rpoplpushHandlePush
|
/* We saved touched key, and protect it, since rpoplpushHandlePush
|
||||||
* may change the client command argument vector (it does not
|
* may change the client command argument vector (it does not
|
||||||
* currently). */
|
* currently). */
|
||||||
@ -573,10 +573,10 @@ void rpoplpushCommand(client *c) {
|
|||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
|
|
||||||
/* Delete the source list when it is empty */
|
/* Delete the source list when it is empty */
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"rpop",touchedkey,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,"rpop",touchedkey,c->db->id);
|
||||||
if (listTypeLength(sobj) == 0) {
|
if (listTypeLength(sobj) == 0) {
|
||||||
dbDelete(c->db,touchedkey);
|
dbDelete(c->db,touchedkey);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",
|
||||||
touchedkey,c->db->id);
|
touchedkey,c->db->id);
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,touchedkey);
|
signalModifiedKey(c->db,touchedkey);
|
||||||
@ -638,7 +638,7 @@ void blockForKeys(client *c, robj **keys, int numkeys, mstime_t timeout, robj *t
|
|||||||
}
|
}
|
||||||
listAddNodeTail(l,c);
|
listAddNodeTail(l,c);
|
||||||
}
|
}
|
||||||
blockClient(c,REDIS_BLOCKED_LIST);
|
blockClient(c,BLOCKED_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unblock a client that's waiting in a blocking operation such as BLPOP.
|
/* Unblock a client that's waiting in a blocking operation such as BLPOP.
|
||||||
@ -712,7 +712,7 @@ void signalListAsReady(redisDb *db, robj *key) {
|
|||||||
* 3) Propagate the resulting BRPOP, BLPOP and additional LPUSH if any into
|
* 3) Propagate the resulting BRPOP, BLPOP and additional LPUSH if any into
|
||||||
* the AOF and replication channel.
|
* the AOF and replication channel.
|
||||||
*
|
*
|
||||||
* The argument 'where' is REDIS_TAIL or REDIS_HEAD, and indicates if the
|
* The argument 'where' is LIST_TAIL or LIST_HEAD, and indicates if the
|
||||||
* 'value' element was popped fron the head (BLPOP) or tail (BRPOP) so that
|
* 'value' element was popped fron the head (BLPOP) or tail (BRPOP) so that
|
||||||
* we can propagate the command properly.
|
* we can propagate the command properly.
|
||||||
*
|
*
|
||||||
@ -727,12 +727,12 @@ int serveClientBlockedOnList(client *receiver, robj *key, robj *dstkey, redisDb
|
|||||||
|
|
||||||
if (dstkey == NULL) {
|
if (dstkey == NULL) {
|
||||||
/* Propagate the [LR]POP operation. */
|
/* Propagate the [LR]POP operation. */
|
||||||
argv[0] = (where == REDIS_HEAD) ? shared.lpop :
|
argv[0] = (where == LIST_HEAD) ? shared.lpop :
|
||||||
shared.rpop;
|
shared.rpop;
|
||||||
argv[1] = key;
|
argv[1] = key;
|
||||||
propagate((where == REDIS_HEAD) ?
|
propagate((where == LIST_HEAD) ?
|
||||||
server.lpopCommand : server.rpopCommand,
|
server.lpopCommand : server.rpopCommand,
|
||||||
db->id,argv,2,REDIS_PROPAGATE_AOF|REDIS_PROPAGATE_REPL);
|
db->id,argv,2,PROPAGATE_AOF|PROPAGATE_REPL);
|
||||||
|
|
||||||
/* BRPOP/BLPOP */
|
/* BRPOP/BLPOP */
|
||||||
addReplyMultiBulkLen(receiver,2);
|
addReplyMultiBulkLen(receiver,2);
|
||||||
@ -750,8 +750,8 @@ int serveClientBlockedOnList(client *receiver, robj *key, robj *dstkey, redisDb
|
|||||||
argv[1] = key;
|
argv[1] = key;
|
||||||
propagate(server.rpopCommand,
|
propagate(server.rpopCommand,
|
||||||
db->id,argv,2,
|
db->id,argv,2,
|
||||||
REDIS_PROPAGATE_AOF|
|
PROPAGATE_AOF|
|
||||||
REDIS_PROPAGATE_REPL);
|
PROPAGATE_REPL);
|
||||||
rpoplpushHandlePush(receiver,dstkey,dstobj,
|
rpoplpushHandlePush(receiver,dstkey,dstobj,
|
||||||
value);
|
value);
|
||||||
/* Propagate the LPUSH operation. */
|
/* Propagate the LPUSH operation. */
|
||||||
@ -760,8 +760,8 @@ int serveClientBlockedOnList(client *receiver, robj *key, robj *dstkey, redisDb
|
|||||||
argv[2] = value;
|
argv[2] = value;
|
||||||
propagate(server.lpushCommand,
|
propagate(server.lpushCommand,
|
||||||
db->id,argv,3,
|
db->id,argv,3,
|
||||||
REDIS_PROPAGATE_AOF|
|
PROPAGATE_AOF|
|
||||||
REDIS_PROPAGATE_REPL);
|
PROPAGATE_REPL);
|
||||||
} else {
|
} else {
|
||||||
/* BRPOPLPUSH failed because of wrong
|
/* BRPOPLPUSH failed because of wrong
|
||||||
* destination type. */
|
* destination type. */
|
||||||
@ -819,7 +819,7 @@ void handleClientsBlockedOnLists(void) {
|
|||||||
robj *dstkey = receiver->bpop.target;
|
robj *dstkey = receiver->bpop.target;
|
||||||
int where = (receiver->lastcmd &&
|
int where = (receiver->lastcmd &&
|
||||||
receiver->lastcmd->proc == blpopCommand) ?
|
receiver->lastcmd->proc == blpopCommand) ?
|
||||||
REDIS_HEAD : REDIS_TAIL;
|
LIST_HEAD : LIST_TAIL;
|
||||||
robj *value = listTypePop(o,where);
|
robj *value = listTypePop(o,where);
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
@ -880,7 +880,7 @@ void blockingPopGenericCommand(client *c, int where) {
|
|||||||
} else {
|
} else {
|
||||||
if (listTypeLength(o) != 0) {
|
if (listTypeLength(o) != 0) {
|
||||||
/* Non empty list, this is like a non normal [LR]POP. */
|
/* Non empty list, this is like a non normal [LR]POP. */
|
||||||
char *event = (where == REDIS_HEAD) ? "lpop" : "rpop";
|
char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
|
||||||
robj *value = listTypePop(o,where);
|
robj *value = listTypePop(o,where);
|
||||||
serverAssert(value != NULL);
|
serverAssert(value != NULL);
|
||||||
|
|
||||||
@ -888,11 +888,11 @@ void blockingPopGenericCommand(client *c, int where) {
|
|||||||
addReplyBulk(c,c->argv[j]);
|
addReplyBulk(c,c->argv[j]);
|
||||||
addReplyBulk(c,value);
|
addReplyBulk(c,value);
|
||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,event,
|
notifyKeyspaceEvent(NOTIFY_LIST,event,
|
||||||
c->argv[j],c->db->id);
|
c->argv[j],c->db->id);
|
||||||
if (listTypeLength(o) == 0) {
|
if (listTypeLength(o) == 0) {
|
||||||
dbDelete(c->db,c->argv[j]);
|
dbDelete(c->db,c->argv[j]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",
|
||||||
c->argv[j],c->db->id);
|
c->argv[j],c->db->id);
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,c->argv[j]);
|
signalModifiedKey(c->db,c->argv[j]);
|
||||||
@ -900,7 +900,7 @@ void blockingPopGenericCommand(client *c, int where) {
|
|||||||
|
|
||||||
/* Replicate it as an [LR]POP instead of B[LR]POP. */
|
/* Replicate it as an [LR]POP instead of B[LR]POP. */
|
||||||
rewriteClientCommandVector(c,2,
|
rewriteClientCommandVector(c,2,
|
||||||
(where == REDIS_HEAD) ? shared.lpop : shared.rpop,
|
(where == LIST_HEAD) ? shared.lpop : shared.rpop,
|
||||||
c->argv[j]);
|
c->argv[j]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -910,7 +910,7 @@ void blockingPopGenericCommand(client *c, int where) {
|
|||||||
|
|
||||||
/* If we are inside a MULTI/EXEC and the list is empty the only thing
|
/* If we are inside a MULTI/EXEC and the list is empty the only thing
|
||||||
* we can do is treating it as a timeout (even with timeout 0). */
|
* we can do is treating it as a timeout (even with timeout 0). */
|
||||||
if (c->flags & REDIS_MULTI) {
|
if (c->flags & CLIENT_MULTI) {
|
||||||
addReply(c,shared.nullmultibulk);
|
addReply(c,shared.nullmultibulk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -920,11 +920,11 @@ void blockingPopGenericCommand(client *c, int where) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void blpopCommand(client *c) {
|
void blpopCommand(client *c) {
|
||||||
blockingPopGenericCommand(c,REDIS_HEAD);
|
blockingPopGenericCommand(c,LIST_HEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void brpopCommand(client *c) {
|
void brpopCommand(client *c) {
|
||||||
blockingPopGenericCommand(c,REDIS_TAIL);
|
blockingPopGenericCommand(c,LIST_TAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void brpoplpushCommand(client *c) {
|
void brpoplpushCommand(client *c) {
|
||||||
@ -936,7 +936,7 @@ void brpoplpushCommand(client *c) {
|
|||||||
robj *key = lookupKeyWrite(c->db, c->argv[1]);
|
robj *key = lookupKeyWrite(c->db, c->argv[1]);
|
||||||
|
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
if (c->flags & REDIS_MULTI) {
|
if (c->flags & CLIENT_MULTI) {
|
||||||
/* Blocking against an empty list in a multi state
|
/* Blocking against an empty list in a multi state
|
||||||
* returns immediately. */
|
* returns immediately. */
|
||||||
addReply(c, shared.nullbulk);
|
addReply(c, shared.nullbulk);
|
||||||
|
78
src/t_set.c
78
src/t_set.c
@ -80,7 +80,7 @@ int setTypeAdd(robj *subject, robj *value) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ int setTypeRemove(robj *setobj, robj *value) {
|
|||||||
if (success) return 1;
|
if (success) return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ int setTypeIsMember(robj *subject, robj *value) {
|
|||||||
return intsetFind((intset*)subject->ptr,llval);
|
return intsetFind((intset*)subject->ptr,llval);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ setTypeIterator *setTypeInitIterator(robj *subject) {
|
|||||||
} else if (si->encoding == OBJ_ENCODING_INTSET) {
|
} else if (si->encoding == OBJ_ENCODING_INTSET) {
|
||||||
si->ii = 0;
|
si->ii = 0;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
return si;
|
return si;
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ int setTypeNext(setTypeIterator *si, robj **objele, int64_t *llele) {
|
|||||||
return -1;
|
return -1;
|
||||||
*objele = NULL; /* Not needed. Defensive. */
|
*objele = NULL; /* Not needed. Defensive. */
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Wrong set encoding in setTypeNext");
|
serverPanic("Wrong set encoding in setTypeNext");
|
||||||
}
|
}
|
||||||
return si->encoding;
|
return si->encoding;
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ robj *setTypeNextObject(setTypeIterator *si) {
|
|||||||
incrRefCount(objele);
|
incrRefCount(objele);
|
||||||
return objele;
|
return objele;
|
||||||
default:
|
default:
|
||||||
redisPanic("Unsupported encoding");
|
serverPanic("Unsupported encoding");
|
||||||
}
|
}
|
||||||
return NULL; /* just to suppress warnings */
|
return NULL; /* just to suppress warnings */
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ int setTypeRandomElement(robj *setobj, robj **objele, int64_t *llele) {
|
|||||||
*llele = intsetRandom(setobj->ptr);
|
*llele = intsetRandom(setobj->ptr);
|
||||||
*objele = NULL; /* Not needed. Defensive. */
|
*objele = NULL; /* Not needed. Defensive. */
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
return setobj->encoding;
|
return setobj->encoding;
|
||||||
}
|
}
|
||||||
@ -232,7 +232,7 @@ unsigned long setTypeSize(robj *subject) {
|
|||||||
} else if (subject->encoding == OBJ_ENCODING_INTSET) {
|
} else if (subject->encoding == OBJ_ENCODING_INTSET) {
|
||||||
return intsetLen((intset*)subject->ptr);
|
return intsetLen((intset*)subject->ptr);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ void setTypeConvert(robj *setobj, int enc) {
|
|||||||
zfree(setobj->ptr);
|
zfree(setobj->ptr);
|
||||||
setobj->ptr = d;
|
setobj->ptr = d;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported set conversion");
|
serverPanic("Unsupported set conversion");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ void saddCommand(client *c) {
|
|||||||
}
|
}
|
||||||
if (added) {
|
if (added) {
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_SET,"sadd",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_SET,"sadd",c->argv[1],c->db->id);
|
||||||
}
|
}
|
||||||
server.dirty += added;
|
server.dirty += added;
|
||||||
addReplyLongLong(c,added);
|
addReplyLongLong(c,added);
|
||||||
@ -315,9 +315,9 @@ void sremCommand(client *c) {
|
|||||||
}
|
}
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_SET,"srem",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_SET,"srem",c->argv[1],c->db->id);
|
||||||
if (keyremoved)
|
if (keyremoved)
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],
|
||||||
c->db->id);
|
c->db->id);
|
||||||
server.dirty += deleted;
|
server.dirty += deleted;
|
||||||
}
|
}
|
||||||
@ -352,12 +352,12 @@ void smoveCommand(client *c) {
|
|||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_SET,"srem",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_SET,"srem",c->argv[1],c->db->id);
|
||||||
|
|
||||||
/* Remove the src set from the database when empty */
|
/* Remove the src set from the database when empty */
|
||||||
if (setTypeSize(srcset) == 0) {
|
if (setTypeSize(srcset) == 0) {
|
||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
signalModifiedKey(c->db,c->argv[2]);
|
signalModifiedKey(c->db,c->argv[2]);
|
||||||
@ -372,7 +372,7 @@ void smoveCommand(client *c) {
|
|||||||
/* An extra key has changed when ele was successfully added to dstset */
|
/* An extra key has changed when ele was successfully added to dstset */
|
||||||
if (setTypeAdd(dstset,ele)) {
|
if (setTypeAdd(dstset,ele)) {
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_SET,"sadd",c->argv[2],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_SET,"sadd",c->argv[2],c->db->id);
|
||||||
}
|
}
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
}
|
}
|
||||||
@ -436,7 +436,7 @@ void spopWithCountCommand(client *c) {
|
|||||||
size = setTypeSize(set);
|
size = setTypeSize(set);
|
||||||
|
|
||||||
/* Generate an SPOP keyspace notification */
|
/* Generate an SPOP keyspace notification */
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_SET,"spop",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_SET,"spop",c->argv[1],c->db->id);
|
||||||
server.dirty += count;
|
server.dirty += count;
|
||||||
|
|
||||||
/* CASE 1:
|
/* CASE 1:
|
||||||
@ -444,11 +444,11 @@ void spopWithCountCommand(client *c) {
|
|||||||
* the number of elements inside the set: simply return the whole set. */
|
* the number of elements inside the set: simply return the whole set. */
|
||||||
if (count >= size) {
|
if (count >= size) {
|
||||||
/* We just return the entire set */
|
/* We just return the entire set */
|
||||||
sunionDiffGenericCommand(c,c->argv+1,1,NULL,REDIS_OP_UNION);
|
sunionDiffGenericCommand(c,c->argv+1,1,NULL,SET_OP_UNION);
|
||||||
|
|
||||||
/* Delete the set as it is now empty */
|
/* Delete the set as it is now empty */
|
||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
|
||||||
|
|
||||||
/* Propagate this command as an DEL operation */
|
/* Propagate this command as an DEL operation */
|
||||||
rewriteClientCommandVector(c,2,shared.del,c->argv[1]);
|
rewriteClientCommandVector(c,2,shared.del,c->argv[1]);
|
||||||
@ -494,7 +494,7 @@ void spopWithCountCommand(client *c) {
|
|||||||
/* Replicate/AOF this command as an SREM operation */
|
/* Replicate/AOF this command as an SREM operation */
|
||||||
propargv[2] = objele;
|
propargv[2] = objele;
|
||||||
alsoPropagate(server.sremCommand,c->db->id,propargv,3,
|
alsoPropagate(server.sremCommand,c->db->id,propargv,3,
|
||||||
REDIS_PROPAGATE_AOF|REDIS_PROPAGATE_REPL);
|
PROPAGATE_AOF|PROPAGATE_REPL);
|
||||||
decrRefCount(objele);
|
decrRefCount(objele);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -540,7 +540,7 @@ void spopWithCountCommand(client *c) {
|
|||||||
/* Replicate/AOF this command as an SREM operation */
|
/* Replicate/AOF this command as an SREM operation */
|
||||||
propargv[2] = objele;
|
propargv[2] = objele;
|
||||||
alsoPropagate(server.sremCommand,c->db->id,propargv,3,
|
alsoPropagate(server.sremCommand,c->db->id,propargv,3,
|
||||||
REDIS_PROPAGATE_AOF|REDIS_PROPAGATE_REPL);
|
PROPAGATE_AOF|PROPAGATE_REPL);
|
||||||
|
|
||||||
decrRefCount(objele);
|
decrRefCount(objele);
|
||||||
}
|
}
|
||||||
@ -586,7 +586,7 @@ void spopCommand(client *c) {
|
|||||||
setTypeRemove(set,ele);
|
setTypeRemove(set,ele);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_SET,"spop",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_SET,"spop",c->argv[1],c->db->id);
|
||||||
|
|
||||||
/* Replicate/AOF this command as an SREM operation */
|
/* Replicate/AOF this command as an SREM operation */
|
||||||
aux = createStringObject("SREM",4);
|
aux = createStringObject("SREM",4);
|
||||||
@ -600,7 +600,7 @@ void spopCommand(client *c) {
|
|||||||
/* Delete the set if it's empty */
|
/* Delete the set if it's empty */
|
||||||
if (setTypeSize(set) == 0) {
|
if (setTypeSize(set) == 0) {
|
||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set has been modified */
|
/* Set has been modified */
|
||||||
@ -667,7 +667,7 @@ void srandmemberWithCountCommand(client *c) {
|
|||||||
* The number of requested elements is greater than the number of
|
* The number of requested elements is greater than the number of
|
||||||
* elements inside the set: simply return the whole set. */
|
* elements inside the set: simply return the whole set. */
|
||||||
if (count >= size) {
|
if (count >= size) {
|
||||||
sunionDiffGenericCommand(c,c->argv+1,1,NULL,REDIS_OP_UNION);
|
sunionDiffGenericCommand(c,c->argv+1,1,NULL,SET_OP_UNION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -904,13 +904,13 @@ void sinterGenericCommand(client *c, robj **setkeys,
|
|||||||
if (setTypeSize(dstset) > 0) {
|
if (setTypeSize(dstset) > 0) {
|
||||||
dbAdd(c->db,dstkey,dstset);
|
dbAdd(c->db,dstkey,dstset);
|
||||||
addReplyLongLong(c,setTypeSize(dstset));
|
addReplyLongLong(c,setTypeSize(dstset));
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_SET,"sinterstore",
|
notifyKeyspaceEvent(NOTIFY_SET,"sinterstore",
|
||||||
dstkey,c->db->id);
|
dstkey,c->db->id);
|
||||||
} else {
|
} else {
|
||||||
decrRefCount(dstset);
|
decrRefCount(dstset);
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
if (deleted)
|
if (deleted)
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",
|
||||||
dstkey,c->db->id);
|
dstkey,c->db->id);
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,dstkey);
|
signalModifiedKey(c->db,dstkey);
|
||||||
@ -929,9 +929,9 @@ void sinterstoreCommand(client *c) {
|
|||||||
sinterGenericCommand(c,c->argv+2,c->argc-2,c->argv[1]);
|
sinterGenericCommand(c,c->argv+2,c->argc-2,c->argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REDIS_OP_UNION 0
|
#define SET_OP_UNION 0
|
||||||
#define REDIS_OP_DIFF 1
|
#define SET_OP_DIFF 1
|
||||||
#define REDIS_OP_INTER 2
|
#define SET_OP_INTER 2
|
||||||
|
|
||||||
void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
||||||
robj *dstkey, int op) {
|
robj *dstkey, int op) {
|
||||||
@ -965,7 +965,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
|||||||
* the sets.
|
* the sets.
|
||||||
*
|
*
|
||||||
* We compute what is the best bet with the current input here. */
|
* We compute what is the best bet with the current input here. */
|
||||||
if (op == REDIS_OP_DIFF && sets[0]) {
|
if (op == SET_OP_DIFF && sets[0]) {
|
||||||
long long algo_one_work = 0, algo_two_work = 0;
|
long long algo_one_work = 0, algo_two_work = 0;
|
||||||
|
|
||||||
for (j = 0; j < setnum; j++) {
|
for (j = 0; j < setnum; j++) {
|
||||||
@ -994,7 +994,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
|||||||
* this set object will be the resulting object to set into the target key*/
|
* this set object will be the resulting object to set into the target key*/
|
||||||
dstset = createIntsetObject();
|
dstset = createIntsetObject();
|
||||||
|
|
||||||
if (op == REDIS_OP_UNION) {
|
if (op == SET_OP_UNION) {
|
||||||
/* Union is trivial, just add every element of every set to the
|
/* Union is trivial, just add every element of every set to the
|
||||||
* temporary set. */
|
* temporary set. */
|
||||||
for (j = 0; j < setnum; j++) {
|
for (j = 0; j < setnum; j++) {
|
||||||
@ -1007,7 +1007,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
|||||||
}
|
}
|
||||||
setTypeReleaseIterator(si);
|
setTypeReleaseIterator(si);
|
||||||
}
|
}
|
||||||
} else if (op == REDIS_OP_DIFF && sets[0] && diff_algo == 1) {
|
} else if (op == SET_OP_DIFF && sets[0] && diff_algo == 1) {
|
||||||
/* DIFF Algorithm 1:
|
/* DIFF Algorithm 1:
|
||||||
*
|
*
|
||||||
* We perform the diff by iterating all the elements of the first set,
|
* We perform the diff by iterating all the elements of the first set,
|
||||||
@ -1031,7 +1031,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
|||||||
decrRefCount(ele);
|
decrRefCount(ele);
|
||||||
}
|
}
|
||||||
setTypeReleaseIterator(si);
|
setTypeReleaseIterator(si);
|
||||||
} else if (op == REDIS_OP_DIFF && sets[0] && diff_algo == 2) {
|
} else if (op == SET_OP_DIFF && sets[0] && diff_algo == 2) {
|
||||||
/* DIFF Algorithm 2:
|
/* DIFF Algorithm 2:
|
||||||
*
|
*
|
||||||
* Add all the elements of the first set to the auxiliary set.
|
* Add all the elements of the first set to the auxiliary set.
|
||||||
@ -1076,14 +1076,14 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
|||||||
if (setTypeSize(dstset) > 0) {
|
if (setTypeSize(dstset) > 0) {
|
||||||
dbAdd(c->db,dstkey,dstset);
|
dbAdd(c->db,dstkey,dstset);
|
||||||
addReplyLongLong(c,setTypeSize(dstset));
|
addReplyLongLong(c,setTypeSize(dstset));
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_SET,
|
notifyKeyspaceEvent(NOTIFY_SET,
|
||||||
op == REDIS_OP_UNION ? "sunionstore" : "sdiffstore",
|
op == SET_OP_UNION ? "sunionstore" : "sdiffstore",
|
||||||
dstkey,c->db->id);
|
dstkey,c->db->id);
|
||||||
} else {
|
} else {
|
||||||
decrRefCount(dstset);
|
decrRefCount(dstset);
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
if (deleted)
|
if (deleted)
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",
|
||||||
dstkey,c->db->id);
|
dstkey,c->db->id);
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,dstkey);
|
signalModifiedKey(c->db,dstkey);
|
||||||
@ -1093,19 +1093,19 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sunionCommand(client *c) {
|
void sunionCommand(client *c) {
|
||||||
sunionDiffGenericCommand(c,c->argv+1,c->argc-1,NULL,REDIS_OP_UNION);
|
sunionDiffGenericCommand(c,c->argv+1,c->argc-1,NULL,SET_OP_UNION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sunionstoreCommand(client *c) {
|
void sunionstoreCommand(client *c) {
|
||||||
sunionDiffGenericCommand(c,c->argv+2,c->argc-2,c->argv[1],REDIS_OP_UNION);
|
sunionDiffGenericCommand(c,c->argv+2,c->argc-2,c->argv[1],SET_OP_UNION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdiffCommand(client *c) {
|
void sdiffCommand(client *c) {
|
||||||
sunionDiffGenericCommand(c,c->argv+1,c->argc-1,NULL,REDIS_OP_DIFF);
|
sunionDiffGenericCommand(c,c->argv+1,c->argc-1,NULL,SET_OP_DIFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdiffstoreCommand(client *c) {
|
void sdiffstoreCommand(client *c) {
|
||||||
sunionDiffGenericCommand(c,c->argv+2,c->argc-2,c->argv[1],REDIS_OP_DIFF);
|
sunionDiffGenericCommand(c,c->argv+2,c->argc-2,c->argv[1],SET_OP_DIFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sscanCommand(client *c) {
|
void sscanCommand(client *c) {
|
||||||
|
@ -86,8 +86,8 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire,
|
|||||||
setKey(c->db,key,val);
|
setKey(c->db,key,val);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
if (expire) setExpire(c->db,key,mstime()+milliseconds);
|
if (expire) setExpire(c->db,key,mstime()+milliseconds);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"set",key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"set",key,c->db->id);
|
||||||
if (expire) notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,
|
if (expire) notifyKeyspaceEvent(NOTIFY_GENERIC,
|
||||||
"expire",key,c->db->id);
|
"expire",key,c->db->id);
|
||||||
addReply(c, ok_reply ? ok_reply : shared.ok);
|
addReply(c, ok_reply ? ok_reply : shared.ok);
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ void getsetCommand(client *c) {
|
|||||||
if (getGenericCommand(c) == C_ERR) return;
|
if (getGenericCommand(c) == C_ERR) return;
|
||||||
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
||||||
setKey(c->db,c->argv[1],c->argv[2]);
|
setKey(c->db,c->argv[1],c->argv[2]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"set",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"set",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ void setrangeCommand(client *c) {
|
|||||||
o->ptr = sdsgrowzero(o->ptr,offset+sdslen(value));
|
o->ptr = sdsgrowzero(o->ptr,offset+sdslen(value));
|
||||||
memcpy((char*)o->ptr+offset,value,sdslen(value));
|
memcpy((char*)o->ptr+offset,value,sdslen(value));
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,
|
notifyKeyspaceEvent(NOTIFY_STRING,
|
||||||
"setrange",c->argv[1],c->db->id);
|
"setrange",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
@ -320,7 +320,7 @@ void msetGenericCommand(client *c, int nx) {
|
|||||||
for (j = 1; j < c->argc; j += 2) {
|
for (j = 1; j < c->argc; j += 2) {
|
||||||
c->argv[j+1] = tryObjectEncoding(c->argv[j+1]);
|
c->argv[j+1] = tryObjectEncoding(c->argv[j+1]);
|
||||||
setKey(c->db,c->argv[j],c->argv[j+1]);
|
setKey(c->db,c->argv[j],c->argv[j+1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"set",c->argv[j],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"set",c->argv[j],c->db->id);
|
||||||
}
|
}
|
||||||
server.dirty += (c->argc-1)/2;
|
server.dirty += (c->argc-1)/2;
|
||||||
addReply(c, nx ? shared.cone : shared.ok);
|
addReply(c, nx ? shared.cone : shared.ok);
|
||||||
@ -351,7 +351,7 @@ void incrDecrCommand(client *c, long long incr) {
|
|||||||
value += incr;
|
value += incr;
|
||||||
|
|
||||||
if (o && o->refcount == 1 && o->encoding == OBJ_ENCODING_INT &&
|
if (o && o->refcount == 1 && o->encoding == OBJ_ENCODING_INT &&
|
||||||
(value < 0 || value >= REDIS_SHARED_INTEGERS) &&
|
(value < 0 || value >= OBJ_SHARED_INTEGERS) &&
|
||||||
value >= LONG_MIN && value <= LONG_MAX)
|
value >= LONG_MIN && value <= LONG_MAX)
|
||||||
{
|
{
|
||||||
new = o;
|
new = o;
|
||||||
@ -365,7 +365,7 @@ void incrDecrCommand(client *c, long long incr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"incrby",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"incrby",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,shared.colon);
|
addReply(c,shared.colon);
|
||||||
addReply(c,new);
|
addReply(c,new);
|
||||||
@ -415,7 +415,7 @@ void incrbyfloatCommand(client *c) {
|
|||||||
else
|
else
|
||||||
dbAdd(c->db,c->argv[1],new);
|
dbAdd(c->db,c->argv[1],new);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"incrbyfloat",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"incrbyfloat",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReplyBulk(c,new);
|
addReplyBulk(c,new);
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ void appendCommand(client *c) {
|
|||||||
totlen = sdslen(o->ptr);
|
totlen = sdslen(o->ptr);
|
||||||
}
|
}
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"append",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"append",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReplyLongLong(c,totlen);
|
addReplyLongLong(c,totlen);
|
||||||
}
|
}
|
||||||
|
96
src/t_zset.c
96
src/t_zset.c
@ -1085,7 +1085,7 @@ unsigned int zsetLength(robj *zobj) {
|
|||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
length = ((zset*)zobj->ptr)->zsl->length;
|
length = ((zset*)zobj->ptr)->zsl->length;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
@ -1105,7 +1105,7 @@ void zsetConvert(robj *zobj, int encoding) {
|
|||||||
long long vlong;
|
long long vlong;
|
||||||
|
|
||||||
if (encoding != OBJ_ENCODING_SKIPLIST)
|
if (encoding != OBJ_ENCODING_SKIPLIST)
|
||||||
redisPanic("Unknown target encoding");
|
serverPanic("Unknown target encoding");
|
||||||
|
|
||||||
zs = zmalloc(sizeof(*zs));
|
zs = zmalloc(sizeof(*zs));
|
||||||
zs->dict = dictCreate(&zsetDictType,NULL);
|
zs->dict = dictCreate(&zsetDictType,NULL);
|
||||||
@ -1138,7 +1138,7 @@ void zsetConvert(robj *zobj, int encoding) {
|
|||||||
unsigned char *zl = ziplistNew();
|
unsigned char *zl = ziplistNew();
|
||||||
|
|
||||||
if (encoding != OBJ_ENCODING_ZIPLIST)
|
if (encoding != OBJ_ENCODING_ZIPLIST)
|
||||||
redisPanic("Unknown target encoding");
|
serverPanic("Unknown target encoding");
|
||||||
|
|
||||||
/* Approach similar to zslFree(), since we want to free the skiplist at
|
/* Approach similar to zslFree(), since we want to free the skiplist at
|
||||||
* the same time as creating the ziplist. */
|
* the same time as creating the ziplist. */
|
||||||
@ -1162,7 +1162,7 @@ void zsetConvert(robj *zobj, int encoding) {
|
|||||||
zobj->ptr = zl;
|
zobj->ptr = zl;
|
||||||
zobj->encoding = OBJ_ENCODING_ZIPLIST;
|
zobj->encoding = OBJ_ENCODING_ZIPLIST;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1181,7 +1181,7 @@ int zsetScore(robj *zobj, robj *member, double *score) {
|
|||||||
if (de == NULL) return C_ERR;
|
if (de == NULL) return C_ERR;
|
||||||
*score = *(double*)dictGetVal(de);
|
*score = *(double*)dictGetVal(de);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
return C_OK;
|
return C_OK;
|
||||||
}
|
}
|
||||||
@ -1365,7 +1365,7 @@ void zaddGenericCommand(client *c, int flags) {
|
|||||||
processed++;
|
processed++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1383,7 +1383,7 @@ cleanup:
|
|||||||
zfree(scores);
|
zfree(scores);
|
||||||
if (added || updated) {
|
if (added || updated) {
|
||||||
signalModifiedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_ZSET,
|
notifyKeyspaceEvent(NOTIFY_ZSET,
|
||||||
incr ? "zincr" : "zadd", key, c->db->id);
|
incr ? "zincr" : "zadd", key, c->db->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1443,13 +1443,13 @@ void zremCommand(client *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_ZSET,"zrem",key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_ZSET,"zrem",key,c->db->id);
|
||||||
if (keyremoved)
|
if (keyremoved)
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",key,c->db->id);
|
||||||
signalModifiedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
server.dirty += deleted;
|
server.dirty += deleted;
|
||||||
}
|
}
|
||||||
@ -1542,16 +1542,16 @@ void zremrangeGenericCommand(client *c, int rangetype) {
|
|||||||
keyremoved = 1;
|
keyremoved = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 4: Notifications and reply. */
|
/* Step 4: Notifications and reply. */
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
char *event[3] = {"zremrangebyrank","zremrangebyscore","zremrangebylex"};
|
char *event[3] = {"zremrangebyrank","zremrangebyscore","zremrangebylex"};
|
||||||
signalModifiedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_ZSET,event[rangetype],key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_ZSET,event[rangetype],key,c->db->id);
|
||||||
if (keyremoved)
|
if (keyremoved)
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",key,c->db->id);
|
||||||
}
|
}
|
||||||
server.dirty += deleted;
|
server.dirty += deleted;
|
||||||
addReplyLongLong(c,deleted);
|
addReplyLongLong(c,deleted);
|
||||||
@ -1645,7 +1645,7 @@ void zuiInitIterator(zsetopsrc *op) {
|
|||||||
it->ht.di = dictGetIterator(op->subject->ptr);
|
it->ht.di = dictGetIterator(op->subject->ptr);
|
||||||
it->ht.de = dictNext(it->ht.di);
|
it->ht.de = dictNext(it->ht.di);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
} else if (op->type == OBJ_ZSET) {
|
} else if (op->type == OBJ_ZSET) {
|
||||||
iterzset *it = &op->iter.zset;
|
iterzset *it = &op->iter.zset;
|
||||||
@ -1660,10 +1660,10 @@ void zuiInitIterator(zsetopsrc *op) {
|
|||||||
it->sl.zs = op->subject->ptr;
|
it->sl.zs = op->subject->ptr;
|
||||||
it->sl.node = it->sl.zs->zsl->header->level[0].forward;
|
it->sl.node = it->sl.zs->zsl->header->level[0].forward;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported type");
|
serverPanic("Unsupported type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1674,23 +1674,23 @@ void zuiClearIterator(zsetopsrc *op) {
|
|||||||
if (op->type == OBJ_SET) {
|
if (op->type == OBJ_SET) {
|
||||||
iterset *it = &op->iter.set;
|
iterset *it = &op->iter.set;
|
||||||
if (op->encoding == OBJ_ENCODING_INTSET) {
|
if (op->encoding == OBJ_ENCODING_INTSET) {
|
||||||
REDIS_NOTUSED(it); /* skip */
|
UNUSED(it); /* skip */
|
||||||
} else if (op->encoding == OBJ_ENCODING_HT) {
|
} else if (op->encoding == OBJ_ENCODING_HT) {
|
||||||
dictReleaseIterator(it->ht.di);
|
dictReleaseIterator(it->ht.di);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
} else if (op->type == OBJ_ZSET) {
|
} else if (op->type == OBJ_ZSET) {
|
||||||
iterzset *it = &op->iter.zset;
|
iterzset *it = &op->iter.zset;
|
||||||
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
REDIS_NOTUSED(it); /* skip */
|
UNUSED(it); /* skip */
|
||||||
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
REDIS_NOTUSED(it); /* skip */
|
UNUSED(it); /* skip */
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported type");
|
serverPanic("Unsupported type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1705,7 +1705,7 @@ int zuiLength(zsetopsrc *op) {
|
|||||||
dict *ht = op->subject->ptr;
|
dict *ht = op->subject->ptr;
|
||||||
return dictSize(ht);
|
return dictSize(ht);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
} else if (op->type == OBJ_ZSET) {
|
} else if (op->type == OBJ_ZSET) {
|
||||||
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
@ -1714,10 +1714,10 @@ int zuiLength(zsetopsrc *op) {
|
|||||||
zset *zs = op->subject->ptr;
|
zset *zs = op->subject->ptr;
|
||||||
return zs->zsl->length;
|
return zs->zsl->length;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported type");
|
serverPanic("Unsupported type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1754,7 +1754,7 @@ int zuiNext(zsetopsrc *op, zsetopval *val) {
|
|||||||
/* Move to next element. */
|
/* Move to next element. */
|
||||||
it->ht.de = dictNext(it->ht.di);
|
it->ht.de = dictNext(it->ht.di);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
} else if (op->type == OBJ_ZSET) {
|
} else if (op->type == OBJ_ZSET) {
|
||||||
iterzset *it = &op->iter.zset;
|
iterzset *it = &op->iter.zset;
|
||||||
@ -1776,10 +1776,10 @@ int zuiNext(zsetopsrc *op, zsetopval *val) {
|
|||||||
/* Move to next element. */
|
/* Move to next element. */
|
||||||
it->sl.node = it->sl.node->level[0].forward;
|
it->sl.node = it->sl.node->level[0].forward;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported type");
|
serverPanic("Unsupported type");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1796,7 +1796,7 @@ int zuiLongLongFromValue(zsetopval *val) {
|
|||||||
if (string2ll(val->ele->ptr,sdslen(val->ele->ptr),&val->ell))
|
if (string2ll(val->ele->ptr,sdslen(val->ele->ptr),&val->ell))
|
||||||
val->flags |= OPVAL_VALID_LL;
|
val->flags |= OPVAL_VALID_LL;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported element encoding");
|
serverPanic("Unsupported element encoding");
|
||||||
}
|
}
|
||||||
} else if (val->estr != NULL) {
|
} else if (val->estr != NULL) {
|
||||||
if (string2ll((char*)val->estr,val->elen,&val->ell))
|
if (string2ll((char*)val->estr,val->elen,&val->ell))
|
||||||
@ -1831,7 +1831,7 @@ int zuiBufferFromValue(zsetopval *val) {
|
|||||||
val->elen = sdslen(val->ele->ptr);
|
val->elen = sdslen(val->ele->ptr);
|
||||||
val->estr = val->ele->ptr;
|
val->estr = val->ele->ptr;
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported element encoding");
|
serverPanic("Unsupported element encoding");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val->elen = ll2string((char*)val->_buf,sizeof(val->_buf),val->ell);
|
val->elen = ll2string((char*)val->_buf,sizeof(val->_buf),val->ell);
|
||||||
@ -1867,7 +1867,7 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
} else if (op->type == OBJ_ZSET) {
|
} else if (op->type == OBJ_ZSET) {
|
||||||
zuiObjectFromValue(val);
|
zuiObjectFromValue(val);
|
||||||
@ -1889,10 +1889,10 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unsupported type");
|
serverPanic("Unsupported type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1918,7 +1918,7 @@ inline static void zunionInterAggregate(double *target, double val, int aggregat
|
|||||||
*target = val > *target ? val : *target;
|
*target = val > *target ? val : *target;
|
||||||
} else {
|
} else {
|
||||||
/* safety net */
|
/* safety net */
|
||||||
redisPanic("Unknown ZUNION/INTER aggregate type");
|
serverPanic("Unknown ZUNION/INTER aggregate type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2018,7 +2018,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
dstzset = dstobj->ptr;
|
dstzset = dstobj->ptr;
|
||||||
memset(&zval, 0, sizeof(zval));
|
memset(&zval, 0, sizeof(zval));
|
||||||
|
|
||||||
if (op == REDIS_OP_INTER) {
|
if (op == SET_OP_INTER) {
|
||||||
/* Skip everything if the smallest input is empty. */
|
/* Skip everything if the smallest input is empty. */
|
||||||
if (zuiLength(&src[0]) > 0) {
|
if (zuiLength(&src[0]) > 0) {
|
||||||
/* Precondition: as src[0] is non-empty and the inputs are ordered
|
/* Precondition: as src[0] is non-empty and the inputs are ordered
|
||||||
@ -2060,7 +2060,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
}
|
}
|
||||||
zuiClearIterator(&src[0]);
|
zuiClearIterator(&src[0]);
|
||||||
}
|
}
|
||||||
} else if (op == REDIS_OP_UNION) {
|
} else if (op == SET_OP_UNION) {
|
||||||
dict *accumulator = dictCreate(&setDictType,NULL);
|
dict *accumulator = dictCreate(&setDictType,NULL);
|
||||||
dictIterator *di;
|
dictIterator *di;
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
@ -2133,7 +2133,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
/* We can free the accumulator dictionary now. */
|
/* We can free the accumulator dictionary now. */
|
||||||
dictRelease(accumulator);
|
dictRelease(accumulator);
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown operator");
|
serverPanic("Unknown operator");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbDelete(c->db,dstkey)) {
|
if (dbDelete(c->db,dstkey)) {
|
||||||
@ -2150,25 +2150,25 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
dbAdd(c->db,dstkey,dstobj);
|
dbAdd(c->db,dstkey,dstobj);
|
||||||
addReplyLongLong(c,zsetLength(dstobj));
|
addReplyLongLong(c,zsetLength(dstobj));
|
||||||
if (!touched) signalModifiedKey(c->db,dstkey);
|
if (!touched) signalModifiedKey(c->db,dstkey);
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_ZSET,
|
notifyKeyspaceEvent(NOTIFY_ZSET,
|
||||||
(op == REDIS_OP_UNION) ? "zunionstore" : "zinterstore",
|
(op == SET_OP_UNION) ? "zunionstore" : "zinterstore",
|
||||||
dstkey,c->db->id);
|
dstkey,c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
} else {
|
} else {
|
||||||
decrRefCount(dstobj);
|
decrRefCount(dstobj);
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
if (touched)
|
if (touched)
|
||||||
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",dstkey,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",dstkey,c->db->id);
|
||||||
}
|
}
|
||||||
zfree(src);
|
zfree(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zunionstoreCommand(client *c) {
|
void zunionstoreCommand(client *c) {
|
||||||
zunionInterGenericCommand(c,c->argv[1], REDIS_OP_UNION);
|
zunionInterGenericCommand(c,c->argv[1], SET_OP_UNION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zinterstoreCommand(client *c) {
|
void zinterstoreCommand(client *c) {
|
||||||
zunionInterGenericCommand(c,c->argv[1], REDIS_OP_INTER);
|
zunionInterGenericCommand(c,c->argv[1], SET_OP_INTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zrangeGenericCommand(client *c, int reverse) {
|
void zrangeGenericCommand(client *c, int reverse) {
|
||||||
@ -2269,7 +2269,7 @@ void zrangeGenericCommand(client *c, int reverse) {
|
|||||||
ln = reverse ? ln->backward : ln->level[0].forward;
|
ln = reverse ? ln->backward : ln->level[0].forward;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2458,7 +2458,7 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withscores) {
|
if (withscores) {
|
||||||
@ -2547,7 +2547,7 @@ void zcountCommand(client *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
addReplyLongLong(c, count);
|
addReplyLongLong(c, count);
|
||||||
@ -2625,7 +2625,7 @@ void zlexcountCommand(client *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
zslFreeLexRange(&range);
|
zslFreeLexRange(&range);
|
||||||
@ -2802,7 +2802,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
zslFreeLexRange(&range);
|
zslFreeLexRange(&range);
|
||||||
@ -2900,7 +2900,7 @@ void zrankGenericCommand(client *c, int reverse) {
|
|||||||
addReply(c,shared.nullbulk);
|
addReply(c,shared.nullbulk);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redisPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user